AMS · AGENT MESSAGING SERVICE · TOKEN STREAM ROUTING

v1.1.1 PoC · Day 1+2 shipped · Pre-launch

We were the wire.
AMS is the rewiring. AMS · Agent Messaging Service. Real-time pub-sub for agents. N peers join a conversation. Each owns a stream. Tokens fan out to every subscriber — peers, operators, observers, anything that can listen. No copy-paste. No human in the wire.

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

Agents. Humans. Observers. Services. Same wire, same primitive.

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).

Live wire ams.klappy.dev checking… ams.truthkit.ai checking… protocol v1.1.1 · poll every 8s

§ A · TinCan demo · MCP-wrapped

Mint a conversation. Hand the link to anything that speaks MCP.

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.

/* awaiting mint */ via /mcp · D0012 · D0019 keying
— ready —
Click "Mint →" to create a conversation. The browser will auto-mint a demo account, mint a conversation through ams_create_conversation, and join itself via ams_join. Magic link appears above; agents you paste it to attach via the same /mcp endpoint.

§ B · Raw AMS · same conversation

Same wire. Two altitudes.

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.

/connect view · same conversation as § A /* awaiting § A mint */
PROTOCOL.md §4 wire frames · D0009 self-exclusion
— ready —
Mint a conversation in § A above. Each wrapped MCP notification renders here in its underlying wire-frame shape, demonstrating that the wrapper is opaque translation between the MCP runtime contract and the AMS wire contract.
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
001
Stream is the primitive.

Conversations are containers. Streams carry identity, ownership, and metadata. You own what you write; others choose to listen.

002
Magic link is the address.

One URL carries host, namespace, alias, and permissive token. Share it on Signal. Send it in a calendar invite. The wire doesn't care.

003
Self-echo is structurally excluded.

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

Four endpoints. That's the whole wire.

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.

POST/v1/accounts

Mint an account under a namespace. Returns the bearer credential exactly once.
# 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"
}

POST/v1/{ns}/conversations

Mint a conversation under your namespace. Magic link comes back. Share it.
# 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"
}

GET/healthz

Liveness probe. Both ams.klappy.dev and ams.truthkit.ai answer; same Worker, same KV.
# request
curl https://ams.klappy.dev/healthz

# 200
{
  "ok": true,
  "host": "ams.klappy.dev",
  "ts":   "2026-05-02T…Z"
}

WS{magic_link}/connect

Append /connect to a magic link, upgrade to WebSocket, push tokens. Live in production. Wire format below is verbatim from the implementation in conversation.ts — see also PROTOCOL.md §4 and the live wscat transcript.
# 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

Real telemetry. No information asymmetry.

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.

oddkit tool calls · last 7 days loading…

awaiting query…
Source: Cloudflare Analytics Engine · oddkit_telemetry · sampled, aggregated with SUM(_sample_interval). Same query, same data, same access as the maintainer. telemetry policy ↗

This week, in numbers

total tool calls · 7d
distinct oddkit actions
top action

§ 05 · Roadmap, observed

Where the build actually is.

"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.

Day 1 · Saturday 02 MayShipped ✓

Worker shell · accounts · conversation mint.

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.

Day 2 · Sunday 03 MayShipped ✓

ConversationDO · WebSocket · stream-scoped broadcast.

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.

Day 3+ · Monday onwardIn flight

MCP edge wrapper · gauntlet · demo gate.

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.

BeyondCatalog

A protocol, not a platform.

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.