@titon-network/mcp
v0.8.0
Published
Model Context Protocol server for dapp authors building on the Titon network. Kronos automation (TSA-audited — zero findings) + Fortuna threshold-BLS VRF (TSA-audited — zero findings) + Phoebe price oracle (TSA-audited — zero findings) + Themis sealed-bid
Downloads
75
Readme
@titon-network/mcp
Model Context Protocol server for dapp authors building on the Titon network. Kronos automation + Fortuna threshold-BLS VRF, exposed as MCP tools + resources for any AI client. One install gives Claude Desktop / Claude Code / Cursor / any MCP-aware agent the vocabulary to call Kronos / Fortuna directly — not just generate code that calls them.
Runs on Cloudflare Workers; deployable to Akash as a decentralized mirror.
// ~/.config/Claude/claude_desktop_config.json (or your client's MCP config)
{
"mcpServers": {
"titon": { "url": "https://mcp.titon.network" }
}
}That's the entire client setup. Restart your AI client; you'll see kronos.* and fortuna.* tools available, plus titon:// resources.
Scope: dev-facing services only
This server only exposes services dapp devs consume. Operator/admin/infrastructure surfaces (forgeton pool admin, atlas DKG bootstrap, automaton staking, oracle deploy, BLS share registration, fulfillment submission) live in their own SDK CLIs for the audiences that need them — they're not appropriate for an MCP that any AI agent can invoke.
What you can do
Kronos — decentralized automation
Register recurring on-chain jobs; permissionless automatons execute them. 🛡️ TSA-audited — zero findings (report).
| Tool | What it does |
|------|--------------|
| kronos.get_config | Registry config (limits, fees, reserves) |
| kronos.get_job | Full state for one job |
| kronos.list_summary | Top-level registry stats |
| kronos.is_due | Job in execute window? (active + funded + windowed) |
| kronos.window_state | Detailed window: never-executed / too-early / primary / fallback / too-late / expired |
| kronos.assigned_automaton | Address that should execute next |
| kronos.preview_economics | Per-execution cost estimator |
| kronos.preview_funding | Recommended attached value for RegisterJob |
| kronos.explain_exit_code | Diagnose any Kronos / TVM exit code |
| kronos.decode_event | Parse an external-out body into a typed event |
| kronos.prepare_register_job | Build a wallet-ready RegisterJob tx (sign client-side) |
| kronos.prepare_execute | Build a wallet-ready Execute tx |
| kronos.prepare_fund | Build a wallet-ready FundJob tx |
| kronos.prepare_pause / _resume | Build a wallet-ready Pause/Resume tx |
| kronos.prepare_cancel | Build a wallet-ready CancelJob tx |
| kronos.prepare_withdraw_job | Build a wallet-ready WithdrawJob tx |
Fortuna — verifiable randomness (threshold-BLS VRF)
Add unbiasable randomness to a product contract: raffle, NFT trait roll, dice, lottery, mystery box, shuffled queue. 🛡️ TSA-audited — zero findings (report).
| Tool | What it does |
|------|--------------|
| fortuna.get_config | Oracle tunables (baseRequestFee, submitterReward, requestTtl, reserves) |
| fortuna.oracle_summary | Top-level health: ownership pins, paused flag, config, group key, schema, pending upgrade |
| fortuna.get_request | Per-pending-request state (consumer, queryId, deadline, fee, callbackGas, groupEpoch) |
| fortuna.get_operator | Per-automaton operator state mirrored from ForgeTON |
| fortuna.get_group_key | Current cached BLS group key + epoch |
| fortuna.preview_request_value | Compute the right valueTon for sendRequestRandomness |
| fortuna.prepare_request_randomness | Consumer → Fortuna randomness request |
| fortuna.prepare_reclaim_request | Consumer fund recovery after deadline |
| fortuna.next_query_id | Monotone u64 generator (avoids Date.now() collisions → 120 DuplicateRequest) |
| fortuna.explain_exit_code | Diagnose any Fortuna / TVM exit code |
| fortuna.decode_event / try_decode_event | Typed event parser (throw / null variants) |
Resources
| URI | What it returns |
|-----|------------------|
| titon://deployment/testnet | Live testnet addresses + bundled SDK versions for kronos + fortuna |
| titon://deployment/mainnet | Live mainnet addresses + bundled SDK versions (post-audit, end-to-end VRF round-trip verified) |
| titon://protocols | The mounted-protocol manifest (kronos + fortuna) |
| titon://errors/cross-protocol | Quick reference for the reverts a dapp author hits most (120, 124, 161, 240, …) |
Hard rule: every
prepare_*tool returns{ to, valueNano, bodyBoc, bodyHex }for the user's wallet to sign. The MCP server never custodies private keys. See SECURITY.md.
Live deployment addresses
Mainnet (post-audit, live since 2026-05-06; end-to-end VRF round-trip verified):
kronos.registry = UQCH-JO4hkLVMjQnG5YU8eLbUpSBy1rBmGF8JDieARVh6Wvq
npm: @titon-network/[email protected]
pypi: titon-network-kronos-sdk==0.8.4
fortuna.oracle = UQD7G7CeJi1ta2Xsu4T8ZmP8x_h3HH9d-Z3CmtGmX9U5clAJ
npm: @titon-network/[email protected]
pypi: titon-network-fortuna-sdk==0.4.0
phoebe.oracle = UQA0puv5JEGFvyRYW_XEveKiI0--XdVKsJv8wk0CmhFlc0-u
npm: @titon-network/[email protected]
pypi: titon-network-phoebe-sdk==0.5.0
themis.factory = UQDN0Kaa8IR9vnv2zCQ6aG5WaYLJK2LnepFqD75tgIONd9di
npm: @titon-network/[email protected]
pypi: titon-network-themis-sdk==0.3.0The PyPI pins for kronos (0.8.4) and fortuna (0.4.0) lag their npm siblings (0.8.5 / 0.6.0) — the MCP server runs on the npm pins (it's a TS Cloudflare Worker), the PyPI numbers above are the actual currently-published versions a Python dapp author would
pip install. Phoebe + themis ship in lockstep across both registries.
Testnet:
kronos.registry = 0QD92bDtZ037uRNVr51jWCgz6_nhHdkQJv3S_0Um36WvrNNt
fortuna.oracle = 0QAryuGOSeCSkJaS95CW4tS06J3AcPHF407mrknes3JuvvAi
phoebe.oracle = 0QDpuv4PEKctvS4Oj1bZ8doILQbC1iM7TNzTz4OIHVXPB-Mm
themis.factory = 0QAjfthdCPwVvkNYIT3FlKIJ6yamt6S-whGmb4g0UU6aLK06Also exported as KRONOS_TESTNET / KRONOS_MAINNET / FORTUNA_TESTNET / FORTUNA_MAINNET from the respective SDKs (same constant names in both languages) and surfaced via the titon://deployment/testnet and titon://deployment/mainnet resources.
MCP vs SDK: The MCP tools work with any client and require no SDK install. If you'd rather call the SDK directly (TS or Python) — both surfaces match the MCP tool boundary 1:1 and ship typed dataclasses / interfaces for every input and result.
Local development
npm install
npm run dev # wrangler dev — local Worker on http://localhost:8787
npm test # vitest
npm run build # tsc --noEmit (typecheck)wrangler dev spins up the local Workers runtime. Hit POST http://localhost:8787/mcp with any MCP JSON-RPC request:
curl -s -X POST http://localhost:8787/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | jqOr point your local Claude Desktop at http://localhost:8787/mcp while iterating on tools.
Linking the SDKs during development
All four sibling SDKs are now published to npm, so the MCP repo pins versioned deps:
"@titon-network/kronos-sdk": "^0.8.5",
"@titon-network/fortuna-sdk": "^0.6.0",
"@titon-network/phoebe-sdk": "^0.5.0",
"@titon-network/themis-sdk": "^0.3.0"If you're iterating on an SDK locally and want the MCP to pick up your
changes, temporarily swap a versioned dep for a file:../<repo>/sdks/typescript
dep — run pnpm run build inside the sibling SDK first so its dist/
exists, then pnpm install here.
Deployment
# Staging (testnet)
npm run deploy -- --env staging
# Production (mainnet RPC)
npm run deploy -- --env productionSet the optional toncenter API key for higher rate limits:
wrangler secret put TONCENTER_API_KEY --env productionThen point mcp.titon.network at the deployed Worker (Cloudflare dashboard → Workers → Routes).
Adding a new dev-facing protocol
This server is built dispatcher-style — one folder per protocol module, mounted by the central server.
- Create
src/protocols/<your-protocol>/:src/protocols/<name>/ ├── index.ts # exports `<name>: ProtocolModule` ├── schemas.ts # zod schemas for tool inputs └── tools/ ├── reads.ts # RPC reads ├── prepares.ts # wallet-ready tx builders └── helpers.ts # pure helpers - Implement
register(registry, env)— callregistry.add({ name, description, inputSchema, handler })for each tool. - (optional) Implement
registerResources(resources, env)for any URI-addressable read-only blobs. - Mount it in
src/server.ts:import { yours } from './protocols/yours'; const MODULES = [kronos, fortuna, yours];
Tool names follow <protocol>.<verb_object> so they group cleanly in MCP clients. Resource URIs follow titon://<protocol>/<topic>.
Operator/admin/infrastructure surfaces stay out of the MCP — they belong to operator binaries or SDK CLIs for the audiences that need them.
Architecture in one diagram
┌──────────────────────────────────────────────────────────────────┐
│ Cloudflare Workers — POST /mcp │
│ │
│ src/index.ts (fetch handler) │
│ │ │
│ ▼ │
│ src/server.ts ──▶ McpServer (transport.ts) │
│ │ │ │
│ │ └─▶ JSON-RPC dispatch: │
│ │ initialize / tools/list / │
│ │ tools/call / resources/list / │
│ │ resources/read / ping │
│ │ │
│ ▼ │
│ src/protocols/ │
│ ├─ kronos/ ──▶ @titon-network/kronos-sdk (KronosRegistry) │
│ ├─ fortuna/ ──▶ @titon-network/fortuna-sdk (Fortuna) │
│ └─ shared-resources.ts ──▶ titon://deployment/* etc. │
│ │
│ src/infra/ │
│ ├─ ton-client.ts ──▶ @ton/ton TonClient (per-request) │
│ ├─ schemas.ts ──▶ shared zod parsers │
│ ├─ format.ts ──▶ shared JSON formatter (bigint, Cell) │
│ └─ errors.ts ──▶ unified explainExitCode │
└──────────────────────────────────────────────────────────────────┘Status
- v0.8.0 — Phoebe + Themis Python parity. Both protocols now ship Python SDKs on PyPI (
[email protected]+[email protected]) at parity with their TS siblings; thetiton://protocols+titon://deployment/*resources already advertised both languages in v0.7.0, so no tool wiring changed. Bumped npm deps:@titon-network/fortuna-sdk^0.4.1 → ^0.6.0(testnet ABI was redeployed; mainnet address unchanged),@titon-network/phoebe-sdkmoved from workspacefile:dep to^0.5.0npm pin. PyPI pin manifest now lists all four protocols. - v0.7.0 — Phoebe + Themis as MCP tools. Added 18 Phoebe tools (11 reads + 2 prepares + 5 helpers) and 21 Themis tools (16 reads + 2 prepares + 3 helpers);
titon://protocolsresource now enumerates four products. Bumped@titon-network/atlas-sdkto^0.5.0(required transitively by Themis SDK). - v0.6.0 — Mainnet live.
titon://deployment/mainnetreturns the canonical mainnet manifest (kronosUQCH-JO4…h6Wvq, fortunaUQD7G7Ce…clAJ);[env.production]shipsDEFAULT_*mainnet addresses. Pinned to TSA-audited SDKs:@titon-network/[email protected]+@titon-network/[email protected](npm) /titon-network-kronos-sdk==0.8.4+titon-network-fortuna-sdk==0.4.0(PyPI). Fortuna runs a multi-op threshold-BLS group (t = n, ≥ 2 operators) end-to-end on mainnet — the dapp-facingprepare_request_randomness/get_request/ event surface is identical to solo-mode, so no tool changes were needed. - v0.5.2 — Python SDK parity. The
titon://protocolsandtiton://deployment/testnetresources advertise both npm and PyPI distributions; tool descriptions that named TS-specific helpers (JobBuilder.build,computeAlpha,QueryIdStream) now mention the Python equivalents (register_job_opts,compute_alpha,QueryIdStream) so AI clients with a Python user audience get the right hints. - v0.5.1 — pinned to TSA-audited SDKs:
@titon-network/[email protected](zero findings, 7 checkers) +@titon-network/[email protected](zero findings, 5 checkers). - v0.5 — Model Context Protocol server for dapp authors (full kronos + fortuna surface).
- v0.4 — dapp-author scope. Cut forgeton tools (operator/admin domain). Rebuilt Fortuna module against the current SDK (current getter shape, current event names, correct fee floor 0.22 TON, no slash mechanics — D-011 says no slashing). Cross-protocol error reference covers the dapp-author hot codes.
- v0.3 —
@titon-network/*package scope rename. - v0.2 — Forgeton + Fortuna parity (since cut from v0.4).
- v0.1 — Kronos read + prepare + helper tools.
- Planned: write-tool simulation (dry-run on a sandbox fork).
License
MIT.
