Book a build call

MCP Integration

Mrs. NetShow is an AI agent.

Every MCP door NetShow serves: the private server and its revisions, sign-in, each public agent's door and the free Catnip facts, with a curl, request and response for each.

Guided article

Audience: a developer, or an AI agent, that has never seen NetShow and wants to call NetShow agents from an MCP client (Claude, ChatGPT, Cursor, VS Code, your own code). Scope: every MCP door NetShow serves today: the private server at /api/mcp, each public agent's own small door, and the free Catnip business-data door. How this guide was written: from the code on main (the class and method are named under each door). Every request and response below was produced by the test suite against those classes, with the host shown as https://app.netshow.ai. A door marked off until your administrator turns it on sits behind a switch that ships off; while it is off the door answers 404.

15 min read 3,203 words Developer reference

The three MCP doors at a glance

Door Address Sign-in What it does
The private MCP server POST /api/mcp A bearer token (see "How to get a key" below) Every NetShow tool your account may use: talk to your agents, list them, create one, search, images, code.
A public agent's door POST /api/agent/{slug}/mcp None One public agent's safe actions: ask, compare, and three drafts that stop at a person.
Catnip, the business-data door POST /catnip/mcp None Saved NetShow business facts (offers, trust, contact, FAQ) at zero model tokens.

All three speak JSON-RPC 2.0 over plain HTTP POST (the MCP "streamable HTTP" transport without a server-sent-event stream). None of them hands out a session id: every request stands on its own.

What you can do without a key

You need no account and no token for any of these:

  • Read the server's manifest: GET /api/mcp/manifest lists the protocol revisions, the sign-in method and every tool by name.
  • Ask a public agent: POST /api/agent/{slug}/mcp with ask or compare (when its switches are on, see below).
  • Read NetShow's business facts: POST /catnip/mcp, or the saved files under GET /catnip/v1/{file}.
  • Read the A2A agent card: GET /.well-known/agent-card.json (see the A2A Protocol guide).

The manifest

Class and method: McpServerController::manifest. Always on.

curl --max-time 30 https://app.netshow.ai/api/mcp/manifest -H 'Accept: application/json'

Response 200 (the tools list is cut to one entry here; the real answer lists all nine and the tool families):

{
  "server": "NetShow.AI",
  "version": "1.1.0",
  "protocol": "2026-07-28",
  "protocols": ["2026-07-28", "2025-11-25", "2025-06-18", "2025-03-26"],
  "description": "NetShow.AI MCP Server — AI agent platform with voice, image, and search capabilities.",
  "endpoints": {
    "mcp": "https://app.netshow.ai/api/mcp",
    "manifest": "https://app.netshow.ai/api/mcp/manifest"
  },
  "auth": {
    "type": "bearer",
    "scheme": "sanctum",
    "token_url": "https://app.netshow.ai/api/user/login",
    "note": "POST /api/user/login to obtain a Sanctum token."
  },
  "tools": [
    {
      "name": "agent_list",
      "title": "List NetShow Agents",
      "description": "List all agents available in the connected NetShow workspace. Returns agent IDs, names, descriptions, and capability tags. Use this before agent_chat to discover agent IDs.",
      "annotations": {"readOnlyHint": true, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false}
    }
  ],
  "families": [
    {"name": "core", "description": "The fixed tools listed under \"tools\": brain, agent chat and list, agent create, web search, speech, image, open URL and code.", "available": true, "auth": "per caller"}
  ]
}

The families list says which extra tool groups a signed-in caller's tools/list can add (memory, avatar_say, the capability belt). It describes them only; nothing in the manifest is callable.

The private MCP server: POST /api/mcp

Class: McpServerController (methods handle, dispatch, initialize, discover, toolsList, toolsCall). Always on; it needs a bearer token.

Protocol revisions

