codec-metamcp (Docker)

MetaMCP gateway with Codec binary transport. The MCP aggregator, but tool-call results ship as length-prefixed msgpack instead of newline-delimited JSON-RPC.

codec-metamcp is a pre-built Docker image of MetaMCP — the MCP aggregator/orchestrator/gateway — with the Codec binary transport patch applied. Stand it up like the upstream image, point any MCP client at it, and tool-heavy sessions ship dramatically smaller wire bytes when the client opts into Codec.

Unlike codec-sglang / codec-vllm / codec-llamacpp, this image doesn’t bundle a Python control plane. MetaMCP already ships an admin UI as its frontend (Next.js) for namespace + server management, so there’s nothing for codec-supervisor to add. The image is just MetaMCP, built from the wdunn001/metamcp fork.

Quick start

docker run -d \
  -p 12008:12008 \
  -e APP_URL=http://localhost:12008 \
  -e POSTGRES_URL=postgres://user:pass@db:5432/metamcp \
  --name codec-metamcp \
  wdunn001/codec-metamcp:latest

Frontend admin UI is on :12008 — create a namespace, add a few MCP servers, click through to copy the namespace endpoint URL. That URL works against any standard MCP client (Claude Desktop, Cursor, Cline, etc.) byte-for-byte identically to upstream MetaMCP.

The Codec wire format is opt-in per request — clients that don’t negotiate it see exactly the JSON-RPC bytes upstream MetaMCP would emit.

Negotiation

Three equivalent ways to opt in. Resolution order, first match wins:

?stream_format=msgpack     # or protobuf  (URL query param)
Accept: application/x-codec-msgpack    # request header
?stream_format=json        # explicit opt-out (back to JSON-RPC)

Add Accept-Encoding: zstd, br, gzip, identity for the full v0.4.1 compression menu (server picks per spec order zstd > br > gzip > identity; MCP-shaped zstd dict ships ~4.7× over JSON+gzip on real MCP traffic).

What you get

For tool-heavy sessions — long file reads, web fetches, RAG context, model-generated text piped through tools — the wire weight collapses. Same physics as the cross-stack benchmark matrix:

  • Length-prefixed msgpack/protobuf framing instead of newline-delimited JSON-RPC envelopes
  • Full v0.4.1 compression stack (gzip + brotli + dict-zstd) on top via standard Accept-Encoding negotiation, per spec preference order zstd > br > gzip > identity
  • TTFB unchanged — first-body-byte stays within 1 ms of the JSON-RPC path on the same server
  • MCP-shaped zstd dictionary negotiation — the gateway loads a pre-trained 16 KB dict at startup and emits a Codec-Zstd-Dict: sha256:… header so a Codec-aware client can fetch the matching dict and decompress every frame against it. +78.8 % wire-byte reduction over no-dict zstd; ~4.7× over JSON+gzip on real MCP traffic (2026-05-08T22-24-23Z bench).
  • Leaf-mode bypass for Codec-aware tools — tools that wrap their results with _codec_meta blocks (see @codecai/mcp-leaf and the codec-time-leaf reference image) tell the gateway “the IDs are already here, don’t re-tokenize.” [Codec][leaf] log fires on bypass; [Codec][shim] log fires on legacy fallback.
  • Frame shape compatible with @codecai/web, codecai, and the four other client libraries — same decodeStream decoders that work end-to-end against codec-sglang / codec-vllm / codec-llamacpp work here too.

The follow-up release adds per-token Codec encoding for text content blocks beyond the leaf-mode path (the headline wire reduction lives there) plus a Translator middleware for cross-vocab tool handoff. The framing foundation for both is live today.

Codec-aware tools (leaf mode)

