Skip to content

Agent-to-agent

Every mounted agent is also an MCP server. So agents can delegate to each other without extra infrastructure. One agent hands a question to another, and the peer answers in its own session with its own instructions, tools, and context. Any external MCP client can do the same. A peer MCP connection makes the wiring one line.

This guide wires a concierge agent that delegates weather questions to a weather-agent peer mounted on the same host.

The MCP endpoint

Each agent serves the Model Context Protocol over streamable HTTP at /<slug>/v1/mcp (or /v1/mcp in single mode). The surface is stateless (session identity travels in tool arguments) and runs the same route auth chain as the session API. It exposes three tools:

ToolBehavior
askSend a message. Runs a model turn in this agent's own session and returns { status, sessionId, reply }. Omit sessionId for a fresh session; pass it back to follow up.
checkWait for or poll a running session (waitSeconds: 0 polls without blocking).
call_toolCall one of the agent's server tools directly, no model turn. Registered only when the agent has server tools.

Waits are bounded at roughly 50 seconds, below typical MCP client request timeouts: a long turn returns status: "running" and the caller keeps waiting with check. Sessions created this way live on the mcp channel, bind to the calling principal, and show up in the playground and GET /v1/sessions like any other session.

Any MCP client can attach to this endpoint. It isn't only for other Agent SDK agents.

Wire a peer MCP connection

A peer MCP connection points one agent at another mounted on the same serve host. Author an MCP connection whose transport is the peer's slug:

ts
// agents/concierge/agent/mcp-connections/weather.ts
import { defineConnection } from "@cursor/july/connections";

export default defineConnection({
  agent: "weather-agent",
  description: "Delegate weather questions to the weather agent.",
});

The parent model now sees the peer's ask and check (and call_tool) tools under the weather server name. It reads like subagent delegation, except the peer is a full agent that keeps its own instructions, tools, MCP connections, and sessions.

bash
agent-sdk serve --dir ./agents --dev
agent-sdk chat --url http://127.0.0.1:3000/concierge \
  --message "What's the weather in Paris right now?"
# concierge → weather.ask → weather-agent's own session/tools → reply

Peer or subagent?

The two delegation mechanisms solve different problems.

Subagent (agent/subagents/<id>/)Peer (defineConnection({ agent }))
Runs asan SDK custom subagent inside the parent's harnessan independent agent on the same host
Own tools, MCP connections, sessionsno, inherits the parent's surfaceyes, everything is its own
Visible to othersonly its parentany MCP client, other agents, its own playground
Reach for it whensplitting one job into specialist rolescomposing independently useful agents

How peer URLs resolve

Peer URLs resolve when the server starts, so the ephemeral ports run and eval use work too. Local-runtime turns (and host-side ctx.host.mcp or channel-handler calls) reach the peer over loopback, which works under the default auth. Cloud-runtime turns execute on a VM that cannot reach this host's loopback address: pass --public-url https://agent-sdk.example.com (or serve(dir, { publicUrl })) so peers resolve to a reachable URL. Without one, peers are omitted from cloud turns and the server warns at startup. With --bearer-token, the token is attached to peer calls automatically so they pass the target agent's auth chain.

Guardrails

Unknown peer slugs and self-references fail serve at startup, so you find out immediately rather than at delegation time. Peers require the multi-agent layout (each agent mounted under its slug, the default).

The framework does not provide cross-host loop protection. If agent A's instructions delegate to B and B's delegate back to A, they can recurse. Scope each agent's delegation instructions narrowly. The concierge delegates weather questions to weather-agent, not everything.

Call a peer from host code

Peer MCP connections are ordinary MCP connections, so deterministic host code can use them too. A channel handler or server tool can call host.mcp.callTool("weather", "ask", { message: "…" }) without any model turn deciding to. See MCP connections for the three places every MCP connection is available.

What's next

Continue with these pages: