Appearance
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:
| Tool | Behavior |
|---|---|
ask | Send 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. |
check | Wait for or poll a running session (waitSeconds: 0 polls without blocking). |
call_tool | Call 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 → replyPeer or subagent?
The two delegation mechanisms solve different problems.
Subagent (agent/subagents/<id>/) | Peer (defineConnection({ agent })) | |
|---|---|---|
| Runs as | an SDK custom subagent inside the parent's harness | an independent agent on the same host |
| Own tools, MCP connections, sessions | no, inherits the parent's surface | yes, everything is its own |
| Visible to others | only its parent | any MCP client, other agents, its own playground |
| Reach for it when | splitting one job into specialist roles | composing 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:
- MCP connections: all four MCP connection transports
- Subagents: the in-harness alternative
- HTTP API: the endpoint contract