Skip to navigation

MCP servers

Use Model Context Protocol (MCP) servers to connect flows and agents to external tools and data sources. Runtype lists the tools that each server exposes and passes each tool’s input schema to the model. You can save a server for reuse or pass its configuration at runtime.

This page covers calling external MCP servers from Runtype. To expose your own Runtype product as an MCP server instead, see Setting up an MCP surface.

Choose a server type

Choose a server type based on how you supply its configuration:

Server typeUse it whenHow to reference it
SavedYou reuse the same server across flows or agents.Add its tool IDs to toolIds, such as mcp:SERVER_NAME:TOOL_NAME.
RuntimeThe server URL or credentials vary by request.Add its configuration to mcpServers.

Use saved MCP servers

Save a custom MCP server to reuse its tools across flows and agents.

Add a saved server

Choose a dashboard or API workflow:

To add a saved server from the dashboard, follow these steps:

  1. On Tools, click Create Tool.
  2. In the Type menu, select MCP Server. The dashboard opens the server form.
  3. In Server URL, enter the MCP server endpoint.
  4. In Display name, enter a name for the server.
  5. In Environment, select All environments, Development, or Production. For more information, see Use environment-specific servers.
  6. In Authentication, select an authentication type and enter its credentials.
  7. Click Discover Tools. The dashboard lists the tools that it finds.
  8. Click Add Server. The dashboard saves the server.

If you already have the server in a Claude or Cursor client config, paste the JSON, such as {"mcpServers": {...}}, into Server URL. The dashboard reads only the first server in mcpServers. When that server has a url, the dashboard fills in the URL, display name, and authentication headers. When it has no url, the dashboard pastes the text unchanged.

Discover tools from a saved server

To verify a saved server and list its tools, send a POST request:

cURL
curl -X POST https://api.runtype.com/v1/mcp/servers/customer_support/test \
-H "Authorization: Bearer YOUR_API_KEY"

The API returns a response similar to the following:

Response
{
"success": true,
"toolsDiscovered": 2,
"tools": [
{
"name": "search_articles",
"description": "Search support articles"
},
{
"name": "create_ticket",
"description": "Create a support ticket"
}
]
}

Replace YOUR_API_KEY with your Runtype API key.

A failed discovery still returns HTTP 200. Check the success field, not only the status code:

Failed discovery response
{
"success": false,
"error": "Connection refused",
"tools": [],
"toolsDiscovered": 0
}

The error value varies with the failure. When no saved server has that name, the API returns 404 with the message “Custom MCP server not found”.

Discover tools from a URL

To list a server’s tools before you save it, send the URL to the discover endpoint:

cURL
curl -X POST https://api.runtype.com/v1/mcp/discover \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/mcp",
"auth": { "type": "bearer", "token": "YOUR_MCP_TOKEN" },
"timeout": 30000
}'

Replace the placeholders with your values:

  • YOUR_API_KEY: Your Runtype API key.
  • YOUR_MCP_TOKEN: The token that the MCP server accepts.

The request body accepts url (required), auth, timeout, and serverName. When you pass serverName without auth, Runtype uses the credentials of a server with that name that you saved. It doesn’t use credentials that a teammate saved. The API returns a response similar to the following:

Response
{
"url": "https://example.com/mcp",
"tools": [
{
"name": "search_articles",
"description": "Search support articles",
"parametersSchema": {
"type": "object",
"properties": { "query": { "type": "string" } }
}
}
],
"total": 1
}

The Runtype MCP server offers the same discovery through its discover_mcp_server_tools tool. For more information, see Runtype MCP server.

Use saved tools in a flow

Add saved MCP tool IDs to the tools object in a prompt step. The following examples use the customer_support server:

Use the TypeScript SDK to dispatch a flow with saved MCP tools:

