Blog

Beta4 Is Here. Upgrade All Your MCP Servers With One Line.

Brian Sloane ·August 18, 2026
Table of contents

Three weeks ago we wrote that the 2026-07-28 MCP revision was the biggest breaking change since the protocol launched, and that capabilities running on Ikanos would ride through it as one engine upgrade with zero edits to any capability file. At the end of that post, we said we would show the diff when Ikanos shipped support.

Ikanos v1.0.0-beta4 shipped this week with 2026-07-28 support. This is that post.

We took two capabilities from earlier write-ups, the Notion to GitHub spec sync and the support voice assistant, ran them on beta3, changed one thing, and pointed a real MCP client at both before and after. Every command and diff below was run against the real engine.

The bump

The engine is a plain docker run, straight from the install docs. The version is the image tag. Moving from beta3 to beta4 means changing that tag:

- ghcr.io/naftiko/ikanos:v1.0.0-beta3
+ ghcr.io/naftiko/ikanos:v1.0.0-beta4
$ docker run -p 9095:9095 -p 9198:9198 \
    -v $(pwd)/capabilities/notion-github-spec-sync.yaml:/app/ikanos.yaml \
    ghcr.io/naftiko/ikanos:v1.0.0-beta4
MCP Server started on 0.0.0.0:9095 (namespace: spec-sync)
Capability started successfully.

If you manage the engine through docker-compose.yml, it’s the same edit in a file instead of on the command line. Ikanos doesn’t care how the image gets pulled, only which tag it is. Compose just means the tag lives somewhere you can diff:

$ docker compose up -d
notion-github-spec-sync-1  | MCP Server started on 0.0.0.0:9095 (namespace: spec-sync)
support-voice-assistant-1  | MCP Server started on 0.0.0.0:9096 (namespace: voice)
notion-github-spec-sync-1  | Capability started successfully.
support-voice-assistant-1  | Capability started successfully.

Both capabilities are back up on the current MCP specification. Their own files were not touched, including the ikanos: line inside each one.

The diff on every capability

A real git diff across the tagged commits, on both capability files, before the bump and after:

$ git diff before after -- 'capabilities/*.yaml'
(exit code: 0)

Zero files changed. Zero insertions. Zero deletions. Not “no breaking changes we noticed.” Zero bytes.

The file that describes what your capability does was never a place the transport migration could touch, because the transport never lived there. It lives in the engine.

The diff on the tool contract

Unchanged YAML is half the promise. The other half is that the agent sees the same thing before and after. We captured tools/list against both engine versions and diffed the raw responses:

$ diff fixtures/beta3/tools-list.json fixtures/beta4/tools-list.json
       ]
+      "resultType": "complete",
+      "ttlMs": 0,
+      "cacheScope": "private",
+      "_meta": {
+        "io.modelcontextprotocol/serverInfo": {
+          "name": "spec-sync",
+          "version": "unspecified"
+        }
+      }

That is the entire substantive difference, and it repeats identically for the second capability. The tool itself is identical left to right — same name, title, description, inputSchema, and safety hints, byte for byte, for all three tools across both capabilities.

The only additions sit outside the tool definition: ttlMs and cacheScope, response-level caching hints from the 2026-07-28 spec. A client can use them. A capability author never has to think about them.

The transport actually moved

The wire underneath changed shape, which is the reason a migration post exists at all. beta3 spoke the old session-based handshake:

# beta3 · POST /mcp · initialize
HTTP/1.1 200 OK
Mcp-Session-Id: 6f04252a-5320-4aca-99b4-ecb6175ab30c

{"result":{"protocolVersion":"2025-11-25", ...}}

Send that same request to beta4 and it doesn’t get as far as being an unknown method:

HTTP/1.1 400 Bad Request

{"jsonrpc":"2.0","id":1,"error":{"code":-32020,
  "message":"Missing mandatory header: Mcp-Method"}}

beta4 speaks the stateless 2026-07-28 core. No handshake. Protocol version and method travel with every request instead of being negotiated once:

# beta4 · POST /mcp · tools/list, no prior handshake
Mcp-Method: tools/list
MCP-Protocol-Version: 2026-07-28

{"result":{"tools":[...], "resultType":"complete",
  "ttlMs":0, "cacheScope":"private"}}

That is a real break for a client hardcoded to the old handshake, and it is meant to be. The MCP spec’s own compatibility matrix documents legacy client × modern server → fails as the expected outcome for a modern-only server. It’s not an Ikanos choice.

The current Tier-1 SDKs (TypeScript, Python, Go, C#) already speak 2026-07-28, and the Python and TypeScript v2 SDKs support every earlier revision too. The one thing to check before you change the tag in production is what your agent’s client dependency is running. Not your capability files.

One certification, not many

Before Ikanos, verifying a transport migration was safe meant re-reviewing every capability that touches MCP. Two capabilities meant you had to do two reviews. Here it is one engine, reviewed once, inherited by both. Every capability you add later inherits the same guarantee without a second audit, because the thing that changed was never expressed in any of them.

What we verified:

  • Capability YAML — 0 bytes changed across both files
  • Tool contract — identical name, description, schema, hints
  • Engine — started clean on beta4, serving both capabilities
  • Wire protocol — checked against the public 2026-07-28 spec, not just the release notes

Also in beta4

Naftiko’s 1.0.0-beta4 releases didn’t stop there. The rest of the releases are about testing what we say holds.

  • Ikanos has its first real end-to-end suite. CI brings up Keycloak and Microcks in Docker Compose, starts Ikanos against them, and exercises the OAuth 2.1 and Bearer paths with real tokens and real JWKS discovery, plus an invalid token to confirm rejection works.
  • A feature coverage tracker maps all 32 blueprint features against test depth and delivery progress. It works as a roadmap and as a plain list of what is still thin.
  • Polychro’s “iso-functional with Spectral” claim is now a harness rather than a sentence. Same ruleset, same document, run through both engines, diagnostics diffed.
  • Trivy scans now gate Polychro’s Maven and CLI release pipelines. CLI binaries ship with SHA256 checksums. Five CVEs patched.
  • Polychro fix: paths in .polychro.yml resolve against the config file, not the working directory.

Crafter, Warden, and Skipper picked up the beta4 schema and engine versions in the same coordinated release.

The takeaway

The migration cost was real. It landed where the architecture said it would: in the engine, once, instead of in every capability, every time.

If you run Ikanos today, the action item is not “audit your YAML.” It’s “change the image tag, and make sure whatever calls you is on a current MCP client.”

Subscribe to the Naftiko Manifest

Want to learn more and stay up to date on the latest from Naftiko? Get new posts, releases, and signals from the capability fleet in your inbox.