Files
mcpedia/content/docs/mcp/streamable-http.md
T
asepharyana 53d636af0e
CI / typecheck + build (turbo) (push) Canceled after 0s
feat(phase7): grow corpus, MCP write-tools+auth, /metrics observability
- content/: +5 real docs (caddy, bullmq, mcp-streamable-http, postgres-fts,
  cloudflare-525 writeup) across docs/writeups/notes. Reindexed: 9 docs, 17
  chunks, 5 revisions (was 4 docs).
- apps/mcp: add write-tools index_document/reindex_all/restore_revision (require
  x-webhook-secret) + queue_status (public). createMcpServer(authSecret?) threads
  the HTTP header; stdio keeps writes open (trusted local).
- apps/api: GET /metrics (Prometheus text: uptime + queue job gauges).
- Caddy: expose /metrics on wiki. domain -> :4020.
Verified live: /metrics 200; MCP tools/list -> 10; index_document unauth -> error,
auth -> enqueues + worker drains; typecheck green.
2026-08-20 10:04:16 +07:00

1.9 KiB

id, title, type, tags, status, author, created_at, updated_at
id title type tags status author created_at updated_at
mcp-streamable-http MCP Streamable HTTP Transport documentation
mcp
protocol
http
infra
published asep 2026-08-20 2026-08-20

MCP Streamable HTTP Transport

The MCPedia MCP server is served over Streamable HTTP (the MCP 2025-03-26 transport) so remote clients — Claude, a Discord bot, a web frontend — can call its tools and read its resources without spawning a stdio subprocess.

Why stateless

The server uses StreamableHTTPServerTransport in stateless mode (sessionIdGenerator: undefined):

  • One McpServer + transport is created per request.
  • No session affinity, no shared-transport connect() race, no session-map memory leak under burst traffic.
  • Re-registering the 6 tools + 4 resources per request is negligible for a KB-sized corpus.

Stateful mode (a sessionIdGenerator returning a UUID) would require holding a transport map keyed by session id and cleaning it up on onclose. For this read-mostly knowledge base, stateless is simpler and equally correct.

Endpoint

POST https://mcp.asepharyana.my.id/mcp
Content-Type: application/json
Accept: application/json, text/event-stream

Responses use SSE framing (event: message / data: {...}) even for unary results. Clients must send Accept: application/json, text/event-stream or the server returns 406. The MCP initialize handshake sets protocolVersion: "2025-03-26".

CORS

/mcp returns permissive CORS headers (Access-Control-Allow-Origin: *) so browser clients can call it directly. Preflight OPTIONS is answered with 204.

Auth for write tools

Read tools (search_documents, get_document, ...) are open. Write tools (index_document, reindex_all, restore_revision) require the x-webhook-secret header to match WEBHOOK_SECRET — the same shared secret used by the git-sync webhook. A missing/invalid header makes the tool return an error before any mutation.