think
16px
820px

MCP module — design

Approved (user): build as a PAID module (mcp in KnownModules).

What it is

A Model Context Protocol server inside the existing Go monolith: MCP clients (Claude
Desktop / Claude Code / any MCP-capable agent) connect to POST /api/v1/mcp (Streamable
HTTP, stateless JSON-RPC 2.0 — hand-rolled, no new dependency) using an existing Obscura
API key as the bearer token. Every tool call resolves through the standard
Authenticator middleware to that key's user Principal — same ACL filtering, module gates
and generic-error discipline as the UI. GET /api/v1/mcp returns 405 (stateless servers
need no SSE listening stream; no Mcp-Session-Id is issued — permitted by the spec).

Tools (v1 — read-only, DLP-safe)

tool maps to notes
search_documents dms.SearchAdvanced full-text over title+content+tags
list_folders dms.ListFolders optional parent_id
list_documents dms.ListDocuments by folder
get_document dms.GetDocument + versions metadata only
read_document extracted content text text only, never raw bytes — the watermark/DLP egress chokepoint cannot be bypassed by an AI client
semantic_search semantic chunk search only when semantic module licensed

ask_archive and write tools (upload / add version, behind a per-key scope) are v1.5.

Gating

  • License: requireModule("mcp") on the endpoint and the admin routes; mcp added to
    KnownModules (licensegen validates against it).
  • Admin kill switch: single-row mcp_settings table (mig 00119), enabled default TRUE
    (the license is the paid gate; the toggle is operational). Endpoint 403s
    mcp.disabled when off.

Admin → MCP tab (module-gated)

Status (module active + enabled toggle) · endpoint URL with copy · ready-to-paste Claude
Code / Claude Desktop config snippet · API-key manager (issue/list/revoke — backend
IssueAPIKey existed with no UI; List/Revoke routes added) · Download API docs
(existing public /api/v1/openapi.yaml) + the MCP tool list rendered inline.

Non-goals (v1)

OAuth flows (API keys are the auth story), sessions/resumable SSE, write tools,
per-tool scopes, prompts/resources capabilities (tools only).

Verification

Live on demo (license regenerated with mcp): initialize → tools/list → tools/call
(search + read) via curl with a real API key; 401 without a key; 403 with the toggle
off; admin tab screenshot; /me enabled_modules includes mcp.