MCP Servers

A collection of Model Context Protocol servers, templates, tools and more.

ChronicleMCP is a secure, local-first [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that allows AI agents (like Claude Desktop, Cursor, and IDEs) to search your local browser history.

Created 2/4/2026
Updated 20 days ago
Repository documentation and setup instructions

ChronicleMCP

Secure, local-first Model Context Protocol (MCP) server for browser history

PyPI Version License Tests Coverage


Table of Contents

  1. Quick Start
  2. Features
  3. Installation
  4. Usage
  5. Configuration
  6. Security & Privacy
  7. Supported Browsers
  8. Troubleshooting
  9. Development
  10. Contributing
  11. License

Quick Start

# Install
pip install chronicle-mcp

# Run MCP server (stdio mode for AI agents like Claude, Cursor)
chronicle-mcp mcp

# Or start an HTTP server
chronicle-mcp http --port 8080

# Check available browsers
chronicle-mcp list-browsers

Features

| Feature | Description | |---------|-------------| | 🔒 Privacy-First | All data stays on your machine. No cloud sync, no data collection. | | 🌐 Multi-Browser | Chrome, Firefox, Edge, Brave, Safari, Vivaldi, Opera support | | 🔍 Multiple Search Tools | Search by query, date range, domain, or recent history | | 📊 Output Formats | Markdown (default) or JSON | | ⚡ Fast Performance | Built with Python and SQLite | | 🔐 Secure | URL sanitization removes sensitive query parameters | | 🐳 Docker Support | Run as a container | | 🔧 CLI Interface | Full command-line control | | 🌐 HTTP API | RESTful API for integrations | | 🔖 Bookmarks | Read bookmarks from all supported browsers | | ⬇️ Downloads | Track download history from all supported browsers |


Installation

pip (Recommended)

pip install chronicle-mcp

pipx (Isolated Installation)

pipx install chronicle-mcp

Docker

# Pull the latest image
docker pull ghcr.io/nikolasil/chronicle-mcp:latest

# Run the server
docker run -p 8080:8080 ghcr.io/nikolasil/chronicle-mcp

From Source

git clone https://github.com/nikolasil/chronicle-mcp.git
cd chronicle-mcp
pip install -e .

Homebrew (macOS)

brew tap nikolasil/chronicle-mcp
brew install chronicle-mcp

Usage

CLI Commands

chronicle-mcp mcp

Run the MCP server for AI agents.

# Stdio mode (default for AI assistants)
chronicle-mcp mcp

# SSE mode for HTTP clients
chronicle-mcp mcp --sse --port 8080

| Option | Description | |--------|-------------| | --sse | Use SSE transport instead of stdio | | --host | Host to bind (SSE mode only) | | --port | Port to listen on (SSE mode only) |

chronicle-mcp http

Start a long-running HTTP REST API server.

# Default (foreground, port 8080)
chronicle-mcp http

# Custom port
chronicle-mcp http --port 9000

# Daemon mode
chronicle-mcp http --port 8080 --daemon

# Different browser
chronicle-mcp http --browser firefox

| Option | Description | |--------|-------------| | --host | Host to bind (default: 127.0.0.1) | | --port | Port to listen on (default: 8080) | | --browser | Default browser (default: chrome) | | --foreground | Run in foreground (default: true) | | --daemon | Run as daemon |

chronicle-mcp status

Check if the server is running.

chronicle-mcp status --port 8080

chronicle-mcp logs

View server logs.

chronicle-mcp logs --port 8080 --lines 100

chronicle-mcp version

Show version information.

chronicle-mcp version

chronicle-mcp list-browsers

List available browsers on the system.

chronicle-mcp list-browsers
# Output: Available browsers: chrome, edge

chronicle-mcp completion

Generate shell completion scripts.

# Bash
chronicle-mcp completion bash >> ~/.bashrc

# Zsh
chronicle-mcp completion zsh >> ~/.zshrc

# Fish
chronicle-mcp completion fish > ~/.config/fish/completions/chronicle-mcp.fish

MCP Tools

search_history

Search browser history for keywords in titles or URLs.

def search_history(
    query: str,
    limit: int = 5,
    browser: str = "chrome",
    format_type: str = "markdown"
) -> str

Example:

# Markdown output (default)
search_history("python tutorial", limit=10, browser="chrome")

# JSON output
search_history("github", limit=5, format_type="json")

get_recent_history

Get recent browsing history from the last N hours.

def get_recent_history(
    hours: int = 24,
    limit: int = 20,
    browser: str = "chrome",
    format_type: str = "markdown"
) -> str

Example:

# Last 24 hours
get_recent_history(hours=48, limit=20)

count_visits

Count total visits to a specific domain.

def count_visits(
    domain: str,
    browser: str = "chrome"
) -> str

Example:

count_visits("github.com", browser="chrome")
# Output: Visits to 'github.com' in chrome: 42

list_top_domains

Get the most visited domains.

def list_top_domains(
    limit: int = 10,
    browser: str = "chrome",
    format_type: str = "markdown"
) -> str

Example:

list_top_domains(limit=20)

search_history_by_date

Search history within a date range.

def search_history_by_date(
    query: str,
    start_date: str,  # ISO format: YYYY-MM-DD
    end_date: str,    # ISO format: YYYY-MM-DD
    limit: int = 10,
    browser: str = "chrome",
    format_type: str = "markdown"
) -> str

Example:

search_history_by_date(
    "python",
    start_date="2024-01-01",
    end_date="2024-12-31",
    limit=20
)

list_available_browsers

Returns a list of browsers with detected history databases.

def list_available_browsers() -> str

Example:

list_available_browsers()
# Output: Available browsers: chrome, edge, firefox, brave

delete_history

Delete history entries matching a query.

def delete_history(
    query: str,
    limit: int = 100,
    browser: str = "chrome",
    confirm: bool = False
) -> str

Example:

# Preview what would be deleted (default)
delete_history("spam.com", browser="chrome")
# Actually delete
delete_history("spam.com", browser="chrome", confirm=True)

search_by_domain

Search history within specific domain(s).

def search_by_domain(
    domain: str,
    query: str = None,
    limit: int = 20,
    browser: str = "chrome",
    format_type: str = "markdown",
    exclude_domains: list[str] = None
) -> str

Example:

search_by_domain("github.com", browser="chrome")

get_browser_stats

Get browsing statistics for the browser database.

def get_browser_stats(browser: str = "chrome") -> str

Example:

get_browser_stats(browser="firefox")
# Returns JSON with total visits, domains, date range, etc.

get_most_visited_pages

Get the most visited individual pages.

def get_most_visited_pages(
    limit: int = 20,
    browser: str = "chrome",
    format_type: str = "markdown"
) -> str

Example:

get_most_visited_pages(limit=10, browser="chrome")

export_history

Export history to CSV or JSON format.

def export_history(
    format_type: str = "csv",
    limit: int = 1000,
    query: str = None,
    browser: str = "chrome"
) -> str

Example:

# Export to CSV
export_history(format_type="csv", limit=1000, browser="chrome")

# Export to JSON
export_history(format_type="json", limit=500, browser="firefox")

search_history_advanced

Advanced search with multiple options including regex and fuzzy matching.

def search_history_advanced(
    query: str,
    limit: int = 20,
    browser: str = "chrome",
    format_type: str = "markdown",
    exclude_domains: list[str] = None,
    sort_by: str = "date",
    use_regex: bool = False,
    use_fuzzy: bool = False,
    fuzzy_threshold: float = 0.6
) -> str

Example:

# Fuzzy search
search_history_advanced("pythn tutorial", use_fuzzy=True, fuzzy_threshold=0.7)

# Regex search
search_history_advanced(r"github\.com/.*/issues/\d+", use_regex=True)

sync_history

Sync history between browsers.

def sync_history(
    source_browser: str,
    target_browser: str,
    merge_strategy: str = "latest",
    dry_run: bool = True
) -> str

Example:

# Preview sync
sync_history("chrome", "firefox", dry_run=True)

# Actually sync
sync_history("chrome", "firefox", dry_run=False)

list_available_bookmarks

Returns a list of browsers with detected bookmarks.

def list_available_bookmarks() -> str

Example:

list_available_bookmarks()
# Output: Available browsers with bookmarks: chrome, edge, firefox

list_available_downloads

Returns a list of browsers with detected downloads history.

def list_available_downloads() -> str

Example:

list_available_downloads()
# Output: Available browsers with downloads: chrome, edge, firefox

get_bookmarks

Get bookmarks from a browser.

def get_bookmarks(
    query: str = None,
    limit: int = 50,
    browser: str = "chrome",
    format_type: str = "markdown"
) -> str

Example:

# Get all bookmarks
get_bookmarks(browser="chrome")

# Search bookmarks
get_bookmarks(query="python", browser="firefox")

get_downloads

Get downloads history from a browser.

def get_downloads(
    query: str = None,
    limit: int = 50,
    browser: str = "chrome",
    format_type: str = "markdown"
) -> str

Example:

# Get all downloads
get_downloads(browser="chrome")

# Search downloads
get_downloads(query="pdf", browser="firefox")

HTTP API

Endpoints

| Method | Endpoint | Description | |--------|---------|-------------| | GET | /health | Health check | | GET | /ready | Readiness check | | GET | /metrics | Basic metrics | | GET | /metrics/prometheus | Prometheus metrics | | GET | /api/browsers | List available browsers | | POST | /api/search | Search history | | POST | /api/recent | Recent history | | POST | /api/count | Count domain visits | | POST | /api/top-domains | Top domains | | POST | /api/search-date | Search by date | | POST | /api/delete | Delete history entries | | POST | /api/domain-search | Search by domain | | POST | /api/stats | Browser statistics | | POST | /api/most-visited | Most visited pages | | POST | /api/export | Export history | | POST | /api/advanced-search | Advanced search | | POST | /api/sync | Sync between browsers | | GET | /api/bookmarks | List available bookmarks | | POST | /api/bookmarks/query | Query bookmarks | | GET | /api/downloads | List available downloads | | POST | /api/downloads/query | Query downloads |

Request/Response Examples

POST /api/search

curl -X POST http://localhost:8080/api/search \
  -H "Content-Type: application/json" \
  -d '{"query": "python tutorial", "limit": 10, "browser": "chrome", "format": "markdown"}'

Response:

{
  "results": [
    {
      "title": "Python Tutorial",
      "url": "https://docs.python.org/3/tutorial/",
      "timestamp": "2024-01-15T10:30:00+00:00"
    }
  ],
  "count": 1
}

GET /health

curl http://localhost:8080/health

Response:

{
  "status": "healthy",
  "service": "chronicle-mcp",
  "version": "1.1.0",
  "timestamp": "2024-01-15T10:30:00+00:00"
}

Configuration

ChronicleMCP can be configured using environment variables or a config file.

Environment Variables

| Variable | Description | Default | |----------|-------------|---------| | CHRONICLE_CONFIG | Path to config file | ~/.config/chronicle-mcp/config.toml | | CHRONICLE_PORT | Default port | 8080 | | CHRONICLE_HOST | Default host | 127.0.0.1 | | CHRONICLE_BROWSER | Default browser | chrome |

Config File

Create ~/.config/chronicle-mcp/config.toml:

[default]
browser = "chrome"
limit = 10
format = "markdown"
log_level = "INFO"

Security & Privacy

  • Local-Only: All data stays on your machine
  • URL Sanitization: Sensitive query parameters are automatically removed:
    • token, session, key, password, auth, sid, access_token
  • Temp Files: History is copied to temporary files that are cleaned up after each query
  • No Data Collection: Your browsing data is never sent to any server
  • Error Messages: No sensitive file paths are exposed

Supported Browsers

ChronicleMCP supports reading history from the following browsers:

| Browser | Version | Windows | macOS | Linux | |---------|---------|---------|-------|-------| | Chrome | 120+ | %LocalAppData%\Google\Chrome\User Data\Default\History | ~/Library/Application Support/Google/Chrome/Default/History | ~/.config/google-chrome/Default/History | | Edge | 120+ | %LocalAppData%\Microsoft\Edge\User Data\Default\History | ~/Library/Application Support/Microsoft Edge/Default/History | ~/.config/microsoft-edge/Default/History | | Firefox | 121+ | %AppData%\Mozilla\Firefox\Profiles\*.default\places.sqlite | ~/Library/Mozilla/Firefox/Profiles/*.default/places.sqlite | ~/.mozilla/firefox/*.default/places.sqlite | | Brave | 1.30+ | %LocalAppData%\BraveSoftware\Brave-Default\History | ~/Library/Application Support/BraveSoftware/Brave-Default/History | ~/.config/BraveSoftware/Brave-Default/History | | Safari | 16+ | N/A | ~/Library/Safari/History.db | N/A | | Vivaldi | 6.0+ | %LocalAppData%\Vivaldi\Default\History | ~/Library/Application Support/Vivaldi/Default/History | ~/.config/vivaldi/Default/History | | Opera | 105+ | %AppData%\Opera Software\Opera Stable\History | ~/Library/Application Support/com.operasoftware.Opera/History | ~/.config/opera/History |


Troubleshooting

"Browser history not found"

  • Ensure the browser is installed
  • Check that Chrome/Edge isn't currently open (locks the database)
  • Run chronicle-mcp list-browsers to see detected browsers

"Permission denied"

  • Check file permissions on the browser's history database
  • On Windows, ensure the browser is closed before querying

Empty results

  • Try a more specific search term
  • Check the date range for search_history_by_date
  • Verify the browser has history data

Performance issues

  • Large history databases may take longer to query
  • Consider reducing the limit parameter

Development

Running Tests

# Run all tests
pytest

# Verbose output
pytest -v

# Specific test file
pytest tests/test_database.py

# Single test
pytest -k test_name

# With coverage
pytest --cov=chronicle_mcp

Development Server

# Run MCP server (stdio mode)
python -m chronicle_mcp mcp

# Run HTTP server
python -m chronicle_mcp http --port 8080

Code Quality

# Linting
ruff check .

# Formatting
ruff format .

# Type checking
mypy chronicle_mcp/

Contributing

Contributions are welcome! Please read our Contributing Guide for details.


License

MIT License - See LICENSE file for details.


Built with ❤️ for AI agents and developers

Quick Setup
Installation guide for this server

Install Package (if required)

uvx chronicle-mcp

Cursor configuration (mcp.json)

{ "mcpServers": { "nikolasil-chronicle-mcp": { "command": "uvx", "args": [ "chronicle-mcp" ] } } }