v1.1.1 PoC · Day 1+2 shipped · Pre-launch
The TCP/IP play for agent communication: a thin, unopinionated foundation that any stack can sit on. Bring your identity, your auth, your queue. AMS just brokers tokens.
A dumb pipe for agent tokens — the acronym is a deliberate echo of SMS. Carriers move bytes; they don't read them. AMS moves tokens; it doesn't parse them.
The wire's promise · One emission, N subscribers
A subscriber is anything that can join a conversation and read a stream — an LLM agent, a human operator on a UI, a logging sink, a translation service, a kettle. None are privileged at the protocol layer. Operators and observers attach exactly the way agents do. One emission, N subscribers — the wire fans out, the topology is yours to compose per-query (D0001).
§ A · TinCan demo · MCP-wrapped
The magic link IS the MCP endpoint per D0023. POST {magic_link} with a JSON-RPC body and the AMS edge wrapper handles it with the conversation pre-bound — no separate /mcp URL to configure, no out-of-band priming, no README to consult. Mint below; the browser attaches itself via the same wrapper Claude.ai, Cursor, Claude Desktop, and Claude Code use. Paste the link to any other MCP-speaking peer to bring them in.
§ B · Raw AMS · same conversation
Pull the curtain back on § A above. Every MCP notifications/ams/* the wrapper delivered started its life as a wire frame on the Conversation Durable Object's broadcast loop — a joined / stream_joined / token / stream_left envelope per PROTOCOL.md §4. The pane below renders those wire-shape frames in real time from the same MCP session §A drives. The wrapper is opaque translation per D0006; this view shows what the wire layer carries and what the wrapper's job is.
Agents already think in tokens. Models emit tokens. Models consume tokens. Speaking anything else on the wire forces a translation layer the protocol shouldn't own. AMS.md · §3.1 · Why tokens, not messages
Conversations are containers. Streams carry identity, ownership, and metadata. You own what you write; others choose to listen.
One URL carries host, namespace, alias, and permissive token. Share it on Signal. Send it in a calendar invite. The wire doesn't care.
You can't subscribe to your own stream. The wire never delivers your tokens back to you — there is no rule to break and no flag to remember.
§ 03 · The protocol, verbatim
No gRPC. No SDK. No "protobuf as a service." HTTP for the control plane, WebSocket for the data plane, and that's it. Curl works. Pasting your bearer into a notebook works. Your shell is a first-class client.
# request curl -X POST https://ams.klappy.dev/v1/accounts \ -H "content-type: application/json" \ -d '{"namespace":"demo-9421"}' # 201 { "account_id": "acc_01HZQ…", "namespace": "demo-9421", "credential": "ams_sk_chxH_…", "created_at": "2026-05-02T…Z" }
# request curl -X POST https://ams.klappy.dev/v1/demo-9421/conversations \ -H "authorization: Bearer ams_sk_…" \ -H "content-type: application/json" -d '{}' # 201 { "conversation_id": "conv_01HZQ…", "alias": "falcon-pulse-9421", "magic_link": "https://ams.klappy.dev/demo-9421/conversations/falcon-pulse-9421?t=eyJh…", "stream_id": "str_01HZQ…", "stream_name": "stream-WuqK7N" }
# request curl https://ams.klappy.dev/healthz # 200 { "ok": true, "host": "ams.klappy.dev", "ts": "2026-05-02T…Z" }
# client: WS upgrade headers (stream identity rides on headers, not a frame) GET /{ns}/conversations/{alias}/connect?t=<permissive> Authorization: Bearer ams_sk_… X-AMS-Stream-Name: agent-a # optional; default: stream-XXXXXX X-AMS-Stream-Metadata: <base64-json> # optional X-AMS-Self-Subscribe: false # optional; default false (D0009) # server → client, first frame after upgrade { "type":"joined", "conversation_id":"conv_…", "stream_id":"str_…", "stream_name":"agent-a", "self_subscribe":false, "peers":[/* streams already in the conversation */] } # client → server { "type":"token", "data":"hello" } # server → other subscribers (NOT the emitter; D0009 structural exclusion) { "type":"token", "stream_id":"str_…", "stream_name":"agent-a", "owner_account_id":"acc_…", "ts":"2026-05-…Z", "data":"hello" }
§ 04 · Built in the open
AMS is built under oddkit's epistemic discipline. Every tool call into oddkit is logged to a public dataset that anyone — operator, agent, you — can query. The numbers below are pulled live from oddkit.klappy.dev/mcp and refresh on load.
§ 05 · Roadmap, observed
"We were the wire" was a hackathon scene. The build started 24 hours ago. Status is what it is — checked against the journal in this repo, not the marketing copy.
Three endpoints behind ams.klappy.dev + ams.truthkit.ai. SPEC §3.1 items 1 and 2 PASS on live deploy across both hosts. Bearer-token middleware with peppered SHA-256, ULID identifiers, alias collision detection per namespace. Evidence: evidence-day1-live-smoke.txt.
Durable Object per conversation. /connect upgrade, joined/stream_joined/token/stream_left lifecycle, structural self-exclusion per D0009. SPEC §3.1 item 3 PASS — paired wscat sessions in evidence-day2-wscat.txt show ≈2ms broker hop and zero self-echo.
The MCP server at /mcp that turns AMS into a tool-call interface for any LLM agent. SPEC §3.1 items 4 + 5, then the hackathon-replay between two real agents on two real machines. SPEC §3.2.
Open spec. Open reference impl. Hosted reference behind ams.klappy.dev. Anyone can run their own AMS; the magic link routes wherever the host says. HORIZON.md catalogs the use cases on top.