Peer agents
A peer connection lets one agent ask an independent specialist for help. The specialist keeps its own instructions, tools, and sessions. On Cursor hosting, team-owned agents reach each other by deployment slug, and Agent SDK handles routing and authentication for you.
Delegate a question to a specialist
Ask the concierge about the weather, and it hands the question to the weather agent and returns the answer.
// bot/mcp-connections/weather.tsimport { defineConnection } from "@grok/agent-sdk/connections";export default defineConnection({ agent: "weather-agent", description: "Delegate weather questions to the weather specialist.",});The filename, weather.ts, becomes the
MCP server name, and agent
is the specialist's lowercase deployment slug. Give the concierge a one-way
routing rule, so the agents never pass a request back and forth:
When a request needs current weather, ask the `weather` peer. Return itsanswer.Deploy both agents from pushed Git refs:
agent-sdk deploy --dir ./agents/weather-agent --slug weather-agentagent-sdk deploy --dir ./agents/concierge --slug conciergeContinue the specialist's session
The first ask returns { status, sessionId, reply } as text. Pass that
sessionId on the next ask to continue the specialist's earlier work.
const first = await ctx.host.mcp.callTool("weather", "ask", { message: "What's the weather in Paris right now?",});const firstText = first.content.find((part) => part.type === "text");if (firstText?.text === undefined) { throw new Error("weather ask returned no text payload");}const { sessionId } = JSON.parse(firstText.text) as { sessionId: string };await ctx.host.mcp.callTool("weather", "ask", { message: "How does that compare with tomorrow?", sessionId,});If the specialist is still working, ask returns status: "running", and
check waits for the answer.
await ctx.host.mcp.callTool("weather", "check", { sessionId, waitSeconds: 20,});Call a peer tool directly
Use call_tool when you want to run a tool on a peer agent directly, without
starting a model turn on that agent. The peer needs at least one server tool,
and the call follows the
direct-call rules.
const result = await ctx.host.mcp.callTool("weather", "call_tool", { toolName: "get_forecast", input: { city: "Paris" },});const part = result.content.find((item) => item.type === "text");if (part?.text === undefined) { return { ok: false, forecast: null };}const payload = JSON.parse(part.text) as { isError?: boolean; result?: unknown;};return { ok: result.isError !== true && payload.isError !== true, forecast: payload.result ?? null,};Try it locally
To try it locally, run both projects in one process:
agent-sdk dev ./agentsagent-sdk chat --url http://127.0.0.1:3000/concierge \ --message "What's the weather in Paris right now?"Locally, agent is the specialist's mount slug, usually its directory name.
Peer or subagent?
Use a subagent to split one agent's job into roles. Use a peer when the specialist is a complete agent you also run on its own.
| Subagent | Peer | |
|---|---|---|
| Context | Child role inside one agent | Independent agent and session |
| Tools and connections | Inherits the parent project | Owns its project surface |
| Reachability | Parent only | Local co-hosted agents, or declared deployments on the same team |
Other hosts
To self-host, run the peers under one agent-sdk process, and if turns run on
remote workers, protect it with --bearer-token and set --public-url as
Deployment describes.