13. The MCP server is part of the app: streamable HTTP, add-only writes#
Date: 2026-10-20 (#37, #93)
Status#
Accepted. Revises the first design’s implicit idea of a local scrap mcp command. See also
19. Kinds and tags editable over MCP, made safe by metadata revisions, which adds the edit_meta, rename_tag,
revisions and revert tools, and 20. Text enrichment: Claude tags, summarises and relates text pages, apart from the text, whose output read returns as
by_model.
Context#
Claude is meant to be how scrap is queried: search, read and add pages. A client session needs a server it can add with one line, from anywhere on the tailnet.
Decision#
Served at
/mcpby the official MCP SDK inside the FastAPI process: Streamable HTTP, stateless, JSON replies. A stdio command was rejected because it needs a shell where the database is, which no client session has.Tools:
search(the search box’s syntax),read,recent,todos,tags, andwrite. Results carry each page’s PWA URL ($SCRAP_PUBLIC_URL/p/<slug>) and its images as URLs, so Claude links to the PWA instead of trying to show pictures. Page text is returned as JSON field data.writeonly adds: a new page, or a section appended to a page written over MCP. It cannot edit or delete the user’s own pages. Provenance is the capture sourcemcp(which HTTP clients cannot send), authorclaude, andfields.origin; the PWA shows a badge andis:claudefilters. A client key is hashed into the capture id, reusing the retry key mechanism.Deferred: ingest of URLs or text, a
contexttool replaying a photo’s model run, deleting, and changing an existing page’s kind or status (writecan set kind, status, due and priority on a new page).
Consequences#
/mcpchecks the Host/Origin of requests, which guards against DNS rebinding.No separate process or credentials; the tailnet protects it as in 7. Tailscale Serve is the only way in; no login code.
Page text may contain prompt injection, so sessions with other powerful credentials should not mount it. Add-only writes bound the damage.
Mixing skills with the tool is a documented pattern: see Connect a Claude Code session, and the
sccommands incommands/in the repository.No MCP tool calls the Claude API:
writeadds text andreadreturns what enrichment stored (by_model: summary, Claude’s tags, related pages, marked as model output and data, never instructions), so MCP use adds nothing to the daily budget of 10. Queue error classes: outages pause, charged failures count, spend is capped.