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.
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.
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/manifestlists the protocol revisions, the sign-in method and every tool by name. -
Ask a public agent:
POST /api/agent/{slug}/mcpwithaskorcompare(when its switches are on, see below). -
Read NetShow's business facts:
POST /catnip/mcp, or the saved files underGET /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 aYYYY-MM-DDdate gets error-32602with the supported list. -
The stateless revision (2026-07-28). There is no
initialize. Each request carriesparams._meta["io.modelcontextprotocol/protocolVersion"], theMCP-Protocol-Versionheader with the same value, and anMcp-Methodheader naming the method (plusMcp-Namenaming the tool ontools/call). A missing or different header is error-32020with HTTP400.server/discoveranswers in every revision. -
The header. A request without
MCP-Protocol-Versionis treated as 2025-03-26. A header naming a revision the server does not speak is HTTP400with error-32022and the supported list. -
Batches. A JSON array of requests is accepted for 2025-03-26 clients: at most 100 items and 10
tools/callper 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:
- The client calls
/api/mcpwith no token. The401now carries the headerWWW-Authenticate: Bearer resource_metadata="https://app.netshow.ai/.well-known/oauth-protected-resource/api/mcp". - The client reads that metadata and the authorization server metadata.
- It registers itself at
POST /oauth/register(dynamic client registration; no client secret). - It sends the owner to
GET /oauth/authorizewith PKCE (S256), themcpscope andresource=https://app.netshow.ai/api/mcp. The owner signs in, picks one of their agents and says yes. - The client trades the code at
POST /oauth/token(authorization_code, laterrefresh_token) and calls/api/mcpwith 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.
-
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
mcpability 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. -
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. -
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