TypeScript SDK
import { FlowBuilder, RuntypeClient } from '@runtypelabs/sdk'
const client = new RuntypeClient({
apiKey: process.env.RUNTYPE_API_KEY,
})
const result = await new FlowBuilder()
.createFlow({ name: 'Customer support agent' })
.prompt({
name: 'Support agent',
model: 'claude-sonnet-5',
userPrompt: 'Find the open support tickets for this customer',
tools: {
toolIds: ['mcp:customer_support:search_articles', 'mcp:customer_support:create_ticket'],
},
})
.run(client, { streamResponse: true })

This example reads the API key from the RUNTYPE_API_KEY environment variable.

Use the Python SDK to dispatch the same flow:

Python SDK
import os
from runtype import RuntypeClient
client = RuntypeClient(api_key=os.environ["RUNTYPE_API_KEY"])
for event in client.dispatch({
"flow": {
"name": "Customer support agent",
"steps": [{
"type": "prompt",
"config": {
"model": "claude-sonnet-5",
"userPrompt": "Find the open support tickets for this customer",
"tools": {
"toolIds": [
"mcp:customer_support:search_articles",
"mcp:customer_support:create_ticket"
]
}
}
}]
}
}):
print(event)

This example reads the API key from the RUNTYPE_API_KEY environment variable.

Send the same flow with cURL:

cURL
curl https://api.runtype.com/v1/dispatch \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"flow": {
"name": "Customer support agent",
"steps": [{
"type": "prompt",
"config": {
"model": "claude-sonnet-5",
"userPrompt": "Find the open support tickets for this customer",
"tools": {
"toolIds": [
"mcp:customer_support:search_articles",
"mcp:customer_support:create_ticket"
]
}
}
}]
}
}'

Replace YOUR_API_KEY with your Runtype API key.

Use passthrough mode

To attach every tool that a saved server exposes, add a wildcard entry to toolIds:

Passthrough tool configuration
{
"tools": {
"toolIds": ["mcp:customer_support:*"]
}
}

The wildcard expands into concrete tool IDs at execution time. This behavior means:

  • New tools from the MCP server are available without editing the flow.
  • Approval rules, toolConfigs, perToolLimits, and usage tracking use concrete tool IDs.
  • When toolIds contains both the wildcard and a curated ID for one server, Runtype uses the wildcard and ignores the curated ID.

Choose passthrough mode when you trust every tool on the server and want to receive new tools without changing the flow. Choose curated tool IDs when you need to review each tool.

Use the TypeScript SDK to attach passthrough tools:

TypeScript SDK
const result = await new FlowBuilder()
.createFlow({ name: 'Customer support agent' })
.prompt({
name: 'Support agent',
model: 'claude-sonnet-5',
userPrompt: 'Help me manage support requests',
tools: {
toolIds: ['mcp:customer_support:*'],
},
})
.run(client, { streamResponse: true })

Send the same passthrough configuration with cURL:

cURL
curl https://api.runtype.com/v1/dispatch \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"flow": {
"name": "Customer support agent",
"steps": [{
"type": "prompt",
"config": {
"model": "claude-sonnet-5",
"userPrompt": "Help me manage support requests",
"tools": { "toolIds": ["mcp:customer_support:*"] }
}
}]
}
}'

Replace YOUR_API_KEY with your Runtype API key.

Share saved servers

Saved MCP servers in an organization are shared with its members. Members can list and use them, view metadata, test connections, and discover tools. Runtype encrypts saved credentials and does not return credential values in API responses.

Server owners and organization admins can perform these actions:

  • Edit the server configuration, including the URL, timeout, transport, and allowed tools.
  • Rotate or replace credentials.
  • Refresh or reconnect the OAuth2 connection.
  • Turn the server on or off.
  • Delete the server.

Other members can view server details but cannot manage them. A management request from another member returns 403 with this message: “This MCP server was added by a teammate. Only the person who added it or an org admin can change it.”

Use the following fields in GET /v1/mcp/servers and GET /v1/mcp/servers/:name responses to control management actions in client code:

FieldDescription
ownedByCurrentUserTrue when the authenticated user registered the server.
canManageTrue when the user is the server owner or an organization admin.

Servers that you register outside an organization stay private to your account and are not visible to other users.

