OpenAI Responses API는 remote MCP 서버와 connector를 mcp built-in tool로 연결할 수 있습니다. 이 기능은 모델이 외부 서비스의 도구를 호출하게 만드는 강력한 방식입니다. 하지만 강력한 만큼 위험합니다. MCP 서버가 무엇을 할 수 있는지, 어떤 데이터가 넘어가는지, 승인을 어디서 받을지 설계하지 않으면 보안 사고로 이어질 수 있습니다.
MCP는 Model Context Protocol의 약자입니다. 간단히 말하면 모델이 외부 도구 목록을 읽고, 필요한 도구를 호출하고, 결과를 다시 컨텍스트로 받는 표준 인터페이스입니다. OpenAI 문서에서는 remote MCP server와 Google Workspace, Dropbox 같은 connector를 같은 tool 타입으로 다룰 수 있다고 설명합니다.
기존 function calling은 개발자가 함수 schema를 직접 정의하고 실행도 직접 처리하는 방식입니다. 단순하고 통제하기 좋지만, 연결할 서비스가 많아질수록 서버 코드가 복잡해집니다. 반면 remote MCP는 도구 정의와 실행을 MCP 서버가 제공합니다. 모델은 서버에서 tool list를 가져오고, 필요한 tool을 호출합니다.
예를 들어 사내 문서 검색, 이슈 트래커 조회, 결제 링크 생성, CRM 업데이트 같은 기능을 각각 function으로 구현하지 않고 MCP 서버로 노출할 수 있습니다. 여러 모델/클라이언트가 같은 MCP 서버를 공유할 수도 있습니다.
하지만 이 장점은 곧 위험이 됩니다. MCP 서버가 신뢰할 수 없다면 모델 컨텍스트에 들어간 민감한 정보가 외부로 전송될 수 있습니다. OpenAI 문서도 remote MCP 서버를 신뢰해야 하며, 악의적 서버가 모델 컨텍스트의 민감한 데이터를 exfiltrate할 수 있다고 경고합니다.
Responses API에서 MCP tool을 지정하면 API는 MCP 서버에서 사용 가능한 도구 목록을 가져옵니다. 성공하면 mcp_list_tools output item이 생기고, 도구 이름, 설명, input_schema 같은 정보가 포함됩니다. 문서에 따르면 이 item이 컨텍스트에 남아 있으면 매 turn마다 도구 목록을 다시 가져오지 않아도 됩니다.
실무에서는 이 점이 중요합니다. tool list 요청이 매번 발생하면 latency와 비용이 늘어납니다. 특히 MCP 서버가 도구를 수십 개 노출하거나 인증이 필요한 경우 첫 응답 시간이 길어질 수 있습니다. 따라서 대화형 워크플로우에서는 mcp_list_tools 결과를 다음 요청의 컨텍스트에 유지하는 전략을 써야 합니다.
다만 tool list도 버전 관리가 필요합니다. MCP 서버가 schema를 바꿨는데 오래된 list를 계속 쓰면 호출 실패가 납니다. 서버 배포 버전, tool schema hash, 마지막 갱신 시간을 함께 저장하고, 변경 시 새로 가져오도록 설계하세요.
MCP 서버가 도구를 많이 제공한다고 해서 모두 모델에게 보여줄 필요는 없습니다. OpenAI 문서에는 allowed_tools로 관심 있는 도구만 import하는 예시가 나옵니다. 이 설정은 비용, 지연시간, 안전성 모두에 영향을 줍니다.
모델에게 도구가 많을수록 선택 공간이 커집니다. 비슷한 이름의 도구가 있으면 잘못 고를 가능성도 생깁니다. 또한 각 tool definition은 토큰을 사용합니다. 도구가 많으면 프롬프트가 무거워지고 응답도 느려집니다.
실무 기준은 workflow별 allowlist입니다. 예를 들어 결제 링크 생성 워크플로우라면 create_payment_link, get_customer, list_products 정도만 열고, refund_payment, delete_customer, update_bank_account 같은 도구는 제외해야 합니다. 읽기 도구와 쓰기 도구를 같은 범위에 넣는 것도 피하는 편이 좋습니다.
MCP tool call에는 승인 흐름이 있습니다. 기본적으로 OpenAI는 connector나 remote MCP 서버로 데이터가 공유되기 전에 개발자 승인을 요청합니다. 승인 요청은 mcp_approval_request item으로 나타나고, 개발자는 이후 응답에 mcp_approval_response를 붙여 승인 또는 거절할 수 있습니다.
운영에서 중요한 것은 require_approval을 무조건 never로 두지 않는 것입니다. 신뢰하는 서버라 하더라도 모든 도구가 같은 위험도를 갖지 않습니다.
권장 분류는 다음과 같습니다.
승인 UI에는 도구 이름만 보여주면 부족합니다. 모델이 보낼 arguments, 대상 서비스, 사용자에게 미칠 영향, 민감 데이터 포함 여부를 함께 보여줘야 합니다. 개발자용 내부 도구라면 JSON arguments 전체를 보여주는 편이 낫고, 일반 사용자용 제품이라면 사람이 이해할 수 있는 문장으로 변환해야 합니다.
대부분의 MCP 서버는 인증이 필요합니다. OpenAI 문서는 OAuth access token을 authorization 필드로 전달하는 방식을 설명하며, 이 값은 Responses API에 저장되지 않고 Response 객체에도 노출되지 않는다고 안내합니다. 따라서 필요한 경우 매 요청마다 authorization 값을 다시 보내야 합니다.
이 설계는 안전하지만 구현 실수를 부릅니다. 토큰이 없으면 tool call이 실패하고, 오래된 토큰이면 승인 후에도 실패합니다. 제품 서버는 MCP 호출 전 토큰 유효성을 확인하거나, 실패 시 refresh token으로 갱신하는 흐름을 가져야 합니다.
절대 하면 안 되는 것은 토큰을 모델 입력 텍스트에 넣는 것입니다. 토큰은 tool 설정의 authorization 필드로 전달해야 하며, 로그에도 남기면 안 됩니다. 운영 로그에는 token 존재 여부, 만료 시간, scope 정도만 남기세요.
MCP call 실패는 여러 층에서 발생합니다. 서버 연결 실패, tool list 실패, schema mismatch, 인증 실패, approval 거절, tool 실행 오류, 모델의 잘못된 arguments가 모두 다릅니다. 하나로 묶어 “AI가 실패했습니다”라고 표시하면 디버깅이 어렵습니다.
로그와 사용자 메시지는 층을 나눠야 합니다.
이 분류가 있어야 재시도 전략도 세울 수 있습니다. 인증 실패는 토큰 갱신 후 재시도할 수 있고, schema 오류는 개발자가 고쳐야 하며, 승인 거절은 재시도하면 안 됩니다.
사내 MCP 서버를 공개 인터넷에 직접 노출하는 것은 조심해야 합니다. OpenAI 문서는 private, on-premises, firewall 뒤의 MCP 서버에는 Secure MCP Tunnel을 사용할 수 있다고 안내합니다. 공개 endpoint가 꼭 필요하지 않다면 터널 또는 별도 게이트웨이를 통해 접근을 제한하는 편이 안전합니다.
또한 MCP 서버 자체에서도 권한 검사를 해야 합니다. 모델 호출 쪽에서 allowed_tools를 제한하더라도 서버는 최종 방어선이어야 합니다. 사용자 id, 조직 id, scope, row-level permission을 서버에서 확인해야 합니다. 모델이 “이 사용자 데이터 조회해줘”라고 요청해도 서버가 권한 없는 데이터는 반환하지 않아야 합니다.
allowed_tools를 설정해 도구 노출 범위를 줄였는가출처: OpenAI API MCP and Connectors 문서, Responses API remote MCP examples.