MCP 서버를 4단계로 만들기: 조사, 구현, 테스트, 평가 문항 작성
외부 API를 LLM이 쓸 수 있게 TypeScript(SDK v2) 또는 Python MCP 서버로 만들고, MCP Inspector로 점검한 뒤 평가 질문 10개를 XML로 작성해요.
WebFetch → Claude Code → MCP Inspector → Claude Code
외부 API나 서비스를 LLM 에이전트가 도구로 쓸 수 있게 MCP 서버로 감싸야 할 때 써요.
입력값
{{service_name}}연동할 서비스필수- MCP 서버로 감쌀 외부 API나 서비스 이름이에요.
- 예: GitHub
{{language}}구현 언어필수- TypeScript(권장) 또는 Python이에요.
- 예: TypeScript
1단계, 사람이. MCP 설계 원칙 정하기
직접 하기
API 전체를 덮는 도구와 특정 작업용 워크플로 도구 사이에서 균형을 잡아요. 잘 모르겠으면 API 전체를 덮는 쪽을 먼저 고려해요. 도구 이름은 `github_create_issue`처럼 일관된 접두사와 동작 중심으로 짓고, 설명은 짧게 쓰고, 결과는 필터와 페이지 나누기를 지원해요. 오류 메시지에는 다음에 할 일을 구체적으로 넣어요.
- 기대 결과
- 도구 범위, 이름 규칙, 오류 메시지 방침이 정리돼요.
- 확인하는 법
- 도구 이름에 공통 접두사가 있고 동작이 드러나는지 봐요.
2단계, 사람이. MCP 프로토콜 문서 읽기
WebFetch
`https://modelcontextprotocol.io/sitemap.xml`에서 필요한 페이지를 찾고, 주소 끝에 `.md`를 붙여 마크다운으로 가져와요. 명세 개요와 구조, 전송 방식(streamable HTTP, stdio), 도구·리소스·프롬프트 정의를 확인해요.
- 기대 결과
- 명세 개요, 전송 방식, 도구 정의의 핵심을 파악해요.
- 확인하는 법
- 원격 서버는 stateless JSON 기반 Streamable HTTP, 로컬 서버는 stdio를 쓰기로 정했는지 확인해요.
3단계, 사람이. 프레임워크 문서 불러오기
WebFetch
언어를 정해요. TypeScript를 권장해요. TypeScript SDK는 새 서버라면 v2(`@modelcontextprotocol/server`)를 쓰고, `package.json`에 이미 `@modelcontextprotocol/sdk`(v1)가 있을 때만 v1을 써요. 한 프로젝트에 둘을 섞지 않아요. Python은 FastMCP를 써요. SDK README와 MCP 모범 사례 문서(`reference/mcp_best_practices.md`), 언어별 가이드를 불러와요.
- 기대 결과
- 사용할 SDK 버전과 참고 문서가 정해져요.
- 확인하는 법
- v1과 v2 import가 섞여 있지 않은지 확인해요.
4단계, 사람이. 구현 계획 세우기
직접 하기
대상 서비스의 API 문서에서 주요 엔드포인트, 인증 방식, 데이터 모델을 확인해요. 가장 흔한 작업부터 구현할 엔드포인트 목록을 만들어요.
- 기대 결과
- 구현할 엔드포인트 목록과 인증 요구사항이 정리돼요.
- 확인하는 법
- 자주 쓰는 작업이 목록 앞쪽에 있는지 봐요.
5단계, AI에게. 프로젝트 구조와 공통 기반 만들기
Claude Code
언어별 가이드에 따라 프로젝트를 세팅해요. 인증이 들어간 API 클라이언트, 오류 처리 도우미, 응답 포맷(JSON/Markdown), 페이지 나누기 지원을 공통 코드로 만들어요.
- 기대 결과
- 공통 유틸리티를 갖춘 프로젝트 뼈대가 만들어져요.
- 확인하는 법
- API 호출과 오류 처리가 한곳에 모여 중복이 없는지 봐요.
6단계, AI에게. 도구 구현하기
Claude Code
도구마다 Zod(TypeScript) 또는 Pydantic(Python)으로 입력 스키마를 정의하고, 제약 조건과 필드 설명, 예시를 넣어요. 가능하면 `outputSchema`와 `structuredContent`로 구조화된 결과도 돌려줘요. I/O는 async/await로 처리하고, 해당하는 곳에는 페이지 나누기를 넣어요. `readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint` 주석도 달아요.
- 기대 결과
- 엔드포인트별 도구가 스키마, 설명, 주석과 함께 구현돼요.
- 확인하는 법
- 모든 도구에 입력 스키마와 4가지 주석이 있는지 봐요.
7단계, 사람이. 코드 품질 검토하기
직접 하기
중복 코드, 일관된 오류 처리, 전체 타입 적용, 도구 설명의 명확성을 검토해요.
- 기대 결과
- 고칠 점이 정리되고 반영돼요.
- 확인하는 법
- 같은 로직이 여러 곳에 복사돼 있지 않은지 봐요.
8단계, 명령 실행. 빌드하고 테스트하기
MCP Inspector
TypeScript는 `npm run build`로 컴파일을 확인해요. v2 프로젝트는 v2 가이드의 자체 점검 스크립트를 빌드된 서버에 돌려요. Python은 문법을 확인해요. 둘 다 MCP Inspector로 시험해요.
명령 npm run build npx @modelcontextprotocol/inspector # Python 문법 확인 python -m py_compile your_server.py
- 기대 결과
- 빌드가 성공하고 Inspector에서 도구가 호출돼요.
- 확인하는 법
- Inspector에서 도구 목록이 보이고 호출이 정상 응답하는지 확인해요.
9단계, AI에게. 평가 질문 10개 만들기
Claude Code
평가 가이드(`reference/evaluation.md`)를 따라요. 먼저 도구 목록을 살피고, 읽기 전용 작업으로 데이터를 탐색해요. 그다음 복잡하고 현실적인 질문 10개를 만들고 직접 풀어 답을 검증해요. 각 질문은 서로 독립적이고 읽기 전용이며, 여러 번 도구를 호출해야 풀리고, 문자열 비교로 확인되는 하나의 답이 있고, 시간이 지나도 답이 변하지 않아야 해요.
- 기대 결과
- 질문과 검증된 답 10쌍이 만들어져요.
- 확인하는 법
- 각 질문을 직접 풀어 답이 일치하는지, 답이 시간이 지나도 변하지 않는지 확인해요.
결과 →
{{evaluation_questions}}10단계, 사람이. 평가 XML 파일로 저장하기
직접 하기
질문과 답을 `<evaluation>` 아래 `<qa_pair>` 구조의 XML 파일로 저장해요.
프롬프트 <evaluation> <qa_pair> <question>Find discussions about AI model launches with animal codenames. One model needed a specific safety designation that uses the format ASL-X. What number X was being determined for the model named after a spotted wild cat?</question> <answer>3</answer> </qa_pair> <!-- More qa_pairs... --> </evaluation>
- 기대 결과
- qa_pair 10개가 담긴 XML 평가 파일이 생겨요.
- 확인하는 법
- XML이 올바른 구조이고 질문 10개가 모두 들어 있는지 확인해요.
주의할 점
v1(`@modelcontextprotocol/sdk`)과 v2(`@modelcontextprotocol/server`) 코드를 한 프로젝트에 섞으면 v1 샘플이 v2에 맞지 않아요.
- 원격 서버를 stateful 세션이나 스트리밍으로 만들면 확장과 유지가 어려워져요. stateless JSON을 권장해요.
- 평가 질문에 쓰기·삭제 같은 파괴적 작업이 들어가면 안 돼요.
- 시간이 지나면 답이 바뀌는 질문은 평가에 맞지 않아요.
- 원본이 가리키는 `reference/` 문서는 이 문서에 없어서, 세부 내용은 원 저장소에서 따로 확인해야 해요.
출처
- 1mcp-buildergithub.com