검색
← 모듈 로드맵

Claude Code·Codex의 MCP 호환성 비교

발행 출처 m3.sineframe.com · stag

클로드 코드비교전문가

나중에 보기좋아요
공유 · 인쇄
후기댓글

우리는 같은 10개의 MCP 서버를 대상으로 Claude Code와 Codex를 실행해 보았습니다. 10개 기능 중 5개는 한 에이전트에서는 동작하고 다른 에이전트에서는 실패했으며, 두 에이전트가 같은 기능에서 동시에 실패한 적은 없었습니다.

MCP 서버를 배포한다면, 아마 이런 문제를 본 적이 있을 것입니다: “Claude Code에 도구가 나타나지 않는다” 또는 “Codex가 잘못된 인자를 보낸다.” 우리가 시작할 당시 에이전트 저장소 전반에 이런 이슈가 약 28개 열려 있었습니다. 어느 에이전트의 어느 버전이 어떤 MCP 기능에서 깨지는지 알려 주는 것은 하나도 없었습니다.

그래서 우리는 그런 표를 만들었습니다. 우리는 이것을 Harness Quirks Matrix라고 부르며, M3 위에서 동작합니다. M3는 MCP 서버를 테스트하고 그것을 사용하는 에이전트를 테스트하기 위한 오픈소스 도구입니다.

결과: 10개 MCP 기능 중 5개가 에이전트를 갈랐다

2026년 10월 9일, 우리는 Claude Code 2.1.287(claude-sonnet-5-5)과 Codex 0.162.0(gpt-5.6-sol)에 대해 10개의 MCP 기능을 각각 3회씩 실행했습니다. Claude Code는 그중 3개 기능에서 실패했고, Codex는 나머지 2개 기능에서 실패했습니다.

MCP 기능Claude Code 2.1.287Codex 0.162.0
도구 인자에 ids[]라는 이름이 있음0/3회 누락3/3회 동작
12,000자짜리 도구 오류의 중간에 마커가 있음결과가 0/3회 소실됨3/3회 동작
content와 structuredContent를 모두 가진 결과결과가 0/3회 소실됨3/3회 동작
도구 목록 변경 후 새 도구가 추가됨3/3회 동작0/3회 누락
14 KB 입력 스키마에 중첩된 필수 필드가 있음3/3회 동작0/3회 누락
inputSchema의 루트 수준 anyOf3/3회 동작3/3회 동작
outputSchema가 draft-07을 선언함3/3회 동작3/3회 동작
기본값이 있는 선택적 매개변수를 생략함3/3회 동작3/3회 동작
전체 이름 길이가 65자인 도구3/3회 동작3/3회 동작
결과에 resource_link 블록이 있음3/3회 동작3/3회 동작

2026년 10월 9일 M3로 측정. 셀마다 3회씩 시험했으며, 호출이 예상한 인자와 함께 서버에 도달했고 결과가 답변까지 도달했을 때만 셀이 통과합니다. MCP 서버를 관리한다면, 다음 5개 실패가 무엇을 의미하는지 알 수 있습니다.

Claude Code는 입력 속성 이름이 ids[]인 도구를 절대 호출하지 않습니다. 오류도 표시하지 않고, 도구는 그냥 존재하지 않는 것처럼 됩니다. OpenAPI로 생성된 서버는 종종 이런 이름을 만듭니다.

또한 Claude Code는 도구 오류의 앞뒤 약 5,000자만 유지하므로, 중간에 있는 내용은 모델에 도달하지 않습니다. 오류 메시지의 맨 앞에 코드, 원인, 다음 단계를 넣으십시오. 그리고 결과에 content와 structuredContent가 함께 있으면, 모델은 구조화된 값을 보고 텍스트 값은 잃어버렸습니다.

Codex는 서버가 새 도구를 알린 뒤에도 오래된 도구 목록을 계속 사용했기 때문에, 새 도구를 호출하지 못했습니다. 또한 큰 입력 스키마를 예산에 맞추기 위해 압축하는데, 우리의 14 KB 스키마에서는 필요한 중첩 필드도 함께 사라졌습니다. Codex의 서버당 스키마 예산을 20,000으로 늘리자 호출이 복구되었습니다.

