The 2026-07-28 revision made MCP stateless — no initialize handshake, no sessions, no server-initiated requests. That is a far better fit for a shell script than what came before, so this release brings the SDK up to that revision and takes advantage of it.
Highlights
- MCP 2026-07-28 — per-request version negotiation via
params._meta,server/discover,resultType, cache hints on list results. - Both standard transports — stdio and Streamable HTTP, from the same server file (
--http). Both call the sameprocess_request, so they cannot drift. - Four runnable examples — git, weather (API wrapping), filesystem (path-traversal boundary), movies — plus a build-your-own walkthrough.
- Verified on macOS, Debian, Alpine and Ubuntu.
./scripts/test-linux.sh allreproduces it. - Documentation site with 7 ADRs and 3 runnable spikes.
Bugs fixed that only appeared on Linux
- Tool payloads over ~128 KB failed. Linux caps a single
argventry atMAX_ARG_STRLENregardless ofARG_MAX; macOS has no such cap. Passing tool output throughjq --argworked on the dev machine and failed in production. Large content now goes tojqon stdin. - The HTTP server could not be stopped. bash defers traps until the current foreground command finishes, and
ncblocks waiting for a connection, soSIGTERMstayed pending forever. The accept pipeline now runs backgrounded with an interruptiblewait— shutdown is instant, no orphans, and the HTTP suite went from ~2 minutes to ~2 seconds. - Dropped the
bcdependency (absent from slim images); the netcat listen syntax is probed rather than sniffed.
Breaking changes
- Clients older than
2026-07-28are rejected with-32022. The revision removed theinitializehandshake; this SDK implements the new one only. See ADR-0002. - A tool returning non-zero is now a successful result with
isError: true, not a JSON-RPC-32603, so the model can see the failure and self-correct. Tool authors keep the sameecho+return 0|1contract. Missing tool moves-32601→-32602. MCP_CONFIG_FILEis now aserver/discoverbody (supportedVersions,capabilities,ttlMs,cacheScope,serverInfo) rather than aninitializeresult.- Internal:
create_responsereads its result object from stdin instead of$2. A custom transport calling it with two arguments must pipe instead.
Verification
31 unit · 19 HTTP transport · 6 schema-conformance tests against the official published schema (vendored at spec/schema-2026-07-28.json). Green on macOS under both bash 3.2 and 5.3, and on Debian, Alpine (musl + busybox) and Ubuntu.
Full changelog in VERSIONS.md.