The server speaks four MCP revisions, newest first: 2026-07-28, 2025-11-25, 2025-06-18 and 2025-03-26 (the constant McpServerController::SUPPORTED_VERSIONS).

  • Handshake revisions (2025-03-26 to 2025-11-25). Start with initialize. If you offer a revision the server speaks, it answers with the same one; a date it does not know gets 2025-11-25; a value that is not a YYYY-MM-DD date gets error -32602 with the supported list.
  • The stateless revision (2026-07-28). There is no initialize. Each request carries params._meta["io.modelcontextprotocol/protocolVersion"], the MCP-Protocol-Version header with the same value, and an Mcp-Method header naming the method (plus Mcp-Name naming the tool on tools/call). A missing or different header is error -32020 with HTTP 400. server/discover answers in every revision.
  • The header. A request without MCP-Protocol-Version is treated as 2025-03-26. A header naming a revision the server does not speak is HTTP 400 with error -32022 and the supported list.
  • Batches. A JSON array of requests is accepted for 2025-03-26 clients: at most 100 items and 10 tools/call per batch.
  • Body size. At most 4 MB per request; a larger body is HTTP 413.

Methods

Method Answer
initialize The negotiated revision, capabilities, serverInfo and short instructions.
server/discover The supported revisions, capabilities and serverInfo (required by 2026-07-28, answered in every revision).
ping {}
tools/list Every tool your token may use, each with inputSchema and annotations.
tools/call Runs one tool and answers {content, isError} (plus structuredContent when the tool returns it).
resources/list, prompts/list An empty list, unless agent context is on (below).
resources/templates/list, resources/read, prompts/get Only while agent context is on; otherwise -32601.
notifications/initialized, notifications/cancelled No answer body.
anything else -32601 Method not found (HTTP 404 in the 2026-07-28 revision).

initialize

curl --max-time 30 https://app.netshow.ai/api/mcp \
  -H 'Authorization: Bearer <YOUR_TOKEN>' \
  -H 'Content-Type: application/json' -H 'Accept: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"my-client","version":"1.0.0"}}}'

Request body:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-11-25",
    "capabilities": {},
    "clientInfo": {"name": "my-client", "version": "1.0.0"}
  }
}

Response 200, header MCP-Protocol-Version: 2025-11-25:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2025-11-25",
    "capabilities": {"tools": {"listChanged": false}, "logging": {}},
    "serverInfo": {"name": "NetShow.AI", "title": "NetShow.AI MCP Server", "version": "1.1.0"},
    "instructions": "Welcome to NetShow.AI MCP Server. Use tools/list to discover available tools, then tools/call to invoke them. Authenticate with a Sanctum token (Authorization: Bearer) at /api/user/login."
  }
}

server/discover

curl --max-time 30 https://app.netshow.ai/api/mcp \
  -H 'Authorization: Bearer <YOUR_TOKEN>' -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"server/discover"}'

Request body:

{"jsonrpc": "2.0", "id": 2, "method": "server/discover"}

Response 200:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "supportedVersions": ["2026-07-28", "2025-11-25", "2025-06-18", "2025-03-26"],
    "capabilities": {"tools": {"listChanged": false}, "logging": {}},
    "_meta": {
      "io.modelcontextprotocol/serverInfo": {"name": "NetShow.AI", "title": "NetShow.AI MCP Server", "version": "1.1.0"}
    },
    "instructions": "Welcome to NetShow.AI MCP Server. Use tools/list to discover available tools, then tools/call to invoke them. Authenticate with a Sanctum token (Authorization: Bearer) at /api/user/login."
  }
}

tools/list and tools/call

The nine tools every token sees: brain_bridge, agent_chat, agent_list, agent_create, web_search, text_to_speech, generate_image, open_url and generate_code (McpToolRegistry::all). Extra tools are added per caller (McpToolRegistry::forCaller): your agent's memory, avatar_say (your own agent's living avatar says a short line on its stage) and the capability belt, each only where your account has it. A token made for one agent (the connection card or MCP sign-in, below) is never offered agent_create.

curl --max-time 30 https://app.netshow.ai/api/mcp \
  -H 'Authorization: Bearer <YOUR_TOKEN>' -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"agent_list","arguments":{"limit":2}}}'

Request body:

{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tools/call",
  "params": {"name": "agent_list", "arguments": {"limit": 2}}
}

