MCP 도구에 annotations 달기 — description 밖에서 행동을 힌트하는 법
MCP 도구는 description 말고도 annotations라는 채널로 자신의 행동 특성을 알릴 수 있다. readOnlyHint·destructiveHint·idempotentHint·openWorldHint 네 필드가 각각 무엇을 뜻하는지, 왜 힌트일 뿐 보장이 아닌지, registerTool에 실제로 붙이는 코드까지 정리한다.
32개의 글 · 2 / 4 페이지
MCP 도구는 description 말고도 annotations라는 채널로 자신의 행동 특성을 알릴 수 있다. readOnlyHint·destructiveHint·idempotentHint·openWorldHint 네 필드가 각각 무엇을 뜻하는지, 왜 힌트일 뿐 보장이 아닌지, registerTool에 실제로 붙이는 코드까지 정리한다.
MCP의 세 primitive(Tools, Resources, Prompts)는 클라이언트가 서버에게 요청하는 방향이지만, Sampling은 그 반대다 — 서버가 클라이언트에게 LLM 완성을 요청한다. 서버가 API 키 없이도 지능을 빌리는 이 흐름의 동작 방식과, 이 블로그의 무인 발행 파이프라인이 대신 헤드리스 호출을 택한 이유를 코드로 정리한다.
MCP 서버와 cron 사이의 빈칸 — 에이전트를 깨우고 성공을 판정하는 오케스트레이터를 만들었다. Agent SDK 라이브러리 대신 셸 스크립트 + claude -p 헤드리스를 고른 이유, 성공 판정을 모델의 말이 아니라 파일시스템에 두는 설계, 슬래시 프롬프트가 헤드리스에서 발동되지 않아 프롬프트를 텍스트로 주입한 우회까지 실제 코드로 정리한다.
MCP가 에이전트 아래로 도구를 꽂는 수직 연결이라면, A2A는 에이전트끼리 옆으로 대화하는 수평 연결이다. 상대를 스키마가 정해진 함수로 보느냐, 속을 알 수 없는 행위자로 보느냐 — 두 프로토콜이 다른 문제를 푸는 이유를 Agent Card와 Task 개념으로 정리한다.
MCP 서버의 진짜 검증은 단위 테스트가 아니라 실전 클라이언트다. claude mcp add 한 줄로 Claude Code에 붙이고, 도구 선택·거부 메시지·경계 강제라는 상호작용 단위의 테스트법과 stdout 오염·재빌드 미스 같은 함정을 이 프로젝트의 Phase 2 경험으로 정리한다.
MCP와 function calling은 경쟁 관계가 아니라 다른 층에 있다. function calling은 모델이 도구 호출 의사를 표현하는 출력 형식이고, MCP는 그 형식에 흘려 넣을 도구를 조달하는 공급 규격이다. 두 층이 한 번의 도구 호출에서 어떻게 맞물리는지 실제 요청 형태로 구분한다.
매일 자동 발행의 Claude 호출 비용을 어디에 물릴 것인가. 구독(정액 한도제)과 API 키(종량제)의 구조 차이, CI에서 환경변수 하나로 갈리는 인증, 하루 1회 발행의 비용 어림, 그리고 이 프로젝트가 API 키를 고른 이유 — 격리 관점에서 정리한다.
MCP에서 도구 실패는 프로토콜 에러와 실행 에러 두 층으로 나뉘고, 실행 에러는 isError: true를 얹은 정상 결과로 돌아간다. 이 텍스트는 LLM이 읽고 행동을 바꾸는 입력이다 — 무엇이·왜 실패했고 다음에 뭘 하면 되는지를 담는 에러 메시지 설계법을 실제 코드로 정리한다.
매일 글을 자동 발행하려면 스케줄러가 필요하다. 서버에 crontab을 거는 대신 GitHub Actions의 schedule 트리거로 매일 도는 워크플로를 만든다. UTC 시차, 정시 지연, 60일 비활성화 같은 함정과 workflow_dispatch를 함께 두는 이유까지, 그대로 쓸 수 있는 워크플로 파일로 정리한다.
MCP 도구는 description 말고도 annotations라는 채널로 자신의 행동 특성을 알릴 수 있다. readOnlyHint·destructiveHint·idempotentHint·openWorldHint 네 필드가 각각 무엇을 뜻하는지, 왜 힌트일 뿐 보장이 아닌지, registerTool에 실제로 붙이는 코드까지 정리한다.
MCP의 세 primitive(Tools, Resources, Prompts)는 클라이언트가 서버에게 요청하는 방향이지만, Sampling은 그 반대다 — 서버가 클라이언트에게 LLM 완성을 요청한다. 서버가 API 키 없이도 지능을 빌리는 이 흐름의 동작 방식과, 이 블로그의 무인 발행 파이프라인이 대신 헤드리스 호출을 택한 이유를 코드로 정리한다.
MCP 서버와 cron 사이의 빈칸 — 에이전트를 깨우고 성공을 판정하는 오케스트레이터를 만들었다. Agent SDK 라이브러리 대신 셸 스크립트 + claude -p 헤드리스를 고른 이유, 성공 판정을 모델의 말이 아니라 파일시스템에 두는 설계, 슬래시 프롬프트가 헤드리스에서 발동되지 않아 프롬프트를 텍스트로 주입한 우회까지 실제 코드로 정리한다.
MCP가 에이전트 아래로 도구를 꽂는 수직 연결이라면, A2A는 에이전트끼리 옆으로 대화하는 수평 연결이다. 상대를 스키마가 정해진 함수로 보느냐, 속을 알 수 없는 행위자로 보느냐 — 두 프로토콜이 다른 문제를 푸는 이유를 Agent Card와 Task 개념으로 정리한다.
MCP 서버의 진짜 검증은 단위 테스트가 아니라 실전 클라이언트다. claude mcp add 한 줄로 Claude Code에 붙이고, 도구 선택·거부 메시지·경계 강제라는 상호작용 단위의 테스트법과 stdout 오염·재빌드 미스 같은 함정을 이 프로젝트의 Phase 2 경험으로 정리한다.
MCP와 function calling은 경쟁 관계가 아니라 다른 층에 있다. function calling은 모델이 도구 호출 의사를 표현하는 출력 형식이고, MCP는 그 형식에 흘려 넣을 도구를 조달하는 공급 규격이다. 두 층이 한 번의 도구 호출에서 어떻게 맞물리는지 실제 요청 형태로 구분한다.
매일 자동 발행의 Claude 호출 비용을 어디에 물릴 것인가. 구독(정액 한도제)과 API 키(종량제)의 구조 차이, CI에서 환경변수 하나로 갈리는 인증, 하루 1회 발행의 비용 어림, 그리고 이 프로젝트가 API 키를 고른 이유 — 격리 관점에서 정리한다.
MCP에서 도구 실패는 프로토콜 에러와 실행 에러 두 층으로 나뉘고, 실행 에러는 isError: true를 얹은 정상 결과로 돌아간다. 이 텍스트는 LLM이 읽고 행동을 바꾸는 입력이다 — 무엇이·왜 실패했고 다음에 뭘 하면 되는지를 담는 에러 메시지 설계법을 실제 코드로 정리한다.
매일 글을 자동 발행하려면 스케줄러가 필요하다. 서버에 crontab을 거는 대신 GitHub Actions의 schedule 트리거로 매일 도는 워크플로를 만든다. UTC 시차, 정시 지연, 60일 비활성화 같은 함정과 workflow_dispatch를 함께 두는 이유까지, 그대로 쓸 수 있는 워크플로 파일로 정리한다.
비공개로 의견 보내기
작성자에게만 전달돼요. 이름·이메일을 비우면 완전 익명입니다.