Skip to content

MCP Server

David edited this page May 31, 2026 · 1 revision

MCP Server

Semantic Reading ships an MCP server that exposes the vault tag index, concept hubs, due-cards queue, domain profiles, and the AI suggest tool over JSON-RPC 2.0 / HTTP. Compatible with Claude Desktop, Cursor, VS Code, and any MCP client.

Enabling

Settings → MCP server → toggle Enable MCP server.

  • Bound to 127.0.0.1 only — no LAN exposure.
  • Default port 8745. Change if collides.
  • Optional bearer token. With a token set, clients must send Authorization: Bearer <token>.
  • Desktop Obsidian only. No-op on mobile (no Node sockets available).

Client config

Click Copy config in the MCP settings panel to copy a ready-to-paste snippet:

{
  "mcpServers": {
    "semantic-reading": {
      "url": "http://127.0.0.1:8745/",
      "headers": { "Authorization": "Bearer <your-token>" }
    }
  }
}

Drop into Claude Desktop's claude_desktop_config.json or Cursor's mcp.json. Restart the client.

Tools

10 tools total. All read-only against the vault index except sr_suggest_tags, which calls Anthropic's API using your configured key.

Query tools

sr_query_by_tag

List every mention of a tag across the vault.

{ "tag": "Q" }

Returns { tag, count, mentions: [{ notePath, paraIndex, blockId, text, note?, wikilink? }] }.

sr_list_concepts

All concept (Def) hub entries with mention counts and top co-occurring concepts, sorted by mentions desc.

{ "limit": 100 }

Returns { totalConcepts, returned, concepts: [{ canonical, display, mentions, coOccurs }] }.

sr_get_concept

Single concept by canonical slug.

{ "canonical": "cognition" }

Use sr_canonicalize first if the user provided free-form text (e.g. "Cognition""cognition").

sr_canonicalize

Convert free-form display text into the canonical slug used internally for hub lookups.

{ "text": "Public Health!" }

Returns { input, canonical: "public-health" }.

sr_open_questions

Every open question (Q-tagged span) across the vault.

sr_due_cards

Cards (Def + Q) currently due for review per the FSRS scheduler.

{ "limit": 50 }

sr_tag_counts

tag -> mention count map across the whole vault.

sr_get_hub_content

Read the markdown body of a concept hub page (Concepts/<canonical>.md).

Domain tools

sr_domains_list

List configured domain profiles with their tag sigils and merge modes.

sr_domains_for_note

Resolve the active domain profile and effective tag dictionary for a note path.

{ "notePath": "Inbox/today.md" }

Returns:

{
  "notePath": "Inbox/today.md",
  "domain": { "name": "meeting", "label": "Meeting", "mergeMode": "add" },
  "tags": [
    { "sigil": "Def", "name": "Definition", "family": "Meaning", ... },
    { "sigil": "Dec", "name": "Decision", "family": "Execution", ... },
    ...
  ]
}

Use this when an MCP client needs to know which sigils are valid in a given note before suggesting tags.

AI tool

sr_suggest_tags

Ask the AI co-reader to propose semantic tags for a paragraph.

{
  "paragraph": "Cognition depends on attention, but attention is a limited resource.",
  "mode": 3,
  "existingTags": [{ "tag": "Def", "text": "cognition" }]
}

Returns { suggestions: [{ tag, span, confidence?, rationale? }] }.

Requires the plugin's Anthropic API key to be configured (Settings → AI co-reader). The active reading mode's palette bounds the suggestions; pass mode to override.

Protocol details

  • Transport: HTTP POST to / with Content-Type: application/json.
  • Format: JSON-RPC 2.0.
  • Errors: standard JSON-RPC error codes. Missing Authorization returns 401.
  • Initialization handshake: standard MCP initialize → server returns capabilities (tools only — no resources or prompts yet).
  • Discovery: tools/list returns the 10 tools with full input schemas.

Verifying it's up

In Obsidian: Cmd-P → MCP server: show status. Notice shows the port and whether auth is required.

From shell:

curl -X POST http://127.0.0.1:8745/ \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <your-token>' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

See also

Clone this wiki locally