콘텐츠로 이동

모델 컨텍스트 프로토콜 (MCP)

Model Context Protocol (MCP)은 애플리케이션이 LLM에 도구와 컨텍스트를 제공하는 방식을 표준화하는 공개 프로토콜입니다. MCP 문서에서는 다음과 같이 설명합니다.

MCP는 애플리케이션이 LLM에 컨텍스트를 제공하는 방식을 표준화하는 공개 프로토콜입니다. MCP를 AI 애플리케이션용 USB-C 포트라고 생각할 수 있습니다. USB-C가 기기를 다양한 주변 장치 및 액세서리에 연결하는 표준화된 방식을 제공하듯이, MCP는 AI 모델을 다양한 데이터 소스 및 도구에 연결하는 표준화된 방식을 제공합니다.

이 SDK는 세 가지 유형의 MCP 서버를 지원합니다.

  1. 호스티드 MCP 서버 도구OpenAI Responses API가 도구로 사용하는 원격 MCP 서버
  2. 스트리밍 가능한 HTTP MCP 서버스트리밍 가능한 HTTP 전송 방식을 구현하는 로컬 또는 원격 서버
  3. Stdio MCP 서버 – 표준 입력/출력을 통해 접근하는 서버(가장 간단한 옵션)

참고: SDK에는 레거시 Server-Sent Events 전송 방식을 위한 MCPServerSSE도 포함되어 있지만, MCP 프로젝트에서 SSE는 더 이상 사용되지 않습니다. 새로운 연동에는 스트리밍 가능한 HTTP 또는 stdio를 사용하는 것이 좋습니다.

사용 사례에 따라 서버 유형을 선택합니다.

필요한 기능권장 옵션
기본 OpenAI Responses 모델로 공개적으로 접근 가능한 원격 서버 호출1. 호스티드 MCP 도구
공개적으로 접근 가능한 원격 서버를 사용하되 도구 호출은 로컬에서 트리거2. 스트리밍 가능한 HTTP
로컬에서 실행되는 스트리밍 가능한 HTTP 서버 사용2. 스트리밍 가능한 HTTP
OpenAI Responses가 아닌 모델에서 스트리밍 가능한 HTTP 서버 사용2. 스트리밍 가능한 HTTP
표준 I/O 프로토콜만 지원하는 로컬 MCP 서버 사용3. Stdio

Agents SDK는 내부적으로 MCP TypeScript SDK v2 클라이언트를 사용합니다. 그렇다고 MCP 서버를 v2 서버 패키지로 마이그레이션해야 하는 것은 아닙니다. stdio 및 스트리밍 가능한 HTTP 연결에서 Agents SDK는 프로토콜을 자동으로 협상하며, 호환되는 프로토콜 버전을 지원하는 경우 MCP TypeScript SDK v1로 구현된 기존 서버와도 계속 호환됩니다.

애플리케이션에서 Agents SDK의 MCPServerStdio, MCPServerStreamableHttp 또는 MCPServerSSE 클래스만 사용한다면 이러한 호환성을 위해 MCP v1 및 v2 패키지를 설치하거나 연결할 필요가 없습니다. v2 MCP SDK API를 도입하려는 경우 애플리케이션이 소유한 MCP SDK 객체를 별도로 마이그레이션하세요. 자세한 내용은 MCP TypeScript SDK의 v1에서 v2로의 마이그레이션 가이드를 참고하세요.

호스티드 툴은 전체 왕복 과정을 모델 내에서 처리합니다. 코드가 MCP 서버를 호출하는 대신 OpenAI Responses API가 원격 도구 엔드포인트를 호출하고 결과를 모델로 다시 스트리밍합니다.

다음은 호스티드 MCP 도구를 사용하는 가장 간단한 예입니다. 원격 MCP 서버의 레이블과 URL을 hostedMcpTool 유틸리티 함수에 전달할 수 있으며, 이 함수는 호스티드 MCP 서버 도구를 생성할 때 유용합니다.

hostedAgent.ts
import { Agent, hostedMcpTool } from '@openai/agents';
export const agent = new Agent({
name: 'MCP Assistant',
instructions: 'You must always use the MCP tools to answer questions.',
tools: [
hostedMcpTool({
serverLabel: 'deepwiki',
serverUrl: 'https://mcp.deepwiki.com/mcp',
}),
],
});

그런 다음 run 함수 또는 직접 사용자 지정한 Runner 인스턴스의 run 메서드로 에이전트를 실행할 수 있습니다.

호스티드 MCP 도구로 실행
import { run } from '@openai/agents';
import { agent } from './hostedAgent';
async function main() {
const result = await run(
agent,
'Which language is the repo I pointed in the MCP tool settings written in?',
);
console.log(result.finalOutput);
}
main().catch(console.error);

MCP 결과를 점진적으로 스트리밍하려면 Agent를 실행할 때 stream: true를 전달합니다.

호스티드 MCP 도구로 실행(스트리밍)
import { isOpenAIResponsesRawModelStreamEvent, run } from '@openai/agents';
import { agent } from './hostedAgent';
async function main() {
const result = await run(
agent,
'Which language is the repo I pointed in the MCP tool settings written in?',
{ stream: true },
);
for await (const event of result) {
if (
isOpenAIResponsesRawModelStreamEvent(event) &&
event.data.event.type !== 'response.mcp_call_arguments.delta' &&
event.data.event.type !== 'response.output_text.delta'
) {
console.log(`Got event of type ${JSON.stringify(event.data)}`);
}
}
console.log(`Done streaming; final result: ${result.finalOutput}`);
}
main().catch(console.error);

민감한 작업의 경우 개별 도구 호출에 사람의 승인을 요구할 수 있습니다. requireApproval: 'always' 또는 도구 이름을 'never'/'always'에 매핑하는 세분화된 객체를 전달합니다.

도구 호출의 안전 여부를 프로그래밍 방식으로 판단할 수 있다면 onApproval 콜백을 사용하여 도구 호출을 승인하거나 거부할 수 있습니다. 사람의 승인이 필요한 경우 로컬 함수 도구와 마찬가지로 interruptions를 사용하는 휴먼 인 더 루프 (HITL) 방식을 사용할 수 있습니다.

호스티드 MCP 도구의 휴먼 인 더 루프
import { Agent, run, hostedMcpTool, RunToolApprovalItem } from '@openai/agents';
async function main(): Promise<void> {
const agent = new Agent({
name: 'MCP Assistant',
instructions: 'You must always use the MCP tools to answer questions.',
tools: [
hostedMcpTool({
serverLabel: 'deepwiki',
serverUrl: 'https://mcp.deepwiki.com/mcp',
// 'always' | 'never' | { never, always }
requireApproval: {
never: {
toolNames: ['read_wiki_structure', 'read_wiki_contents'],
},
always: {
toolNames: ['ask_question'],
},
},
}),
],
});
let result = await run(
agent,
'For the repository openai/codex, tell me the primary programming language.',
);
while (result.interruptions && result.interruptions.length) {
for (const interruption of result.interruptions) {
// Human in the loop here
const approval = await confirm(interruption);
if (approval) {
result.state.approve(interruption);
} else {
result.state.reject(interruption);
}
}
result = await run(agent, result.state);
}
console.log(result.finalOutput);
}
import { stdin, stdout } from 'node:process';
import * as readline from 'node:readline/promises';
async function confirm(item: RunToolApprovalItem): Promise<boolean> {
const rl = readline.createInterface({ input: stdin, output: stdout });
const name = item.name;
const params = item.arguments;
const answer = await rl.question(
`Approve running tool (mcp: ${name}, params: ${params})? (y/n) `,
);
rl.close();
return answer.toLowerCase().trim() === 'y';
}
main().catch(console.error);

hostedMcpTool(...)은 MCP 서버 URL과 커넥터 기반 서버를 모두 지원합니다.

옵션유형참고
serverLabelstring이벤트와 트레이스에서 호스티드 MCP 서버를 식별하는 필수 레이블입니다.
serverUrlstring원격 MCP 서버 URL입니다(일반 호스티드 MCP 서버에 사용).
connectorIdstringOpenAI 커넥터 ID입니다(커넥터 기반 호스티드 서버에서는 serverUrl 대신 사용).
authorizationstring호스티드 MCP 백엔드로 전송되는 선택적 인증 토큰입니다.
headersRecord<string, string>선택적인 추가 요청 헤더입니다.
allowedToolsstring[] | object모델에 노출할 도구 이름의 허용 목록입니다. string[] 또는 { toolNames?: string[] }를 전달합니다.
allowedCallers('direct' | 'programmatic')[]호스티드 MCP 도구를 직접 호출할지, 프로그래매틱 도구 호출을 통해 호출할지, 또는 두 방식 모두로 호출할지를 제어하는 Responses 전용 비어 있지 않은 목록입니다.
deferLoadingboolean호스티드 MCP 도구를 위한 Responses 전용 지연 로딩입니다. 동일한 에이전트에 toolSearchTool()이 필요합니다.
requireApproval'never' | 'always' | object호스티드 MCP 도구 호출에 대한 승인 정책입니다. 도구별 재정의에는 객체 형식을 사용합니다. 기본값은 'never'입니다.
onApproval승인 콜백requireApproval에서 승인 처리를 요구할 때 프로그래밍 방식으로 승인하거나 거부하기 위한 선택적 콜백입니다.

도구 정의를 미리 노출하지 않고 도구 검색을 통해 필요할 때 호스티드 MCP 서버의 도구 정의를 모델이 로드하도록 하려면 deferLoading: true를 설정합니다. 이 기능은 OpenAI Responses API에서만 작동하고 동일한 요청에 toolSearchTool()이 필요하며, GPT-5.4 및 이후에 출시된 지원 모델과 함께 사용해야 합니다. 전체 지연 로딩 설정은 도구 가이드를 참고하세요.

호스티드 MCP 도구를 모델이 생성한 JavaScript에서만 호출해야 한다면 allowedCallers: ['programmatic']을 설정하고, 두 경로를 모두 허용하려면 'direct''programmatic'을 모두 포함합니다. 동일한 에이전트에 programmaticToolCallingTool()을 추가합니다. 프로그램이 MCP 도구를 호출할 때도 기존 requireApprovalonApproval 정책이 적용됩니다. 전체 설정은 프로그래매틱 도구 호출을 참고하세요.

requireApproval의 객체 형식에는 선택적인 alwaysnever 항목을 사용할 수 있습니다. 각 항목은 toolNames 또는 읽기 전용 어노테이션으로 도구를 선택할 수 있습니다. 선택적 onApproval 콜백은 현재 실행 컨텍스트와 승인 항목을 받은 다음 approve와 선택적 reason을 포함하는 프로미스를 반환합니다.

호스티드 MCP는 OpenAI 커넥터도 지원합니다. serverUrl을 제공하는 대신 커넥터의 connectorIdauthorization 토큰을 전달합니다. 그러면 Responses API가 인증을 처리하고 호스티드 MCP 인터페이스를 통해 커넥터의 도구를 노출합니다.

커넥터 기반 호스티드 MCP 도구
import { Agent, hostedMcpTool } from '@openai/agents';
const authorization = process.env.GOOGLE_CALENDAR_AUTHORIZATION!;
export const connectorAgent = new Agent({
name: 'Calendar Assistant',
instructions:
"You are a helpful assistant that can answer questions about the user's calendar.",
tools: [
hostedMcpTool({
serverLabel: 'google_calendar',
connectorId: 'connector_googlecalendar',
authorization,
requireApproval: 'never',
}),
],
});

이 예에서 GOOGLE_CALENDAR_AUTHORIZATION 환경 변수에는 Google OAuth Playground에서 얻은 OAuth 토큰이 들어 있으며, 이 토큰은 커넥터 기반 서버가 Calendar API를 호출하도록 승인합니다. 스트리밍도 보여주는 실행 가능한 샘플은 examples/connectors를 참고하세요.

완전히 동작하는 샘플(호스티드 툴/스트리밍 가능한 HTTP/stdio + 스트리밍, HITL, onApproval)은 GitHub 리포지토리의 examples/mcp에 있습니다.

전송 방식을 선택하는 것 외에도 Agent.mcpConfig를 설정하여 로컬 MCP 도구가 준비되는 방식을 조정할 수 있습니다.

에이전트의 로컬 MCP 도구 설정
import { Agent, MCPServerStreamableHttp } from '@openai/agents';
const server = new MCPServerStreamableHttp({
url: 'https://your-own-domain-here/mcp',
name: 'Docs server',
});
const agent = new Agent({
name: 'Assistant',
mcpServers: [server],
mcpConfig: {
// Try to convert MCP tool schemas to strict JSON schema.
convertSchemasToStrict: true,
// Set to null to raise MCP tool failures instead of returning model-visible error text.
errorFunction: null,
// Prefix local MCP tool names with their server name.
includeServerInToolNames: true,
},
});

참고:

  • convertSchemasToStrict는 최선형(best-effort)으로 작동합니다. 스키마를 변환할 수 없으면 원래 스키마가 사용됩니다.
  • errorFunction은 MCP 도구 호출 실패를 모델에 표시하는 방식을 제어합니다.
  • errorFunction이 설정되지 않으면 SDK는 기본 도구 오류 포매터를 사용합니다.
  • 서버 수준의 errorFunction 값은 해당 서버의 Agent.mcpConfig.errorFunction을 재정의합니다.
  • includeServerInToolNames는 선택적으로 활성화합니다. 활성화하면 각 로컬 MCP 도구가 결정론적인 서버 접두사 이름으로 모델에 노출되므로 여러 MCP 서버가 같은 이름의 도구를 게시할 때 발생하는 충돌을 방지하는 데 도움이 됩니다.
  • SDK는 URL에서 파생된 서버 이름과 전송 오류를 로그, 트레이스, 오류 메시지에 노출하기 전에 URL 자격 증명, 쿼리 매개변수, 프래그먼트를 제거합니다. 안정적인 서버 레이블이 필요한 경우 명시적이고 고유하며 비밀이 아닌 name을 설정하세요.
  • 서로 다른 URL에서 파생된 서버 이름이 자격 증명, 쿼리 매개변수, 프래그먼트를 제거한 후 동일해지고 같은 도구 이름을 게시하면 모델 요청 전에 설정이 실패합니다. 이러한 서버에는 명시적이고 고유하며 비밀이 아닌 name 값을 설정하세요.

에이전트가 로컬 또는 원격의 스트리밍 가능한 HTTP MCP 서버와 직접 통신하는 경우 서버의 url, name 및 선택적 설정을 사용하여 MCPServerStreamableHttp를 인스턴스화합니다.

스트리밍 가능한 HTTP MCP 서버로 실행
import { Agent, run, MCPServerStreamableHttp } from '@openai/agents';
async function main() {
const mcpServer = new MCPServerStreamableHttp({
url: 'https://mcp.deepwiki.com/mcp',
name: 'DeepWiki MCP Server',
});
const agent = new Agent({
name: 'DeepWiki Assistant',
instructions: 'Use the tools to respond to user requests.',
mcpServers: [mcpServer],
});
try {
await mcpServer.connect();
const result = await run(
agent,
'For the repository openai/codex, tell me the primary programming language.',
);
console.log(result.finalOutput);
} finally {
await mcpServer.close();
}
}
main().catch(console.error);

생성자 옵션:

옵션유형참고
urlstring스트리밍 가능한 HTTP 서버 URL입니다.
namestring서버의 선택적 레이블입니다.
cacheToolsListboolean지연 시간을 줄이기 위해 도구 목록을 캐시합니다.
clientSessionTimeoutSecondsnumberMCP 클라이언트 세션의 제한 시간입니다.
toolFilterMCPToolFilterCallable | MCPToolFilterStatic사용 가능한 도구를 필터링합니다.
toolMetaResolverMCPToolMetaResolver호출별 MCP _meta 요청 필드를 삽입합니다.
toolInputGuardrailsToolInputGuardrailDefinition[]이 서버에서 변환된 모든 도구 호출 전에 이러한 가드레일을 실행합니다.
toolOutputGuardrailsToolOutputGuardrailDefinition[]이 서버에서 변환된 모든 도구 호출 후에 이러한 가드레일을 실행합니다.
useStructuredContentboolean사용할 수 있고 결과가 오류가 아닌 경우 JSON으로 직렬화된 MCP structuredContent를 모델에 표시되는 출력으로 사용합니다. 기본값은 false입니다.
customDataExtractorMCPToolCustomDataExtractor생성된 로컬 MCP 도구 출력 항목에 SDK 전용 JSON 메타데이터를 연결합니다. 콜백은 MCP 결과의 _meta, structuredContent, isError 및 모델에 표시되는 도구 출력을 읽을 수 있습니다.
errorFunctionMCPToolErrorFunction | nullMCP 호출 실패를 모델에 표시되는 텍스트로 매핑합니다.
timeoutnumber요청별 제한 시간(밀리초)입니다.
loggerLogger사용자 지정 로거입니다.
authProviderOAuthClientProviderMCP TypeScript SDK의 OAuth 제공자입니다.
requestInitRequestInit요청에 대한 Fetch 초기화 옵션입니다.
fetchFetchLike사용자 지정 Fetch 구현입니다.
reconnectionOptionsStreamableHTTPReconnectionOptions재연결 조정 옵션입니다.
sessionIdstringMCP 연결을 위한 명시적 세션 ID입니다.

생성자는 authProvider, requestInit, fetch, reconnectionOptions, sessionId 같은 추가 MCP TypeScript SDK 옵션도 받습니다. 자세한 내용은 MCP TypeScript SDK 리포지토리와 해당 문서를 참고하세요.

toolInputGuardrailstoolOutputGuardrails는 SDK의 로컬 함수 도구 가드레일 파이프라인을 사용합니다. 스트리밍 및 비스트리밍 실행에서 이 서버로부터 변환된 모든 도구에 적용됩니다. Responses API가 원격으로 실행하는 호스티드 MCP 도구에는 적용되지 않습니다. 거부 동작 및 승인 순서는 도구 가드레일을 참고하세요.

표준 I/O만 노출하는 서버의 경우 fullCommand를 사용하여 MCPServerStdio를 인스턴스화합니다.

Stdio MCP 서버로 실행
import { Agent, run, MCPServerStdio } from '@openai/agents';
import * as path from 'node:path';
async function main() {
const samplesDir = path.join(__dirname, 'sample_files');
const mcpServer = new MCPServerStdio({
name: 'Filesystem MCP Server, via local package',
fullCommand: `pnpm exec mcp-server-filesystem ${samplesDir}`,
});
await mcpServer.connect();
try {
const agent = new Agent({
name: 'FS MCP Assistant',
instructions:
'Use the tools to read the filesystem and answer questions based on those files. If you are unable to find any files, you can say so instead of assuming they exist.',
mcpServers: [mcpServer],
});
const result = await run(agent, 'Read the files and list them.');
console.log(result.finalOutput);
} finally {
await mcpServer.close();
}
}
main().catch(console.error);

생성자 옵션:

옵션유형참고
command / argsstring / string[]stdio 서버를 위한 명령어와 인수입니다.
fullCommandstringcommand + args를 대체하는 전체 명령어 문자열입니다.
envRecord<string, string>서버 프로세스의 환경 변수입니다.
cwdstring서버 프로세스의 작업 디렉터리입니다.
cacheToolsListboolean지연 시간을 줄이기 위해 도구 목록을 캐시합니다.
clientSessionTimeoutSecondsnumberMCP 클라이언트 세션의 제한 시간입니다.
namestring서버의 선택적 레이블입니다.
encodingstringstdio 스트림의 인코딩입니다.
encodingErrorHandler'strict' | 'ignore' | 'replace'인코딩 오류 처리 전략입니다.
toolFilterMCPToolFilterCallable | MCPToolFilterStatic사용 가능한 도구를 필터링합니다.
toolMetaResolverMCPToolMetaResolver호출별 MCP _meta 요청 필드를 삽입합니다.
toolInputGuardrailsToolInputGuardrailDefinition[]이 서버에서 변환된 모든 도구 호출 전에 이러한 가드레일을 실행합니다.
toolOutputGuardrailsToolOutputGuardrailDefinition[]이 서버에서 변환된 모든 도구 호출 후에 이러한 가드레일을 실행합니다.
useStructuredContentboolean사용할 수 있고 결과가 오류가 아닌 경우 JSON으로 직렬화된 MCP structuredContent를 모델에 표시되는 출력으로 사용합니다. 기본값은 false입니다.
customDataExtractorMCPToolCustomDataExtractor생성된 로컬 MCP 도구 출력 항목에 SDK 전용 JSON 메타데이터를 연결합니다. 콜백은 MCP 결과의 _meta, structuredContent, isError 및 모델에 표시되는 도구 출력을 읽을 수 있습니다.
errorFunctionMCPToolErrorFunction | nullMCP 호출 실패를 모델에 표시되는 텍스트로 매핑합니다.
timeoutnumber요청별 제한 시간(밀리초)입니다.
loggerLogger사용자 지정 로거입니다.

여러 MCP 서버를 사용할 때 connectMcpServers를 사용하면 서버를 한 번에 연결하고 실패를 추적하며 한곳에서 종료할 수 있습니다. 이 헬퍼는 active, failed, errors 컬렉션이 포함된 MCPServers 인스턴스를 반환하므로 정상 서버만 에이전트에 전달할 수 있습니다.

여러 MCP 서버 관리
import {
Agent,
MCPServerStreamableHttp,
connectMcpServers,
run,
} from '@openai/agents';
async function main() {
const servers = [
new MCPServerStreamableHttp({
url: 'https://mcp.deepwiki.com/mcp',
name: 'DeepWiki MCP Server',
}),
new MCPServerStreamableHttp({
url: 'http://localhost:8001/mcp',
name: 'Local MCP Server',
}),
];
const mcpServers = await connectMcpServers(servers, {
connectInParallel: true,
});
try {
console.log(`Active servers: ${mcpServers.active.length}`);
console.log(`Failed servers: ${mcpServers.failed.length}`);
for (const [server, error] of mcpServers.errors) {
console.warn(`${server.name} failed to connect: ${error.message}`);
}
const agent = new Agent({
name: 'MCP lifecycle agent',
instructions: 'Use MCP tools to answer user questions.',
mcpServers: mcpServers.active,
});
const result = await run(
agent,
'Which language is the openai/codex repository written in?',
);
console.log(result.finalOutput);
} finally {
await mcpServers.close();
}
}
main().catch(console.error);

사용 사례:

  • 여러 서버 동시 사용: 모든 서버를 병렬로 연결하고 에이전트에 mcpServers.active를 사용합니다.
  • 부분 실패 처리: failed + errors를 검사하고 계속 진행할지 또는 재시도할지 결정합니다.
  • 실패한 서버 재시도: mcpServers.reconnect()를 호출합니다(기본적으로 실패한 서버만 재시도).

엄격한 “전부 아니면 전무” 연결이나 다른 제한 시간이 필요하다면 connectMcpServers(servers, options)를 사용하고 환경에 맞게 옵션을 조정합니다.

connectMcpServers 옵션:

옵션유형기본값참고
connectTimeoutMsnumber | null10000각 서버의 connect() 제한 시간입니다. 비활성화하려면 null을 사용합니다.
closeTimeoutMsnumber | null10000각 서버의 close() 제한 시간입니다. 비활성화하려면 null을 사용합니다.
dropFailedbooleantrue실패한 서버를 active에서 제외합니다.
strictbooleanfalse서버 연결이 하나라도 실패하면 예외를 발생시킵니다.
suppressAbortErrorbooleantrue실패한 서버는 계속 추적하면서 중단과 유사한 오류는 무시합니다.
connectInParallelbooleanfalse서버를 순차적으로 연결하는 대신 모든 서버를 동시에 연결합니다.

mcpServers.reconnect(options) 지원 옵션:

옵션유형기본값참고
failedOnlybooleantrue실패한 서버만 재시도하거나(true) 모든 서버를 다시 연결합니다(false).

다시 연결하기 전에 MCPServers는 선택한 서버를 종료합니다. 성공적으로 종료된 서버만 다시 연결하며, 정리 실패는 failederrors를 통해 계속 확인할 수 있습니다.

런타임에서 Symbol.asyncDispose를 지원하는 경우 MCPServersawait using 패턴을 지원합니다. TypeScript에서는 tsconfig.json에서 esnext.disposable을 활성화합니다.

{
"compilerOptions": {
"lib": ["ES2018", "DOM", "esnext.disposable"]
}
}

그런 다음 다음과 같이 작성할 수 있습니다.