When an organization has duplicate server names, an admin’s by-name DELETE request returns 409 with candidate IDs. Pass the optional id query parameter, as in DELETE /v1/mcp/servers/:name?id=SERVER_ID, to identify the registration to remove.

Use runtime MCP servers

Pass a server configuration inline when its URL or credentials vary by request.

Choose runtime servers

Use runtime MCP servers for these cases:

  • Pass per-user credentials in a multi-tenant application.
  • Test a server before saving it.
  • Configure a one-off integration.
  • Set a server URL at request time.

Configure a runtime server

Pass the server configuration in the prompt step’s tools object:

TypeScript SDK
const mcpServers = [
{
id: 'user_notion',
name: 'User Notion',
url: 'https://example.com/mcp',
auth: {
type: 'bearer',
token: userCredentials.mcpToken,
},
timeout: 30000,
transport: 'streamable_http',
allowedTools: ['search_articles', 'create_ticket'],
},
]
const result = await new FlowBuilder()
.createFlow({ name: 'User support agent' })
.prompt({
name: 'Support agent',
model: 'claude-sonnet-5',
userPrompt: 'Help me manage my support requests',
tools: {
mcpServers,
},
})
.run(client)

Pass the per-user token from your application in userCredentials.mcpToken.

Use the Python SDK to pass the same runtime configuration:

Python SDK
mcp_servers = [{
"id": "user_notion",
"name": "User Notion",
"url": "https://example.com/mcp",
"auth": {
"type": "bearer",
"token": user_credentials["mcp_token"]
},
"timeout": 30000,
"allowedTools": ["search_articles", "create_ticket"]
}]
for event in client.dispatch({
"flow": {
"steps": [{
"type": "prompt",
"config": {
"model": "claude-sonnet-5",
"userPrompt": "Help me manage my support requests",
"tools": {
"mcpServers": mcp_servers
}
}
}]
}
}):
print(event)

Pass the per-user token from your application in user_credentials["mcp_token"].

Send the runtime configuration with cURL:

cURL
curl https://api.runtype.com/v1/dispatch \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"flow": {
"steps": [{
"type": "prompt",
"config": {
"model": "claude-sonnet-5",
"userPrompt": "Help me manage my support requests",
"tools": {
"mcpServers": [{
"id": "user_notion",
"url": "https://example.com/mcp",
"auth": {
"type": "bearer",
"token": "YOUR_MCP_TOKEN"
},
"timeout": 30000
}]
}
}
}]
}
}'

Replace the placeholders with your values:

  • YOUR_API_KEY: Your Runtype API key.
  • YOUR_MCP_TOKEN: The token that the MCP server accepts.

An Agent accepts the same entries in its tools.mcpServers list, including an Agent that you define with defineAgent and converge with ensure. For an example, see Connect inline MCP servers.

Authentication types

Choose one of the following authentication types for a custom MCP server:

TypeFieldsExample
bearertoken{"type": "bearer", "token": "YOUR_MCP_TOKEN"}
api_keyheaderName, token{"type": "api_key", "headerName": "X-API-Key", "token": "YOUR_API_KEY"}
basicusername, password{"type": "basic", "username": "YOUR_USERNAME", "password": "YOUR_PASSWORD"}
custom_headerheaderName, token{"type": "custom_header", "headerName": "X-Custom", "token": "YOUR_TOKEN"}
headersheaders{"type": "headers", "headers": {"X-Api-Key": "{{secret:API_KEY}}", "X-Base-URL": "https://example.com"}}
oauth2Managed by Runtype for saved servers.Use the dashboard authorization-code flow or register client credentials through the API.
noneNone.{"type": "none"}

Replace every credential placeholder in the table with a value that the server accepts. Replace the name inside each {{secret:NAME}} reference with a managed secret name from your account.

Every credential field in auth (token, username, password, and each headers value) accepts a {{secret:NAME}} reference, which Runtype resolves from your managed secrets when it calls the server. Put MCP credentials here, not in a saved MCP tool’s config, which rejects {{secret:NAME}} references.

