Build and vet are clean on the go1.27.1 toolchain. One pre-existing failure, TestServe_HandlerSeesTheConnection, fails identically with this change reverted -- a socket path limit in the test, not the toolchain. Co-authored-by: Hanzo Dev <[email protected]>
@zap-proto/mcp
Docs: Model Context Protocol over ZAP · part of the ZAP Protocol
Model Context Protocol over ZAP — mutually authenticated, non-repudiable AI agent ↔ tool communication.
zap-proto.io · Spec · Paper · Discord
@zap-proto/mcp layers AI agent ↔ tool semantics over the ZAP wire layer. Post-quantum confidentiality, mutual authentication, and zero-copy parse come from the wire (@zap-proto/zap); this package adds only the AI agent ↔ tool message shape: clients, servers, tool calls, and the transport that carries them.
Install
pnpm add @zap-proto/mcp
@zap-proto/zap (the ZAP wire layer) is a dependency and is installed automatically.
Usage
// MCP server
import { ZapServer } from "@zap-proto/mcp/server";
const server = new ZapServer({ port: 9999 });
server.tool("search", "Search the web", {}, async (params) => ({
content: [{ type: "text", text: "results" }],
}));
await server.start();
// Browser extension client
import { ExtensionClient } from "@zap-proto/mcp/browser";
const client = new ExtensionClient({ browser: "chrome", version: "1.0.0" });
const mcps = await client.discover();
const result = await client.callTool("search", { query: "hello" });
Go
go get github.com/zap-proto/mcp
github.com/zap-proto/mcp is the sibling of zap-proto/http:
same seams, same relationship to the ZAP core, neither depending on the other.
// server — no HTTP listener anywhere in the path
srv := &zapmcp.Server{Network: "unix", Addr: "/run/zip/tools.sock", Handler: h}
srv.ListenAndServe()
func h(ctx context.Context, f *zapmcp.Frame) *zapmcp.Frame {
if f.Method != "tools/call" {
return f.Fail(zapmcp.CodeMethod, "method not found: "+f.Method)
}
return f.Answer(result)
}
// client
c := zapmcp.Dial("unix", "/run/zip/tools.sock")
out, err := c.Call(ctx, "tools/call", args)
One value, two projections
MCP is JSON-RPC 2.0; ZAP is binary. Rather than two message types kept in step
by hand there is one — Frame — and two renderings of it:
zapmcp.Marshal(f) |
the ZAP wire (schema/zap_mcp.zap) |
json.Marshal(f) |
the JSON-RPC 2.0 message |
A server answers frames and never learns which door a frame came in, which is what lets one handler serve ZAP natively and have HTTP be an adapter over it rather than a peer of it.
Layering
| Layer | Package | Owns |
|---|---|---|
| Application | @zap-proto/mcp (TS) · github.com/zap-proto/mcp (Go) |
MCP message shape — tools, calls, agent ↔ tool semantics |
| Wire | @zap-proto/zap |
ZAP zero-copy wire codec + Level-1 RPC primitives |
By the composability theorem, @zap-proto/mcp inherits ZAP's PQ confidentiality and mutual auth from the wire — no MCP-specific PQ analysis required.
Why
| Property | MCP-over-HTTP+SSE / stdio | @zap-proto/mcp |
|---|---|---|
| Confidentiality | TLS (classical) | X-Wing hybrid PQ (default) |
| Authentication | bearer / TLS cert | KEM keypair at transport |
| Wire encoding | text or per-protocol binary | ZAP wire, zero-copy |
| Identity binding | DNS / cert chain | zap-rns keypair |
| Future-quantum | classical only | hybrid by construction |
Sub-protocol family
zap-http— HTTP request/response over ZAPzap-ws— multi-stream pubsubzap-fix— FIX 4.4 / 5.0 trading channelzap-rns— KEM-bound service namingzap-mcp— Model Context Protocol over ZAPzap-acp— Agent Communication Protocolzap-a2a— Google Agent2Agent over ZAP
License
MIT OR Apache-2.0