Integrate local and remote MCP servers for dynamic tool provisioning.
The SDK supports three types of MCP server connections.
/**
* Stdio-based MCP server (local process)
*/
class MCPServerStdio implements MCPServer {
constructor(options: MCPServerStdioOptions);
}
interface MCPServerStdioOptions {
/** Command to execute (e.g., 'node', 'python') */
command?: string;
/** Full command array including executable and arguments */
fullCommand?: string[];
/** Server identifier (defaults to command) */
name?: string;
/** Cache tool definitions (default: true) */
cacheToolsList?: boolean;
/** Filter tools by name or callable function */
toolFilter?: MCPToolFilterCallable | MCPToolFilterStatic;
/** Logger instance */
logger?: Logger;
/** Connection timeout in milliseconds */
timeout?: number;
}
/**
* HTTP streaming MCP server
*/
class MCPServerStreamableHttp implements MCPServer {
constructor(options: MCPServerHttpOptions);
}
interface MCPServerHttpOptions {
/** Server URL (required) */
url: string;
/** Server identifier (defaults to URL) */
name?: string;
/** Cache tool definitions (default: true) */
cacheToolsList?: boolean;
/** Filter tools */
toolFilter?: MCPToolFilterCallable | MCPToolFilterStatic;
/** Logger instance */
logger?: Logger;
/** Connection timeout in milliseconds */
timeout?: number;
}
/**
* Server-Sent Events MCP server
*/
class MCPServerSSE implements MCPServer {
constructor(options: MCPServerSSEOptions);
}
interface MCPServerSSEOptions {
/** Server URL (required) */
url: string;
/** Server identifier (defaults to URL) */
name?: string;
/** Cache tool definitions (default: true) */
cacheToolsList?: boolean;
/** Filter tools */
toolFilter?: MCPToolFilterCallable | MCPToolFilterStatic;
/** Logger instance */
logger?: Logger;
/** Connection timeout in milliseconds */
timeout?: number;
}Usage Examples:
import { Agent, run, MCPServerStdio, MCPServerStreamableHttp, MCPServerSSE } from '@openai/agents';
// Stdio server (local process)
const stdioServer = new MCPServerStdio({
command: 'node',
fullCommand: ['node', '/path/to/mcp-server.js'],
name: 'my-local-server',
});
const agent1 = new Agent({
name: 'StdioAgent',
instructions: 'You have access to local MCP tools',
mcpServers: [stdioServer],
});
await run(agent1, 'Use the local tools');
// HTTP streaming server
const httpServer = new MCPServerStreamableHttp({
url: 'https://mcp.example.com',
name: 'remote-server',
});
const agent2 = new Agent({
name: 'HttpAgent',
instructions: 'You have access to remote MCP tools',
mcpServers: [httpServer],
});
await run(agent2, 'Use the remote tools');
// SSE server
const sseServer = new MCPServerSSE({
url: 'https://mcp.example.com/sse',
name: 'sse-server',
});
const agent3 = new Agent({
name: 'SSEAgent',
instructions: 'You have access to SSE MCP tools',
mcpServers: [sseServer],
});
await run(agent3, 'Use the SSE tools');
// Python MCP server
const pythonServer = new MCPServerStdio({
command: 'python',
fullCommand: ['python', '-m', 'mcp_server'],
name: 'python-tools',
});
// Multiple MCP servers
const multiAgent = new Agent({
name: 'MultiMCPAgent',
instructions: 'You have access to multiple MCP servers',
mcpServers: [stdioServer, httpServer, pythonServer],
});
await run(multiAgent, 'Use tools from any server');Base interface implemented by all MCP server types.
/**
* Base MCP server interface
*/
interface MCPServer {
/** Server identifier */
name: string;
/**
* Connect to the MCP server
*/
connect(): Promise<void>;
/**
* Close the connection
*/
close(): Promise<void>;
/**
* List available tools from server
* @returns Array of MCP tools
*/
listTools(): Promise<MCPTool[]>;
/**
* Call a tool on the server
* @param toolName - Name of tool to call
* @param args - Tool arguments
* @returns Tool result content
*/
callTool(toolName: string, args: any): Promise<CallToolResultContent>;
/**
* Invalidate the cached tools list
*/
invalidateToolsCache(): Promise<void>;
}
interface MCPTool {
/** Tool name */
name: string;
/** Tool description */
description?: string;
/** Input schema */
inputSchema: JsonObjectSchema;
}
type CallToolResultContent =
| { type: 'text'; text: string }
| { type: 'image'; data: string; mimeType: string }
| { type: 'resource'; uri: string; mimeType?: string; text?: string };Usage Examples:
import { MCPServerStdio } from '@openai/agents';
const server = new MCPServerStdio({
command: 'node',
fullCommand: ['node', 'mcp-server.js'],
name: 'my-server',
});
// Connect to server
await server.connect();
// List available tools
const tools = await server.listTools();
console.log('Available tools:', tools.map(t => t.name));
// Call a tool directly
const result = await server.callTool('search', {
query: 'OpenAI',
limit: 10,
});
console.log('Tool result:', result);
// Invalidate cache to refresh tool list
await server.invalidateToolsCache();
const updatedTools = await server.listTools();
// Close connection when done
await server.close();Filter MCP tools by name or custom logic.
/**
* Static tool filter by allowed/blocked names
*/
interface MCPToolFilterStatic {
/** Allowed tool names (whitelist) */
allowedToolNames?: string[];
/** Blocked tool names (blacklist) */
blockedToolNames?: string[];
}
/**
* Dynamic tool filter function
*/
type MCPToolFilterCallable = (tool: MCPTool) => boolean;
/**
* Create a static tool filter
* @param options - Filter configuration
* @returns Static filter object
*/
function createMCPToolStaticFilter(
options: MCPToolFilterStatic
): MCPToolFilterStatic;Usage Examples:
import { Agent, run, MCPServerStdio, createMCPToolStaticFilter } from '@openai/agents';
// Whitelist specific tools
const whitelistServer = new MCPServerStdio({
command: 'node',
fullCommand: ['node', 'mcp-server.js'],
toolFilter: {
allowedToolNames: ['search', 'calculate', 'weather'],
},
});
// Blacklist specific tools
const blacklistServer = new MCPServerStdio({
command: 'node',
fullCommand: ['node', 'mcp-server.js'],
toolFilter: {
blockedToolNames: ['delete', 'destroy', 'remove'],
},
});
// Dynamic filtering with callable
const dynamicServer = new MCPServerStdio({
command: 'node',
fullCommand: ['node', 'mcp-server.js'],
toolFilter: (tool) => {
// Custom filtering logic
return tool.name.startsWith('safe_') && !tool.name.includes('delete');
},
});
// Using helper function
const filter = createMCPToolStaticFilter({
allowedToolNames: ['read', 'list', 'search'],
blockedToolNames: [], // Optional
});
const filteredServer = new MCPServerStdio({
command: 'node',
fullCommand: ['node', 'mcp-server.js'],
toolFilter: filter,
});
const agent = new Agent({
name: 'FilteredAgent',
instructions: 'You have access to filtered MCP tools',
mcpServers: [filteredServer],
});Utility functions for working with MCP servers.
/**
* Get tools from multiple MCP servers
* @param options - Server and filter options
* @returns Array of MCP tools
*/
function getAllMcpTools(options: {
mcpServers: MCPServer[];
toolFilter?: MCPToolFilterCallable | MCPToolFilterStatic;
}): Promise<MCPTool[]>;
/**
* Invalidate tool cache for a specific server
* @param serverName - Name of server to invalidate
*/
function invalidateServerToolsCache(serverName: string): Promise<void>;
/**
* Convert MCP tool to function tool
* @param mcpTool - MCP tool to convert
* @param server - Server that provides the tool
* @param convertStrict - Enable strict mode (default: true)
* @returns FunctionTool instance
*/
function mcpToFunctionTool(
mcpTool: MCPTool,
server: MCPServer,
convertStrict?: boolean
): FunctionTool;Usage Examples:
import {
Agent,
run,
MCPServerStdio,
getAllMcpTools,
invalidateServerToolsCache,
mcpToFunctionTool,
} from '@openai/agents';
// Get tools from multiple servers
const server1 = new MCPServerStdio({
command: 'node',
fullCommand: ['node', 'server1.js'],
name: 'server1',
});
const server2 = new MCPServerStdio({
command: 'node',
fullCommand: ['node', 'server2.js'],
name: 'server2',
});
await server1.connect();
await server2.connect();
const allTools = await getAllMcpTools({
mcpServers: [server1, server2],
toolFilter: {
allowedToolNames: ['search', 'calculate'],
},
});
console.log('All MCP tools:', allTools.map(t => t.name));
// Invalidate cache for a server
await invalidateServerToolsCache('server1');
// Convert MCP tool to function tool
const mcpTools = await server1.listTools();
const mcpTool = mcpTools[0];
const functionTool = mcpToFunctionTool(mcpTool, server1, true);
const agent = new Agent({
name: 'ConvertedToolAgent',
instructions: 'You have access to converted tools',
tools: [functionTool],
});
await run(agent, 'Use the converted tool');Access MCP tools through the Agent class.
/**
* Fetch tools from configured MCP servers
* @param runContext - Current run context
* @returns Array of function tools from MCP servers
*/
Agent.prototype.getMcpTools(runContext: RunContext<TContext>): Promise<FunctionTool[]>;
/**
* Get all configured tools (MCP + function tools)
* @param runContext - Current run context
* @returns Array of all tools
*/
Agent.prototype.getAllTools(runContext: RunContext<TContext>): Promise<Tool[]>;Usage Examples:
import { Agent, run, MCPServerStdio } from '@openai/agents';
const mcpServer = new MCPServerStdio({
command: 'node',
fullCommand: ['node', 'mcp-server.js'],
name: 'mcp-tools',
});
const agent = new Agent({
name: 'MCPAgent',
instructions: 'You have access to MCP tools',
mcpServers: [mcpServer],
});
// Get MCP tools
const result = await run(agent, 'List available tools', {
context: {},
});
// Access tools from within agent execution
const runContext = result.state.runContext;
const mcpTools = await agent.getMcpTools(runContext);
console.log('MCP tools:', mcpTools.map(t => t.name));
// Get all tools (MCP + function tools)
const allTools = await agent.getAllTools(runContext);
console.log('All tools:', allTools.length);Combine MCP servers with custom function tools.
Usage Examples:
import { z } from 'zod';
import { Agent, run, tool, MCPServerStdio } from '@openai/agents';
// Define custom function tool
const customTool = tool({
name: 'custom_calculator',
description: 'Perform custom calculations',
parameters: z.object({
expression: z.string(),
}),
execute: async (input) => {
// Evaluate expression safely
return `Result: ${eval(input.expression)}`;
},
});
// Define MCP server
const mcpServer = new MCPServerStdio({
command: 'node',
fullCommand: ['node', 'external-tools.js'],
name: 'external-tools',
});
// Agent with both MCP and function tools
const agent = new Agent({
name: 'HybridAgent',
instructions: 'You have access to both custom and MCP tools',
tools: [customTool], // Custom function tools
mcpServers: [mcpServer], // MCP tools
});
const result = await run(
agent,
'Calculate 5 + 3 and then search for "mathematics"'
);Control tool list caching behavior.
Usage Examples:
import { Agent, run, MCPServerStdio } from '@openai/agents';
// Enable caching (default)
const cachedServer = new MCPServerStdio({
command: 'node',
fullCommand: ['node', 'mcp-server.js'],
cacheToolsList: true, // Tools fetched once
});
// Disable caching (always fetch fresh)
const uncachedServer = new MCPServerStdio({
command: 'node',
fullCommand: ['node', 'mcp-server.js'],
cacheToolsList: false, // Tools fetched every time
});
// Manually invalidate cache
const server = new MCPServerStdio({
command: 'node',
fullCommand: ['node', 'mcp-server.js'],
cacheToolsList: true,
});
await server.connect();
// Initial tool fetch (cached)
const tools1 = await server.listTools();
// Force refresh
await server.invalidateToolsCache();
// Fresh tool fetch
const tools2 = await server.listTools();Handle MCP server connection and execution errors.
Usage Examples:
import { Agent, run, MCPServerStdio, SystemError } from '@openai/agents';
const server = new MCPServerStdio({
command: 'node',
fullCommand: ['node', 'nonexistent-server.js'],
name: 'faulty-server',
timeout: 5000,
});
const agent = new Agent({
name: 'MCPAgent',
instructions: 'You have MCP tools',
mcpServers: [server],
});
try {
await run(agent, 'Use MCP tools');
} catch (error) {
if (error instanceof SystemError) {
console.error('MCP system error:', error.message);
}
}
// Handle connection errors
try {
await server.connect();
} catch (error) {
console.error('Failed to connect to MCP server:', error);
}
// Handle tool execution errors
try {
const result = await server.callTool('nonexistent_tool', {});
} catch (error) {
console.error('Tool execution failed:', error);
}Configure logging for MCP server operations.
Usage Examples:
import { MCPServerStdio } from '@openai/agents';
// Custom logger
const logger = {
debug: (message: string, ...args: any[]) => {
console.log('[DEBUG]', message, ...args);
},
info: (message: string, ...args: any[]) => {
console.log('[INFO]', message, ...args);
},
warn: (message: string, ...args: any[]) => {
console.warn('[WARN]', message, ...args);
},
error: (message: string, ...args: any[]) => {
console.error('[ERROR]', message, ...args);
},
};
const server = new MCPServerStdio({
command: 'node',
fullCommand: ['node', 'mcp-server.js'],
logger,
});
// Logger will output MCP operations
await server.connect();
await server.listTools();
await server.callTool('search', { query: 'test' });File System Tools:
import { Agent, run, MCPServerStdio } from '@openai/agents';
const filesystemServer = new MCPServerStdio({
command: 'npx',
fullCommand: ['npx', '-y', '@modelcontextprotocol/server-filesystem', '/path/to/workspace'],
name: 'filesystem',
toolFilter: {
allowedToolNames: ['read_file', 'write_file', 'list_directory'],
},
});
const fileAgent = new Agent({
name: 'FileAgent',
instructions: 'You can read and write files',
mcpServers: [filesystemServer],
});
await run(fileAgent, 'List all files in the current directory');Database Tools:
import { Agent, run, MCPServerStdio } from '@openai/agents';
const databaseServer = new MCPServerStdio({
command: 'node',
fullCommand: ['node', 'database-mcp-server.js'],
name: 'database',
});
const dbAgent = new Agent({
name: 'DatabaseAgent',
instructions: 'You can query the database',
mcpServers: [databaseServer],
});
await run(dbAgent, 'Find all users created in the last week');Weather API:
import { Agent, run, MCPServerStreamableHttp } from '@openai/agents';
const weatherServer = new MCPServerStreamableHttp({
url: 'https://weather-mcp.example.com',
name: 'weather',
});
const weatherAgent = new Agent({
name: 'WeatherAgent',
instructions: 'You provide weather information',
mcpServers: [weatherServer],
});
await run(weatherAgent, 'What is the weather forecast for Tokyo?');