MCP & A2A
Connect AI agents to Prism using the Model Context Protocol (MCP) and Google's Agent-to-Agent (A2A) protocol.
About
Prism supports two interoperability protocols for AI agents:
- MCP (Model Context Protocol): Agents connect to Prism to discover and call tools from a unified interface
- A2A (Agent-to-Agent): Agents delegate tasks to other agents through a standardized protocol
Both protocols enable you to build agent networks where Prism acts as a central hub for tool aggregation and agent coordination.
MCP — Model Context Protocol
How Prism uses MCP
Prism operates as both an MCP server and an MCP client simultaneously:
- As an MCP server: Your AI agents connect to Prism at
/mcpto discover and call tools - As an MCP client: Prism connects to your upstream tool servers and aggregates their tools into a single namespace
This dual role lets you build a tool mesh where agents see all available tools through Prism, regardless of where those tools actually run.
Agent → /mcp → Prism → Tool Server A
├→ Tool Server B
└→ Tool Server C
Connecting an agent to Prism via MCP
Agents connect to Prism using JSON-RPC 2.0 over HTTP. Start by initializing a session:
curl -X POST https://gateway.futureagi.com/mcp \
-H "Authorization: Bearer sk-prism-..." \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-11-25",
"capabilities": {},
"clientInfo": {
"name": "my-agent",
"version": "1.0"
}
}
}'import requests
import json
response = requests.post(
"https://gateway.futureagi.com/mcp",
headers={
"Authorization": "Bearer sk-prism-...",
"Content-Type": "application/json",
},
json={
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-11-25",
"capabilities": {},
"clientInfo": {
"name": "my-agent",
"version": "1.0"
}
}
}
)
print(response.json())const response = await fetch("https://gateway.futureagi.com/mcp", {
method: "POST",
headers: {
"Authorization": "Bearer sk-prism-...",
"Content-Type": "application/json",
},
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "initialize",
params: {
protocolVersion: "2025-11-25",
capabilities: {},
clientInfo: {
name: "my-agent",
version: "1.0"
}
}
})
});
const data = await response.json();
console.log(data); Listing and calling tools
Once initialized, list available tools and call them:
# List available tools
curl -X POST https://gateway.futureagi.com/mcp \
-H "Authorization: Bearer sk-prism-..." \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}'
# Call a tool
curl -X POST https://gateway.futureagi.com/mcp \
-H "Authorization: Bearer sk-prism-..." \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "search",
"arguments": {
"query": "latest AI research"
}
}
}'import requests
# List tools
list_response = requests.post(
"https://gateway.futureagi.com/mcp",
headers={
"Authorization": "Bearer sk-prism-...",
"Content-Type": "application/json",
},
json={
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}
)
tools = list_response.json()["result"]["tools"]
print(f"Available tools: {[t['name'] for t in tools]}")
# Call a tool
call_response = requests.post(
"https://gateway.futureagi.com/mcp",
headers={
"Authorization": "Bearer sk-prism-...",
"Content-Type": "application/json",
},
json={
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "search",
"arguments": {
"query": "latest AI research"
}
}
}
)
result = call_response.json()["result"]
print(result)// List tools
const listResponse = await fetch("https://gateway.futureagi.com/mcp", {
method: "POST",
headers: {
"Authorization": "Bearer sk-prism-...",
"Content-Type": "application/json",
},
body: JSON.stringify({
jsonrpc: "2.0",
id: 2,
method: "tools/list",
params: {}
})
});
const listData = await listResponse.json();
const tools = listData.result.tools;
console.log(`Available tools: ${tools.map(t => t.name).join(", ")}`);
// Call a tool
const callResponse = await fetch("https://gateway.futureagi.com/mcp", {
method: "POST",
headers: {
"Authorization": "Bearer sk-prism-...",
"Content-Type": "application/json",
},
body: JSON.stringify({
jsonrpc: "2.0",
id: 3,
method: "tools/call",
params: {
name: "search",
arguments: {
query: "latest AI research"
}
}
})
});
const callData = await callResponse.json();
console.log(callData.result); MCP methods
Prism supports the following MCP methods:
| Method | Description |
|---|---|
initialize | Start an MCP session with Prism |
tools/list | List all available tools (supports cursor pagination) |
tools/call | Execute a tool with arguments |
resources/list | List all available resources |
resources/read | Read a resource by URI |
prompts/list | List prompt templates |
prompts/get | Get a prompt with arguments |
ping | Health check |
Management endpoints
Prism exposes admin endpoints for monitoring and testing MCP:
| Method | Path | Description |
|---|---|---|
| GET | /-/mcp/status | Get MCP session count, tool count, resource count, and server statuses |
| GET | /-/mcp/tools | List all registered tools as JSON |
| POST | /-/mcp/test | Test a tool by name with arguments: {"name": "tool_name", "arguments": {...}} |
| GET | /-/mcp/resources | List all registered resources |
| GET | /-/mcp/prompts | List all registered prompts |
Note
Management endpoints require authentication and are intended for debugging and monitoring. Use them to verify tool availability and test tool execution before deploying agents.
Per-key tool access control
API keys can restrict which tools are accessible. This allows you to give different agents access to different tool subsets. For example, you might give a research agent access to search tools but deny access to destructive operations.
When you create or update an API key, you can specify allowed and denied tool lists. Prism enforces these restrictions at the MCP layer, so agents using that key will only see and be able to call permitted tools.
Tool naming and validation
Tool names must be 1-128 characters and contain only alphanumeric characters, hyphens, underscores, and periods: [A-Za-z0-9_\-.]
Tool annotations help agents understand tool behavior:
readOnlyHint: Tool does not modify statedestructiveHint: Tool may delete or modify dataidempotentHint: Tool can be called multiple times with the same arguments safelyopenWorldHint: Tool can accept arbitrary arguments
A2A — Agent-to-Agent Protocol
How Prism uses A2A
Prism acts as an A2A node: it can receive tasks from other agents and delegate tasks to downstream A2A agents. This enables agent-to-agent communication and task delegation without requiring direct connections between agents.
Routing to A2A agents
The simplest way to use A2A is to route requests to downstream agents using the a2a/<agent-name> model identifier in any standard chat completion request:
from prism import Prism
client = Prism(
api_key="sk-prism-...",
base_url="https://gateway.futureagi.com",
)
# Route to a downstream A2A agent called "research-agent"
response = client.chat.completions.create(
model="a2a/research-agent",
messages=[
{
"role": "user",
"content": "What are the top 3 AI papers published this week?"
}
],
)
print(response.choices[0].message.content)const response = await client.chat.completions.create({
model: "a2a/research-agent",
messages: [
{
role: "user",
content: "What are the top 3 AI papers published this week?"
}
],
});
console.log(response.choices[0].message.content);curl -X POST https://gateway.futureagi.com/v1/chat/completions \
-H "Authorization: Bearer sk-prism-..." \
-H "Content-Type: application/json" \
-d '{
"model": "a2a/research-agent",
"messages": [
{
"role": "user",
"content": "What are the top 3 AI papers published this week?"
}
]
}' Prism routes the request to the named agent and returns the response. The agent handles the task asynchronously and returns results when ready.
Listing registered agents
View all downstream A2A agents registered with Prism:
curl https://gateway.futureagi.com/v1/agents \
-H "Authorization: Bearer sk-prism-..."
Agent card
Prism exposes its own A2A agent card at /.well-known/agent.json. This metadata describes Prism’s capabilities, skills, and authentication schemes to other A2A-compatible systems.
The agent card includes:
name,description,url,version: Basic agent metadatacapabilities: Supported features likestreamingandpushNotificationsskills: Array of available skills with ID, name, description, tags, and examplessecuritySchemes: Authentication methods (bearer token, API key, or none)
A2A endpoints
| Method | Path | Description |
|---|---|---|
| GET | /.well-known/agent.json | Prism’s agent card with capabilities and skills |
| POST | /a2a | Send a message or task to Prism as an A2A agent |
| GET | /v1/agents | List all registered downstream A2A agents |
Task lifecycle
When you send a task to an A2A agent, it progresses through these statuses:
working: Task is being processedcompleted: Task finished successfullyfailed: Task encountered an errorcanceled: Task was canceled by the user or systeminput_required: Task is waiting for additional input from the user
You can poll the task status or subscribe to status updates via server-sent events (SSE) to track progress.
Tip
Use streaming when you need real-time updates on task progress. This is especially useful for long-running tasks where you want to show the user incremental results.
Authentication
A2A agents support multiple authentication schemes:
bearer: Bearer token in theAuthorizationheaderapi_key: API key in a custom header or query parameternone: No authentication required
Prism’s agent card specifies which schemes it supports. When routing to downstream agents, Prism automatically includes the appropriate credentials.