Asopitech With · Note app
Evernote Web Clipper with Alopex DB
Evernote Web Clipper saves web pages and articles as notes in Evernote, the note app. What if we rebuilt it with Alopex DB?
Updated: Oct 12, 2026
What the service does
Evernote Web Clipper saves web pages, articles and PDFs as notes. Saved items get tags, go into notebooks, and are found by keyword. The data is page text, URLs, tags and notebooks.
Where the data lives
- SQL tables: clips, notebooks and tags live in tables.
- JSON: details that differ from page to page, such as title, URL and capture time, go in a JSON column.
- Full-text search: a full-text index on the text finds pages by keyword.
- Vectors: text embeddings in a vector column answer questions such as “the article about that inn I saved last year”.
The app captures the page and computes the embeddings.
Deployment
Alopex DB is embedded in the device and desktop apps, with clips in one file on the device. For team sharing, Alopex DB runs as a server with the same SQL.
Why Alopex DB fits
A clip is only useful once it can be found again. Alopex DB handles fixed tables and per-page JSON in the same SQL, and finds clips by keyword and by meaning.
See it in code
Clips and tags live in tables, and you search both by keyword (words in the body) and by meaning (embedding distance). Just the search core.
import alopex
import numpy as np
# 端末のアプリに組み込む想定
db = alopex.Database.open("evernote.alopex")
# クリップ(本文+埋め込み)とタグを持つ。埋め込みはアプリが作る
db.execute_sql("""
CREATE TABLE IF NOT EXISTS clips (
id INTEGER PRIMARY KEY,
title TEXT,
url TEXT,
body TEXT,
embedding VECTOR(4)
)
""")
db.execute_sql("""
CREATE TABLE IF NOT EXISTS clip_tags (
clip_id INTEGER,
tag TEXT
)
""")
# クリップを保存する(ベクトルは説明用の小さな値。実際はモデルの埋め込み)
clips = [
(1, "京都の宿", "https://ex.com/kyoto", "旅行で泊まった宿の記事", [0.9, 0.1, 0.0, 0.0], "旅行"),
(2, "確定申告のやり方", "https://ex.com/tax", "税金の手続きのまとめ", [0.0, 0.0, 0.9, 0.1], "お金"),
]
for cid, title, url, body, emb, tag in clips:
db.execute_sql(
"INSERT INTO clips (id, title, url, body, embedding) VALUES (?, ?, ?, ?, ?)",
[cid, title, url, body, np.array(emb, dtype=np.float32)],
)
db.execute_sql("INSERT INTO clip_tags (clip_id, tag) VALUES (?, ?)", [cid, tag])
# キーワードで探す(本文に語を含む)
for row in db.execute_sql("SELECT title FROM clips WHERE body LIKE ?", ["%宿%"]):
print("keyword:", row["title"])
# 意味で探す(「旅行」に近い埋め込みを上位に)
query = np.array([1.0, 0.0, 0.0, 0.0], dtype=np.float32)
rows = db.execute_sql(
"SELECT title, vector_similarity(embedding, ?, 'cosine') AS score FROM clips ORDER BY score DESC LIMIT 1",
[query],
)
for row in rows:
print("semantic:", round(row["score"], 3), row["title"])Keyword search and embedding-distance search run in the same SQL; you reach a clip by meaning even when you cannot recall the words.
Alopex DB handles fixed tables and per-page JSON in the same SQL, and suits a clipping app well. Take a look at the quickstart first.