A server tool is one the gateway runs itself, inside the request. You declare it in tools beside your own functions, as {"type": "autonomousrelay:<name>"}; when the model calls it, the gateway executes it, hands the result back to the model and continues, and you receive only the final answer. Three kinds exist: the built-in tools, your organisation’s own MCP servers, and marketplace plugins you have installed.
Built-in tools
{
"model": "anthropic/claude-sonnet-5",
"messages": [{"role": "user", "content": "What day is it in Toronto, and which Claude models can I use?"}],
"tools": [
{"type": "autonomousrelay:datetime", "parameters": {"timezone": "America/Toronto"}},
{"type": "autonomousrelay:experimental__search_models"}
]
}autonomousrelay:datetime— the current date and time.parameters.timezonesets the default zone (IANA, e.g.America/Toronto); the model may name another; otherwise UTC.autonomousrelay:experimental__search_models— the catalogue, searched by words in a model’s id or name (query, at mostlimit10): ids, names and context lengths.
Those two are the tools that run today. The catalogue (GET /v1/tools, and the Tools page in your workspace) also lists web_search, web_fetch, advisor, subagent, fusion, shell, bash, apply_patch, image_generation and tool_search, each marked as not available. A request that declares one of them is refused with a 400 naming it, never silently served without the tool. PUT /v1/tools with {"disabled": [...]} turns a built tool off for the organisation (a seat with config:write); a request that then declares it is refused.
"plugins": [{"id": "web"}] lets the model search with its provider’s own search — Anthropic’s web search on Claude, Google Search grounding on Gemini 3, OpenAI’s and xAI’s web_search on GPT-5 and later and Grok 4 — so a query goes nowhere the request was not already going. Only those endpoints are candidates; each search is metered at the provider’s published price per thousand; the pages cited come back as url_citation annotations. Outside engines are refused. The options (max_uses, allowed_domains, excluded_domains) are in the API reference under plugins.Your own MCP servers
{
"name": "crm",
"url": "https://mcp.example.com/mcp",
"allowed_tools": ["search_accounts", "get_account"],
"header_name": "Authorization",
"header_value": "Bearer ..."
}Register a server once: a name (1 to 32 lowercase letters, digits or hyphens), its public https URL, optionally the tools it may offer and one credential header. The header value is sealed on arrival and never shown again (the API returns its last four characters); up to 20 servers per organisation. GET /v1/mcp-servers/:id/tools asks the server for its tools live, which is how a registration is checked. The MCP servers tab of the Tools page does the same.
"tools": [{"type": "autonomousrelay:mcp", "server": "crm", "allowed_tools": ["search_accounts"]}]In a request, that declaration offers the server’s tools to the model as functions named mcp__<server>__<tool>; the gateway calls the server on its stored credential and returns the result to the model. At most five servers in one request. A name that is not registered is a 404, a server turned off is a 403, and one that cannot list its tools is a 502 — before any provider is called.
Marketplace plugins
"tools": [{"type": "autonomousrelay:plugin", "plugin": "slack", "allowed_tools": ["search_messages"]}]An installed plugin is an MCP server its developer hosts. Its tools reach the model as plugin__<slug>__<tool>, called on the credential the install holds; a plugin that is not installed is a 404 and one turned off a 403. Up to five per request. Installing is done from the Plugins tab of the Tools page; building one is its own guide.
All connected tools
"tools": [{"type": "autonomousrelay:connected"}]Offers the model every connection your organisation has — each installed plugin and each registered MCP server — without naming them, so a chatbot picks up a connector the day it is connected. include and exclude take plugin slugs and MCP server names to narrow it. An explicit autonomousrelay:plugin or autonomousrelay:mcp declaration in the same request wins for its connection.
- Read-only by default. Only a connection’s read tools are offered: a tool counts as one when it says it is read-only and, for a plugin, its manifest agrees. A write tool is offered only when
writesnames it exactly as the model sees it (plugin__zendesk__add_note), and a named write always waits for a person: the request needs arun_idwhose agent has an approval policy, and is refused with a 400 otherwise. - A connection that does not work is skipped, not an error: one never connected, expired, turned off, or that does not answer within five seconds. The answer comes from the rest, or from the model alone. The
X-Autonomous-Relay-Connected-Toolsresponse header says what was used and skipped (used=notion;skipped=slack:expired), as doesagentrouter_metadata.connected_toolswhen you ask for metadata. - Your organisation is told, not your customer. A skipped connection goes to the alert channels that take usage alerts, or by email to the organisation’s owners when there are none, at most once a day per connection and reason, with how to fix it. The person chatting sees only the answer.
- Limits. At most 10 connections and 128 functions per request, taken plugins first, then MCP servers, each by name; the rest are reported as skipped with the reason
limit, which is never announced. A connection’s tools are offered whole or not at all.
What the declaration would draw on: each connection with its status (ok, not_connected, expired, disabled, unreachable) and its tools, each named as the model sees it and marked read or write. Asked live with an inference or management key; a plugin that cannot be asked shows its stored manifest’s tools, with tools_source: "manifest". 30 requests a minute per key.
On by default for a key
{"connected_tools": "read"}A chatbot that sends plain chat requests can use your connections without a code change: set connected_tools to read on its inference key (with POST /v1/keys, PATCH /v1/keys/:hash, or Connected tools on the API keys page). Every request on that key is then answered as if it declared {"type": "autonomousrelay:connected"}, with everything above: read tools only, skipped connections, the response header and the notice to your organisation.
- Never writes. The key’s default has no
writes, and nothing on the key can add one. A write still needs the request’s own declaration and a run with an approval policy. - The request’s own declaration wins. A request that declares
autonomousrelay:connecteditself keeps itsinclude,excludeandwrites; its functions andautonomousrelay:pluginorautonomousrelay:mcpdeclarations combine with the default as they would with a declaration. - Opting out, per request. Send the request header
X-Autonomous-Relay-Connected-Tools: off, which works from any SDK as an extra header (any other value is a 400). A hosted agent’s turns (run_id) never get the default: an agent definition declares its own tools. - Not cached. An answer drawn from live connections can change with them, so these requests are never answered from the response cache, even on a key with the cache on.
- Inference keys only. A management key never calls a model, so
connected_tools: "read"on one is a 400. Off is the default.
How the loop runs
- Rounds. Each round is a complete, non-streaming completion. A round’s server-tool calls run together, their results go back as
toolmessages, and the next round begins. The loop ends when the model answers without calling a server tool — or when it calls one of your functions, which is returned to you as usual. - A ceiling.
max_tool_calls(1 to 30, default 30) caps the executions in one request. Past it the last answer is returned withnative_finish_reasonautonomousrelay:max_tool_calls; a later round the provider fails returns the previous answer withautonomousrelay:round_failed. - Streaming. With
stream: truethe loop still runs whole rounds. Progress arrives as SSE comment lines (: autonomousrelay {"type": "tool.called", ...}—turn.completed,tool.called,tool.result), which SDKs ignore, then the answer as ordinary chunks. - Usage.
usage.server_tool_usecounts the calls by tool. The built-in tools cost nothing; the model’s tokens for every round are metered as usual. - Not combined with the response cache or batches: a tool runs inside a live request.
- Approvals. A request made inside a hosted agent’s run (
run_id) whose approval policy covers a tool stops before running it: the answer carriesnative_finish_reasonautonomousrelay:approval_requiredand anautonomousrelay_approvalobject, and the run waits on the Agents page.