Peer agents
A peer connection lets one agent ask an independent specialist for help. On Cursor-managed hosting, team-owned agents reach peers by deployment slug. Deploy both agents and BDK handles routing and authentication; you don't configure a URL, header, or secret. The specialist keeps its own instructions, tools, and session while the caller decides when to delegate and returns the answer to the user.
Delegate a question to a specialist
Ask the concierge about the weather and it hands the question to the specialist. The weather agent answers in its own context, then the concierge returns that answer to you.
// bot/mcp-connections/weather.tsimport { defineConnection } from "@cursor/bdk/connections";export default defineConnection({ agent: "weather-agent", description: "Delegate weather questions to the weather specialist.",});Give the concierge a narrow routing rule:
When a request needs current weather, ask the `weather` peer. Return itsanswer.Deploy the specialist and caller from pushed Git refs:
bdk deploy --dir ./agents/weather-agent --slug weather-agentbdk deploy --dir ./agents/concierge --slug conciergeThe connection filename, weather.ts, becomes the MCP server name the
concierge calls. Set agent to the specialist's lowercase deployment slug.
Continue the specialist's session
Ask a follow-up about the same forecast and the specialist picks up
where it left off, with its own instructions and tool history still in
place. The first ask returns { status, sessionId, reply } as text on
the callTool result. Parse sessionId and pass it on the next ask
so the peer remembers its earlier work instead of starting fresh.
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"
with the session ID, and you can do other work before calling check.
await ctx.host.mcp.callTool("weather", "check", { sessionId, waitSeconds: 20,});The peer owns this session, so follow-ups continue the specialist's context.
Call a deterministic peer tool
You need a forecast for Paris, and the weather agent already has
get_forecast. Host code calls that tool in the specialist's workspace
and the forecast comes back to the concierge, with no second model turn.
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,};call_tool appears only when the peer declares at least one
deterministic server tool.
Try it locally
Run both projects under one process to try the same connection locally:
bdk dev ./agentsbdk chat --url http://127.0.0.1:3000/concierge \ --message "What's the weather in Paris right now?"In a local multi-agent serve, agent is the specialist's mount slug,
normally its directory name.
Peer or subagent?
Use a subagent to split one agent's job into roles that share its project. Use a peer when the specialist is a complete agent you would also run, inspect, or expose 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 |
Affinity
Peer sessions appear in the specialist's playground. Only the calling deployment can continue a hosted peer session.
Practices
-
Give each caller a one-way routing rule, and don't configure reciprocal routes for the same request.
-
Prefer
askwhen the specialist should reason. Usecall_toolwhen host code already knows which server tool to run.
Other hosts
For self-hosting, run peers under one bdk process. If turns run on remote
workers, protect the process with --bearer-token and set its external URL
with --public-url. Hosts that run one agent per process can supply
--peers-url; Cursor-managed hosting configures it automatically. See
Deployment for the secure hosting setup.
Related
- MCP connections: peer configuration and connection naming
- MCP endpoint: exact
ask,check, andcall_toolschemas - Subagents: specialists inside one agent
- Deployment: secure shared-host setup