Self-hosted AI memory for the links that matter.
Send a link → get AI-searchable memory. Works from Telegram, browser bookmarklet, or any HTTP client. Everything runs on a $5 VPS you control. No subscription. No data sent to third parties.
Quick Start · Features · MCP Integration · Roadmap · Contributing
| Pocket / Raindrop | Readwise | AlManak | |
|---|---|---|---|
| Self-hosted | ❌ | ❌ | ✅ |
| Your data only | ❌ | ❌ | ✅ |
| AI agent (MCP) | ❌ | ❌ | ✅ |
| Semantic search | ❌ | ✅ | ✅ |
| Telegram bot | ❌ | ❌ | ✅ |
| Free forever | ❌ | ❌ | ✅ |
| Open source | ❌ | ❌ | ✅ |
AlManak turns your saved links into a queryable knowledge base that your AI agent (Claude, VS Code Copilot, Hermes, any MCP client) can search in natural language — all without your data leaving your machine.
You find a link ──→ Telegram bot ──┐
anywhere │
Bookmarklet ──┼──→ AlManak (VPS) ──→ MCP ──→ AI agent
API / CSV ──┘ │
└──→ SQLite + Qdrant
- Capture — send a URL to your Telegram bot, click the bookmarklet, or POST to the API
- Enrich — AlManak fetches title, description, content, auto-classifies type & subject, deduplicates
- Index — stored in SQLite + vectorized in Qdrant
- Retrieve — any MCP client (VS Code, Claude Desktop, Hermes…) can semantic-search your KB
| 📱 Telegram bot | Send links from your phone as naturally as messaging a friend |
| 🔖 Bookmarklet | One-click save from any browser, including iOS Safari |
| 🤖 MCP HTTP + stdio | Connects to any MCP-compatible AI agent (VS Code, Claude, Hermes…) |
| 🔍 Semantic search | Qdrant + FastEmbed (BAAI/bge-small-en-v1.5) — CPU only, no GPU needed |
| 💾 FTS fallback | SQLite FTS5 full-text search when Qdrant is unavailable |
| 🕸️ Knowledge graph | Tag co-occurrence, same-domain, cosine similarity links |
| 🏷️ Auto-classification | Detects type (repo, article, video, model…) and subject (ai, dev-tools…) |
| 🔁 Deduplication | URL fingerprinting — no duplicate entries |
| 🔐 Bearer auth | All HTTP endpoints protected by API key |
| 🔒 Auto-HTTPS | Caddy handles Let's Encrypt automatically |
| 🐳 Docker Compose | One-command deploy on any VPS |
git clone https://github.com/almanak-app/almanak
cd almanak
make setup # creates .env, generates API key
# → edit .env: set MCP_DOMAIN=mcp.example.com (or leave for IP-only)
make up # starts everything (Qdrant + MCP + Ingest + Caddy)
make token # prints your URL + VS Code config snippetPrerequisites: Docker + Docker Compose. That's it.
The Telegram bot is your "buddy that remembers everything". Send it a URL from anywhere — it replies with the extracted title, type, and subject in seconds.
- Create a bot via @BotFather →
/newbot→ copy the token - Find your Telegram user ID: message @userinfobot
- Set in
.env:BENCHMARK_BOT_TOKEN=123456789:AAF...your_token... ALLOWED_USER_ID=123456789 - Add to
docker-compose.yml(see below) anddocker compose up bot -d
Just send a URL — the bot does the rest:
You: https://github.com/microsoft/markitdown
Bot: ✅ Saved #847
📌 MarkItDown — Microsoft
Convert files and office documents to Markdown
🏷 repo · dev-tools · python, markdown, office
You can also add tags and a note inline:
You: https://arxiv.org/abs/2307.09288 #llm #research worth reading
Bot: ✅ Saved #848
📌 LLaMA 2: Open Foundation and Fine-Tuned Chat Models
🏷 research · ai · llm, research
| Command | Description |
|---|---|
<url> [#tag1 #tag2] [note] |
Save URL with optional tags and note |
/list [N] |
Last N entries (default 10) |
/search <query> |
Full-text search |
/tag <id> <tags> |
Set tags on an entry |
/note <id> <text> |
Add or update a note |
/rm <id> |
Delete an entry |
/stats |
Counts by type and subject |
/export |
Receive a CSV of all entries |
/help |
Show help |
bot:
build: .
command: ["python", "bot/telegram_bot.py"]
env_file: .env
volumes:
- ./data:/app/data
depends_on:
- qdrant
restart: unless-stopped- Visit
https://mcp.example.com/bookmarklet?key=YOUR_INGEST_API_KEY - Drag "+ Save to AlManak" to your bookmarks bar
- On any page, click it → popup confirms → closes in 3 seconds
For integrations (Raycast, Alfred, n8n, iOS Shortcuts, scripts — anything that can make an HTTP request):
curl -X POST https://mcp.example.com/ingest/links \
-H "Authorization: Bearer YOUR_INGEST_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "tags": "ai, research", "notes": "great paper"}'mcp_servers:
almanak:
transport: http
url: https://mcp.example.com/mcp
headers:
Authorization: "Bearer YOUR_MCP_API_KEY"mcp_servers:
almanak:
command: python3
args: [-m, open_benchmark.mcp_server.server]
env:
BENCHMARK_DB_PATH: /abs/path/to/data/benchmarks.db
QDRANT_URL: http://localhost:6333| Tool | Description |
|---|---|
search_benchmarks |
Semantic search (Qdrant or FTS fallback) |
get_benchmark |
Retrieve entry by ID |
list_benchmarks_stats |
Counts by type and subject |
get_related_benchmarks |
Entries linked by tag, domain, or similarity |
list_subjects |
All subjects in DB |
list_types |
All types in DB |
list_tags |
Most common tags with counts |
explain_relationships |
Human-readable relation summary for an entry |
Caddy is included in docker-compose and handles HTTPS automatically.
- DNS A record:
mcp.example.com → <vps-ip> .env:MCP_DOMAIN=mcp.example.com- VPS firewall: open ports 80 + 443
make up— cert issued automatically
- Leave
MCP_DOMAINunset - Open port 443
make up- Add
"allowInsecureCertificate": truein VS Code MCP config
almanak/
src/open_benchmark/ # Python package
config.py # Typed env config (pydantic-settings)
storage/db.py # SQLite schema, CRUD, graph tables
extractor/ # URL fetch, classify, GitHub enrichment
indexer/ # Qdrant upsert + semantic search
graph/ # Tag/domain/cosine similarity graph
mcp_server/ # FastMCP (stdio + HTTP)
ingest/ # FastAPI ingest + bookmarklet endpoints
bot/
telegram_bot.py # Telegram ingestion bot
scripts/ # index.py, seed.py
data/ # .gitignored — SQLite + CSV
Caddyfile # Auto-HTTPS config
docker-compose.yml
Makefile
| Variable | Default | Description |
|---|---|---|
BENCHMARK_DB_PATH |
data/benchmarks.db |
SQLite path |
QDRANT_URL |
http://localhost:6333 |
Qdrant endpoint |
QDRANT_ENABLED |
true |
Disable for FTS-only mode |
MCP_API_KEY |
`` | Bearer token for MCP |
MCP_DOMAIN |
localhost |
Domain for auto-HTTPS |
INGEST_API_KEY |
`` | Bearer token for ingest API + bookmarklet |
BENCHMARK_BOT_TOKEN |
`` | Telegram bot token (from @BotFather) |
ALLOWED_USER_ID |
`` | Your Telegram user ID |
FEATURE_TRAFILATURA |
true |
Readable content extraction |
FEATURE_GRAPH |
true |
Knowledge graph building |
- Web UI — browse, search and annotate links from a browser dashboard
- LLM enrichment — optional GPT/Ollama pass to improve classification & summaries
- Browser extension — Chrome/Firefox, replaces the bookmarklet
- iOS Shortcuts template — pre-made
.shortcutfile for one-tap save from Safari Share Sheet (the REST API already works manually) - RSS ingestion — automatically ingest feeds into your KB
- Duplicate clustering — group near-duplicate URLs across sources
- Export — Markdown, JSON, Obsidian vault
Have a feature request? Open an issue — PRs are very welcome.
Contributions are welcome! Please read CONTRIBUTING.md first.
git clone https://github.com/codeurali/almanak
cd almanak
pip install -e ".[dev]"
pytestIf AlManak saves you time or helps your workflow, leaving a star is the best way to support it and help others discover it.
MIT