Skip to Content
Platform
IntegrationsMCP & Federation

MCP & federation

Your agents call out to MCP servers as tools, and identity federation makes each call act as the right end user.

The Model Context Protocol  shows up on the platform in two ways: your agents call out to MCP servers as tools, and identity federation lets each call act as the right end user. The sections below take them in turn.

Recipe MCP: agents calling out

Your agent or recipe can call external MCP servers as tools. You make a server available by configuring an mcp endpoint binding; the binding decides which server is reached and how the call is authenticated. The agent then calls the server’s tools the same way it calls any other tool.

Discovery happens once, when a task boots: the runtime reads each server’s tool catalog at that point and uses it for the task’s lifetime. Attaching or re-pointing an MCP endpoint takes effect on the next task, the same way recipe pins do.

Which tools an agent gets

Access to MCP tools is declared in the recipe, and the runtime enforces it. Three independent gates apply, and the effective tool set is their intersection:

  1. The recipe package declares which servers the recipe may use, and which of their tools, in package.json under pi.mcp:

    { "pi": { "mcp": { "manifest": "mcp.json", "servers": [ { "id": "contacts", "tools": { "include": ["*"], "exclude": ["delete_contact"] } } ] } } }
  2. Each agent selects the subset it needs in its agent YAML, in an mcp: block keyed by server id:

    tools: - bash mcp: contacts: include: ["*"] exclude: [delete_contact]
  3. The endpoint binding determines which tools the server actually exposes at boot.

include is required for every selected server: ["*"] means the server’s whole tool set (including tools the server adds later), a list of exact names means just those, and [] means none. exclude subtracts exact names after inclusion. "*" is a whole-toolset sentinel, not a globsearch_* is invalid. Omitting a server from the agent’s mcp: block means no access to it, and omitting the block entirely means the agent gets no MCP tools at all. Empty objects are validation errors, not implicit wildcards, so a recipe can never grant more than it wrote down.

An invalid MCP policy fails closed: the task won’t launch the agent with guessed access. Validate at author time with recipes check, which reports precise diagnostics (undeclared servers, undeclared tools, missing include, zero-tool intersections).

The in-session mcp CLI

Inside the sandbox, an agent that declares MCP access gets a session-local mcp command (materialized at .pi/bin/mcp and put on the session’s PATH), invoked through its command-execution tool — normally bash. The CLI is capability-scoped: it can only see the servers and tools the recipe and agent selected, it rejects ad-hoc servers, config overrides, and transport flags, and OAuth is always headless (cached credentials work; no browser flow can launch from a task).

It exposes exactly four commands:

CommandWhat it does
mcp search "<query>" [--limit N] [--regex]Search the session’s available tools over names, descriptions, and argument docs.
mcp list [server[.tool]] [--schema]Inventory: servers with tool counts, one server’s compact tool signatures, or one tool’s input/output contract with --schema.
mcp call server.tool key=value…Invoke one tool. Named args are schema-coerced; pass nested payloads with --json '<json>' (or --json - from stdin) and file contents with key=@path.
mcp run [--var KEY=value] [file]Run a JavaScript workflow (from a file or stdin) that composes several tool calls.

mcp run scripts call tools as tools["server"]["tool"]({ ...args }) and get decoded JSON back by default; --var KEY=value passes dynamic values in as vars.KEY so heredocs stay quoted. Workflows are resource-bounded (2-minute wall clock, 60s per call, 100 calls, bounded concurrency) and every call must be awaited. Search and list output is compact text designed for token efficiency; JSON is reserved for actual tool results.

Nothing is injected into the agent’s prompt automatically: the runtime adds no implicit MCP instructions or capability notices. A recipe that wants its agent to use MCP tools says so in its own SYSTEM.md or the agent’s system_instructions; the CLI itself is discoverable via mcp --help.

Acting as the end user

When an agent reaches a partner’s MCP server on behalf of one of their users, federation guarantees the agent acts as that specific user:

  • Each user’s tasks stay isolated from every other user’s.
  • The credential is applied at the network boundary and never enters the sandbox.

This means a partner can connect their own users in without per-user OAuth dances, stored tokens, or consent screens, and still have every upstream call attributed to the right person.

Authentication modes for an MCP endpoint

An mcp endpoint can authenticate in one of three ways, independent of the protocol it speaks:

ModeWhat it does
Authorized applicationThe agent acts as the end user against the partner’s own MCP server.
Bearer tokenA shared token is applied to every call (for example, a bot token). No per-user identity.
UnauthenticatedNo credential; allowlist-only egress.

Acting as the end user applies when the upstream MCP server is the one that connected the user in, so the agent can be attributed to that user against the partner’s own systems.

  • Bindings: where mcp endpoints and their credentials live.
  • Authentication: runtime API keys, member-authenticated CLI login, and the token model federation builds on.
  • API Reference: the REST surface behind these features.
Last updated on