Counter
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Counterfind the business for +1-555-0100, check tomorrow at 3pm, and book it"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
AGENT HANDSHAKE
Counter Protocol · AI ↔ AI on a phone call
When two AIs meet on a phone call, they should not keep talking in synthesized speech. They recognize each other with a two-second tone, prove who they are over HTTPS, and finish the booking through an API. People on the line never hear it.
Live demo → · Run it locally · Use it from your agent · How it works · Honest numbers · Spec · 한국어

3 tone frames · 7 steps · 4 call paths · 5 MCP tools · 25 tests · 0 runtime dependencies · English + 한국어
Watch the handoff
The shop's AI hears a caller say it is an AI, plays a 16-digit OFFER frame, and from there the phone line is only used to prove that the API session belongs to this call. On the spectrogram, speech is a smear of harmonics; every DTMF digit is two pure tones, one row and one column of the keypad.

Recognize | Prove | Commit |
The caller discloses it is an AI. The receptionist answers with an OFFER frame: a registry digit and a 10-digit rendezvous code, about 2 seconds of DTMF. | The caller resolves the code at a registry that vouches for the dialed number, then presents its key, a proof and a mandate over HTTPS. A 6-digit BIND frame ties that session to this exact call. | Availability, hold and booking happen over the API. The business signs a receipt that the agent keeps for the person it works for. |
Related MCP server: acmeshop
Proof instead of memory
A voice booking leaves nothing to check. A handshake booking leaves a business-signed receipt, plus a record of who the agent was and what it was allowed to do.