The fast path on a Codec-aware gateway isn’t the gateway tokenizing tool results — it’s the tool itself doing the tokenization once, against a pinned tokenizer map, and shipping IDs alongside the original text. The gateway recognizes the pre-tokenized output and bypasses its back-compat shim entirely. Three pieces:

  • @codecai/mcp-leaf — tool-author-side helper. wrapToolCall(result, meta) annotates every text content block with a per-block _meta['ai.codec/leaf-tokenization'] payload carrying the token IDs. Idempotent; non-Codec-aware clients in the same namespace ignore the _meta field per the MCP spec.
  • codec-time-leaf — reference Codec-aware MCP server (the canonical demo of leaf mode). Two trivial tools (get_current_time, convert_time) chosen for predictability. Drop it in any metamcp namespace; gateway logs flip from [Codec][shim] warns to [Codec][leaf] info.
  • Reader-side helperreadCodecMeta(result) / takeIds(result) in @codecai/mcp-leaf for clients that want to lift the IDs back out symmetrically (no re-tokenization on the receive side). Accepts both the v0.3.2+ per-block _meta shape and the v0.3.0/v0.3.1 legacy sibling-block shape (back-compat).

The contract is additive — the leaf-mode path is invisible to legacy clients in the same namespace, no MCP version bump.

Live as of v0.3.2 — the [Codec][leaf] log fires end-to-end on real lab traffic. See the 2026-05-09 mcp-live results for the bench numbers. Tools/list (40 tools): 3.6× wire reduction (msgpack-both+gzip vs JSON-RPC).

Running with the upstream compose

codec-metamcp is a drop-in for the upstream image in MetaMCP’s own docker-compose.yml — replace metatool-ai/metamcp:latest with wdunn001/codec-metamcp:latest and the database / network wiring stays identical:

services:
  metamcp:
    image: wdunn001/codec-metamcp:latest
    ports:
      - "12008:12008"
    environment:
      APP_URL: http://localhost:12008
      POSTGRES_URL: postgres://metamcp:metamcp@db:5432/metamcp
    depends_on:
      - db
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: metamcp
      POSTGRES_PASSWORD: metamcp
      POSTGRES_DB: metamcp
    volumes:
      - metamcp-db:/var/lib/postgresql/data

volumes:
  metamcp-db:

Pointing a Codec client at it

Once a namespace is set up and you’ve copied its endpoint URL (e.g. http://localhost:12008/metamcp/<namespace-uuid>/mcp), the same @codecai/web decoder you’d use against any Codec server works:

import { decodeStream } from "@codecai/web";

const resp = await fetch(
  "http://localhost:12008/metamcp/<uuid>/mcp?stream_format=msgpack",
  {
    method: "POST",
    headers: {
      "Content-Type":         "application/json",
      "Accept":               "application/x-codec-msgpack",
      "Accept-Encoding":      "zstd, br, gzip, identity",  // full v0.4.1 stack
      "Codec-Client-Version": "0.4",                        // v0.4 normative
    },
    body: JSON.stringify({
      jsonrpc: "2.0",
      id: 1,
      method: "tools/list",
      params: {},
    }),
  },
);

for await (const frame of decodeStream(resp.body!, "msgpack")) {
  console.log(frame); // JSON-RPC message, decoded
}

The MCP-over-Codec frames carry plain JSON-RPC bodies inside the msgpack envelope — same fields, same semantics, same tool-call results. Just smaller on the wire.

When to use this vs upstream MetaMCP

  • Use codec-metamcp when any of your MCP clients support Codec (today: anything that imports @codecai/web / codecai / Codec.Net / etc.) and you want bandwidth savings on tool-call results without changing how you administer the gateway.
  • Use upstream MetaMCP for everything else — the Codec patch is fully backwards-compatible per-request, but if no client negotiates it the image just runs the same code as upstream with one extra Express middleware mounted.

The wire is bit-identical between the upstream and codec-metamcp paths when no client opts in. Switching is a no-op until something in the cluster speaks Codec.

License

The Codec patch is published under BSL 1.1 by Quasarke LLC; free for non-production use and for production use under US $5M annual gross revenue. The bundled MetaMCP retains its upstream Apache-2.0 license. Commercial licensing for the patch above the threshold: licensing@quasarke.com.

See also