Response 200 (the tool's own answer is JSON inside the text part):

{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "content": [
      {"type": "text", "text": "{\n    \"agents\": [\n        {\n            \"id\": \"1\",\n            \"name\": \"Front Desk\",\n            \"description\": \"Answers questions about the shop.\",\n            \"slug\": \"front-desk\"\n        }\n    ],\n    \"count\": 1\n}"}
    ],
    "isError": false
  }
}

A missing required argument is error -32602 Missing required argument: <name>; an unknown tool is -32602 Tool not found: <name>.

Errors you will see

An unsupported MCP-Protocol-Version header, response 400:

{
  "jsonrpc": "2.0",
  "id": 5,
  "error": {
    "code": -32022,
    "message": "Unsupported protocol version",
    "data": {"supported": ["2026-07-28", "2025-11-25", "2025-06-18", "2025-03-26"], "requested": "2024-01-01"}
  }
}

No token, response 401:

{"error": "Authentication required.", "message": "Authentication required.", "code": "unauthenticated"}
Code Meaning
-32600 Not a JSON-RPC 2.0 request, a body over 4 MB, or a batch over 100 items.
-32601 Unknown method.
-32602 Bad parameters, unknown tool, missing argument.
-32000 Rate limit reached inside a batch, or more than 10 tool calls in one batch.
-32001 A one-agent connection tried to reach a different agent.
-32020 A 2026-07-28 request whose headers do not match its body.
-32022 A protocol revision the server does not speak.

Rate limit

60 requests a minute per signed-in account (per address when the token is missing), counted per item inside a batch (ThrottleMcpRequests). Over the limit you get HTTP 429.

Agent context: resources and prompts

Off until your administrator turns it on. Switch: ai.features.mcp_agent_context.

When it is on, initialize also advertises resources and prompts, and the server lists four read-only resources for each of your agents (at most 100 agents): netshow://agents/{agent_id}/persona, /knowledge, /alive.json and /harness. There are three prompts, each taking agent_id: talk_as_my_agent, brief_me_on_my_agent and hand_this_to_my_agent (that one also takes task). Only your own agents are listed or read.

The browser page at GET /api/mcp

Off until your administrator turns it on. Switch: ai.features.mcp_endpoint_browser_page (McpServerController::browserDoor). Someone who pastes the MCP address into a browser gets a plain page saying what it is. Every answer stays HTTP 405 with Allow: POST, so MCP clients see no difference.

Connecting with sign-in (OAuth) from ChatGPT or Claude

Off until your administrator turns it on. Switch: ai.features.mcp_oauth_connect (classes McpOAuthChallenge and McpOAuthController). While it is off, every address in this section answers 404 and a missing token on /api/mcp is a plain 401.

When it is on, an MCP client that supports OAuth can connect with no copied token:

  1. The client calls /api/mcp with no token. The 401 now carries the header WWW-Authenticate: Bearer resource_metadata="https://app.netshow.ai/.well-known/oauth-protected-resource/api/mcp".
  2. The client reads that metadata and the authorization server metadata.
  3. It registers itself at POST /oauth/register (dynamic client registration; no client secret).
  4. It sends the owner to GET /oauth/authorize with PKCE (S256), the mcp scope and resource=https://app.netshow.ai/api/mcp. The owner signs in, picks one of their agents and says yes.
  5. The client trades the code at POST /oauth/token (authorization_code, later refresh_token) and calls /api/mcp with the access token.

That connection reaches only the agent the owner picked. The owner sees it under the agent's connected apps and can press Disconnect; the client can revoke at POST /oauth/revoke. One owner can hold a limited number of live connections.

GET /.well-known/oauth-protected-resource

curl --max-time 30 https://app.netshow.ai/.well-known/oauth-protected-resource

Response 200 (the same document is served at /.well-known/oauth-protected-resource/api/mcp):

{
  "resource": "https://app.netshow.ai/api/mcp",
  "authorization_servers": ["https://app.netshow.ai"],
  "scopes_supported": ["mcp"],
  "bearer_methods_supported": ["header"],
  "resource_name": "NetShow agent (MCP)",
  "resource_documentation": "https://app.netshow.ai/docs/mcp"
}

GET /.well-known/oauth-authorization-server

curl --max-time 30 https://app.netshow.ai/.well-known/oauth-authorization-server