각 결과는 고정된 버전의 하나의 클라이언트와 모델 조합을 다루며, 명시적인 프롬프트를 사용합니다. 실패한 셀은 데이터가 서버에서 모델의 답변까지 전달되지 않았음을 의미할 뿐, 어느 계층에서 사라졌는지는 알려 주지 않습니다. 각 셀에는 실행 매니페스트, 바이너리 SHA-256, 와이어 트레이스가 함께 저장됩니다.

직접 프로브에서 발견한 8개의 추가 실패

우리는 M3 없이 Claude Code와 Codex 바이너리를 직접 프로브해서, 적어도 한쪽에서 실패하는 기능 8개를 더 발견했습니다. 아직 어느 것도 M3를 거치지는 않았으므로, 그때까지는 잠정적인 단서로 보아야 합니다.

MCP 기능Claude Code 2.1.295Codex 0.162.0
properties 옆에 있는 루트 oneOf동작속성 이름이 사라짐
한 서버에 도구 2,049개동작2,048개를 넘는 도구는 누락됨
루트 type이 없는 도구 1개전체 서버가 누락됨동작
int64 인자 1234567890123456789반올림됨문자열이거나 반올림됨
anyOf 안의 Enum, 5 KB가 넘는 스키마동작enum이 지워짐
prefixItems 튜플동작Array<string>로 선언됨
한 서버에 fetch.page와 fetch_page가 있음하나가 잘못 라우팅됨동작
outputSchema가 선언되어 있고 텍스트만 있는 결과성공이 오류로 바뀜동작

M3 없이 각 에이전트 바이너리를 직접 프로브한 결과입니다. 아직 M3 아래에서는 측정되지 않았습니다. 이 프로브는 오래된 용의자 몇 가지도 해소했습니다. 현재 버전에서는 Claude Code의 루트 anyOf 문제와 65자 이름 문제는 더 이상 재현되지 않으며, Codex의 resource_link 처리도 마찬가지로 재현되지 않으므로, 서버 작성자는 해당 우회책을 제거해도 됩니다.

M3가 각 셀을 실행하는 방법

각 셀은 M3가 실제 에이전트 바이너리에 대해, 정확한 버전으로 실행하는 일반적인 pytest 테스트이며, 그 과정에서 와이어를 통해 오가는 내용을 기록합니다. ids[] 사례의 전체 테스트는 다음과 같습니다:

python
@pytest.mark.m3(suite_name="quirks")
def test_q05_args_property_name_brackets(agent) -> None:
    state = run_eval(agent, Path(__file__).resolve().parent)
    assert state == "works", state

run_eval은 agent.run(prompt, servers=(control, quirk))를 호출한 다음, M3의 expect(result).to_have_tool_call(...)로 와이어 증거와 대조해 결과를 확인합니다. agent 픽스처는 명령줄에서 가져옵니다:

sh
m3 test --runtime=managed \
  --harness [email protected]=claude-sonnet-5-5 \
  --harness [email protected]=gpt-5.6-sol \
  --trials 3 -- quirks/

몇 가지 장치가 셀의 신뢰성을 유지해 줍니다:

  1. M3는 각 에이전트 릴리스를 캐시에 내려받고 버전과 SHA-256을 기록하므로, 새 릴리스는 저마다 별도의 열을 갖게 됩니다.
  1. M3는 에이전트가 툴 호출을 보고했는지와 서버가 실제로 그 호출을 받았는지를 따로 기록합니다. 위의 실패 대부분은 이 두 지점 사이에서 발생합니다.
  1. 각 실행은 테스트 대상 서버 옆에 일반 echo 서버를 함께 둡니다. echo가 실패하면 해당 셀은 측정되지 않음으로 표시되므로, 깨진 설정이 에이전트 버그로 보일 수 없습니다.
  1. 서버는 모든 시도마다 무작위 마커를 생성하므로, 모델이 프롬프트만 보고 정답을 알아낼 수 없습니다.
  1. 우리는 모든 실패를 M3 없이 같은 바이너리로 다시 실행해, M3 자체가 원인이 아님을 확인합니다.
  1. 표는 저장된 파일만으로 렌더링되며, 다시 렌더링해도 같은 바이트가 나옵니다.