Use the headers type when a server requires two or more HTTP headers. Each header value can contain a {{secret:NAME}} reference, which Runtype resolves from your managed secrets when it sends the request. The headers field is valid only with type: "headers" and must contain at least one valid HTTP header.

A saved server’s auth header values can also send the verified identity of the end user that an agent run serves. Use {{_identity.token}} for a short-lived JWT that Runtype signs for each connection, or {{_tenant.id}} and {{_endUser.id}} for the plain IDs:

Saved server auth that sends the verified identity
{
"type": "headers",
"headers": {
"Authorization": "Bearer {{_identity.token}}",
"X-Tenant-Id": "{{_tenant.id}}"
}
}

Runtype fills in these values when it lists the server’s tools and when it calls a tool. The agent must have a tenancy strategy, and the server URL must use https. When a run has no verified identity, Runtype doesn’t call the server. The token’s aud is the server’s canonical resource URI, for example https://mcp.example.com/mcp, not its host name. For the conditions and the token’s claims, see Send the assertion to a saved MCP server.

In the dashboard, open Advanced authentication and select Multiple headers. Runtype encrypts saved header values and hides them. To edit them, enter a complete replacement set. The same headers record works with POST /v1/mcp/servers, inline tools.mcpServers, and full product object (FPO) agent configurations.

Machine-to-machine OAuth2

For an MCP server that accepts OAuth2 client credentials, register the connection through the API. Runtype resolves your managed secrets and requests access tokens itself, so the client secret and access token never reach the model or sandbox code.

In an organization, only an organization admin can register a client-credentials server or change its credentials, URL, or transport. An API key that registers a server with managed-secret references needs the SECRETS:READ scope in addition to TOOLS:WRITE.

To register the server, create managed secrets named TEAMBRIDGE_CLIENT_ID and TEAMBRIDGE_CLIENT_SECRET in Settings > Secrets, and then send the following request:

Register a machine-to-machine server
curl -X POST https://api.runtype.com/v1/mcp/servers \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "teambridge_context",
"url": "https://mcp.example.com/mcp/",
"auth": {
"type": "oauth2",
"grantType": "client_credentials",
"tokenUrl": "https://tenant.example.com/oauth/token",
"clientId": "{{secret:TEAMBRIDGE_CLIENT_ID}}",
"clientSecret": "{{secret:TEAMBRIDGE_CLIENT_SECRET}}",
"audience": "https://api.example.com/",
"scope": "read:api"
}
}'

Replace YOUR_API_KEY with your Runtype API key. Replace the example MCP URL, token URL, audience, and scope with your provider’s values. The two secret references name the managed secrets you created. audience, resource, and scope are optional. audience and the RFC 8707 resource parameter are distinct, and Runtype sends each one separately. Your token endpoint must accept client_secret_post client authentication and return a bearer token.

Bind the returned server.id to an agent’s config.tools, or a flow step’s config.tools, without repeating the auth configuration:

Bind a registered server
{
"mcpServers": [
{ "id": "SERVER_ID", "url": "https://mcp.example.com/mcp/" }
]
}

Replace SERVER_ID with the returned provkey_ ID. Keep auth absent. Runtype resolves the saved registration in the execution’s organization and environment; its saved endpoint and credentials take precedence over the URL in the binding. Add allowedTools to select named tools, or use toolIds: ["mcp:SERVER_ID:*"] instead of mcpServers to bind without a URL.

Runtype requests a token on first use and reuses it until shortly before it expires. It requests a new token after expiry, or once after the MCP server returns HTTP 401. Runtype doesn’t reuse a token that has no expires_in value. Your token endpoint can receive more than one token request for the same server. When a secret is missing or the token endpoint fails, Runtype stops the request instead of calling the MCP server without authentication.

Rotate the managed secrets without editing each bound agent. To change the token URL, audience, or scope, send the complete auth object to PATCH /v1/mcp/servers/teambridge_context. The registry encrypts auth at rest and does not return credentials in list, create, or update responses. Token endpoints must use public HTTPS URLs and cannot redirect credential requests.

