MCP servers
Give an agent tools from remote MCP servers. Bind or Connect the credential in Swirls Cloud.
What it is. A named slot for a remote MCP server the agent can draw tools from. You declare the slot in git; Swirls Cloud holds the credential; at runtime the agent discovers the server's tools and calls them alongside its workflow tools.
Use it when an agent needs tools from an external service that speaks MCP: observability queries, product analytics, or any vendor with a remote MCP endpoint. Any MCP server URL works.
Works with agents (attached via mcp:), profiles (narrowed per profile), and the project MCP servers page in Swirls Cloud (where slots are bound or connected).
An mcp block requires a remote url: and an auth: mode in git. Credentials stay out of the file and are obtained per project in Cloud. For auth: static, the token is optional when the server is public.
This page is about your agent as an MCP client: it consumes tools from a remote server. For the inverse, exposing your agent as an MCP server that external clients like Claude Desktop and Claude Code connect to, see MCP channels.
The mcp block
The mcp block is a top-level declaration. There is no type: field; the keyword identifies the block.
mcp observability {
label: "Observability"
description: "Query traces, logs, and metrics"
url: "https://mcp.example.com/mcp"
auth: static
}Field reference
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Absolute https URL of the remote MCP server. Validated by swirls doctor. |
auth | enum | Yes | How Cloud obtains credentials. static — paste an API key or token (Bind). interactive — browser OAuth (Connect). |
label | string | No | Display name shown on the MCP servers page in Swirls Cloud. |
description | string | No | Description shown on the MCP servers page. |
The block name is the slot handle. Names must match ^[a-zA-Z0-9_]+$ and be unique across every file in the project. Unknown keys are rejected.
Attach a slot to an agent
List slot names in the agent's mcp: field. It is a bare-identifier array, same style as tools: and skills:.
secret vendor_keys {
vars: [OPENROUTER_API_KEY]
}
mcp observability {
label: "Observability"
url: "https://mcp.example.com/observability"
auth: static
}
mcp product_analytics {
label: "Product analytics"
url: "https://mcp.example.com/analytics"
auth: interactive
}
agent sre_assistant {
label: "SRE assistant"
secrets: vendor_keys
model: "openai/gpt-4o-mini"
mcp: [observability, product_analytics]
system: @ts {
return "You investigate production issues. If an MCP tool set is missing, tell the user to connect the slot on the MCP servers page in Swirls Cloud."
}
profile readonly {
mcp: [observability]
}
}A profile may narrow mcp: to a subset of the agent's list, the same rule as tools: and skills:.
Two boundaries to know:
- MCP is agent-only. Workflows use
httpandintegrationnodes. There is no MCP node type and no MCP syntax inside a workflow. - Subagents do not inherit slots. A
team:member resolves its ownmcp:declaration, not the caller's.
Declare URL and auth in git; Bind or Connect in Cloud
The .swirls file carries the slot name, optional label and description, the required url:, and the required auth:. It never carries a token, an OAuth grant, or a tool list. Credentials live in Swirls Cloud, per project, keyed by slot name.
auth: | Cloud actions | Credential |
|---|---|---|
static | Bind / Unbind / Test | API key or access token (optional for public servers), stored encrypted |
interactive | Connect / Disconnect / Test | Browser OAuth; Swirls brokers the grant and mints short-lived access tokens |
Static cards never offer Connect. Interactive cards never accept a pasted bearer.
- Deploy with
git pushorswirls deploy. Eachmcpblock appears as a slot on the project's MCP servers page. The dashboard shows the server URL and auth mode from the deployment (read-only). - On that page, Bind a static slot (token optional for public servers; by default the token is sent as
Authorization: Bearer <token>, or a binding can name a custom auth header) or Connect an interactive slot (browser OAuth — Swirls handles client registration for you). - A DSL
url:andauth:alone do not make tools available. Runtime discovery only runs after the slot is ready (bound or connected).
If interactive Connect fails because the server does not support the OAuth registration Swirls needs, use auth: static or another server. Some grants issue an access token without a refresh token; when that access token expires, reconnect the slot.
Older deployments that predate declarative url: or auth: may still edit the server URL on the binding, and missing auth: is treated as static at runtime, until you redeploy with both fields in the file.
Runtime tool discovery
On the first agent turn of a session, the platform connects to each ready slot (bound static or connected interactive) that has an effective URL, lists its tools, and merges them into the agent's tool set. Every tool the server exposes becomes callable.
Tool naming
Discovered tools are exposed to the model as mcp__<slot>__<tool>. A slot named observability with a server tool queryDataset surfaces as mcp__observability__queryDataset. The prefix keeps names collision-free across servers.
First-turn latency
Discovery adds seconds to the first turn of a session, roughly proportional to the number of ready slots. Later turns reuse the discovered tools. Budget for this if you call the agent through the API and measure first-response time.
Tool lists are live
MCP tools are vendor-maintained. When the remote server adds or removes tools, the agent picks the change up within minutes. A redeploy is never required.
Unready slots
A slot that is unbound, unconnected, unreachable, or whose credential fails yields no tools. The turn continues without them; nothing crashes. Steer this in the system prompt: tell the agent to ask the user to open the MCP servers page in Swirls Cloud when its tools are missing.
Validation
swirls doctor validates block shape, the required https url:, the required auth:, and references. It never contacts a remote server and never discovers tools, so a missing Cloud binding or Connect surfaces on the first agent turn, not at doctor time.
| Check | Severity |
|---|---|
Block name does not match ^[a-zA-Z0-9_]+$ | Error |
Missing or empty url: | Error |
url: is not an absolute https URL | Error |
Missing auth: | Error |
auth: is not static or interactive | Error |
Duplicate mcp block name, in one file or across the project | Error |
agent.mcp: entry does not resolve to a declared mcp block | Error |
Profile mcp: not a subset of the agent's mcp: | Error |
Unknown key inside the mcp block | Error |
Common mistakes
Token in the block
Put the server address in url: and the credential mode in auth:. Never put a bearer token (or other secret) in the .swirls file — Bind or Connect on the MCP servers page in Swirls Cloud.
// Incorrect: token does not belong in the file
mcp bad_slot {
url: "https://mcp.example.com/mcp"
auth: static
token: "sk-secret"
}// Correct: url and auth in git; Bind the token in Cloud
mcp good_slot {
label: "Example"
description: "Example vendor tools"
url: "https://mcp.example.com/mcp"
auth: static
}Missing url:
url: is required. An mcp block with only label / description fails swirls doctor.
// Incorrect
mcp bad_slot {
label: "Example"
auth: static
}// Correct
mcp good_slot {
label: "Example"
url: "https://mcp.example.com/mcp"
auth: static
}Missing auth:
auth: is required. An mcp block with only url: fails swirls doctor.
// Incorrect
mcp bad_slot {
url: "https://mcp.example.com/mcp"
}// Correct
mcp good_slot {
url: "https://mcp.example.com/mcp"
auth: static
}Expecting deploy alone to connect
Deploying a slot with url: and auth: ships the address and mode, but tools appear only after you Bind (static) or Connect (interactive) on the MCP servers page. Until then the slot yields no tools.
MCP on a workflow
mcp: is an agent field. There is no MCP node type, and a workflow's tools: cannot carry MCP slots. To call an external HTTP API from a workflow, use an http node.
Profile slots not a subset
A profile's mcp: must be a subset of the agent's mcp:. Listing a slot only in the profile is a validation error.
// Incorrect: product_analytics is not on the agent
agent bad_agent {
model: "gpt-4o"
secrets: llm_creds
mcp: [observability]
profile analyst {
mcp: [product_analytics]
}
}// Correct
agent good_agent {
model: "gpt-4o"
secrets: llm_creds
mcp: [observability, product_analytics]
profile analyst {
mcp: [product_analytics]
}
}Expecting doctor to catch a bad binding
Doctor validates the DSL only (including url: and auth:). An unbound or unconnected slot, an unreachable server, or an expired credential shows up as missing tools on the agent's first turn. Check the MCP servers page in Swirls Cloud when an agent reports its tools are unavailable.
Expecting subagents to inherit slots
Team members do not inherit the caller's mcp: list. Declare mcp: on every agent that needs the tools.
Further reading
- Agents: The
agentblock, tools, profiles, and how a turn runs. - MCP channels: The inverse. Expose an agent as a remote MCP server for external clients.
- Skills: Knowledge packages for agents, the sibling extension point.
- Connections: Declare-in-git, credential-in-Cloud for outbound OAuth grants.
- Swirls Cloud: Projects, deploys, and the hosted platform.