MCP servers

Use Model Context Protocol (MCP) servers to connect flows and agents to external tools and data sources. Runtype supports saved and runtime MCP servers.

Overview

MCP servers expose tools to the model during flow execution. You can save a server for reuse or pass its configuration at runtime.

MCP servers provide these capabilities:

  • Tool discovery: Runtype lists tools that the server exposes.
  • Parameter schemas: Runtype exposes each tool’s input schema.
  • Session support: MCP clients can maintain sessions with compatible servers.
  • Standard protocol: Runtype connects to MCP-compatible servers.

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. Choose an authentication type and enter its credentials.
  5. Click Discover Tools. The dashboard lists the tools that it finds.
  6. Click Add Server. The dashboard saves the server.

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
1{
2 "success": true,
3 "toolsDiscovered": 2,
4 "tools": [
5 {
6 "name": "search_articles",
7 "description": "Search support articles"
8 },
9 {
10 "name": "create_ticket",
11 "description": "Create a support ticket"
12 }
13 ]
14}

Replace YOUR_API_KEY with your Runtype API key.

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
1import { FlowBuilder, RuntypeClient } from '@runtypelabs/sdk'
2
3const client = new RuntypeClient({
4 apiKey: process.env.RUNTYPE_API_KEY,
5})
6
7const result = await new FlowBuilder()
8 .createFlow({ name: 'Customer support agent' })
9 .prompt({
10 name: 'Support agent',
11 model: 'gpt-5.4',
12 userPrompt: 'Find the open support tickets for this customer',
13 tools: {
14 toolIds: ['mcp:customer_support:search_articles', 'mcp:customer_support:create_ticket'],
15 },
16 })
17 .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
1import os
2
3from runtype import RuntypeClient
4
5client = RuntypeClient(api_key=os.environ["RUNTYPE_API_KEY"])
6
7for event in client.dispatch({
8 "flow": {
9 "name": "Customer support agent",
10 "steps": [{
11 "type": "prompt",
12 "config": {
13 "model": "gpt-5.4",
14 "userPrompt": "Find the open support tickets for this customer",
15 "tools": {
16 "toolIds": [
17 "mcp:customer_support:search_articles",
18 "mcp:customer_support:create_ticket"
19 ]
20 }
21 }
22 }]
23 }
24}):
25 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": "gpt-5.4",
> "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
1{
2 "tools": {
3 "toolIds": ["mcp:customer_support:*"]
4 }
5}

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
1const result = await new FlowBuilder()
2 .createFlow({ name: 'Customer support agent' })
3 .prompt({
4 name: 'Support agent',
5 model: 'gpt-5.4',
6 userPrompt: 'Help me manage support requests',
7 tools: {
8 toolIds: ['mcp:customer_support:*'],
9 },
10 })
11 .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": "gpt-5.4",
> "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 /mcp/servers and GET /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 /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
1const mcpServers = [
2 {
3 id: 'user_notion',
4 name: 'User Notion',
5 url: 'https://example.com/mcp',
6 auth: {
7 type: 'bearer',
8 token: userCredentials.mcpToken,
9 },
10 timeout: 30000,
11 transport: 'streamable_http',
12 allowedTools: ['search_articles', 'create_ticket'],
13 },
14]
15
16const result = await new FlowBuilder()
17 .createFlow({ name: 'User support agent' })
18 .prompt({
19 name: 'Support agent',
20 model: 'gpt-5.4',
21 userPrompt: 'Help me manage my support requests',
22 tools: {
23 mcpServers,
24 },
25 })
26 .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
1mcp_servers = [{
2 "id": "user_notion",
3 "name": "User Notion",
4 "url": "https://example.com/mcp",
5 "auth": {
6 "type": "bearer",
7 "token": user_credentials["mcp_token"]
8 },
9 "timeout": 30000,
10 "allowedTools": ["search_articles", "create_ticket"]
11}]
12
13for event in client.dispatch({
14 "flow": {
15 "steps": [{
16 "type": "prompt",
17 "config": {
18 "model": "gpt-5.4",
19 "userPrompt": "Help me manage my support requests",
20 "tools": {
21 "mcpServers": mcp_servers
22 }
23 }
24 }]
25 }
26}):
27 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": "gpt-5.4",
> "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.

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 the OAuth2 flow.Configure it through the dashboard OAuth2 flow.
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.

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.

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.

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.

The discovery flow also handles servers whose authorization-server metadata is at the host root while the issuer contains a path.

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.

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.

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:*

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.
timeoutNoRequest timeout in milliseconds. The default is 30000 and the maximum is 60000.
transportNostreamable_http (default) or rest.
allowedToolsNoTool names to expose. Runtype exposes all discovered tools when you omit this field.
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
1{
2 "options": {
3 "environment": "production"
4 }
5}

Limits

Runtype applies these limits to runtime MCP configuration:

LimitValue
Maximum custom MCP servers per step5
Maximum timeout60 seconds
Tool discovery cache30 seconds

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
1const tools = {
2 toolIds: ['mcp:customer_support:search_articles', 'builtin:openai_web_search', 'YOUR_TOOL_ID'],
3 mcpServers: [
4 {
5 id: 'runtime_server',
6 url: 'https://example.com/mcp',
7 },
8 ],
9 runtimeTools: [
10 {
11 name: 'get_customer',
12 description: 'Get customer information',
13 toolType: 'external',
14 parametersSchema: {
15 type: 'object',
16 properties: {},
17 },
18 config: {
19 url: 'https://example.com/customer',
20 method: 'GET',
21 },
22 },
23 ],
24}

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 managed secret references instead of hardcoding tokens.

Set allowedTools to limit the tools that a server can expose when possible.

Troubleshoot MCP servers

When a required saved MCP server cannot load its tools, the execution stops with a message naming the connection and a recovery action. Authorization failures require reconnecting the server; timeouts and temporary outages receive at most one discovery retry before the execution stops. These failures do not trigger model fallback or additional agent turns.

Structured execution errors include error.details.mcpFailure with serverId, serverName, stage, code, retryable, and diagnosticId. Keep the diagnostic reference when investigating a failed run. Browser voice tests display the same safe message and provide a button to open Tools → MCP servers. Upstream response bodies and credentials are not included in these messages.

An unavailable required MCP connection stops execution before prompt fallbacks, including fixed-message fallbacks. Reconnect or repair the required connection before running the flow or agent again.

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 60000 milliseconds.
  • 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 /mcp/servers response.
  • Ask the server owner or an organization admin to make the change.

Check these settings:

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

API reference

Use these endpoints to manage saved servers and discover tools:

EndpointDescription
GET /mcp/serversLists saved custom MCP servers.
POST /mcp/serversCreates a saved custom MCP server.
GET /mcp/servers/:nameGets saved server details.
PATCH /mcp/servers/:nameUpdates saved server configuration.
DELETE /mcp/servers/:nameDeletes a saved server. Use the optional ?id=SERVER_ID query parameter to disambiguate duplicate names.
POST /mcp/servers/:name/testTests a saved server and lists discovered tools.
GET /mcp/toolsLists configured integration tools.
POST /mcp/discoverDiscovers tools from a server URL.

Next steps

Continue with these guides: