Back to Discover

xbookmark

connector

isezen

MCP server to sync X bookmarks to Obsidian vault

View on GitHub
0 starsMITSynced Aug 2, 2026

Install to Claude Code

/plugin marketplace add isezen/xbookmark

README

XBookmark

MCP server that syncs X (Twitter) bookmarks to an Obsidian vault. Multi-account support, OAuth 2.0 PKCE authentication, and structured JSON storage.

Features

  • Multi-account support — unlimited X accounts via profiles
  • One-click OAuth login — browser opens, callback captured, tokens saved automatically
  • Centralized storage — all bookmarks in a single bookmarks.json (atomic writes)
  • Thread detection — automatic thread fetching for multi-tweet threads
  • Cross-account deduplication — same tweet bookmarked from 2 accounts = 1 entry
  • Rate limit handling — sequential processing with automatic retry
  • Two-step workflow — sync first, delete later (safe for testing)
  • AI-powered digest/xbookmark-digest Claude Code skill for analysis & categorization

Available Tools

ToolDescription
Auth
xbookmark_auth_login(profile)One-click OAuth — browser + callback + token exchange
xbookmark_auth_url(profile)Get OAuth authorization URL (manual fallback)
xbookmark_auth_callback(code, state)Complete authorization (manual fallback)
xbookmark_auth_status(profile)Check auth status (None = all profiles)
xbookmark_auth_logout(profile)Clear stored tokens
xbookmark_list_profiles()List all profiles and auth status
Sync
xbookmark_sync(profile)Sync bookmarks to bookmarks.json
xbookmark_delete(profile, tweet_ids, limit)Delete synced bookmarks from X (selective or all)
xbookmark_list(profile)List bookmarks from X API
xbookmark_get_tweet(tweet, profile)Fetch single tweet by ID or URL (with thread)
xbookmark_sync_all()Sync ALL profiles with deduplication

Quick Install (Claude Code Plugin)

The easiest way to use XBookmark with Claude Code:

  1. Set X API credentials (add to ~/.bashrc or ~/.zshrc):

    export X_CLIENT_ID="your_oauth2_client_id"
    export X_CLIENT_SECRET="your_client_secret"          # optional
    export X_REDIRECT_URI="http://localhost:8080/callback" # optional
    
  2. Install the plugin (in Claude Code):

    /plugin marketplace add isezen/XBookmarks
    /plugin install xbookmark@XBookmarks
    
  3. Restart Claude Code. The MCP server is auto-installed on first start.

  4. Use it:

    /xbookmark:digest                          # Analyze all bookmarks
    /xbookmark:digest https://x.com/.../12345  # Process single tweet
    

Developer Installation

Prerequisites

  • Python 3.10+
  • uv package manager (recommended) or pip
  • X Developer Account with OAuth 2.0 enabled

Setup

  1. Clone and install

    git clone git@github-isezen:isezen/XBookmarks.git
    cd XBookmarks
    uv sync
    
  2. Set environment variables

    cp .env.example .env
    

    Edit .env with your X API credentials:

    X_CLIENT_ID="your_client_id"
    X_CLIENT_SECRET="your_client_secret"
    X_REDIRECT_URI="http://localhost:8080/callback"
    
  3. Create config (optional — defaults work for most setups)

    mkdir -p ~/.config/XBookmark
    cat > ~/.config/XBookmark/config.json << 'EOF'
    {
      "obsidian_vault_path": "/path/to/your/obsidian/vault",
      "xbookmarks_folder": "XBookmarks"
    }
    EOF
    

    Or set XBOOKMARK_HOME env var to use a custom config directory.

X API Setup

Get OAuth 2.0 Credentials

  1. Go to X Developer Portal
  2. Create a Project and an App
  3. Under App Settings, enable OAuth 2.0 with:
    • Type: Confidential client (or Public)
    • Redirect URI: http://localhost:8080/callback
  4. Required scopes: bookmark.read, bookmark.write, tweet.read, users.read, offline.access
  5. Copy Client ID and Client Secret to your .env file

Note: Bookmark endpoints require Basic tier access or pay-per-usage credits.

Usage with MCP Clients

Claude Code / Claude Desktop

Add to your MCP settings:

{
  "mcpServers": {
    "xbookmark": {
      "command": "/path/to/XBookmarks/.venv/bin/xbookmark-mcp"
    }
  }
}

Workflow

Step 1: Authenticate

> "Login to my X account"

The agent calls xbookmark_auth_login() — browser opens, you authorize, tokens are saved.

For multiple accounts, use profiles:

> "Login to my work X account as 'work'"

Step 2: Sync Bookmarks

> "Sync my X bookmarks"

The agent calls xbookmark_sync_all() which:

  • Downloads from all authenticated profiles
  • Deduplicates across accounts
  • Saves to XBookmarks/bookmarks.json
  • Does NOT delete from X

Step 3: Process & Categorize

Use the /xbookmark-digest skill (or manually):

  1. Read bookmark entries from bookmarks.json
  2. Analyze tweet content, fetch linked URLs
  3. Create enriched notes in Obsidian topic folders
  4. Track processed tweets in index.json

Step 4: Delete from X (optional)

> "Delete processed bookmarks from X"

The agent calls xbookmark_delete() (with no profile argument, which deletes from all profiles) and cleans up bookmarks.json.

Data Storage

bookmarks.json

All synced bookmarks are stored in XBookmarks/bookmarks.json as a flat JSON array. Each entry contains tweet text, author info, entities, media, thread replies, and source profiles. Writes use atomic tmp-then-rename for crash safety.

index.json

Tracks which tweets have been processed by the digest skill. Maps tweet_id to {path, date, tags} for Obsidian cross-references.

Development

Quick Commands

# Install with dev dependencies
uv sync --extra dev

# Run all tests
.venv/bin/pytest

# Run single test
.venv/bin/pytest tests/test_config.py::TestLoadConfig -v

# Coverage report
.venv/bin/pytest --cov=src/xbookmark

# Lint & format
.venv/bin/ruff check . && .venv/bin/ruff format .

# Run MCP server
.venv/bin/xbookmark-mcp

# Debug with MCP Inspector
npx @modelcontextprotocol/inspector .venv/bin/xbookmark-mcp

Project Structure

XBookmarks/
├── .claude-plugin/
│   └── marketplace.json       # Claude Code plugin marketplace
├── plugins/xbookmark/         # Claude Code plugin
│   ├── .claude-plugin/plugin.json
│   ├── .mcp.json              # MCP server config
│   ├── commands/
│   │   └── digest.md          # AI digest skill (source of truth)
│   ├── hooks/hooks.json       # SessionStart auto-install hook
│   └── scripts/ensure-installed.sh
├── .claude/commands/
│   └── xbookmark-digest.md    # Symlink → plugins/xbookmark/commands/digest.md
├── src/xbookmark/
│   ├── config.py              # Config loading, lazy singleton
│   ├── mcp/
│   │   ├── server.py          # FastMCP entry point
│   │   ├── tools_auth.py      # 6 OAuth 2.0 PKCE auth tools
│   │   └── tools_sync.py      # 6 sync/delete/list tools
│   ├── x_api/
│   │   ├── auth.py            # OAuth 2.0 PKCE flow, token storage
│   │   ├── callback_server.py # Local HTTP server for one-click login
│   │   ├── client.py          # Async HTTP client with retry
│   │   ├── bookmarks.py       # Bookmark CRUD (X API v2)
│   │   └── tweets.py          # Tweet/thread fetching
│   └── obsidian/
│       └── writer.py          # Markdown generation, JSON I/O
├── tests/
│   ├── conftest.py            # Shared fixtures
│   ├── test_config.py
│   ├── test_writer.py
│   └── test_tools.py
├── docs/                      # Architecture & API docs
├── pyproject.toml
├── CLAUDE.md                  # Claude Code guidance
└── README.md

Testing

  • Framework: pytest with asyncio_mode = "auto"
  • HTTP mocking: respx library
  • Fixtures: tests/conftest.py (mock_config, mock_oauth_manager, mock_tweet, etc.)
  • Tests organized as classes per module

Code Style

  • Python 3.10+, ruff rules: E/F/I/N/W/UP
  • Modern type hints: str | None, list[str]
  • Double quotes, trailing commas in multi-line structures

License

MIT

Rendered live from isezen/xbookmark's GitHub README — not stored, always reflects the source repo.

1 Plugin

NameDescriptionCategorySource
xbookmarkMCP server for X bookmark sync/search/delete and an AI digest command that analyzes, enriches, and saves bookmarks as organized Obsidian notes.productivity./plugins/xbookmark

0 Comments

Login required
Log in to post a comment or update on this repo.

No comments yet — be the first to share an update.