Honest numbers
Same shop, same request, same booked slot. Only the path differs.
Path | Call time, English script | Call time, Korean script | Voice turns | API calls | Signed receipt |
AI ↔ AI with the handshake | 24.3 s | 27.8 s | 4 | 7 | ✓ |
AI without the protocol (OFFER ignored) | 58.5 s | 71.4 s | 12 | 1 | — |
Human caller (no tones played) | 47.0 s | 59.6 s | 11 | 0 | — |
No call: look up the number, use the API | 0.7 s | 0.7 s | 0 | 6 | ✓ |
What these numbers are and are not:
Simulated clock. Speech time is estimated from text length (65 ms per character in English, 150 ms in Korean, plus a 700 ms pause per turn). API time is measured on localhost plus an assumed 120 ms round trip. Results vary slightly per run.
Scripted speech. Each utterance carries the intent a real speech-recognition stack would extract. There is no real phone line yet.
Real protocol. The registry and the shop are real HTTP servers. Ed25519 signatures, mandates, single-use sessions, channel binding, holds, bookings and waitlist offers all run for real, and are covered by tests.
Where the time goes. Most of the remaining 24 seconds is the greeting and the AI disclosure. The data exchange itself takes under a second.
What you are looking at
Panel | Shows |
Front panel | Modem-style LEDs ( |
Line monitor | A live spectrogram of the phone line with a typed caption of what is being said. DTMF row and column frequencies are marked, so you can read the digits off the screen. |
Topology | Caller, shop and registry. HTTPS packets fly with trails; the data link locks with a |
DTMF decoder | The current frame on a dot-matrix display, decoded into type, registry, code and Luhn check, with the keypad key and its two frequencies lighting up. |
Receipt | The business-signed receipt prints line by line and gets a |
Call log · Trust · Call time | Every utterance, tone and request (click a request to see decoded payloads), the six trust checks, and all four paths side by side. |
Explore your way
Four paths: AI ↔ AI, AI without the protocol, human caller, no call.
Run / Pause, Step to the next event, and 1× 2× 4× 8× speed.
Real DTMF tones play through your speakers (toggle with Tones).
English and 한국어, switchable at any time.
Keyboard: Space run/pause, → step, 1–4 speed, R restart.
URL options:
?scenario=handshake|ai-no-cp|human|direct,?lang=en|ko,?speed=4,?sound=0,?paused, and?at=15.2to open paused at a moment you want to share.Works on phones, and respects reduce motion.

Run locally
Requires Node.js 22.18 or newer. TypeScript runs directly; there is nothing to install or build.
git clone https://github.com/viva-lee/agent-handshake.git
cd agent-handshake
npm run playground # → http://127.0.0.1:4317Other entry points:
npm run demo # the three call paths in the terminal
npm run demo -- handshake --lang ko # one path with its full timeline, in Korean
npm run mcp # the MCP server on stdio (see below)
npm test # 25 tests, node:test, no dependencies
npm install && npm run typecheck # optional strict TypeScript check
npm run build:pages # rebuild the static live demo in docs/ (GitHub Pages)Use it from your own agent (MCP)
src/mcp/server.ts is an MCP server that runs on your machine over stdio, so there is nothing to host. It starts a sandbox registry and the two demo shops inside its own process and gives your assistant five tools: find_business, check_availability, book, cancel_booking and verify_receipt. Every registry record and receipt is signature-checked.
Claude Code:
claude mcp add counter -- node /absolute/path/to/agent-handshake/src/mcp/server.tsClaude Desktop, Cursor and other MCP clients (forward slashes work on Windows too):
{
"mcpServers": {
"counter": { "command": "node", "args": ["/absolute/path/to/agent-handshake/src/mcp/server.ts"] }
}
}Then ask something like "Book me a women's cut at +1-602-555-0123 this Saturday afternoon and keep the receipt." Your agent finds the shop, checks free slots, confirms with you, books, and shows the receipt the business signed. Or try the Seoul shop at +82-2-555-0123 in Korean. Nothing real is booked: the shops live inside the server process and reset when it restarts.
This is the API half of the protocol, the "no call" path in the playground. ChatGPT and claude.ai connectors need a hosted remote server, which is next on the roadmap.
How it works
sequenceDiagram
participant CA as Caller agent
participant BA as Shop's AI
participant RG as Registry
BA->>CA: "Hi, this is the AI receptionist"
CA->>BA: "I'm an AI assistant calling for Alex"
BA->>RG: request a rendezvous code (signed)
BA->>CA: ♫ OFFER *#1048151623426#
CA->>RG: resolve code → registry-signed record
Note over CA: check signature, expiry, tel == dialed number
CA->>BA: HTTPS accept: identity + mandate + proof
BA-->>CA: session token + bind code
CA->>BA: ♫ BIND *#32718280#
CA->>BA: availability → hold → booking
BA-->>CA: business-signed receipt
BA->>CA: "Booked: Saturday 2 PM with Kim. Goodbye!"Frame | Direction | Digits | Meaning |
| shop → caller |
| "I speak the protocol; here is where to find me." |
| caller → shop |
| "I speak it too; offer if you can." |
| caller → shop |
| "The party on your API is the party on this call." |
Only 0-9 * # are used, so any telephony API can send the frames, and a Luhn check digit drops corrupted ones. If anything fails at any step, both sides simply keep talking.
The protocol
Document | Covers |
Frames, when to offer, the 10-step flow, registry API, security considerations, patent notice | |
Mandates and proofs, sessions, the business card, availability, holds, bookings, changes, waitlist offers, receipts, errors | |
MCP, A2A, GibberLink, STIR/SHAKEN, Web Bot Auth, AP2, ACP and how Counter Protocol relates to each |
Counter Protocol sits on top of MCP and A2A rather than competing with them: it defines what an agent and a business say about commitments, and how two agents that meet on a phone line find each other.
Repository layout
spec/ the protocol: handshake, commit, prior art
src/crypto/ Ed25519 compact JWS
src/protocol/ DTMF frames, wire types, time helpers
src/registry/ reference rendezvous registry
src/business/ reference shop endpoint (CP-Commit + the shop side of the handshake)
src/agents/ caller agent, AI receptionist, simulated call, dialog in English and Korean
src/demo/ fixtures and the scenario runner
src/mcp/ MCP server on stdio, with the sandbox shops in-process
src/playground/ the dashboard (one HTML file, bundled fonts, dot-matrix logo)
test/ node:test suites
docs/ images and the promo video used in this READMERoadmap
Bring your own agent. ✓ A local MCP server (above). Next: a hosted MCP endpoint for ChatGPT and claude.ai connectors, and an open phone-line endpoint so independent agents can call each other and show up live in the playground.
Real calls. Adapters for Pipecat, LiveKit Agents and Twilio.
Ecosystem. An A2A extension and Agent Card entry, registry federation, deposits bound to ACP or AP2 payment tokens.
Review. An external security review of the channel-binding step.
Patent notice
Ribbon Communications holds active US patents on identifying AI-originated calls and handling them differently, including directing AI callers to a web service, for example US10645216B1 and US11588933B2. Get legal advice before deploying this commercially. Nothing here is legal advice or a statement about patent coverage.
License
Code and spec: Apache-2.0. Fonts: Geist, Geist Mono and Doto under the SIL Open Font License, with license files in src/playground/assets/fonts. Shop names and phone numbers in the demo are fictional.
This server cannot be deployed
Maintenance
Related MCP Connectors
Agent-to-business commerce sandbox: intents, offers, bookings. Demo data, ed25519-signed calls.
Free agent-service discovery, OpenAPI document checks, and receipt verification. No API key needed.
Structured B2B supply search, quoting, sandbox orders and fulfillment status for agents.
51Find local services, read availability, and create short-lived booking holds.
Related MCP Servers
AlicenseAqualityFmaintenanceEnables agents to search and inspect live service offerings, generate x402 payment snippets, and understand blockchain-only balance policies.440 npm3MIT- FlicenseNot gradedqualityCmaintenanceEnables an AI agent to investigate AcmeShop operational data and create incidents through a mock REST API using a local stdio transport.-
- FlicenseNot gradedqualityCmaintenanceExposes vaccination-appointment scheduling as standardized MCP tools backed by an in-memory mock backend. Enables agents to list available slots by date and vaccine type, book appointments, check confirmation status, and cancel bookings.-
- AlicenseNot gradedqualityBmaintenanceEnables any agent to send a message by name into a live chat or another agent's conversation, and to receive replies by long-polling an inbox cursor that yields each message exactly once, in order, in roughly a tenth of a second. Also lets agents discover reachable chats, threads, and registered agents, with unresolvable names optionally routed to a relay agent for delivery.3 npmMIT