MCP 2026-07-28 (stateless) spec support - #5
Conversation
Add a concrete tools-only Streamable HTTP server for native compilation. Typed request envelopes, raw JSON fragments, concrete handlers, and explicit sessions avoid dynamic Function and Dict dispatch while preserving initialize, tools/list, tools/call, ping, and session lifecycle behavior.
…med responses - Return tools/prompts/resources/templates lists in deterministic sorted order so clients get stable prompt-cache-friendly results - Unknown tool/prompt in tools/call & prompts/get now return -32602 (Invalid params) instead of -32601; unknown resource in resources/read returns -32002 (Resource not found) per the 2025-11-25 spec - Client now handles Streamable HTTP POST responses delivered as SSE streams: request-scoped notifications/server requests are dispatched to registered handlers and the final JSON-RPC response is extracted Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
JSON.lazy/typed-parse request paths reach Parsers' recursive float parsing and repr()-based error formatting, neither of which passes the JuliaC --trim=safe verifier (456 errors). Replace them with a minimal self-contained scanner (string unescape incl. surrogate pairs, value extent skipping, Int64 ids) so the static server's entire request graph verifies clean. Drops the StructUtils dependency. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- test/trim_compile_tests.jl: standard trim harness (compiles workloads with --trim=safe in a temp env, requires 0 verifier errors/warnings, runs the produced executable); skips on Julia < 1.12/prerelease/32-bit - test/mcp_trim_safe.jl: StaticMCPServer workload exercising the full session + tools request lifecycle over in-memory HTTP requests - New testset covering deterministic list ordering, spec error codes, and SSE-streamed POST response handling in the client Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Dual-era server: requests declaring 2026-07-28 (via params._meta io.modelcontextprotocol/protocolVersion or the MCP-Protocol-Version header) are served statelessly with no session or initialize handshake; legacy clients keep the existing session flow on the same endpoint. Server: - server/discover with supportedVersions/capabilities/serverInfo - Mcp-Method/Mcp-Name request header validation incl. the =?base64?...?= sentinel encoding (HeaderMismatch -32020), header/_meta version consistency, UnsupportedProtocolVersionError -32022 with supported list - resultType on all results; ttlMs/cacheScope on list/read results (config: cache_ttl_ms, cache_scope) - MRTR: handlers return MCPInputRequired to request client input; input_responses/request_state context accessors on the retry - Request-scoped notifications: send_progress!/send_log! (gated on progressToken / io.modelcontextprotocol/logLevel _meta) delivered as an SSE response stream ahead of the final response; handlers stay on the request task so task-local auth contexts survive - subscriptions/listen long-lived streams with acknowledgment, subscriptionId tagging, and graceful closure via close_subscription_listeners!; wired into list-changed/resource-updated broadcasts - Removed-in-2026-07-28 methods (initialize, ping, logging/setLevel, resources/subscribe...) return 404/-32601 on the modern path; resource-not-found maps to -32602 per the new spec Client: - protocol_version >= 2026-07-28 skips the initialize handshake, injects _meta (protocolVersion/clientInfo/clientCapabilities) into every request, and sends Mcp-Method/Mcp-Name headers - discover_server_info!, is_input_required, call_tool/get_prompt/ read_resource input_responses/request_state kwargs, call_tool meta kwarg, listen_subscriptions! real-time notification stream Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ptions Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ion tests Two CI failures under HTTP.jl 2.x (CI resolves 2.5.5; local dev env had 1.11, which masked both): - Tool/prompt/resource/completion/logging/cancellation handlers and the request hook are now invoked via Base.invokelatest: handlers registered after HTTP serving starts were hitting 'method too new to be called from this world context' when connection tasks dispatched them. - HTTP.jl 2.x's server buffers SSE response bodies until the stream closes (reproducible with its own sse_stream do-block example), so mid-stream subscriptions/listen events only reach the client at graceful closure there. The subscriptions test now asserts live delivery only where the transport streams (HTTP 1.x) and asserts complete delivery at graceful close under both. Fixing the buffering belongs in HTTP.jl itself. Full suite verified green under both HTTP 1.11 and HTTP 2.5.5. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
CI is fixed — two distinct issues, both only reproducible under HTTP.jl 2.x (CI resolves 2.5.5; the local dev manifest had 1.11.0 which masked them):
Full suite verified locally under both HTTP 1.11.0 and HTTP 2.5.5 (fresh-resolve env mirroring CI). |
Validate JSON, initialization parameters, tool schemas, and result shapes in the trim-safe server. Prevent request-only methods from running as notifications and return stable JSON-RPC errors for handler failures. Add regression tests and executable documentation.
…x/review-pr5-fixes # Conflicts: # src/server.jl
# Conflicts: # test/runtests.jl
Summary
Implements the released MCP
2026-07-28protocol as a dual-era client and server. Stateful2025-11-25clients continue to use initialization and sessions. Modern clients use stateless request metadata andserver/discoveron the same Streamable HTTP endpoint.Server
_meta, protocol headers,Mcp-Method,Mcp-Name, and recognizedMcp-Param-*headers before handler execution.server/discover, cache metadata, request-scoped progress and log events, and filteredsubscriptions/listenstreams.input_requiredresults from tools, prompts, and resources. Unsupported client interactions are filtered by declared capabilities.Client
x-mcp-headerschema validation, tool filtering, nested parameter extraction, safe-integer checks, Base64 encoding, and schema caching.server/discoverinstead of the removed initialization handshake in modern mode.Compatibility and documentation
2025-11-25, OAuth, MCP Apps, and JuliaC static-server behavior.Validation
2026-07-28checks.--trim=safecompile check passed.0.2.0-alpha.10: 97/97 relevant checks passed with no warnings. This covers stateless metadata, standard headers, custom headers on both client and server, malformed-tool filtering, elicitation, sampling, roots, prompt MRTR, and capability filtering.Support limit
Request-scoped progress and log events use the correct SSE wire format and order, but the current server buffers them until the handler returns. Long-lived independent notifications use
subscriptions/listen.Co-authored by Codex