전체 실행은 66번의 실행과 약 16분이 걸렸습니다. Claude Code는 실행당 평균 9.8초였고, Codex는 평균 18.2초였습니다.

20개 테스트 모두 M3 저장소의 benchmarks/harness-quirks 에 있으며, 직접 실행할 명령도 함께 들어 있습니다.

예상 밖이었던 점

첫 번째 버전은 아무것도 찾아내지 못했습니다. 공개 버그 보고서에서 가져온 다섯 가지 특징으로 시작했는데, 36번의 모든 실행이 두 에이전트에서 모두 통과했습니다. 그 버그들은 이미 수정되었거나 우리가 테스트하지 않은 환경에서만 나타났던 것이어서, 그래서 결국 바이너리를 직접 살펴보게 되었습니다.

프롬프트의 한 문장이 모든 Codex 실행을 망가뜨렸습니다. 처음 프롬프트는 "If a tool is not available, say which one and stop."로 끝났습니다. Codex는 이를 포기하라는 신호로 받아들였고, 모든 셀에서 control failed가 반환되었습니다. 제어 서버가 없었다면, 우리는 이것을 Codex 버그로 발표했을 것입니다.

gpt-5.6-sol에서는 Codex가 code 모드로 실행되므로, 모델은 사용자의 JSON Schema를 전혀 보지 못합니다. 대신 그로부터 생성된 압축된 TypeScript 선언을 받으며, 이 글의 Codex 실패 몇 가지는 바로 그 변환 과정에서 발생합니다.

모든 에이전트에서 자신의 MCP 서버를 테스트해 보세요

매트릭스는 그냥 M3 테스트일 뿐이며, 여러분의 서버도 같은 테스트를 약 열 줄 정도로 작성할 수 있습니다. CLI를 설치하고 프로젝트를 스캐폴딩합니다:

sh
uv tool install sf-m3-cli
m3 init      # a skipped starter test and an .env.example
m3 setup

관심 있는 동작을 일반 pytest 테스트로 작성합니다:

python
import pytest
from m3 import expect

@pytest.mark.m3
def test_shipping(agent, shipping_server):
    result = agent.run("Get a local shipping quote", server=shipping_server)
    expect(result).to_have_tool_call("shipping_quote", server=shipping_server.name,
                                     status="success")

그다음 원하는 만큼 많은 에이전트와 버전에서 실행합니다:

sh
m3 test --runtime=managed \
  --harness [email protected]=claude-sonnet-5-5 \
  --harness [email protected]=gpt-5.6-sol \
  --trials 3 -- tests/test_shipping.py

M3에는 Claude Code, Codex, OpenCode, Pi가 기본으로 포함되어 있으며, ACP를 지원하는 에이전트라면 작은 매니페스트만으로 추가할 수 있습니다. 실행 결과는 로컬에 저장되고 저장된 기준선과 비교할 수 있으므로, 새 에이전트 릴리스가 여러분의 서버를 망가뜨리면 사용자가 버그를 보기 전에 실패한 테스트로 먼저 확인할 수 있습니다. 이를 풀 리퀘스트 검사로 만들려면 CI에서 MCP 서버 게이팅하기 를 참고하세요.

M3는 Apache 2.0 라이선스의 오픈 소스입니다: github.com/sineframe/m3 . 문서 부터 시작하세요. 여러분의 서버에 매트릭스에 추가해야 할 특이한 동작이 있다면, 그곳에 이슈를 열어 주세요.

출처

  • 원문: https://m3.sineframe.com/blog/claude-code-vs-codex-mcp (2026-10-10 · stag)

자료 변경 기록을 불러오는 중입니다.

다음 자료를 불러오는 중입니다.

후기

아직 후기가 없습니다

직접 적용한 결과와 주의할 점을 공유하는 공간입니다.

로그인하고 후기 쓰기

참고 자료 · 도구와 릴리스 노트

댓글