비동기 해제로 연결된 MCP 서버 종료
import { MCPServerStreamableHttp, connectMcpServers } from '@openai/agents';
async function main() {
const servers = [
new MCPServerStreamableHttp({
url: 'https://your-own-domain-here/mcp',
name: 'Docs server',
}),
];
await using mcpServers = await connectMcpServers(servers);
}
main().catch(console.error);

스트리밍 가능한 HTTPStdio 서버의 경우 Agent가 실행될 때마다 사용 가능한 도구를 검색하기 위해 list_tools()를 호출할 수 있습니다. 이 왕복 과정은 특히 원격 서버에서 지연 시간을 늘릴 수 있으므로 MCPServerStdio 또는 MCPServerStreamableHttpcacheToolsList: true를 전달하여 결과를 메모리에 캐시할 수 있습니다.

도구 목록이 변경되지 않는다고 확신할 때만 이 기능을 활성화하세요. 나중에 캐시를 무효화하려면 서버 인스턴스에서 invalidateToolsCache()를 호출합니다. getAllMcpTools(...)를 통해 공유 MCP 도구 캐싱을 사용하는 경우 invalidateServerToolsCache(serverName)으로 서버 이름별 캐시를 무효화할 수도 있습니다.

고급 사용 사례에서는 getAllMcpTools({ generateMCPToolCacheKey })를 사용하여 캐시 분할 방식을 사용자 지정할 수 있습니다(예: 서버 + 에이전트 + 실행 컨텍스트 기준).

기본적으로 로컬 MCP 도구는 MCP 서버가 보고한 도구 이름을 유지합니다. 두 로컬 MCP 서버가 같은 도구 이름을 노출하면 모델이 두 도구 중 하나를 안전하게 선택할 수 없으므로 SDK에서 중복 도구 이름 오류가 발생합니다.

결정론적인 서버 접두사 이름을 사용하려면 에이전트에서 mcpConfig.includeServerInToolNames: true를 설정합니다.

로컬 MCP 도구 이름에 서버 이름 접두사 추가
import { Agent, MCPServerStreamableHttp } from '@openai/agents';
const docsServer = new MCPServerStreamableHttp({
url: 'https://your-own-domain-here/docs/mcp',
name: 'docs',
});
const calendarServer = new MCPServerStreamableHttp({
url: 'https://your-own-domain-here/calendar/mcp',
name: 'calendar',
});
const agent = new Agent({
name: 'Assistant',
mcpServers: [docsServer, calendarServer],
mcpConfig: {
includeServerInToolNames: true,
},
});

이 설정을 사용하면 docs 서버의 search 도구는 모델에 mcp_docs__search로 노출되고, calendar 서버의 search 도구는 mcp_calendar__search로 노출됩니다. SDK는 여전히 원래 서버에서 원래 MCP 도구 이름을 호출합니다.

생성된 이름은 ASCII에 안전하고 FunctionTool 인스턴스의 이름 길이 제한을 준수하며, 동일한 에이전트에 있는 로컬 FunctionTool 인스턴스 또는 활성화된 핸드오프의 이름과 충돌하지 않습니다. 이 설정은 스트리밍 가능한 HTTP, SSE, stdio를 포함한 모든 로컬 MCP 전송 방식에 영향을 줍니다. 호스티드 MCP 도구는 호스티드 서버 레이블과 도구 메타데이터를 유지합니다.

createMCPToolStaticFilter를 통한 정적 필터 또는 사용자 지정 함수를 전달하여 각 서버에서 노출되는 도구를 제한할 수 있습니다. 다음은 두 방식을 모두 보여주는 결합된 예입니다.

도구 필터링
import {
MCPServerStdio,
MCPServerStreamableHttp,
createMCPToolStaticFilter,
MCPToolFilterContext,
} from '@openai/agents';
interface ToolFilterContext {
allowAll: boolean;
}
const server = new MCPServerStdio({
fullCommand: 'my-server',
toolFilter: createMCPToolStaticFilter({
allowed: ['safe_tool'],
blocked: ['danger_tool'],
}),
});
const dynamicServer = new MCPServerStreamableHttp({
url: 'http://localhost:3000',
toolFilter: async ({ runContext }: MCPToolFilterContext, tool) =>
(runContext.context as ToolFilterContext).allowAll || tool.name !== 'admin',
});