Configure client-credentials auth on the saved server only. Inline mcpServers[].auth and an external tool’s auth field don’t accept OAuth2. Bind the saved server by ID instead.

OAuth 2.1 authentication

Use the dashboard OAuth2 flow when an MCP server requires OAuth instead of a static token.

Detect OAuth2 on URL entry

On the dashboard, enter the MCP server URL. Runtype probes the server for OAuth2 metadata through RFC 9728 protected-resource discovery.

When Runtype finds OAuth2 metadata, the dashboard shows Connect with OAuth2 instead of manual token fields. It displays the discovered issuer and supported scopes.

Authorize in the browser

Click Connect with OAuth2. The dashboard opens a popup for sign-in and consent. Runtype uses PKCE for the authorization-code exchange, so the browser does not handle a client secret.

After you approve access, the popup closes and the dashboard discovers tools for selection.

Keep the connection active

When an access token expires and the server issued a refresh token, Runtype refreshes the token automatically. You don’t need to reconnect on a schedule. When the authorization server rejects the refresh token, for example because access was revoked, runs that use the server fail with the MCP_REAUTH_REQUIRED code. To restore the connection, reconnect the server from Tools.

Use discovery diagnostics

When Runtype does not detect OAuth2, expand OAuth2 not detected. View discovery details. The panel lists each discovery phase, the URL that Runtype probed, the response status, and any error. Use these details to troubleshoot an MCP server that supports OAuth2 but is not detected.

Find OAuth2 setup

Use the OAuth2 setup in either of these locations:

  • On the Tools page, when you create an MCP Server tool.
  • In the agent tool-selection modal, when you add a server while choosing tools for an agent.

Configured OAuth2 servers appear in the agent tool-selection modal with their discovered tool counts.

Tool ID format

Use the following format for a saved custom server tool ID:

Saved MCP tool ID
mcp:SERVER_NAME:TOOL_NAME

For example:

  • mcp:customer_support:search_articles: A tool on the saved customer_support server.
  • mcp:customer_support:create_ticket: Another tool on the same saved server.

Replace SERVER_NAME with the saved server name and TOOL_NAME with the MCP tool name. Runtype stores a saved server name in lowercase, with spaces replaced by underscores. A server that you name Customer Support has tool IDs such as mcp:customer_support:search_articles and the path /v1/mcp/servers/customer_support.

Runtime server tool IDs use the custom_ prefix:

Runtime MCP tool ID
mcp:custom_SERVER_ID:TOOL_NAME

Replace SERVER_ID with the runtime server’s id value and TOOL_NAME with the MCP tool name.

Use the * value as the passthrough wildcard for saved servers:

Passthrough MCP tool ID
mcp:SERVER_NAME:*

Saved server configuration

The POST /v1/mcp/servers and PATCH /v1/mcp/servers/:name requests accept the following fields:

FieldRequiredDescription
nameYes, on createServer name. Runtype stores it in lowercase, with spaces replaced by underscores. You can’t change it later.
urlYes, on createMCP server endpoint URL.
authNoAuthentication configuration. For the supported types, see Authentication types.
timeoutNoRequest timeout in milliseconds. The default is 30000.
transportNostreamable_http (default) or rest.
environmentNodevelopment or production. On create, omit it to apply the server to every environment. On PATCH, send null to apply the server to every environment.
allowedToolsNoTool names to expose. Runtype exposes all discovered tools when you omit this field.
iconUrlNoAn http or https URL for the server icon. On PATCH, send null to remove it.
isActiveNo, PATCH onlySet to false to turn the server off, or true to turn it back on.

To turn off a saved server without deleting it, send a PATCH request:

cURL
curl -X PATCH https://api.runtype.com/v1/mcp/servers/customer_support \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "isActive": false }'

Replace YOUR_API_KEY with your Runtype API key.

A turned-off server doesn’t appear in the GET /v1/mcp/servers list. To turn it back on, send { "isActive": true } to the same path.

PATCH doesn’t accept the environment query parameter. When one name has registrations in more than one environment, a PATCH request can change any one of them. To change a specific registration, delete it with the environment query parameter and create it again.

