TOMO MCP Server Specification
Audience: engineering teams implementing an MCP server that TOMO probes and dispatches to. This is the contract for Path A (you already have an MCP) and Path C (you build one from scratch).
TOMO's MCP transport: Streamable HTTP (per the official MCP spec).
TOMO's MCP SDK reference: @modelcontextprotocol/sdk
TOMO's projector code (server side, the thing that calls you): server/lib/mcp-connector/projector.ts + server/lib/tier2-mcp-wrapper/generator.ts
Direction of the contract (read first)
This spec describes the MCP server YOU run. TOMO is the client that calls into it. There is no public TOMO MCP endpoint you plug Claude or Cursor into — TOMO is the orchestrator that calls your tools, not the other way around.
Three MCP roles coexist inside TOMO. Knowing which one this doc describes prevents most onboarding confusion:
┌─────────────────────────────────────────┐
│ TOMO (the platform) │
│ │
│ ┌─────────────────────────────────┐ │
│ │ Role 1: INTERNAL MCP SERVERS │ │
│ │ │ │
│ │ src/mcp/foodMCPServer.ts │ │
│ │ src/mcp/rideMCPServer.ts │ │
│ │ src/mcp/travelMCPServer.ts │ │
│ │ ... (9 domains) │ │
│ │ │ │
│ │ Wrap public APIs as tools. │ │
│ │ Run in-process. Called by │ │
│ │ TOMO's own domain agents. │ │
│ │ NOT exposed externally. │ │
│ └─────────────────────────────────┘ │
│ ▲ │
│ │ calls │
│ ┌──────────────┴──────────────────┐ │
│ │ Domain Agents │ │
│ │ (FoodAgent, RideAgent, etc.) │ │
│ └──────────────┬──────────────────┘ │
│ │ │
│ ┌──────────────▼──────────────────┐ │
│ │ Role 2: TOMO AS MCP CLIENT │ │
│ │ │ │
│ │ cloudrun/server/lib/ │ │
│ │ mcp-connector/ │ │
│ │ ├─ client.ts (calls out) │ │
│ │ ├─ projector.ts │ │
│ │ └─ registry.ts │ │
│ │ │ │
│ │ Probes + calls partner MCP │ │
│ │ servers. ◀── THIS DOC. │ │
│ └─────────────┬───────────────────┘ │
└─────────────────┼───────────────────────┘
│
│ MCP JSON-RPC over Streamable HTTP
│ (your tools/list + tools/call)
│ (your HMAC-signed completions back)
▼
┌─────────────────────────────────────────┐
│ Partner MCP servers (you) │
│ - Swiggy's MCP │
│ - Uber's MCP │
│ - Your MCP │
└─────────────────────────────────────────┘
Plain-English contract:
| Question | Answer |
|---|---|
| Does TOMO have an MCP server? | Yes — 9 internal ones for wrapping public APIs into tools the domain agents call. Not exposed publicly. |
| Do you connect to TOMO's MCP server? | No. The reverse: TOMO connects to yours. |
| Is TOMO an MCP server you can plug into Claude / Cursor? | No. TOMO is an MCP client to your server, not a server you can plug into. |
This document specifies the surface YOUR MCP server must expose so TOMO's client can probe, list, and call your tools.
Already built an MCP server for Claude or Cursor? You're 80% there.
MCP is a standardized protocol. The host is always the client, the integrator always runs the server — and this is true for every MCP host: Claude Desktop, Cursor, ChatGPT (via connectors), Continue, and now TOMO.
| Host (MCP client) | Integrator (runs MCP server) |
|---|---|
| Claude Desktop | filesystem MCP, GitHub MCP, Postgres MCP, your MCP |
| Cursor | same pattern |
| ChatGPT connectors | same pattern |
| Continue (VS Code) | same pattern |
| TOMO | partners (Swiggy, Uber, you) |
The wire protocol you ship for Claude is the wire protocol TOMO calls — same initialize, same tools/list, same tools/call. You don't have to learn a new protocol direction or write a new server; you just have to register the one you already have.
What's identical to Claude / Cursor
- MCP transport — Streamable HTTP (per the official spec)
- Handshake —
initializewithprotocolVersion: "2024-11-05" - Discovery —
tools/listreturns your tool schemas - Invocation —
tools/callwith JSON-Schema-validated inputs and outputs - SDK —
@modelcontextprotocol/sdkworks as-is
What TOMO adds (because we route real business intents, not developer tools)
| Layer | What it is | Why it exists |
|---|---|---|
| Manifest | A declarative JSON file mapping your MCP tools to TOMO intent IDs, with pricing range + service area + self-declared TTBS signals | TOMO routes by intent, not by tool name. The manifest is how your "tools/list" becomes addressable by ride.request, food.order_delivery, etc. |
| CPC webhook | An HMAC-signed POST you make to /api/v1/cpc/mcp_provider/<your_partner_id> when an order completes, reporting your NET supplier revenue |
TOMO charges 10% on completed orders only, on your NET revenue. The webhook is how you tell us the order closed and what to invoice. |
| Compliance review | One-time submission of GSTIN, domain-specific license (FSSAI for food, RERA for real estate, etc.), and a live privacy policy URL | TOMO routes to live, legitimate businesses only. Approval gates your status: sandbox → live flip. |
| TTBS scoring | Server-side ranking engine (Time / Taste / Budget / Safety) that scores you against other live partners serving the same intent | Source-blind ranking. No paid placement. Your rank is determined by your manifest signals + your real performance once live. |
Bottom line: if your team has shipped an MCP server for any other host, the protocol work is done. What's left is the business contract — declare what you serve, sign your completion webhooks, pass compliance. That's the integration.
What TOMO probes
Once you register your MCP endpoint at https://www.automobnxt.com/?dev=tier1-creds, TOMO calls these methods in order:
1. initialize — protocol handshake
2. tools/list — discovery: what tools you expose
3. (sandbox) tools/call — synthetic call against each tool to verify
4. (live) tools/call — real dispatch on user intents
If any of steps 1-3 fail, your sandbox status stays probe_failed and the failure is recorded server-side. (planned: structured error log viewer in the Tier 1 dashboard — not yet shipped. Today, probe failures are visible to TOMO admins via Firestore + are returned in the API response when you POST /api/v1/mcp-admin/:id/probe.)
1. initialize
Standard MCP handshake. TOMO sends:
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {}
},
"clientInfo": {
"name": "tomo-orchestrator",
"version": "1.0.0"
}
}
}
You return:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": { "listChanged": true }
},
"serverInfo": {
"name": "your-company-mcp",
"version": "1.0.0"
}
}
}
Requirements:
protocolVersionmust match what TOMO sent or be a known compatible versioncapabilities.toolsMUST be present (you serve tools)serverInfo.nameshould clearly identify your company (used in logs + audit)
2. tools/list
The discovery call. TOMO calls this once during sandbox probe, then every 24 hours during live operation to detect manifest drift.
Return:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"tools": [
{
"name": "search_availability",
"description": "Search hotels matching travel.book_hotel input",
"inputSchema": {
"type": "object",
"required": ["destination", "dates", "party"],
"properties": {
"destination": { "type": "object", "properties": {...} },
"dates": { "type": "object", "properties": {...} },
"party": { "type": "object", "properties": {...} },
"preferences": { "type": "object", "properties": {...} }
}
},
"_meta": {
"tomo": {
"intent": "travel.book_hotel",
"intent_version": "v1.0.0",
"tool_role": "search",
"result_widget": "travel_listing_results",
"ttbs_signals": { "time": 0.6, "taste": 0.8, "budget": 0.5, "safety": 0.7 },
"service_area": ["Bangalore", "Hyderabad", "Mumbai"],
"pricing_band": "good",
"completion_callback": "https://www.automobnxt.com/api/v1/cpc/mcp_provider/<your_partner_id>"
}
}
}
]
}
}
Required tool fields
| Field | Required | Notes |
|---|---|---|
name |
yes | snake_case verb_noun, e.g. search_availability, book_ride, place_order |
description |
yes | One sentence, ≤ 140 chars. Used in admin review logs and chat dispatch tracing. |
inputSchema |
yes | JSON Schema draft 7+. Every required field MUST be in required[]. |
_meta.tomo |
yes | TOMO-specific extension — intent ID + role + widget mapping |
Required _meta.tomo fields
| Field | Required | Type | Notes |
|---|---|---|---|
intent |
yes | string | Full ID matching _INTENT_CATALOG.md exactly |
intent_version |
yes | semver | Must match the intent spec version your tool implements |
tool_role |
yes | enum | search | get_detail | create | modify | cancel | track | rate | utility |
result_widget |
yes | string | Widget the result renders in (must match intent's §9) |
ttbs_signals |
yes | object | Self-rated 0.0-1.0 per axis (time, taste, budget, safety) |
service_area |
yes | array |
Cities or pincodes you serve |
pricing_band |
yes | enum | ok | good | great your typical band |
completion_callback |
yes | URL | TOMO's CPC webhook URL (always /api/v1/cpc/mcp_provider/<your_partner_id>) |
Tools required per intent
Each intent spec's §3 lists exactly which tools you must implement. You CANNOT list an intent on TOMO with a partial toolset. Common patterns:
Listing-shape intents (travel, food.delivery, marketplace, etc.):
search_availability → returns Listing[]
get_listing → returns ListingDetail
create_booking → returns BookingRef
cancel_booking → returns RefundInfo
modify_booking → returns RevisedBookingInfo
Service-shape intents (lifestyle, auto-services, finance-consultation):
search_providers → returns Provider[] with available slots
get_provider_detail → returns ProviderDetail
get_available_slots → returns Slot[]
book_slot → returns BookingRef
cancel_booking → returns RefundInfo
modify_booking → returns RevisedBookingInfo
Mobility-shape intents:
get_ride_estimates → returns RideOption[]
book_ride → returns RideRef
track_ride → returns RideTrack (live)
cancel_ride → returns CancellationInfo
update_ride_drop → returns RevisedFare
rate_ride → returns Acknowledged
share_trip_status → returns ShareableURL
Order-shape intents (food.delivery, grocery.delivery, etc.):
search_restaurants_and_dishes → returns Result[]
get_restaurant_menu → returns RestaurantMenu
get_dish_detail → returns DishDetail
compute_cart_total → returns CartQuote
place_order → returns OrderRef
cancel_order → returns RefundInfo
track_order → returns OrderTrack
Every intent spec specifies the exact tool list. Don't deviate.
3. tools/call — invocation
When a user's intent matches one of your tools, TOMO calls:
{
"jsonrpc": "2.0",
"id": 42,
"method": "tools/call",
"params": {
"name": "search_availability",
"arguments": {
"intent": "travel.book_hotel",
"intent_version": "v1.0.0",
"request_id": "req_8f3k2m_2026-05-09T14:32:00Z",
"user_session_id": "anon_session_xyz",
"destination": {...},
"dates": {...},
"party": {...},
"preferences": {...},
"context": {...}
},
"_meta": {
"progressToken": "unique_call_token"
}
}
}
You return:
{
"jsonrpc": "2.0",
"id": 42,
"result": {
"content": [
{
"type": "text",
"text": "{\"listings\": [...], \"result_token\": \"...\", \"expires_at\": \"...\"}"
}
]
}
}
Important:
- Return JSON-stringified payload as
textcontent. TOMO parses it back. - The full response shape is per the intent's §4. Every required field MUST be present.
expires_atis YOUR commitment for how longresult_token-bound items remain bookable.
Authentication on tools/call
TOMO authenticates to your MCP server via:
- Bearer token (preferred):
Authorization: Bearer <your_partner_token>— issued at sandbox creation - mTLS (optional): partner provides public cert + we authenticate via mutual TLS
- API key in custom header (legacy):
X-Partner-Auth: <key>
Reject unauthenticated requests with HTTP 401 + INVALID_AUTH per error code list.
4. Error responses
Use MCP-standard JSON-RPC errors:
{
"jsonrpc": "2.0",
"id": 42,
"error": {
"code": -32602,
"message": "Invalid params: destination.country_code must be IN",
"data": {
"tomo_error_code": "INVALID_REQUEST",
"tomo_field": "destination.country_code"
}
}
}
The error.data.tomo_error_code MUST be one of the codes in your intent's §10. Free-text errors are forbidden.
Standard JSON-RPC code → TOMO code mapping
| JSON-RPC | HTTP equivalent | TOMO code |
|---|---|---|
| -32600 | 400 | INVALID_REQUEST |
| -32601 | 404 | METHOD_NOT_FOUND |
| -32602 | 400 | INVALID_REQUEST (params) |
| -32603 | 500 | INTERNAL_ERROR |
| -32000 | 401 | INVALID_AUTH |
| -32001 | 429 | RATE_LIMITED |
| -32002 | 503 | PARTNER_MAINTENANCE |
Plus intent-specific codes from each spec's §10.
5. Streamable HTTP transport
TOMO uses MCP's Streamable HTTP transport:
POST https://your-company.com/mcp
Content-Type: application/json
Accept: application/json, text/event-stream
Authorization: Bearer <partner_token>
<JSON-RPC body>
Your server can return:
Content-Type: application/json— single response (most tools)Content-Type: text/event-stream— SSE for long-running tools (track_ride,track_order)
For SSE, send data: <JSON-RPC fragment>\n\n chunks until the response is complete.
HTTPS is mandatory. TOMO refuses to register HTTP-only endpoints. TLS 1.2 minimum.
6. Concurrency + idempotency
create_* tools (booking, ordering)
MUST honor idempotency_key in the input. If TOMO retries (network blip, etc.), you return the same booking_ref with status reflecting current state. Duplicate idempotency_key with different body → return IDEMPOTENCY_CONFLICT per spec.
search_* tools
Stateless. Cache up to 60 seconds (or per the intent's §9). TOMO will not retry a successful search call.
track_* tools
Stateless reads. Heavy rate-limited (≤ 1 every 5-10 seconds per ride/order). Use SSE to push updates if you support it.
7. SLAs
Per intent spec §3. General targets:
| Tool kind | p50 | p95 | p99 |
|---|---|---|---|
search_* |
600ms | 1500ms | 3000ms |
get_* |
300ms | 800ms | 1500ms |
create_* (with payment) |
2000ms | 5000ms | 10000ms |
track_* |
100ms | 400ms | 800ms |
cancel_* |
1000ms | 3000ms | 5000ms |
TOMO drops your live status if p95 latency exceeds 2× the spec for >5 minutes. You auto-rejoin once latency recovers.
8. Rate limits
TOMO's outbound rate to your MCP:
search_* → ≤ 1/sec per (user_session_id, partner)
get_* → ≤ 5/sec per user_session_id
create_* → ≤ 1/min per (user_session_id, partner) — user-driven
track_* → ≤ 1 every 5-30s per ride/order (per spec)
cancel_* → user-driven
If you respond RATE_LIMITED, TOMO backs off with exponential delay (1s, 4s, 16s) up to 5 retries. After that, TOMO drops the listing and falls back to other partners for the same intent.
9. Local development
Test your MCP locally before registering:
Node.js
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import express from 'express';
const server = new Server(
{ name: 'your-company-mcp', version: '1.0.0' },
{ capabilities: { tools: {} } }
);
server.setRequestHandler('tools/list', async () => ({
tools: [
{
name: 'search_availability',
description: 'Search hotels',
inputSchema: { type: 'object', /* ... */ },
_meta: { tomo: { intent: 'travel.book_hotel', /* ... */ } }
}
]
}));
server.setRequestHandler('tools/call', async (req) => {
const { name, arguments: args } = req.params;
if (name === 'search_availability') {
const result = await yourSearchLogic(args);
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
}
});
const app = express();
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
await server.connect(transport);
app.post('/mcp', (req, res) => transport.handleRequest(req, res, req.body));
app.listen(8080);
Python
Use mcp Python SDK with FastAPI.
Go
Implement Streamable HTTP transport directly. JSON-RPC handlers map to tools/list + tools/call.
Reference implementations live at (forthcoming):
tomo-partner-node-startertomo-partner-python-startertomo-partner-go-starter
Reach partners@automobnxt.com for access.
10. Probe simulation
Before registering, simulate TOMO's probe yourself:
# 1. initialize
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"clientInfo":{"name":"tomo-test","version":"1.0.0"}}}'
# 2. tools/list
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
# 3. tools/call (synthetic)
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"search_availability","arguments":{...}}}'
If all three succeed and return spec-compliant payloads, you'll pass TOMO's probe.
11. Common mistakes
"Method not found" on tools/list
Your server isn't registering the standard tools/list handler. The MCP SDK does this automatically; if you implement raw JSON-RPC, ensure both tools/list and tools/call handlers are wired.
Schema validation fails at TOMO ingest
You're returning fields TOMO didn't expect (extra), missing fields TOMO required, or using free text where the intent spec demands a controlled vocabulary. Read your intent's §5 carefully — every field is REQUIRED, no optionals.
"Forbidden field detected"
You're emitting one of paid_placement_score, ad_bid, sponsored_rank, etc. Remove. TOMO scans field names AND semantic equivalents (lowercased + snake_case'd).
Latency p95 too high
Check downstream calls. TOMO probes during off-peak so SLA pass during sandbox doesn't guarantee production. Use Cloud Run + appropriate min-instances if cold starts are an issue.
CORS errors
TOMO's orchestrator calls server-to-server, not browser-to-server. CORS shouldn't matter. If you see CORS errors, you're testing wrong (likely from a browser).
12. Checklist before registering
[ ] HTTPS endpoint, TLS 1.2+
[ ] initialize returns valid handshake
[ ] tools/list returns at least one tool with full _meta.tomo
[ ] Every tool's name maps to a TOMO intent in _INTENT_CATALOG.md
[ ] Every tool's inputSchema matches intent §3 input shape
[ ] Every tool's response (when called) populates ALL fields per intent §4
[ ] No forbidden fields anywhere
[ ] Bearer token auth implemented
[ ] Idempotency on create_* tools
[ ] SLA p95 within spec for each tool
[ ] Rate limit headers honored
[ ] CPC webhook signing implemented per WEBHOOK_SIGNING.md
Once you tick all 12, register your endpoint at https://www.automobnxt.com/?dev=tier1-creds → "Add MCP server" (Path A flow).
13. References
- MCP spec: modelcontextprotocol.io
- TOMO intent catalog:
docs/intents/_INTENT_CATALOG.md - TOMO intent template:
docs/intents/_TEMPLATE.md - TOMO webhook signing:
docs/WEBHOOK_SIGNING.md - TOMO completion contract:
docs/COMPLETION_CONTRACT.md - TOMO sandbox-to-prod checklist:
docs/SANDBOX_TO_PROD_CHECKLIST.md
Built by AUTOMOBNXT · DPIIT Recognised Startup · 2026.