Repository navigation
Serve MCP 2026-07-28 statelessly from mcp-server-kit - #15
Merged
Merged
Conversation
Move the kit to the official MCP TypeScript SDK 2 and serve every request
through createMcpHandler with a fresh request-local server. Modern clients
get protocol 2026-07-28; 2025-era Streamable HTTP clients are served by the
SDK's stateless legacy mode, so there are no sessions, no Mcp-Session-Id,
and GET/DELETE answer 405.
Tool results are no longer reshaped: the invalid { type: "json" } content
item is gone (ChatGPT rejected results carrying it and retried, duplicating
writes), and tool failures are isError tool results with a platform code
instead of JSON-RPC errors with string codes. platform-conformance reads
failures from those results. Recorded as ADR 0016.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
@codelitdev/mcp-server-kit: MCP 2026-07-28, stateless, on SDK 2The kit was on MCP SDK 1, which tops out at protocol
2025-11-25, and it reshaped SDK results in two non-compliant ways:{ type: "json", json: … }to every tool result'scontent. MCP has nojsoncontent type. ChatGPT rejected every CourseLit tool result because of it and retried the call, so each "failed"products.createcreated another product (three courses for one request)."forbidden"), which JSON-RPC does not allow.SendLit already serves 2026-07-28 on SDK 2, and SendLit, FrontLit and MediaLit are to move onto this kit, so the kit now follows the same design (ADR 0016):
createMcpHandlerwith a fresh request-local server. Modern clients get 2026-07-28:server/discover, per-request envelopes,Mcp-Method/Mcp-Namevalidation,resultType, cache hints ontools/listandserver/discover(five minutes, private;catalogCacheHintoverrides).legacy: "stateless"mode.initializeno longer mintsMcp-Session-Id;GET/DELETEanswer405.createMcpServerKit,handle(),listTools()andshutdown()keep their shape. A legacy reply (a one-response SSE stream) is returned asapplication/json, which Streamable HTTP allows.structuredContentplus onetextcopy. A tool failure, including a destructive call withoutconfirm: true, is anisErrorresult withstructuredContent: { code, message, details }and HTTP 200. Authentication and context failures before dispatch return the platform error body with its HTTP status, as before.$schema. Annotations are spec-only (readOnlyHint,destructiveHint); the risk moves to_meta.risk.sessionsproperty. Hence a minor bump (0.5.0 for the fixed group).platform-conformancereads MCP tool failures fromisErrorresults. The reference product and template tests follow the new shapes.Verification
bun run verifypasses (lint, preset sync, typecheck, drift, tests, build, packed tests).text-only content, a repeat create returning a readableconflicttool result.