# Bookmark Lens

> Local-first bookmark manager with semantic search for MCP-enabled AI assistants. AI-powered organization, smart tagging, and natural language queries. Built on LanceDB. Works with Claude Desktop, Cursor, and other MCP clients.

- **Type:** MCP server
- **Install:** `agentstack add mcp-cornelcroi-bookmark-lens`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [cornelcroi](https://agentstack.voostack.com/s/cornelcroi)
- **Installs:** 0
- **Category:** [Databases](https://agentstack.voostack.com/c/databases)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [cornelcroi](https://github.com/cornelcroi)
- **Source:** https://github.com/cornelcroi/bookmark-lens

## Install

```sh
agentstack add mcp-cornelcroi-bookmark-lens
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

---
title: Bookmark Lens
emoji: 🔖
colorFrom: indigo
colorTo: blue
sdk: docker
pinned: false
license: mit
short_description: Semantic bookmark engine for MCP-enabled AI agents
tags:
  - building-mcp-track-consumer
  - building-mcp-track-creative
---

# Bookmark Lens

**Your AI assistant remembers everything you've saved.**

[](https://badge.fury.io/py/bookmark-lens)
[](https://www.python.org/downloads/)
[](https://opensource.org/licenses/MIT)

## What is Bookmark Lens?

Tired of losing bookmarks in browser folders? Searching for "that article about React hooks" but can't remember if it mentioned "hooks" or "useState" or "functional components"?

**Bookmark Lens** solves this with semantic search. Find bookmarks by what they're *about*, not just exact keywords. Search "authentication tutorials" and get results about login systems, OAuth, JWT - even if they never mention the word "authentication."

**Traditional bookmarks:** Folders → Subfolder → Where did I save it? → Give up, Google it again
**With Bookmark Lens:** "Find that React tutorial from last week" → Found instantly

All processing happens locally on your machine. Your bookmarks stay private.

## See It In Action

*Demo coming soon - intelligent bookmark search in action*

## Features

- **🧠 Semantic Search** – Find bookmarks by meaning, not just keywords  
- **🆓 Completely Free** – No API keys required for core features  
- **🤖 LLM-Enhanced (Optional)** – If your LLM uses this MCP tool, it can generate summaries, auto-tags, and topic classifications  
- **Semantic Search** - Find bookmarks by meaning, not just keywords
- **Rich Metadata** - Automatic extraction of titles, descriptions, and content
- **Smart Tagging** - Manual tags + auto-generated tags (Smart Mode)
- **Topic Classification** - Automatic categorization (Smart Mode)
- **Date Filtering** - Search by time ranges (natural language supported via LLM)
- **MCP Native** - Works with Claude Desktop and other MCP clients
- **Fast** - Local embeddings with sentence-transformers

---

## Quick Setup

### Claude Desktop (stdio mode)

1. Open your Claude Desktop config file:
   - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
   - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`

2. Add bookmark-lens to the `mcpServers` section:

```json
{
  "mcpServers": {
    "bookmark-lens": {
      "command": "uvx",
      "args": ["bookmark-lens"]
    }
  }
}
```

3. Restart Claude Desktop

That's it! No installation, no setup, no configuration needed.

### Other MCP Clients

For other MCP-compatible clients, use:

```bash
uvx bookmark-lens
```

### HTTP Mode (Self-Hosted)

Bookmark Lens also supports **Streamable HTTP** transport for web-based integrations. This requires self-hosting as there is no hosted version available.

```bash
# Run HTTP server on default port (8000)
bookmark-lens --transport http

# Server available at: http://127.0.0.1:8000/mcp

# Custom port
bookmark-lens --transport http --port 8080
```

#### Multi-User Support

HTTP mode supports multiple users via the `X-User-Id` header. Each user's bookmarks are completely isolated:

```bash
# User "alice" saves a bookmark
curl -H "X-User-Id: alice" http://localhost:8000/mcp

# User "bob" saves a bookmark
curl -H "X-User-Id: bob" http://localhost:8000/mcp

# Alice and Bob have separate bookmark collections
```

- **Default**: If no `X-User-Id` header is provided, defaults to `dev-user`
- **Isolation**: Each user can only access their own bookmarks, tags, and statistics
- **Single Instance**: One server can serve multiple users with complete data isolation

> **📖 Self-hosting guide:** See [DEPLOYMENT.md](DEPLOYMENT.md) for detailed instructions on running your own HTTP server, Docker deployment, multi-user setup, and security considerations.

---

## Example Conversations

### Research Workflow

```
You: Save https://arxiv.org/abs/2401.12345 with note "Interesting paper on attention mechanisms"

Claude: Saved! I've extracted:
- Title: "Efficient Attention: A Survey"
- Description: Comprehensive review of attention mechanisms...
- Auto-generated tags: #ai #research #attention #transformers

You: Find papers about attention from this month

Claude: Found 3 bookmarks:
1. "Efficient Attention: A Survey" (arxiv.org) - Today
   Tags: ai, research, attention, transformers

2. "Flash Attention Implementation" (github.com) - 3 days ago
   Tags: pytorch, optimization, gpu

3. "Attention is All You Need - Annotated" (nlp.seas.harvard.edu) - 1 week ago
   Tags: tutorial, transformers, nlp
```

### Learning Path

```
You: I'm learning React. Save good tutorials as I find them with tag #react-learning

Claude: Great! I'll tag them for you.

You: [Later] Show me all my React learning resources

Claude: You have 12 React bookmarks:

**Fundamentals (4 bookmarks):**
- Official React Docs - react.dev
- React Tutorial for Beginners - youtube.com
- Thinking in React - beta.reactjs.org

**Advanced (5 bookmarks):**
- Custom Hooks Patterns - usehooks.com
- React Performance Optimization - web.dev
...

You: Which ones cover hooks?

Claude: 8 of your bookmarks discuss hooks:
[Semantic search finds all hook-related content even without "hooks" in title]
```

### Content Curation

```
You: Show me my GitHub bookmarks by topic

Claude: Here's the breakdown:

**AI/ML (15 bookmarks)**
- Transformer models
- LLM training techniques
- Embedding systems

**Frontend (23 bookmarks)**
- React ecosystem
- Build tools
- State management

**DevOps (8 bookmarks)**
- Kubernetes guides
- CI/CD pipelines

You: What are my top 3 most-saved domains?

Claude:
1. github.com - 47 bookmarks
2. medium.com - 23 bookmarks
3. dev.to - 18 bookmarks
```

> **More examples:** See [USAGE_GUIDE.md](USAGE_GUIDE.md) for detailed workflows and advanced query patterns.

---

## Architecture

```
bookmark-lens/
├── src/bookmark_lens/
│   ├── server.py              # MCP server (stdio + HTTP/SSE)
│   ├── config.py              # Configuration management
│   ├── database/
│   │   ├── duckdb_client.py   # Relational data (bookmarks, tags)
│   │   └── lancedb_client.py  # Vector embeddings
│   ├── models/
│   │   └── bookmark.py        # Pydantic models
│   └── services/
│       ├── content_fetcher.py # Web page fetching
│       ├── embedding_service.py # Text → vectors
│       ├── bookmark_service.py # Orchestration
│       └── search_service.py  # Hybrid search
├── data/                      # Local databases (gitignored)
└── tests/
    └── manual_test.py         # End-to-end testing
```

### Technology Stack

- **FastMCP** - Model Context Protocol with dual transport (stdio + HTTP/SSE)
- **DuckDB** - Relational database (bookmarks, metadata, tags)
- **LanceDB** - Vector database (embeddings for semantic search)
- **sentence-transformers** - Local embedding model (all-MiniLM-L6-v2)
- **readability-lxml** - Content extraction from web pages
- **Pydantic** - Data validation and serialization

> **Technical deep-dive:** See [TECHNICAL.md](TECHNICAL.md) for hybrid search architecture, performance benchmarks, and implementation details.

---

## FAQ

**How is this different from browser bookmarks?**
Browser bookmarks use folders and exact name matching. Bookmark Lens uses AI to understand meaning. Search "authentication" and find bookmarks about login, OAuth, JWT - even if they never use that word.

**What about Raindrop.io or Pocket?**
They're cloud-based (your data on their servers) and require subscriptions for advanced features. Bookmark Lens is 100% local and free. Your data never leaves your machine.

**Do I need an API key?**
No! Core features (save, search, tag) work completely offline with no API keys. Smart Mode (auto-summaries, auto-tags) is optional and uses your own LLM API key.

**How much does Smart Mode cost?**
With Claude Haiku: ~$0.0005 per bookmark (half a cent). Process 1000 bookmarks for $0.50. It's optional - core features are free.

**Is my data private?**
100% private. Everything runs locally. Core features don't use the internet at all. Smart Mode only sends bookmark content to your chosen LLM (not to us).

**What if I have thousands of bookmarks?**
Bookmark Lens handles thousands easily. Vector search is fast even with large collections. The sentence-transformer model runs locally on your CPU.

**Why semantic search instead of keywords?**
Keywords fail when you don't remember exact words. "Find that authentication tutorial" won't find "OAuth guide for beginners." Semantic search understands they're about the same topic.

**Can I export my bookmarks?**
Not yet (roadmap feature). Currently, data is in local DuckDB + LanceDB databases. You can access them directly if needed.

**Can I self-host this with HTTP access?**
Yes! Bookmark Lens supports streamable HTTP transport. See [DEPLOYMENT.md](DEPLOYMENT.md) for self-hosting instructions. Note: There is no hosted version - you must run your own server.

**Does it support multiple users?**
Yes! In HTTP mode, Bookmark Lens supports multiple users via the `X-User-Id` header. Each user's bookmarks are completely isolated - they can only access their own data. One server instance can serve many users with complete data separation. stdio mode is single-user only (defaults to `dev-user`).

---

## MCP Tools

### `save_bookmark`
Save a URL with optional note and tags.

**Parameters:**
- `url` (required): URL to bookmark
- `note` (optional): Context or reason for saving
- `tags` (optional): List of tags

**Example:**
```json
{
  "url": "https://example.com/article",
  "note": "Great explanation of embeddings",
  "tags": ["ai", "ml", "tutorial"]
}
```

### `search_bookmarks`
Search bookmarks semantically with optional filters.

**Parameters:**
- `query` (required): What to search for
- `domain` (optional): Filter by domain (e.g., "github.com")
- `tags` (optional): Filter by tags
- `from_date` (optional): ISO 8601 date string
- `to_date` (optional): ISO 8601 date string
- `limit` (optional): Max results (default: 10)

**Example:**
```json
{
  "query": "machine learning tutorials",
  "domain": "github.com",
  "tags": ["python"],
  "from_date": "2024-11-07T00:00:00Z",
  "limit": 5
}
```

### `get_bookmark`
Get full details about a bookmark by ID.

**Parameters:**
- `id` (required): Bookmark ID

### `update_bookmark`
Update note and/or tags for a bookmark.

**Parameters:**
- `id` (required): Bookmark ID
- `note` (optional): New note
- `tags` (optional): Tags to add/replace
- `tag_mode` (optional): "replace" or "append" (default: "replace")

### `delete_bookmark`
Delete a bookmark and all its associated data.

**Parameters:**
- `id` (required): Bookmark ID

**Example:**
```json
{
  "id": "bkm_abc123"
}
```

### `list_tags`
List all tags with their usage counts.

**Parameters:** None

**Example Response:**
```json
{
  "success": true,
  "count": 5,
  "tags": [
    {"tag": "ai", "count": 20},
    {"tag": "python", "count": 15},
    {"tag": "tutorial", "count": 8}
  ]
}
```

### `get_bookmark_stats`
Get statistics about your bookmark collection with optional filters.

**Parameters:**
- `stat_type` (optional): Type of statistics
  - `"total"` - Total count (default)
  - `"by_domain"` - Breakdown by domain
  - `"by_topic"` - Breakdown by topic
  - `"by_tag"` - Breakdown by tag
  - `"by_date"` - Activity over time
- `domain` (optional): Filter by domain
- `topic` (optional): Filter by topic
- `tags` (optional): Filter by tags
- `from_date` (optional): Filter after date (ISO 8601)
- `to_date` (optional): Filter before date (ISO 8601)
- `limit` (optional): For breakdown stats, top N results (default: 10)

**Examples:**

Total bookmarks:
```json
{
  "stat_type": "total"
}
```

Bookmarks saved this week:
```json
{
  "stat_type": "total",
  "from_date": "2024-11-07T00:00:00Z"
}
```

Top domains:
```json
{
  "stat_type": "by_domain",
  "limit": 5
}
```

AI bookmarks by domain:
```json
{
  "stat_type": "by_domain",
  "topic": "AI"
}
```

---

## Configuration

All configuration is via environment variables (`.env` file):

```bash
# Database paths
BOOKMARK_LENS_DUCKDB_PATH=./data/bookmark_lens.db
BOOKMARK_LENS_LANCEDB_PATH=./data/embeddings.lance

# Embedding model
EMBEDDING_MODEL_NAME=all-MiniLM-L6-v2
EMBEDDING_DIMENSION=384

# Content fetching
BOOKMARK_LENS_FETCH_TIMEOUT=30
BOOKMARK_LENS_USER_AGENT=bookmark-lens/0.1.0
MAX_CONTENT_LENGTH=50000
```

### Installation Options

**Reduce Installation Size (CPU-only PyTorch):**

By default, PyTorch may install with CUDA support (~3GB). For most deployments, CPU-only is sufficient and much smaller (~200MB):

```bash
# Install CPU-only PyTorch first
pip install torch --index-url https://download.pytorch.org/whl/cpu

# Then install bookmark-lens
pip install bookmark-lens
```

This is recommended for Docker containers, serverless deployments, or any environment where you don't need GPU acceleration.

---

## Smart Mode (LLM Enhancements)

Enable Smart Mode to get automatic summaries, tags, and topic classification for your bookmarks.

### Setup

1. Choose an LLM model (see [LiteLLM providers](https://docs.litellm.ai/docs/providers))
2. Get an API key from your provider
3. Add to `.env`:
   ```bash
   LLM_MODEL=claude-3-haiku-20240307
   LLM_API_KEY=your-api-key-here
   ```
4. Restart the server

### Recommended Models

- `claude-3-haiku-20240307` - Fast, cheap, good quality (Anthropic) **[Recommended]**
- `gpt-4o-mini` - Fast, cheap (OpenAI)
- `gpt-4o` - Better quality, more expensive (OpenAI)
- `claude-3-5-sonnet-20241022` - Best quality (Anthropic)

See [LiteLLM documentation](https://docs.litellm.ai/docs/providers) for 100+ supported models.

### What Smart Mode Adds

- **Auto-summaries**: Short (1-2 sentences) and long (1 paragraph) summaries
- **Auto-tags**: 3-5 relevant tags automatically generated
- **Topic classification**: High-level category (AI, Cloud, Programming, Data, Security, DevOps, Design, Business, Science, Other)
- **Better search**: Summaries and topics included in embeddings for improved relevance
- **Markdown extraction**: Full content extracted as Markdown (preserves structure)

### Cost Estimate

With `claude-3-haiku-20240307`: **~$0.0005 per bookmark** (very cheap!)

### Performance

- **Core Mode** (no LLM): Fast saves, only title/description extracted
- **Smart Mode** (with LLM): Slower saves (~5-10s), full content + enhancements

**Note:** Smart Mode is completely optional. All core features work without any LLM configuration.

---

### Embedding Models

Default: `all-MiniLM-L6-v2` (384 dimensions, fast, good quality)

Alternatives:
- `all-mpnet-base-v2` (768 dimensions, better quality, slower)
- `paraphrase-multilingual-MiniLM-L12-v2` (384 dimensions, multilingual)

Change in `.env`:
```bash
EMBEDDING_MODEL_NAME=all-mpnet-base-v2
EMBEDDING_DIMENSION=768
```

---

## How It Works

### Saving a Bookmark

1. **Fetch** - Downloads the web page
2. **Extract** - Pulls out title, description, main content (Markdown in Smart Mode)
3. **Enhance** - Generates summaries, tags, topic (Smart Mode only)
4. **Embed** - Converts text to vector using local model
5. **Store** - Saves to DuckDB (metadata) and LanceDB (vector)

### Searching Bookmarks

1. **Embed Query** - Converts search text to vector
2. **Vector Search** - Finds similar bookmarks (LanceDB)
3. **Filter** - Applies domain/tag/date filters (DuckDB)
4. **Rank** - Sorts by similarity score
5. **Return** - Top N results with relevance scores

### Natural Language Dates

The LLM (via the `bookmark_search_guide` prompt) converts natural language to ISO dates:
- "yesterday" → `2024-11-13T00:00:00Z`
- "last week" → `2024-11-07T00:00:00Z`
- "last month" → `2024-10-14T00:00:00Z`

The server only accepts ISO 8601 format - the LLM does the conversion.

---

## Development

Want to contribute? See [CONTRIBUTING.md](CONTRIBUTING.md) for setup instructions.

### Running Tests

```bash
# Clone the repository
git clone https://github.com/yourusername/bookmark-lens.git
cd bookmark-lens

# Install in development mo

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [cornelcroi](https://github.com/cornelcroi)
- **Source:** [cornelcroi/bookmark-lens](https://github.com/cornelcroi/bookmark-lens)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-cornelcroi-bookmark-lens
- Seller: https://agentstack.voostack.com/s/cornelcroi
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
