Files
Flash5/flash-extensions/flash-ext-mcp/docs/transport.md
T
Zakaria El OrcheandClaude Sonnet 5 d7f36a7aea
CI / Build & Test (push) Failing after 4m57s
feat(ext-mcp): add MCP (Model Context Protocol) server extension
Streamable HTTP transport (JSON-RPC 2.0 over POST), one-class-per-tool/resource/prompt
API mirroring RequestHandler, boot-time-precompiled schema/list payloads for a zero-alloc
hot path, and optional OAuth2 protection built on flash-ext-oidc (lazy-loaded, RFC 8707
audience binding, RFC 9728 Protected Resource Metadata). Registers the module in the
root and flash-extensions POMs and adds the ext-mcp commit scope to AGENTS.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 00:22:40 +00:00

46 lines
2.9 KiB
Markdown

# Transport
`flash-ext-mcp` implements the **Streamable HTTP** transport from the MCP specification
(revision `2025-11-25`). `stdio` is out of scope — Flash5 is an HTTP framework, and a
subprocess-stdio transport doesn't fit its model.
## What this revision implements
- A single `POST {rootPath}` endpoint (default `/mcp`) accepting one JSON-RPC 2.0 message per
request and responding with a plain JSON object — the "standard JSON object response" mode the
specification allows as an alternative to opening a Server-Sent Events stream per request.
- `Origin` header validation (DNS-rebinding protection), configurable via
`McpConfig.allowedOrigins(...)`.
- Full JSON-RPC lifecycle: `initialize`, `notifications/initialized` (and any other
`notifications/*`/id-less message — answered with a bare `202 Accepted`, no body, per
JSON-RPC's notification semantics), `ping`, `tools/list`, `tools/call`, `resources/list`,
`resources/read`, `prompts/list`, `prompts/get`.
## What this revision deliberately does not implement
- **No `Mcp-Session-Id` / session state.** The specification says a server "MAY assign a session
ID at initialization time" — it is optional, not mandatory. This server is stateless: every
`POST` is handled independently, with no server-side session store. `initialize` does not need
to precede other calls for the server to function (there's no session to be "not initialized"
yet), which is a looser contract than a session-aware server would enforce — acceptable for a
static, boot-time-defined tool/resource/prompt catalog.
- **No Server-Sent Events stream.** `GET {rootPath}` (used by session-aware servers to open a
standing SSE stream for server-initiated pushes) is not registered — MCP clients that only
speak the request/response half of Streamable HTTP work unaffected; clients that require a
standing SSE connection are not supported by this revision.
Both are real, intentional scope cuts for a first version — not just to keep the surface area
small: a static, precompiled tool catalog (see `tools-resources-prompts.md`) has no
`listChanged` events to push and no long-running server-initiated messages to stream, so the
stateful half of the transport buys little for the common case this extension targets. Sessions
and SSE are natural extension points if a future revision needs server push (e.g. dynamic tool
registration, elicitation, or sampling requests initiated by the server).
## Why `POST`, not the new `QUERY` HTTP method
Flash5's core recently gained `HttpMethod.QUERY` (safe, idempotent, carries a body — a good
semantic fit for JSON-RPC-over-HTTP in general). It is **not** used here: the MCP Streamable
HTTP specification mandates `POST` for the client-to-server message path. Real MCP clients send
`POST`; using `QUERY` instead would break interoperability with every existing client for a
semantic nicety this extension doesn't need standalone.