모델을 원격 MCP 서버에 연결하거나 Secure MCP Tunnel을 통해 로컬 서버에 연결하세요.
함수 호출로 모델에 도구를 제공하는 것 외에도 원격 MCP 서버 또는 Secure MCP Tunnel을 사용해 모델에 새로운 기능을 추가할 수 있습니다. 이러한 도구를 사용하면 모델이 사용자의 프롬프트에 응답하는 데 필요할 때 외부 서비스에 연결해 작업을 수행할 수 있습니다. 도구 호출을 자동으로 허용하거나 개발자가 명시적으로 승인한 경우에만 허용하도록 설정할 수 있습니다.
Secure MCP Tunnel은 로컬 또는 비공개 MCP 서버를 공개 인터넷에 노출하지 않고 연결합니다.
이 가이드에서는 Responses API에서 MCP 도구를 사용하는 방법을 설명합니다. 기존 모델은 계속 내장 커넥터를 지원합니다. 사용 중단 예정 정책과 호환성 예제는 레거시 커넥터를 참고하세요. Agents API 세션의 경우 MCP 연결에서 관리형 서비스 또는 자체 샌드박스에서 연결하는 방법을 확인하세요.
Secure MCP Tunnel
MCP 서버가 비공개 서버이거나 온프레미스 또는 방화벽 뒤에 있다면 Secure MCP Tunnel을 사용하세요. 서버를 공개 인터넷에 노출하지 않고 지원되는 OpenAI 제품에 연결할 수 있습니다. 최신 공개 릴리스는 openai/tunnel-client에서 다운로드하세요.
빠른 시작
mcp 도구 유형을 Responses API에서 사용하세요. 원격 MCP 서버에 연결하려면 server_url을 설정하고, 로컬 MCP 서버에 연결하려면 tunnel_id를 지정해 Secure MCP Tunnel을 사용하세요. 서버에 따라 authorization 매개변수에 OAuth 액세스 토큰을 제공해야 할 수도 있습니다.
다음 예제에서는 공개 OpenAI 문서 MCP 서버를 사용해 Responses API 출력을 스트리밍하는 방법을 설명하는 문서를 찾습니다. 이 서버는 읽기 전용 문서 도구를 제공하며 인증이 필요하지 않습니다. 예제에서는 공개 문서 검색에 대한 도구 호출 승인을 생략하지만, 민감한 데이터를 공유할 때는 승인을 요구하세요.
Responses API에서 원격 MCP 서버 사용하기
curl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16curlhttps://api.openai.com/v1/responses\-H "Content-Type: application/json"\-H "Authorization: Bearer $OPENAI_API_KEY"\-d '{ "model": "gpt-6-astra", "tools": [ { "type": "mcp", "server_label": "openai_docs", "server_description": "Search and read the public OpenAI documentation.", "server_url": "https://developers.openai.com/mcp", "require_approval": "never" } ], "input": "Search the OpenAI docs for Responses API streaming and return the relevant links." }'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import OpenAI from "openai";const client = new OpenAI();const resp = await client.responses.create({ model: "gpt-6-astra", tools: [ { type: "mcp", server_label: "openai_docs", server_description: "Search and read the public OpenAI documentation.", server_url: "https://developers.openai.com/mcp", require_approval: "never", }, ], input: "Search the OpenAI docs for Responses API streaming and return the relevant links.",});console.log(resp.output_text);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19from openai import OpenAIclient = OpenAI()resp = client.responses.create( model="gpt-6-astra", tools=[ { "type": "mcp", "server_label": "openai_docs", "server_description": "Search and read the public OpenAI documentation.", "server_url": "https://developers.openai.com/mcp", "require_approval": "never", }, ], input="Search the OpenAI docs for Responses API streaming and return the relevant links.",)print(resp.output_text)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27package mainimport ( "context" "fmt" "github.com/openai/openai-go/v3" "github.com/openai/openai-go/v3/responses")func main() { client := openai.NewClient() tool := responses.ToolParamOfMcp("openai_docs") tool.OfMcp.ServerDescription = openai.String("Search and read the public OpenAI documentation.") tool.OfMcp.ServerURL = openai.String("https://developers.openai.com/mcp") tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("never")} response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{ Model: "gpt-6-astra", Tools: []responses.ToolUnionParam{tool}, Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Search the OpenAI docs for Responses API streaming and return the relevant links.")}, }) if err != nil { panic(err) } fmt.Println(response.OutputText())}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24import com.openai.client.OpenAIClient;import com.openai.client.okhttp.OpenAIOkHttpClient;import com.openai.models.responses.ResponseCreateParams;import com.openai.models.responses.Tool;ResponseCreateParams params = ResponseCreateParams.builder() .model("gpt-6-astra") .input( "Search the OpenAI docs for Responses API streaming and return the relevant links.") .addTool( Tool.Mcp.builder() .serverLabel("openai_docs") .serverDescription("Search and read the public OpenAI documentation.") .serverUrl("https://developers.openai.com/mcp") .requireApproval(Tool.Mcp.RequireApproval.McpToolApprovalSetting.NEVER) .build()) .build();client.responses().create(params).output().stream() .flatMap(item -> item.message().stream()) .flatMap(message -> message.content().stream()) .flatMap(content -> content.outputText().stream()) .forEach(text -> System.out.println(text.text()));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19using OpenAI.Responses;#pragma warning disable OPENAI001string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;ResponsesClient client = new(key);CreateResponseOptions options = new() { Model = "gpt-6-astra" };options.Tools.Add( ResponseTool.CreateMcpTool( serverLabel: "openai_docs", serverUri: new Uri("https://developers.openai.com/mcp"), toolCallApprovalPolicy: DefaultMcpToolCallApprovalPolicy.NeverRequireApproval ));options.InputItems.Add(ResponseItem.CreateUserMessageItem("Search the OpenAI docs for Responses API streaming and return the relevant links."));ResponseResult response = await client.CreateResponseAsync(options);Console.WriteLine(response.GetOutputText());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19require "openai"openai = OpenAI::Client.newresponse = openai.responses.create( model: "gpt-6-astra", tools: [ { type: "mcp", server_label: "openai_docs", server_description: "Search and read the public OpenAI documentation.", server_url: "https://developers.openai.com/mcp", require_approval: "never" } ], input: "Search the OpenAI docs for Responses API streaming and return the relevant links.")puts(response.output_text)
Responses API에는 신뢰할 수 있는 원격 MCP 서버만 연결하세요. 악성 서버는 모델의 컨텍스트에 들어오는 모든 내용에서 민감한 데이터를 빼낼 수 있습니다.
이 도구를 사용하기 전에 아래의 위험 및 안전 섹션을 주의 깊게 검토하세요.
API는 모델 응답의 output 배열에 새 항목을 반환합니다. 모델이 MCP 서버를 사용하기로 결정하면 먼저 서버에 사용 가능한 도구 목록을 요청합니다. 이때 mcp_list_tools 출력 항목이 생성됩니다. 아래 예시 출력에는 검색 도구만 표시했으며 도구 설명도 줄였습니다. 서버는 다른 문서 도구도 제공합니다.
아래에서 MCP 도구의 작동 방식, 사용 가능한 도구를 필터링하는 방법, 도구 호출 승인 요청을 처리하는 방법을 자세히 살펴보세요.
작동 방식
대부분의 최신 모델은 Responses API에서 MCP 도구를 지원합니다. 사용하는 모델이 MCP 도구와 호환되는지는 모델 목록에서 확인하세요. MCP 도구를 사용할 때는 도구 정의를 가져오거나 도구를 호출하는 데 사용한 토큰에 대해서만 요금이 부과됩니다. 도구 호출당 추가 요금은 없습니다.
API가 MCP 도구를 호출하는 과정을 단계별로 살펴보겠습니다.
1단계: 사용 가능한 도구 목록 가져오기
tools 매개변수에 원격 MCP 서버를 지정하면 API가 서버에 도구 목록을 요청합니다. Responses API는 Streamable HTTP 또는 HTTP/SSE 전송 프로토콜을 지원하는 원격 MCP 서버와 연동됩니다.
도구 목록을 가져오는 데 성공하면 모델 응답 출력에 새 mcp_list_tools 항목이 나타납니다. 이 객체의 tools 속성에서 성공적으로 가져온 도구를 확인할 수 있습니다. 아래 예시에는 검색 도구만 표시했으며 도구 설명도 줄였습니다.
API 요청의 컨텍스트에 mcp_list_tools 항목이 있으면 API는 대화의 각 턴에서 MCP 서버에 도구 목록을 다시 요청하지 않습니다.
지연 시간을 줄이려면 대화나 워크플로우를 실행할 때마다 모델의 컨텍스트에 이 항목을 유지하는 것이 좋습니다.
도구 필터링
MCP 서버에 따라 수십 개의 도구를 제공하기도 합니다. 모델에 많은 도구를 제공하면 비용이 늘고 지연 시간이 길어질 수 있습니다. MCP 서버가 제공하는 도구 중 일부만 필요하다면 allowed_tools 매개변수를 사용해 해당 도구만 가져올 수 있습니다. 이 예제에서는 문서 링크를 찾는 데 필요한 search_openai_docs만 가져옵니다.
허용할 도구 제한하기
curl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17curlhttps://api.openai.com/v1/responses\-H "Content-Type: application/json"\-H "Authorization: Bearer $OPENAI_API_KEY"\-d '{ "model": "gpt-6-astra", "tools": [ { "type": "mcp", "server_label": "openai_docs", "server_description": "Search and read the public OpenAI documentation.", "server_url": "https://developers.openai.com/mcp", "require_approval": "never", "allowed_tools": ["search_openai_docs"] } ], "input": "Search the OpenAI docs for Responses API streaming and return the relevant links." }'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import OpenAI from "openai";const client = new OpenAI();const resp = await client.responses.create({ model: "gpt-6-astra", tools: [ { type: "mcp", server_label: "openai_docs", server_description: "Search and read the public OpenAI documentation.", server_url: "https://developers.openai.com/mcp", require_approval: "never", allowed_tools: ["search_openai_docs"], }, ], input: "Search the OpenAI docs for Responses API streaming and return the relevant links.",});console.log(resp.output_text);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20from openai import OpenAIclient = OpenAI()resp = client.responses.create( model="gpt-6-astra", tools=[ { "type": "mcp", "server_label": "openai_docs", "server_description": "Search and read the public OpenAI documentation.", "server_url": "https://developers.openai.com/mcp", "require_approval": "never", "allowed_tools": ["search_openai_docs"], } ], input="Search the OpenAI docs for Responses API streaming and return the relevant links.",)print(resp.output_text)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26import com.openai.client.OpenAIClient;import com.openai.client.okhttp.OpenAIOkHttpClient;import com.openai.models.responses.ResponseCreateParams;import com.openai.models.responses.Tool;import java.util.List;ResponseCreateParams params = ResponseCreateParams.builder() .model("gpt-6-astra") .input( "Search the OpenAI docs for Responses API streaming and return the relevant links.") .addTool( Tool.Mcp.builder() .serverLabel("openai_docs") .serverDescription("Search and read the public OpenAI documentation.") .serverUrl("https://developers.openai.com/mcp") .requireApproval(Tool.Mcp.RequireApproval.McpToolApprovalSetting.NEVER) .allowedToolsOfMcp(List.of("search_openai_docs")) .build()) .build();client.responses().create(params).output().stream() .flatMap(item -> item.message().stream()) .flatMap(message -> message.content().stream()) .flatMap(content -> content.outputText().stream()) .forEach(text -> System.out.println(text.text()));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20using OpenAI.Responses;#pragma warning disable OPENAI001string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;ResponsesClient client = new(key);CreateResponseOptions options = new() { Model = "gpt-6-astra" };options.Tools.Add( ResponseTool.CreateMcpTool( serverLabel: "openai_docs", serverUri: new Uri("https://developers.openai.com/mcp"), allowedTools: new McpToolFilter() { ToolNames = { "search_openai_docs" } }, toolCallApprovalPolicy: DefaultMcpToolCallApprovalPolicy.NeverRequireApproval ));options.InputItems.Add(ResponseItem.CreateUserMessageItem("Search the OpenAI docs for Responses API streaming and return the relevant links."));ResponseResult response = await client.CreateResponseAsync(options);Console.WriteLine(response.GetOutputText());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20require "openai"client = OpenAI::Client.newresponse = client.responses.create( model: "gpt-6-astra", input: "Search the OpenAI docs for Responses API streaming and return the relevant links.", tools: [ { type: :mcp, server_label: "openai_docs", server_description: "Search and read the public OpenAI documentation.", server_url: "https://developers.openai.com/mcp", require_approval: :never, allowed_tools: ["search_openai_docs"] } ])puts(response.output_text)
2단계: 도구 호출하기
모델은 도구 정의에 액세스할 수 있게 되면 컨텍스트에 따라 도구 호출 여부를 결정합니다. 모델이 MCP 도구를 호출하기로 결정하면 API는 원격 MCP 서버에 도구 호출을 요청하고 출력을 모델의 컨텍스트에 추가합니다. 이때 mcp_call 항목이 생성됩니다. 아래 예시 출력에서는 검색 결과의 메타데이터를 생략했습니다.
이 항목에는 모델이 도구 호출에 사용하기로 한 인수와 원격 MCP 서버가 반환한 output이 모두 포함됩니다. 모든 모델은 MCP 도구를 여러 번 호출할 수 있으므로 한 번의 API 요청에서 이러한 항목이 여러 개 생성될 수 있습니다.
도구 호출이 실패하면 이 항목의 error 필드에 MCP 프로토콜 오류, MCP 도구 실행 오류 또는 일반 연결 오류가 기록됩니다. MCP 오류에 대한 설명은 MCP 사양의 오류 처리 섹션을 참고하세요.
승인
기본적으로 OpenAI는 커넥터나 원격 MCP 서버와 데이터를 공유하기 전에 개발자에게 승인을 요청합니다. 승인 절차를 사용하면 MCP 서버로 전송되는 데이터를 확인하고 제어할 수 있습니다. 원격 MCP 서버와 공유하는 모든 데이터를 주의 깊게 검토하고 필요하면 로그에 기록할 것을 강력히 권장합니다. 승인 플로우를 시험하려면 빠른 시작 예제의 require_approval을 "always"로 설정해 실행하세요. 예제의 기존 설정값은 "never"입니다. MCP 도구 호출에 대한 승인을 요청하면 Response 객체의 출력에 mcp_approval_request 항목이 생성됩니다. 다음은 그 예시입니다.
승인하기 전에 호출하려는 도구와 인수를 검토하세요. 그런 다음 새 Response 객체를 만들고 mcp_approval_response 항목을 추가해 응답할 수 있습니다. 다음 예제의 응답 ID와 승인 요청 ID를 실제 요청에서 반환된 ID로 바꾸세요. .NET 예제는 첫 번째 응답에서 이 ID들을 가져옵니다. 승인 한 건은 도구 호출 한 번에만 적용됩니다. 이후의 승인 요청도 같은 방식으로 처리하세요.
여기서는 previous_response_id 매개변수를 사용해 새 Response 객체를 승인 요청이 생성된 이전 Response 객체와 연결합니다. 모델의 컨텍스트에 들어가는 내용을 직접 세밀하게 제어하려면 한 응답의 출력을 다른 응답의 입력으로 전달할 수도 있습니다.
원격 MCP 서버를 충분히 신뢰할 수 있다고 판단하면 승인을 생략해 지연 시간을 줄일 수 있습니다. 아래와 같이 MCP 도구의 require_approval 매개변수에 승인을 생략할 도구만 나열한 객체를 지정하세요. 해당 원격 MCP 서버의 모든 도구에 대해 승인을 생략하려면 값을 'never'로 설정하세요.
민감한 토큰의 유출을 방지하기 위해 Responses API는 authorization 필드에 제공된 값을 저장하지 않습니다. 생성된 Response 객체에도 이 값이 표시되지 않습니다. 따라서 Responses API에 응답 생성을 요청할 때마다 authorization 값을 보내야 합니다.
레거시 커넥터
connector_id는 2026년 9월 1일이 지난 뒤 출시된 모델에서 사용 중단 예정(deprecated)입니다.
원격 MCP 서버에 연결하려면 server_url을 사용하세요. 로컬 MCP 서버에 연결하려면
tunnel_id를 지정해
Secure MCP Tunnel을 사용하세요. 기존 모델은 계속 커넥터를 지원합니다.
이 섹션의 예제에서는 기준일 전에 출시된 gpt-5.2를 사용합니다.
Responses API는 일부 타사 서비스용 커넥터를 기본 제공합니다. 이러한 커넥터를 사용하면 Dropbox, Gmail 등 널리 쓰이는 애플리케이션에서 컨텍스트를 가져와 모델이 해당 서비스와 상호작용하도록 할 수 있습니다.
커넥터는 원격 MCP 서버와 같은 방식으로 사용할 수 있습니다. 두 방식 모두 API 요청에서 OpenAI 모델이 타사 도구를 추가로 사용할 수 있게 합니다. 다만 원격 MCP 서버를 호출할 때는 server_url을 전달하지만, 커넥터를 사용할 때는 API에서 해당 커넥터를 고유하게 식별하는 connector_id를 전달합니다.
Step 1: Select and authorize APIs에서 이 권한 범위를 입력하면 API가 Google Calendar 일정을 읽을 수 있습니다.
Google 계정으로 애플리케이션에 권한을 부여하면 Step 2: Exchange authorization code for tokens 단계로 이동합니다. 여기에서 승인 코드를 토큰으로 교환하면 Google Calendar 커넥터를 사용하는 API 요청에 전달할 액세스 토큰이 생성됩니다.
Google Calendar 커넥터 사용하기
curl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16curlhttps://api.openai.com/v1/responses\-H"Content-Type: application/json"\-H"Authorization: Bearer $OPENAI_API_KEY"\-d'{ "model": "gpt-5.2", "tools": [ { "type": "mcp", "server_label": "google_calendar", "connector_id": "connector_googlecalendar", "authorization": "ya29.A0AS3H6...", "require_approval": "never" } ], "input": "What is on my Google Calendar for today?" }'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18import OpenAI from "openai";const client = new OpenAI();const resp = await client.responses.create({ model: "gpt-5.2", tools: [ { type: "mcp", server_label: "google_calendar", connector_id: "connector_googlecalendar", authorization: "ya29.A0AS3H6...", require_approval: "never", }, ], input: "What's on my Google Calendar for today?",});console.log(resp.output_text);
사용 가능한 도구는 OAuth 토큰에 부여된 권한 범위에 따라 달라집니다. 아래 표를 펼쳐 각 애플리케이션에 연결했을 때 사용할 수 있는 도구를 확인하세요.
도구
설명
권한 범위
search
Dropbox에서 쿼리와 일치하는 파일 검색
files.metadata.read, account_info.read
fetch
경로로 파일 가져오기(원본 다운로드 선택 가능)
files.content.read
search_files
Dropbox 파일을 검색하고 결과 반환
files.metadata.read, account_info.read
fetch_file
파일의 텍스트 또는 원본 콘텐츠 가져오기
files.content.read, account_info.read
list_recent_files
사용자가 액세스할 수 있는 파일 중 가장 최근에 수정된 파일 반환
files.metadata.read, account_info.read
get_profile
현재 사용자의 Dropbox 프로필 가져오기
account_info.read
도구
설명
권한 범위
get_profile
현재 Gmail 사용자의 프로필 반환
userinfo.email, userinfo.profile
search_emails
Gmail에서 쿼리 또는 라벨과 일치하는 이메일 검색
gmail.modify
search_email_ids
검색 조건과 일치하는 Gmail 메시지 ID 가져오기
gmail.modify
get_recent_emails
가장 최근에 받은 Gmail 메시지 반환
gmail.modify
read_email
본문을 포함한 Gmail 메시지 한 건 가져오기
gmail.modify
batch_read_email
한 번의 호출로 Gmail 메시지 여러 건 읽기
gmail.modify
도구
설명
권한 범위
get_profile
현재 Google Calendar 사용자의 프로필 반환
userinfo.email, userinfo.profile
search
Google Calendar 일정 검색(기간 지정 가능)
calendar.events
fetch
일정 한 건의 세부 정보 가져오기
calendar.events
search_events
필터로 일정 조회
calendar.events
read_event
ID로 Google Calendar 일정 읽기
calendar.events
도구
설명
권한 범위
get_profile
현재 Drive 사용자의 프로필 반환
userinfo.email, userinfo.profile
list_drives
사용자가 액세스할 수 있는 공유 드라이브 목록 조회
drive.readonly
search
쿼리로 Drive 파일 검색
drive.readonly
recent_documents
가장 최근에 수정된 문서 반환
drive.readonly
fetch
Drive 파일의 콘텐츠 다운로드
drive.readonly
도구
설명
권한 범위
search
Microsoft Teams 채팅 및 채널 메시지 검색
Chat.Read, ChannelMessage.Read.All
fetch
경로로 Teams 메시지 가져오기
Chat.Read, ChannelMessage.Read.All
get_chat_members
Teams 채팅 참여자 목록 조회
Chat.Read
get_profile
인증된 Teams 사용자의 프로필 반환
User.Read
도구
설명
권한 범위
search_events
날짜 필터로 Outlook 일정 검색
Calendars.Read
fetch_event
일정 한 건의 세부 정보 가져오기
Calendars.Read
fetch_events_batch
한 번의 호출로 일정 여러 건 가져오기
Calendars.Read
list_events
지정한 기간의 일정 목록 조회
Calendars.Read
get_profile
현재 사용자의 프로필 가져오기
User.Read
도구
설명
권한 범위
get_profile
Outlook 계정의 프로필 정보 반환
User.Read
list_messages
폴더에서 Outlook 이메일 가져오기
Mail.Read
search_messages
Outlook 이메일 검색(필터 지정 가능)
Mail.Read
get_recent_emails
가장 최근에 받은 이메일 반환
Mail.Read
fetch_message
ID로 이메일 한 건 가져오기
Mail.Read
fetch_messages_batch
한 번의 요청으로 이메일 여러 건 가져오기
Mail.Read
도구
설명
권한 범위
get_site
호스트 이름과 경로로 SharePoint 사이트 찾기
Sites.Read.All
search
키워드로 SharePoint 및 OneDrive 문서 검색
Sites.Read.All, Files.Read.All
list_recent_documents
최근에 액세스한 문서 반환
Files.Read.All
fetch
Graph 파일 다운로드 URL에서 콘텐츠 가져오기
Files.Read.All
get_profile
현재 사용자의 프로필 가져오기
User.Read
MCP 서버의 도구를 필요할 때 로드하기
도구 검색을 사용하면 모델이 필요하다고 판단할 때까지 MCP 서버가 제공하는 함수의 로드를 미룰 수 있습니다. MCP 서버의 도구 정의에 defer_loading: true를 설정하세요.
로드를 미뤄도 모델은 MCP 서버의 라벨과 설명을 보고 해당 서버를 언제 검색할지 판단할 수 있습니다. 개별 함수 정의는 필요할 때만 로드됩니다. 이렇게 하면 전체 토큰 사용량을 줄일 수 있으며, 특히 많은 함수를 제공하는 MCP 서버에 유용합니다.
1
2
3
4
5
6
7
8{"type": "mcp","server_label": "openai_docs","server_description": "Search and read the public OpenAI documentation.","server_url": "https://developers.openai.com/mcp","defer_loading": true,"require_approval": "never"}
위험 및 안전
MCP 도구를 사용하면 OpenAI 모델을 외부 서비스에 연결할 수 있습니다. 강력한 기능인 만큼 위험도 따릅니다.
커넥터를 사용하면 민감한 데이터가 OpenAI로 전송되거나 모델이 해당 서비스에서 민감한 정보를 읽을 수 있게 될 위험이 있습니다.
원격 MCP 서버에도 같은 위험이 있으며, OpenAI는 이러한 서버를 검증하지 않았습니다. 원격 MCP 서버는 모델이 해당 서비스의 데이터에 액세스하고 데이터를 주고받거나 작업을 수행하도록 허용할 수 있습니다. 모든 MCP 서버는 자체 이용약관이 적용되는 타사 서비스입니다.
악성 MCP 서버를 발견하면 security@openai.com으로 신고하세요.
커넥터와 원격 MCP 서버를 연동할 때는 다음 권장 사항을 고려하세요.
프롬프트 인젝션
프롬프트 인젝션은 모든 LLM 애플리케이션에서 중요하게 고려해야 할 보안 위협입니다. 특히 민감한 데이터에 액세스하거나 작업을 수행할 수 있는 MCP 서버와 커넥터를 모델에 연결할 때는 각별한 주의가 필요합니다. 모델의 프롬프트에 사용자가 제공한 콘텐츠가 포함된다면 적절한 보호 조치를 마련하고 신중하게 도구를 사용하세요.
예를 들어 웹 페이지에 모델이 CRM에서 고객을 조회한 뒤 그 고객의 이메일 주소를 URL에 넣도록 지시하는 내용이 있을 수 있습니다. CRM 도구가 읽기 전용이어도 해당 URL로 요청을 보내면 고객의 이메일 주소가 노출됩니다.
회사가 공개한 발표 내용과 비공개 CRM 기록을 비교하려면 첫 번째 요청에서는 웹 검색만 활성화해 공개된 사실을 수집하세요. 그중 비교에 필요한 사실을 두 번째 요청에 전달하고, 이 요청에서는 내부 CRM 검색 도구만 사용할 수 있도록 제한하세요. 이렇게 하면 고객 기록이 웹 검색어나 URL에 포함되지 않습니다.
민감한 작업에는 항상 승인 요구하기
require_approval과 allowed_tools 매개변수를 설정해 모든 민감한 작업이 승인 절차를 거치도록 하세요.
MCP 도구 호출과 출력에 포함된 URL
커넥터나 원격 MCP 서버의 도구 호출 출력에 포함된 URL로 요청을 보내거나 이미지 URL을 삽입하는 것은 위험할 수 있습니다. 애플리케이션 코드에 URL을 삽입하거나 다른 용도로 사용하기 전에 해당 URL을 제공하는 도메인과 서비스를 신뢰할 수 있는지 확인하세요.
신뢰할 수 있는 서버에 연결하기
서비스 제공업체가 직접 호스팅하는 공식 서버를 선택하세요. 예를 들어 Stripe에 연결할 때는 타사가 호스팅하는 Stripe MCP 서버 대신 Stripe가 mcp.stripe.com에서 호스팅하는 서버를 사용하는 것이 좋습니다. 아직 공식 원격 MCP 서버가 많지 않아 해당 서비스를 직접 운영하지 않는 조직이 호스팅하는 MCP 서버를 고려할 수도 있습니다. 이런 서버는 개발자의 API를 통해 해당 서비스로 요청을 중계합니다. 꼭 사용해야 한다면 이러한 ‘중계 업체’를 특히 철저히 검증하고 데이터를 어떻게 사용하는지 꼼꼼하게 검토하세요.
타사 MCP 서버와 공유하는 데이터 기록 및 검토하기
MCP 서버는 자체적으로 도구를 정의하므로 서버 운영자와 공유하기 곤란한 데이터를 요청할 수도 있습니다. 이 때문에 Responses API의 MCP 도구는 기본적으로 MCP 도구를 호출할 때마다 승인을 요구합니다. 애플리케이션을 개발할 때는 MCP 서버와 어떤 종류의 데이터를 공유하는지 철저히 검토하세요. 서버를 충분히 신뢰할 수 있게 되면 승인을 생략해 실행 지연 시간을 줄일 수 있습니다.
MCP 서버로 전송하는 모든 데이터를 로그에 기록하는 것도 권장합니다. Responses API를 store=true로 사용하는 경우, 조직에서 데이터 비보관을 활성화하지 않았다면 API가 이 데이터를 로그에 기록해 30일간 보관합니다. 자체 시스템에도 데이터를 기록하고 주기적으로 검토해 예상한 대로 데이터가 공유되는지 확인할 수 있습니다.
악성 MCP 서버는 OpenAI 모델이 예상과 다르게 동작하도록 유도하는 숨겨진 지시(프롬프트 인젝션)를 포함할 수 있습니다. OpenAI는 이러한 위협을 탐지하고 차단하는 데 도움이 되는 보호 기능을 기본 제공하지만, 입력과 출력을 주의 깊게 검토하고 신뢰할 수 있는 서버에만 연결해야 합니다.
MCP 서버가 예고 없이 도구의 동작을 변경하면 의도하지 않은 동작이나 악의적인 동작이 발생할 수 있습니다.
데이터 비보관 및 데이터 레지던시에 미치는 영향
MCP 도구는 데이터 비보관 및 데이터 레지던시와 호환됩니다. 다만 MCP 서버는 타사 서비스이므로 MCP 서버로 전송한 데이터에는 해당 서비스의 데이터 보존 정책과 데이터 레지던시 정책이 적용됩니다.
예를 들어 조직의 데이터 레지던시가 유럽으로 설정되어 있다면 OpenAI는 MCP 서버에 메시지나 데이터를 보내기 전까지 고객 콘텐츠에 대한 추론과 저장을 유럽 내로 제한합니다. MCP 서버도 조직의 데이터 비보관 또는 데이터 레지던시 요건을 준수하는지 확인할 책임은 해당 조직에 있습니다. 데이터 비보관과 데이터 레지던시에 대한 자세한 내용은 데이터 가이드를 참고하세요.