MCP가 들어오면, 모델은 번역된 이름을 봅니다
외부 server의 도구는 모델 눈에 들어가기 전 번역층을 지납니다. skill 목록은 항상 있고, MCP가 없으면 사람에게 따로 묻습니다.
- 연결 집합을 통째로 배포하고, 이미 있는 binding은 자기 연결을 계속 씁니다runtime.rs L246
- 각 가게의 tools/list를 한 표로 모은 뒤 이름 번역에 넘깁니다tool_catalog.rs L153
- 네임스페이스에 역사 접두사 mcp__를 붙입니다tools.rs L228
- 잘못된 문자는 밑줄로 씻고, 글자·숫자·밑줄만 남깁니다mcp/mod.rs L477
- 완전히 같은 원본 신원은 한 부를 버립니다tools.rs L134
- 세척 뒤 네임스페이스가 부딪히면 끝에 SHA-1 12자리를 붙입니다tools.rs L166
- 세척 뒤 도구 이름이 부딪혀도 같은 12자리 해시를 붙입니다tools.rs L193
- 합쳐 128바이트를 넘으면 잘라 내고 다시 해시하며, 프로토콜 호출은 원본 이름을 씁니다tools.rs L226
codex mcp-server를 Cursor MCP 설정에 넣습니다. Cursor가 client, Codex가 server예요. 이번 tools/list가 내부 GitHub 도구까지 내주면, IDE가 한 번 호출해 내부 능력에 닿습니다. 권한 경계가 “Codex를 한 번 부르기”에서 “내부 도구를 직접 부르기”로 넓어져요.
crate가 두 벌로 갈라집니다. mcp-server는 stdin에서 한 줄에 JSON 하나를 읽어요. initialize는 tools만 엽니다. tools/list는 이름 둘을 박아 둡니다. codex와 codex-reply. codex는 start_thread하고, nested thread가 자기 McpRuntime을 또 띄웁니다. codex-mcp가 연결 집합을 맡고, 외부 server 도구는 목록을 따로 만듭니다.
출처:codex-rs/mcp-server/src/lib.rs 131–152행; codex-rs/mcp-server/src/codex_tool_runner.rs 66–90행; codex-rs/codex-mcp/src/runtime.rs 88–98행
같은 JSON-RPC 선 프로토콜이지만 처리기는 다릅니다. 초기 자료는 종종 한 runtime의 두 얼굴로 그렸어요. 지금 소스에서는 MessageProcessor조차 공유하지 않습니다.
출처:codex-rs/mcp-server/src/message_processor.rs 274–277행; codex-rs/mcp-server/src/message_processor.rs 336–348행
밖으로 한 약속과 안의 능력을 갈라놓는 것이 게이트웨이의 흔한 모양입니다. 언어를 바꿔도 함수는 둘이에요. hosted는 run / continue를, external은 mcp__*를 돌립니다. IDE는 입구만 보고, 세션 안에서야 외부 가게가 보입니다.
두 가게가 모두 search를 내밀면 접두사로 아직 갈라집니다. 한쪽은 basic-server, 한쪽은 basic_server인데, 하이픈을 밑줄로 씻으면 네임스페이스가 부딪혀요. 모델이 같은 이름 도구 둘을 보면 다음 호출이 어느 가게로 갈지 모릅니다. API에는 바이트 상한도 있어요.
server가 붙으면 각 가게의 tools/list를 먼저 한 표로 모은 뒤 normalize_tools_for_model_with_prefix를 탑니다. 순서는 고정된 네 걸음이에요.
1. 네임스페이스에 mcp__ 접두사를 붙입니다.
2. 잘못된 문자는 밑줄로 씻고, 글자·숫자·_만 남깁니다.
3. 완전히 같은 원본 신원은 한 부를 버립니다. 세척 뒤 네임스페이스나 도구 이름이 또 부딪히면 끝에 SHA-1 12자리를 붙입니다.
4. 합쳐 128바이트를 넘으면 잘라 내고 다시 해시합니다. 원본 server_name과 tool.name은 ToolInfo에 남고, 프로토콜 호출은 원본 이름을 씁니다.
출처:codex-rs/codex-mcp/src/tools.rs 105–117행; codex-rs/codex-mcp/src/tools.rs 134–137행; codex-rs/codex-mcp/src/tools.rs 166–194행; codex-rs/codex-mcp/src/tools.rs 226–227행; codex-rs/codex-mcp/src/mcp/mod.rs 477–485행
모델이 보는 이름과 프로토콜 이름은 원래 두 층입니다. 한 층은 사람이 읽고 API가 쓰고, 한 층은 주소를 찾습니다. 해시로 가리는 것은 이름 충돌의 흔한 답이에요. 상한 숫자는 바뀔 수 있지만, 이 번역층은 안 바뀝니다.
MCP가 살아 있는지로 목록을 걸러면, 콜드 스타트 몇 초 동안 모델은 skill이 없다고 생각하고, 다음 라운드에 갑자기 나타납니다. 설명서를 매 라운드에 통째로 넣으면 컨텍스트도 다 먹혀요.
호명 기호는 $입니다. 목록은 enabled와 prompt_visible만 봅니다. 사용자가 이름을 부르거나 과제와 설명이 맞을 때, 이번 라운드가 SKILL.md 본문을 읽어요. Guardian 심사 세션은 빈 주입을 바로 돌리고, 부모 transcript의 $skill은 새 설명서를 다시 트리거하지 못합니다.
출처:codex-rs/skills/src/mentions.rs 41행; codex-rs/ext/skills/src/catalog.rs 261–263행; codex-rs/core/src/session/turn.rs 766–770행; codex-rs/core/src/session/turn.rs 808–817행
MCP가 없으면 사람에게 따로 묻습니다. first-party이고 기능 스위치가 켜져야 Install MCP servers가 뜹니다. 승인이 Never면 조용히 건너뛰어요. 사용자가 Continue anyway를 골라도 목록은 남고, 해당 도구는 여전히 못 쓸 수 있습니다.
출처:codex-rs/core/src/mcp_skill_dependencies.rs 47–60행; codex-rs/core/src/mcp_skill_dependencies.rs 268–270행
발견과 준비는 다른 일입니다. 색인을 먼저 주고, 전문은 필요할 때 주며, 의존성이 없으면 사람에게 묻고, 목록에서 항목을 지우지 마세요. 설치 여부는 설정 변경이고, 올릴지 여부는 발견입니다.
DSH: tools만 다리 놓고, 플러그인 하나가 server 한 대
DSH MCP 클라이언트는 범위를 박아 둡니다. 외부 server 한 대에 연결하고, 도구를 ctx.tools에 등록하며, 공개 이름은 mcp__<serverName>__<rawName>예요. 깨끗한 경우는 그대로 이어 붙입니다. 문자나 길이가 바뀌었으면 끝에 SHA-256 12자리를 붙입니다. 상한은 64자. 제거하면 끊고, 등록을 지우고, 네임스페이스를 놓습니다.
출처:packages/mcp/mcp-client/src/index.ts 1–14행; packages/mcp/mcp-client/src/tools.ts 96–102행
elicitation도 없고, 자신을 MCP server로 내주지도 않습니다. 외부 도구 실패는 평범한 tool 실패로 처리해요. 해시 길이가 우연히 12로 같지만, 알고리즘과 이어 붙이는 규칙은 다릅니다.
소스 대조 완료 · 2026-08-22 · DSH · MCP와 확장Claude Code: skill이 일급 tool입니다
Claude Code는 모델에게 Skill tool을 줍니다. 모델이 call해야 본문을 받아요. 주석은 한 번에 skill 하나만 달린다고 적습니다. tool이 명령을 프롬프트 전체로 펼치거든요.
출처:restored-src/src/tools/SkillTool/SkillTool.ts 331–344행
MCP 위 prompt는 loadedFrom === 'mcp'이고 type === 'prompt'여야 발견 목록에 들어갑니다. 방향이 반대예요. Codex는 skill이 MCP를 필요하고, Claude Code는 MCP가 skill을 보탭니다. 트리거도 다릅니다. Codex는 $name을 훑고 맞으면 <skill>를 주입하며, tool call을 한 번 거치지 않아요.
출처:restored-src/src/tools/SkillTool/SkillTool.ts 81–94행
세척 뒤에 누가 이 가게를 알아보나
basic-server는 lookup을, basic_server는 query를 냅니다. 모델이 보는 네임스페이스 둘을 쓰고, 되부를 때 무엇으로 바른 가게에 들어가는지 말하세요.
한 가지 더: 승인을 Never로 바꾸고 $deploy를 칠 때 skill 목록이 아직 있나요. 관찰 점은 is_model_visible과 should_install_mcp_dependencies입니다.