MCP 도구의 스키마가 변경되었습니다. 당신의 에이전트는 이를 알아차리지 못했습니다.
도구 호출은 충돌하지 않았습니다. 200 상태 코드와 유효한 JSON을 반환했습니다.
하지만 잘못된 컨트랙트(contract)를 대상으로 실행되었습니다. 상위 서버가 3일 전에 필드 하나를 변경했습니다. 당신의 에이전트는 계속해서 이전 이름을 보냈습니다. 서버는 이를 조용히 무시했습니다. 결과는 빈 값으로 돌아왔습니다. 오류는 나타나지 않았습니다. 일주일 동안 아무도 눈치채지 못했습니다.
이것이 바로 '침묵의 실패(silent failure)'입니다. 로그가 빨갛게 변하는 요란한 실패가 아닙니다. 서버는 웃으며 응답하지만, 데이터는 잘못된 종류의 실패입니다.
MCP 서버는 호출 사이에 도구 컨트랙트를 변경할 수 있습니다. 파라미터 이름을 바꾸거나 필드 설명을 변경할 수 있습니다. 이러한 변경 사항은 종종 구조적으로 유효하게 유지됩니다. JSON 검증은 통과합니다. 서버는 200을 응답합니다. 당신의 에이전트는 단 하나의 오류도 없이 잘못된 데이터에 따라 동작합니다.
해결책은 간단합니다: • 각 도구 컨트랙트의 SHA-256 해시를 고정(Pin)합니다. • 해당 해시에 스키마와 설명을 모두 포함합니다. • 매 호출 전에 해시를 확인합니다. • 컨트랙트가 어긋나면(drift) 호출을 중단합니다.
우리는 도구가 응답하는지에 집중합니다. 상태 코드를 확인하고, 타임아웃을 설정하며, 5xx 오류 시 재시도합니다. 에이전트가 스키마를 학습한 시점과 호출을 수행한 시점 사이에 컨트랙트가 변경되었는지 확인하는 사람은 거의 없습니다.
MCP 서버는 tools/list를 통해 도구를 노출합니다. 각 도구는 inputSchema와 description을 가집니다. 당신의 에이전트는 세션 시작 시 이를 한 번 읽습니다.
서버가 업데이트되면 다음과 같은 일이 발생할 수 있습니다:
- 추가 속성을 허용하면서 파라미터 이름을 변경합니다 (예:
query를q로). 이전 파라미터는 조용히 무시됩니다. - 필드의 의미를 변경합니다.
limit가 "max results"에서 "page index"로 바뀔 수 있습니다. 타입은 정수(integer)로 유지되므로 검증은 통과합니다. - enum 범위를 좁힙니다. 유효한 값이 새로운 기본값으로 강제 변환될 수 있습니다.
MCP 명세(spec)에 따르면 서버는 목록이 변경될 경우 클라이언트에 통지해야(SHOULD) 한다고 되어 있습니다. 반드시(MUST) 해야 한다는 뜻은 아닙니다. 많은 서버가 이 알림을 보내지 않습니다. 알림을 보내더라도 특정 도구의 스키마가 변경되었다는 사실까지 알려주지 않을 수 있습니다.
구조적 검증에만 의존하는 것을 멈추십시오. 구조적 검증은 의미의 변화를 감지할 수 없습니다.
MCP 도구를 소프트웨어 의존성(dependency)처럼 취급하십시오. 락파일(lockfile) 방식을 사용하십시오. 처음 접촉할 때 도구의 스키마와 설명에 대한 SHA-256 해시를 생성합니다. 매 호출 전에 해시를 다시 계산합니다. 일치하면 진행하고, 일치하지 않으면 어긋남(drift)을 표시하고 중단하십시오.
설명(description)을 해싱하는 것이 핵심입니다. 파라미터가 "max results"에서 "page index"로 바뀌면 스키마는 동일해 보입니다. 하지만 단어가 바뀌었기 때문에 해시는 변경됩니다. 이를 통해 검증 과정에서 놓치기 쉬운 의미론적 어긋남(semantic drift)을 잡아낼 수 있습니다.
컨트랙트가 어긋났을 때 추측하지 마십시오. 맹목적으로 재시도하지 마십시오. 잠시 멈추고, 차이점을 로그로 남긴 뒤, 컨트랙트를 수정하십시오.
Source: https://dev.to/0012303/the-mcp-tool-your-agent-calls-changed-its-schema-it-didnt-notice-5g6m
Optional learning community: https://t.me/GyaanSetuAi