Runtime server configuration

Configure runtime MCP servers with the following fields:

FieldRequiredDescription
idYesUnique identifier for the server instance. Runtype uses it in tool IDs.
nameNoDisplay name for the dashboard and logs.
urlYesMCP server endpoint URL.
authNoAuthentication configuration. Runtime servers don’t accept oauth2.
timeoutNoRequest timeout in milliseconds. The default is 30000, and the maximum is 300000. For more information, see Limits.
transportNostreamable_http (default) or rest.
allowedToolsNoTool names to expose. Runtype exposes all discovered tools when you omit this field.
iconUrlNoURL of an icon for the server.
enabledNoSet to false to skip the server. The default is true.

Use environment-specific servers

Assign an environment to a saved server when you need separate development and production configurations:

cURL
curl -X POST https://api.runtype.com/v1/mcp/servers \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "customer_support",
"url": "https://example.com/mcp",
"auth": { "type": "bearer", "token": "YOUR_DEVELOPMENT_TOKEN" },
"environment": "development"
}'
curl -X POST https://api.runtype.com/v1/mcp/servers \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "customer_support",
"url": "https://example.com/mcp",
"auth": { "type": "bearer", "token": "YOUR_PRODUCTION_TOKEN" },
"environment": "production"
}'

Replace the placeholders with your values:

  • YOUR_API_KEY: Your Runtype API key.
  • YOUR_DEVELOPMENT_TOKEN: The token for the development server.
  • YOUR_PRODUCTION_TOKEN: The token for the production server.

Add the environment to the dispatch request to select a saved server configuration:

Dispatch environment
{
"options": {
"environment": "production"
}
}

A saved server without an environment applies to every environment. When a dispatch sets an environment, Runtype uses the server registered for that environment and falls back to the server without one. When a dispatch omits options.environment, Runtype uses only servers that have no environment.

To get or delete one registration of a name, add the environment query parameter, as in GET /v1/mcp/servers/customer_support?environment=production. Without the parameter, the request targets the registration that has no environment. If you create a second server with the same name and environment, the API returns 409 with a message such as “A custom MCP server named “customer_support” already exists for production environment”.

Limits

Runtype applies these limits to runtime MCP configuration:

LimitValue
Maximum custom MCP servers per step5
Maximum timeout300 seconds (background runs); 30 seconds (synchronous calls)
Tool discovery cache30 seconds

A background run continues after the original request returns, such as an Agent Loop turn that runs in the background or a detached subagent run. A synchronous call holds the original request open while the tool runs, so Runtype caps its timeout at 30 seconds and logs the reduction.

Combine MCP tools with other tools

Add saved tools, built-in tools, runtime tools, and runtime MCP servers to one prompt. This tools object combines these tool sources:

Combined tool configuration
const tools = {
toolIds: ['mcp:customer_support:search_articles', 'builtin:openai_web_search', 'YOUR_TOOL_ID'],
mcpServers: [
{
id: 'runtime_server',
url: 'https://example.com/mcp',
},
],
runtimeTools: [
{
name: 'get_customer',
description: 'Get customer information',
toolType: 'external',
parametersSchema: {
type: 'object',
properties: {},
},
config: {
url: 'https://example.com/customer',
method: 'GET',
},
},
],
}

Replace YOUR_TOOL_ID with the ID of a saved tool.

Protect MCP credentials

Use these practices to protect MCP credentials:

  • Store saved-server credentials in the server configuration. Runtype encrypts them before storage.
  • Keep runtime credentials out of logs and persistent storage. Use environment variables or {{secret:NAME}} references instead of hardcoded tokens.
  • Set allowedTools to limit the tools that a server exposes.

Troubleshoot MCP servers

A saved server is required when a step references its tools in toolIds. When a required server can’t load its tools, the run stops with a message that names the server and a recovery action. Timeouts and temporary outages get at most one discovery retry. Runtype stops the run without trying model fallbacks, prompt fallbacks (including fixed-message fallbacks), or additional agent turns. Reconnect or repair the server before you run the flow or agent again.