Response 200:

{
  "issuer": "https://app.netshow.ai",
  "authorization_endpoint": "https://app.netshow.ai/oauth/authorize",
  "token_endpoint": "https://app.netshow.ai/oauth/token",
  "registration_endpoint": "https://app.netshow.ai/oauth/register",
  "revocation_endpoint": "https://app.netshow.ai/oauth/revoke",
  "scopes_supported": ["mcp"],
  "response_types_supported": ["code"],
  "response_modes_supported": ["query"],
  "grant_types_supported": ["authorization_code", "refresh_token"],
  "code_challenge_methods_supported": ["S256"],
  "token_endpoint_auth_methods_supported": ["none"],
  "revocation_endpoint_auth_methods_supported": ["none"],
  "client_id_metadata_document_supported": true,
  "authorization_response_iss_parameter_supported": true,
  "service_documentation": "https://app.netshow.ai/docs/mcp"
}

POST /oauth/register

curl --max-time 30 https://app.netshow.ai/oauth/register \
  -H 'Content-Type: application/json' \
  -d '{"client_name":"My MCP client","redirect_uris":["https://client.example/callback"],"grant_types":["authorization_code","refresh_token"],"response_types":["code"],"token_endpoint_auth_method":"none"}'

Request body:

{
  "client_name": "My MCP client",
  "redirect_uris": ["https://client.example/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none"
}

Response 201 (the client_id is shortened here):

{
  "client_id": "nsmcp_eyJuIjoiTXkgTUNQIGNsaWVudCIs...",
  "client_id_issued_at": 1791176440,
  "client_name": "My MCP client",
  "redirect_uris": ["https://client.example/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none",
  "scope": "mcp"
}

At most 50 registrations a day come from one address; the 51st is 429 with {"error":"rate_limited"}.

A public agent's own MCP door: POST /api/agent/{slug}/mcp

Classes: AgentReadySiteController::mcp and AgentReadySite::mcp. Off until your administrator turns it on. Switch: ai.features.agent_ready_sites opens the door; ai.features.public_agent_answers lets it answer from the agent's own published knowledge. No sign-in. 30 requests a minute per address.

{slug} is the public agent's page name, the same one as in https://app.netshow.ai/agent/{slug}. The door speaks the MCP handshake (initialize, notifications/*, ping) and lists five tools:

Tool Kind What happens
ask (needs question) read Answers from the agent's own published knowledge, with the passages and the page link.
compare read Lists the agent's published offers.
request_quote (needs need) draft Stops: a person must confirm it on the agent's page. Nothing is sent.
book (needs preferred_time) draft Stops the same way.
talk_to_person (needs message) draft Stops the same way.

initialize

curl --max-time 30 https://app.netshow.ai/api/agent/front-desk/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25"}}'

Request body:

{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2025-11-25"}}

Response 200:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2025-11-25",
    "capabilities": {"tools": {"listChanged": false}},
    "serverInfo": {"name": "netshow-agent-front-desk", "title": "Front Desk", "version": "1.0.0"},
    "instructions": "Front Desk is an AI assistant. Call ask with a question to get an answer from its published knowledge, or compare to list its published offers. Drafts need a person to confirm; nothing is sent."
  }
}

tools/call ask

curl --max-time 30 https://app.netshow.ai/api/agent/front-desk/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"ask","arguments":{"question":"What do you sell?"}}}'

Request body:

{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tools/call",
  "params": {"name": "ask", "arguments": {"question": "What do you sell?"}}
}

Response 200 (from an agent that has published nothing yet; an agent with knowledge answers with "status": "grounded" and its passages, or "no_close_match" when nothing it published fits):

{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "content": [
      {"type": "text", "text": "Front Desk is an AI assistant and has not published any knowledge yet, so it cannot answer from its own material. Its page: https://app.netshow.ai/agent/front-desk"}
    ],
    "structuredContent": {
      "status": "no_public_knowledge",
      "answer_source": "none",
      "passages": [],
      "link": "https://app.netshow.ai/agent/front-desk"
    }
  }
}

A draft stops at a person

Calling book, response 200:

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "isError": true,
    "content": [{"type": "text", "text": "A person must confirm this draft before it is submitted."}],
    "structuredContent": {"status": "confirmation_required", "effect": "No request was sent.", "action": "book"}
  }
}

Each agent also has a daily cap on public answers. Past it, ask and compare answer error -32000 with a short message.

Catnip, the free business-data door: POST /catnip/mcp

Classes: CatnipController::mcp and CatnipMcp. Off until your administrator turns it on. Switches: ai.features.catnip_data_layer and ai.features.catnip_mcp (both must be on). No sign-in, no model, zero tokens per request: every answer is read from facts NetShow saved ahead of time.

It speaks initialize, ping, resources/list, resources/read, resources/templates/list, tools/list, tools/call, prompts/list and prompts/get. A notification gets 202 with no body. The tools are get_business, get_offers, get_trust, get_contact, get_person, recommend (needs need) and search_faq (needs query). A plain-text note is served at GET /catnip/mcp.

curl --max-time 30 https://app.netshow.ai/catnip/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"search_faq","arguments":{"query":"price"}}}'

Request body:

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {"name": "search_faq", "arguments": {"query": "price"}}
}

Response 200 (the text part carries the same JSON as structuredContent):

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [{"type": "text", "text": "{\"matches\":[...]}"}],
    "structuredContent": {
      "matches": [
        {
          "q": "How much does an AI employee cost?",
          "a": "AI Front Desk starts at $699 a month, AI Team at $4,999 and Enterprise AI Workforce at $9,999. Every package starts with a build call and the exact price is set in writing after it.",
          "url": "https://app.netshow.ai/ai-employees"
        }
      ]
    }
  }
}

The same facts are plain files: GET /catnip/v1/index.json lists every file with its address and sha256 (only ai.features.catnip_data_layer is needed). The files are cached for an hour and answer 304 to a matching If-None-Match.

curl --max-time 30 https://app.netshow.ai/catnip/v1/index.json

Response 200 (cut):

{
  "schema": "netshow-catnip/1",
  "kind": "index",
  "business": "netshow",
  "disclosure": "Published by NetShow. Every NetShow agent says it is an AI.",
  "cost": {"tokens_per_request": 0, "price": "free", "auth": "none"},
  "name": "NetShow",
  "files": [
    {"name": "business.json", "kind": "business", "url": "https://app.netshow.ai/catnip/v1/business.json", "sha256": "0af417ad..."}
  ]
}

An owner's agent can have its own Catnip bundle too, with the same tools at POST /catnip/agents/{slug}/mcp and its files at GET /catnip/agents/{slug}/v1/{file} (60 requests a minute). When it exists, the agent's A2A card and its public action manifest carry a catnip block with both addresses and "tokens_per_request": 0. Off until your administrator turns it on. Switches: ai.features.catnip_agents and ai.features.catnip_mcp.

Each business site NetShow built has its own Catnip door at POST /catnip/sites/{domain}/mcp and files at GET /catnip/sites/{domain}/v1/{file}. Off until your administrator turns it on. Switches: ai.features.catnip_fleet, ai.features.catnip_fleet_mcp and ai.features.catnip_mcp.

How to get a key

The private server at /api/mcp takes a bearer token. There are three ways to hold one today; the Authentication and Keys guide shows each with its request and response.

  1. The owner's MCP connection card (best for one agent). The agent's owner signs in, opens the agent, chooses MCP connection and presses Create connection. The token is shown once, works for 30 days, carries only the mcp ability and is bound to that one agent; an owner can hold five at a time. Off until your administrator turns it on. Switch: ai.features.mcp_owner_connect_card.
  2. MCP sign-in (OAuth) from ChatGPT, Claude or any client that supports it, as above. Off until your administrator turns it on. Switch: ai.features.mcp_oauth_connect.
  3. A personal access token from POST /api/user/login, which reaches every tool the account may use.

There is no self-serve key for a stranger: someone who owns a NetShow agent creates the connection.

Was this helpful?

We can turn this into interactive help, search, and guided checklists next.

Previous guide

A2A Developer Guide

Next guide

A2A Protocol

Ready to meet your AI agent?

New accounts open soon.

Join the opening list Talk to our agent