mirror of
https://github.com/zap-proto/dev.git
synced 2026-10-30 15:05:18 +00:00
Red-team review (this session) caught half the protocol pages were AI
slop — describing Go APIs that don't exist in repos that contain only
schemas, plus performance tables contradicted by the only real bench
harness in tree. This is the surgery:
post-quantum:
- Drop the Z-Wing brand from public docs (user feedback: confusing).
- Reframe PQ as ZAP's stack: IETF X-Wing KEM (transport) + hybrid
Ed25519+ML-DSA-65 (identity) + PQ-RNS (name service). One canonical
story; layers are independent.
- Per-language status matrix shows realistic state (X-Wing KAT shipped
in 4 SDKs, sigs in all, resolver in progress).
protocols/{a2a,acp,fix,ws}:
- Marked "Status — spec-only, January 2026". Schema exists; runtime
doesn't. Removed every Go code snippet that called a non-existent
function. Replaced with a roadmap section.
protocols/rns:
- Rewrote against the actual schema at zap-proto/rns/schema/zap_rns.zap
(Record / Query / Response / signed-by-registry).
- Added the PQ-RNS end-to-end flow diagram and the DID definition
(base32(SHA3-256(kemPk || sigPk))).
- Documents the cross-language KAT fixture published at
zap-proto/rns/testdata/pqrns_kat.json.
protocols/mcp:
- Rewrote against the actual bridge.go API: NewBridge(*zap.Node),
AddServer, GetTools, CallTool, CallToolByName. Bridges existing
stdio MCP servers (it's a bridge, not a from-scratch impl).
- Dropped the invented zmcp.NewServer / Connect / ListTools API.
protocols/http:
- Killed the 6× req/s / 19× p99 / 6.2× RSS table — contradicted by
bench-results.txt which shows ZAP-HTTP currently ~10% slower.
- Replaced with honest current numbers + the value-prop statement.
protocols/native:
- Killed the 18× / 38× / 6.7× / 9.2× gRPC table — the bench harness
has no gRPC comparator, the numbers were fabricated.
- Replaced with the actual concurrency=32 numbers from bench-results
+ an explanation that the win is semantic, not currently latency.
transports:
- Killed the @zap-proto/wasm and Cloudflare-Worker code snippets that
referenced a non-existent npm package.
- Replaced with the honest pattern: browser→TLS→Worker→ZAP-over-X-Wing
to origin. Points readers at the SDK status table.
app/page.tsx:
- Dropped Z-Wing from the home page cards.
113 lines
3.7 KiB
Plaintext
113 lines
3.7 KiB
Plaintext
---
|
||
title: MCP over ZAP
|
||
description: Model Context Protocol bridge — lifts existing stdio MCP servers onto the ZAP wire.
|
||
---
|
||
|
||
# MCP over ZAP
|
||
|
||
`zap-proto/mcp` is a **bridge** that lifts existing **stdio MCP** servers (Anthropic Model Context Protocol) onto the ZAP wire. You don't rewrite your tool host; you point the bridge at it and clients call tools over ZAP instead of stdio.
|
||
|
||
Compared to stdio MCP, you get:
|
||
|
||
- **Mutual KEM authentication** — server and client identities are bound to keypairs at the transport. No bearer tokens.
|
||
- **Network-native** — works across hosts without `ssh -L` tricks.
|
||
- **Multiplexed** — many concurrent tool calls share one connection without head-of-line blocking.
|
||
|
||
> The actual MCP **wire protocol** between client and bridge is built on the ZAP `Node` message handler API. The example below uses the real exported types from [zap-proto/mcp/bridge.go](https://github.com/zap-proto/mcp/blob/main/bridge.go). The bridge wraps existing stdio MCP servers; full client SDK ergonomics will be added once a stable ZAP RPC client lands in the core SDK.
|
||
|
||
## Install
|
||
|
||
```bash
|
||
go get github.com/zap-proto/mcp
|
||
```
|
||
|
||
## Run a bridge over your stdio MCP servers
|
||
|
||
```go
|
||
package main
|
||
|
||
import (
|
||
"context"
|
||
"log"
|
||
|
||
"github.com/luxfi/zap"
|
||
zmcp "github.com/zap-proto/mcp"
|
||
)
|
||
|
||
func main() {
|
||
node, err := zap.NewNode(zap.NodeConfig{
|
||
Listen: "tcp://0.0.0.0:9100",
|
||
})
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
|
||
bridge := zmcp.NewBridge(node)
|
||
|
||
if err := bridge.AddServer("fs", "npx", "-y",
|
||
"@modelcontextprotocol/server-filesystem", "/tmp"); err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
|
||
if err := bridge.AddServer("gh", "npx", "-y",
|
||
"@modelcontextprotocol/server-github"); err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
|
||
log.Println("MCP bridge listening on tcp://0.0.0.0:9100")
|
||
log.Fatal(node.Serve())
|
||
}
|
||
```
|
||
|
||
The bridge:
|
||
1. Spawns each stdio MCP server as a child process
|
||
2. Discovers its tools via the MCP `tools/list` request
|
||
3. Assigns each tool a stable `uint32` ID
|
||
4. Registers ZAP message handlers (`MsgTypeToolList`, `MsgTypeToolCall`) that route to the right child
|
||
|
||
## Call a tool
|
||
|
||
From a Go client speaking the bridge's ZAP message types:
|
||
|
||
```go
|
||
// List discovered tools
|
||
tools := bridge.GetTools()
|
||
for _, t := range tools {
|
||
log.Printf("tool %d: %s — %s", t.ID, t.Name, t.Description)
|
||
}
|
||
|
||
// Call a tool by name
|
||
result, err := bridge.CallToolByName(ctx, "read_file", map[string]interface{}{
|
||
"path": "/etc/hosts",
|
||
})
|
||
```
|
||
|
||
`CallTool(ctx, toolID, args)` calls by stable numeric ID — useful when clients want to avoid round-tripping the name.
|
||
|
||
## ServerConfig
|
||
|
||
For configuration-driven setup:
|
||
|
||
```go
|
||
bridge.AddServerConfig(zmcp.ServerConfig{
|
||
Name: "fs",
|
||
Command: "npx",
|
||
Args: []string{"-y", "@modelcontextprotocol/server-filesystem", "/tmp"},
|
||
})
|
||
```
|
||
|
||
## Performance
|
||
|
||
The package comment claims 10-30× over stdio MCP JSON-RPC. The bridge eliminates per-call JSON encoding/decoding by encoding tool calls in ZAP binary frames; numbers are reproducible from the bench in [zap-proto/bench](https://github.com/zap-proto/bench) once the MCP-specific harness lands. **No specific p50/p99 numbers in these docs until the harness produces them.**
|
||
|
||
## What's not in the bridge yet
|
||
|
||
- A first-class non-Go client SDK. Today the bridge speaks ZAP message types directly; a higher-level `mcp.Client` that wraps `zap-proto/go` is on the roadmap.
|
||
- Bidirectional `sampling/createMessage` (server → client model calls).
|
||
|
||
## Related
|
||
|
||
- [zap-proto/mcp](https://github.com/zap-proto/mcp) — bridge implementation
|
||
- [A2A over ZAP](/docs/protocols/a2a) — for agent-to-agent messaging, not tool calls
|
||
- [Native ZAP RPC](/docs/protocols/native) — what the bridge is built on
|