MCP server for AI agents
A local, self-custody MCP server that lets an AI agent trade the desk as both maker and taker
Cessio ships a local MCP server
(@cessio/agent-mcp-server)
that turns any MCP client — Claude Code, Claude
Desktop, or your own agent loop — into a first-class desk participant. The
agent gets its own Canton party and Ed25519 key, self-registers with the desk,
and can act as both maker and taker: the backend is role-agnostic, so the
server simply speaks the same REST + WebSocket API documented on
this site.
Self-custody is preserved: the server generates and stores the party key
locally (AGENT_STATE_FILE), signs every prepared transaction itself, and the
desk never sees the key. The agent makes the trading decisions; hard operator
rails (below) bound what its signatures can commit to.
Install
The server is published to npm and speaks stdio, so it works in any MCP client with a single config entry — no checkout, no build (Node.js >= 24):
{
"mcpServers": {
"cessio": {
"command": "npx",
"args": ["-y", "@cessio/agent-mcp-server"],
"env": {
"RFQ_BASE_URL": "https://api.devnet.cessio.cc",
"AGENT_DISPLAY_NAME": "my-agent",
"AGENT_MAX_NOTIONAL": "5000"
}
}
}
}In Claude Code that's one command:
claude mcp add cessio -e RFQ_BASE_URL=https://api.devnet.cessio.cc -e AGENT_MAX_NOTIONAL=5000 \
-- npx -y @cessio/agent-mcp-serverAll configuration is env vars:
RFQ_BASE_URL=https://api.devnet.cessio.cc # desk REST/WS base (default http://localhost:4000)
AGENT_STATE_FILE=~/.cessio/agent-identity.json
AGENT_DISPLAY_NAME="my-agent"
AGENT_MAX_NOTIONAL=5000 # required to trade; unset = read-only
AGENT_INSTRUMENT_WHITELIST=cbtc,usdcx # catalog symbols, any case; empty = all
AGENT_MAX_PRICE_DEVIATION_BPS=500The source lives at
cessio-cc/cessio-agent-mcp-server;
from a checkout the same server runs directly as node src/index.ts.
On first start the server registers a fresh party with the desk (the same
self-serve flow as POST /maker/register/start)
and persists the identity in AGENT_STATE_FILE. Delete that file and you get a
brand-new party on the next start.
Tools
Fourteen tools in three groups:
| Group | Tools |
|---|---|
| Info | get_status, get_balances, list_instruments, get_reference_price, request_faucet |
| Taker | create_rfq, list_my_rfqs, get_quotes, accept_quote, cancel_rfq |
| Maker | wait_for_rfq (long-poll), submit_quote, list_maker_trades, list_trades |
A market-making agent loops wait_for_rfq → decide a price → submit_quote.
A taker agent calls create_rfq, inspects the answers with get_quotes, and
settles with accept_quote — the tool signs its side, waits for the atomic DvP
outcome and returns the settled trade with its on-ledger proof, or the reason
the desk failed it (nothing moves on a failure, and the RFQ stays open until
its deadline). While it waits, it also signs whatever the desk queues for the
trade after the accept.
Operator rails
Signing is automatic, so the trust boundary is configuration, not the model's judgment. Every trade the agent attempts is checked against the rails before anything is signed; a breach returns a structured error to the agent and signs nothing. The price check fails closed: with no reference price for the pair, the agent does not trade it.
| Env var | Meaning | Default |
|---|---|---|
AGENT_MAX_NOTIONAL | Max quote-instrument notional per trade. Unset = read-only — the trading tools refuse. | unset |
AGENT_INSTRUMENT_WHITELIST | Comma-separated catalog symbols the agent may trade (any case: cbtc = cBTC) | empty = all |
AGENT_MAX_PRICE_DEVIATION_BPS | Max deviation from the desk's reference price | 500 |
AGENT_SETTLE_TIMEOUT_MS | How long accept_quote waits for the settle outcome | 60000 |
AGENT_POLL_MS | Internal polling interval | 1500 |
Relation to this API
The MCP server is a convenience wrapper, not a privileged client: everything it
does is the public API described in this documentation — the
quickstart flow for the maker side, POST /rfq /
POST /quote/{id}/accept for the taker side, and the
sign queue for signatures. If a tool is missing for
your use case, call the API directly with the same identity: the API key in
AGENT_STATE_FILE is an ordinary desk key.