Structured run errors include error.details.mcpFailure with the serverId, serverName, stage, code, retryable, and diagnosticId fields. Keep the diagnosticId value when you investigate a failed run. Browser voice tests display the same message and a Check SERVER_NAME connection button that opens the server in Tools. These messages don’t include upstream response bodies or credentials.

The stage field is one of configuration, token_refresh, connection, or tool_discovery. The following table lists the code values:

CodeMeaningAction
MCP_REAUTH_REQUIREDThe server rejected the credentials or the OAuth2 token.Reconnect the server from Tools, or replace its credentials.
MCP_ACCESS_DENIEDThe server denied access to the connection.Check the permissions and scopes that the connection uses.
MCP_TIMEOUTThe server didn’t respond within the timeout. Retryable.Try again, or increase timeout.
MCP_UNAVAILABLEThe server was unreachable, rate-limited the request, or returned a server error. Retryable.Try again after the server recovers.
MCP_INVALID_RESPONSEThe server returned a response that isn’t valid MCP.Check the server URL and transport setting.
MCP_CONFIGURATION_ERRORThe saved server is missing, turned off, or couldn’t be loaded.Check that the server exists and is turned on in Tools.
MCP_DISCOVERY_FAILEDTool discovery failed for another reason.Test the server with POST /v1/mcp/servers/:name/test.

Use these checks to troubleshoot common MCP server failures:

Check these settings:

  • Confirm that the server URL is reachable.
  • Increase the timeout value, up to 300000 milliseconds. A value above 30000 takes effect only in background runs. For more information, see Limits.
  • Confirm that firewall and network rules allow the connection.

Check these settings:

  • Confirm that the token is valid and has not expired.
  • Confirm that the auth type matches the server’s requirements.
  • For api_key, confirm that headerName matches the server’s header.

Check these settings:

  • Confirm that the server owner or an organization admin manages the server.
  • Check canManage in the GET /v1/mcp/servers response.
  • Ask the server owner or an organization admin to make the change.
  • Confirm that your API key has the scope that the endpoint requires. For the scope of each endpoint, see API reference.

Check these settings:

  • Send a POST request to /v1/mcp/servers/:name/test to verify discovery, and check the success field.
  • Check the allowedTools filter when you set it.
  • Confirm that the server implements the tools/list method.

Runtype validates tools.mcpServers before the run starts. Match the error to its fix:

  • “Maximum 5 custom MCP servers per step”: Split the servers across steps, or save some servers and reference their tool IDs.
  • “MCP server missing required “id” field”: Add an id value to each server.
  • “missing required “url” field” or “has invalid URL format”: Set url to a complete URL, such as https://example.com/mcp.
  • “has invalid auth type”: Use api_key, bearer, basic, custom_header, headers, or none.
  • “Inline MCP OAuth2 is unsupported”: Save the server with OAuth2, and then bind its ID without auth. For more information, see Machine-to-machine OAuth2.
  • “timeout exceeds the 300s limit”: Set timeout to 300000 milliseconds or less.

API reference

Use these endpoints to manage saved servers and discover tools. When you call an endpoint with an API key, the key needs the listed scope:

EndpointScopeDescription
GET /v1/mcp/serversTOOLS:READLists saved custom MCP servers.
POST /v1/mcp/serversTOOLS:WRITECreates a saved custom MCP server. Returns 409 when the name already exists in that environment.
GET /v1/mcp/servers/:nameTOOLS:READGets saved server details. Use the optional environment query parameter to select a registration.
PATCH /v1/mcp/servers/:nameTOOLS:WRITEUpdates saved server configuration.
DELETE /v1/mcp/servers/:nameTOOLS:WRITEDeletes a saved server. Use the optional environment and id query parameters to select a registration.
POST /v1/mcp/servers/:name/testTOOLS:EXECUTETests a saved server and lists discovered tools.
GET /v1/mcp/toolsTOOLS:READLists configured integration tools.
POST /v1/mcp/discoverTOOLS:READDiscovers tools from a server URL.

Next steps

Continue with these guides: