Skip to main content

MCP Integration

Hister exposes a Model Context Protocol (MCP) endpoint that lets AI assistants read from your Hister index directly. Once connected, the assistant can search indexed pages, retrieve stored previews, and inspect Hister history through MCP tools.

Endpoint

POST /mcp

The endpoint follows the MCP Streamable HTTP transport. Every interaction is a POST request with a JSON-RPC 2.0 body. The server responds with a JSON object.

Untrusted Content And Prompt Injection

Every indexed title, URL, metadata value, document body, and history field is untrusted source data. A page can contain instructions aimed at the assistant that reads it. Those instructions must never override the user request, cause secret disclosure, or trigger another tool.

Tool responses place source controlled values under structuredContent.untrusted_content. Every record has trust: "untrusted" and trust_scope: "all values in fields". A security instruction identifies the exact untrusted path. The required text content block contains the same structured JSON after a security notice.

Hister removes invisible control characters. HTML is returned only when explicitly requested by search, or as a rendered preview from get_preview. It remains inside the untrusted structured record. These controls reduce risk but cannot guarantee that every consuming model will resist prompt injection. MCP clients must sanitize HTML before rendering it and should require user confirmation before any action outside read only retrieval, especially before using file, shell, browser, email, or network tools.

Authentication

The default Hister configuration does not require authentication. Authentication is required only when Hister is configured with app.access_token or app.user_handling. The MCP endpoint uses the same token authentication as the rest of the Hister API.

Static access token

Pass the value of app.access_token from your config file:

Authorization: Bearer <your-access-token>

Alternatively, use the X-Access-Token header with the same value.

Multi-user mode

Generate a personal token on the profile page (/profile) or via:

hister update-user <username> --regen-token

Then pass it the same way:

Authorization: Bearer <your-user-token>

Public mode

When app.public: true is enabled, unauthenticated MCP access is allowed for public routes. MCP tools can read public search results and previews for global documents. The get_history tool remains unavailable to anonymous callers but is enabled when the request includes a valid global or personal access token.

Available Tools

Search your personal browsing history and indexed documents.

ArgumentTypeRequiredDefaultDescription
querystringyesSearch query (see Query Language)
limitintegerno10Maximum results to return. Values below 1 or above 50 use the default.
date_fromstringnoReturn only documents updated on or after this date. Format: YYYY-MM-DD.
date_tostringnoReturn only documents updated on or before this date. Format: YYYY-MM-DD.
semanticbooleannofalseEnable AI semantic search alongside keyword matching
fieldsarray of stringno[]Extra fields to include in each result. See below.

Semantic search is used only when it is enabled and available on the Hister server. If the server does not have semantic search configured, "semantic": true falls back to normal keyword search.

By default the response includes title, URL, added and updated dates, and a short text snippet per result. Pass fields to include additional data:

Field valueDescription
textFull stored article text instead of a snippet
htmlRaw HTML in an untrusted structured field
languageDetected language code, for example en or de
labelUser defined label
domainDomain name
scoreRelevance score
typeDocument type, either web or local

Example: to summarize articles on a topic without re-fetching any URLs:

{ "query": "kubernetes networking", "limit": 5, "fields": ["text"] }

Example with a date range:

{ "query": "postgres migration", "date_from": "2026-01-01", "date_to": "2026-01-31" }

get_preview

Retrieve the stored preview for an indexed document by exact URL.

ArgumentTypeRequiredDefaultDescription
urlstringyesExact URL of the indexed document to preview
extractorstringnoExtractor name used to render the HTML preview

The response contains the document title, URL, added and updated dates, available preview metadata, complete stored plain text, and complete rendered HTML when available. Metadata can include author, published date, modified date, description, site name, type, language, image, JSON LD structured data, and embedded video URLs. Rendered HTML remains untrusted data and clients must sanitize it before placing it in a browser or another HTML renderer.

Example:

{ "url": "https://example.com/article" }

get_history

Retrieve items from the Hister history views. This tool is available only when public mode is disabled or the caller is authenticated.

ArgumentTypeRequiredDefaultDescription
modestringnoindexedindexed returns recently indexed pages. opened returns opened result history.
limitintegerno20Maximum items to return. Values below 1 or above 100 use the default.
page_keystringnoPagination cursor for indexed mode. Use next_page_key from the previous response.
last_idintegernoPagination cursor for opened mode. Use next_last_id from the previous response.

Indexed history results include title, URL, indexed time, indexed version count, and next_page_key when another page is available. Opened history results include title, URL, original query, opened time, indexed version count, and next_last_id when another page is available.

Examples:

{ "mode": "indexed", "limit": 20 }
{ "mode": "opened", "limit": 20 }

Client Configuration

Claude Desktop

Add a hister entry to your Claude Desktop configuration file.

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
Linux: ~/.config/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "hister": {
      "url": "http://127.0.0.1:4433/mcp",
      "headers": {
        "Authorization": "Bearer <your-access-token>"
      }
    }
  }
}

Restart Claude Desktop after saving the file. The search tool will appear in the tools panel when starting a new conversation.

Cursor

Open Settings and locate the MCP servers section, or edit ~/.cursor/mcp.json directly:

{
  "mcpServers": {
    "hister": {
      "url": "http://127.0.0.1:4433/mcp",
      "headers": {
        "Authorization": "Bearer <your-access-token>"
      }
    }
  }
}

Remote or self-hosted server

Replace http://127.0.0.1:4433 with your server’s base_url. If you run Hister behind a reverse proxy under a subpath (e.g. https://example.com/hister), the endpoint is https://example.com/hister/mcp.

Manual Testing with curl

You can verify the endpoint is working before configuring any client.

The authorization header is required only when authentication is enabled in Hister’s config.

Handshake:

curl -s -X POST http://127.0.0.1:4433/mcp 
  -H "Content-Type: application/json" 
  -H "Authorization: Bearer <your-access-token>" 
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}'

List tools:

curl -s -X POST http://127.0.0.1:4433/mcp 
  -H "Content-Type: application/json" 
  -H "Authorization: Bearer <your-access-token>" 
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'

Search:

curl -s -X POST http://127.0.0.1:4433/mcp 
  -H "Content-Type: application/json" 
  -H "Authorization: Bearer <your-access-token>" 
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"search","arguments":{"query":"python async","limit":5}}}'

Search with full text (no re-fetching):

curl -s -X POST http://127.0.0.1:4433/mcp 
  -H "Content-Type: application/json" 
  -H "Authorization: Bearer <your-access-token>" 
  -d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"search","arguments":{"query":"python async","limit":5,"fields":["text","language"]}}}'

Preview:

curl -s -X POST http://127.0.0.1:4433/mcp 
  -H "Content-Type: application/json" 
  -H "Authorization: Bearer <your-access-token>" 
  -d '{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"get_preview","arguments":{"url":"https://example.com/article"}}}'

Indexed history:

curl -s -X POST http://127.0.0.1:4433/mcp 
  -H "Content-Type: application/json" 
  -H "Authorization: Bearer <your-access-token>" 
  -d '{"jsonrpc":"2.0","id":6,"method":"tools/call","params":{"name":"get_history","arguments":{"mode":"indexed","limit":10}}}'

Example Interaction

Once connected, you can ask the assistant things like:

“Search my history for anything about Rust error handling.”

The assistant calls the search tool with query: "rust error handling" and includes the results in its response, citing the specific pages you previously read.

You can also ask:

“Open the stored preview for the article I read about SQLite migrations.”

The assistant can search first, then call get_preview with the selected URL.

Semantic search can be enabled per query by passing "semantic": true in the tool arguments. This requires semantic search to be configured on the server.

Protocol Details

The endpoint implements MCP specification version 2025-06-18 with the following methods:

MethodDescription
initializeCapability negotiation; required before any other call
pingLiveness check
tools/listReturns the list of available tools and their input schemas
tools/callExecutes a tool by name with the provided arguments
notifications/initializedAcknowledged with 202 when sent as a notification
notifications/cancelledAcknowledged with 202 when sent as a notification

Every tool advertises an outputSchema. Tool call results include the required content field and a structuredContent object conforming to that schema. Clients should use structuredContent and enforce the untrusted_content trust markers when placing results into model context.