1. 프로젝트 개요
핵심 포지션 및 목적
mcp-kit는 Model Context Protocol(MCP) 서버를 구축하기 위한 모노레포 키트입니다. 각 패키지는 독립적인 MCP 서버로 동작하며, CLI 도구와 MCP 서버 인터페이스를 동시에 제공합니다. 주 목적은 AI 어시스턴트(Claude 등)가 시스템 유틸리티와 텍스트 처리 기능을 MCP 프로토콜을 통해 직접 호출할 수 있도록 하는 것입니다.
주요 사용자 대상
- 최종 사용자: Claude Desktop, Cursor 등 MCP 클라이언트를 통해 AI 어시스턴트에 시스템/텍스트 유틸리티 기능을 연결하려는 개발자
- 개발자: MCP 서버 패키지를 npm으로 설치하거나 npx로 직접 실행하여 사용
- AI 에이전트: MCP 프로토콜을 통해 도구(tool)를 직접 호출
핵심 기능
각 패키지는 다음 세 가지 인터페이스를 제공합니다:
- 라이브러리 API:
import { tools } from "{package.name}"형태로 Node.js 코드에서 직접 사용 - MCP 서버:
npx {package.name}로 stdio 기반 MCP 서버 실행 - CLI:
npx {package.name}-cli <toolName> [args]로 터미널에서 직접 도구 호출
npx로 MCP 서버가 실행되는 원리 (stdio 전송)
MCP 클라이언트(Claude Desktop, Cursor 등)가 npx {package.name}으로 서버를 실행할 때, 서버는 네트워크 포트를 열지 않습니다. 대신 프로세스의 표준 스트림으로 통신합니다. 흐름은 다음과 같습니다:
-
프로세스 실행(spawn): 클라이언트가 해당 명령을 자식 프로세스(
npx {package.name})로 실행합니다.npx는 npm 레지스트리(또는 로컬 캐시)에서 패키지를 찾아bin엔트리를 실행하는데, 이 스크립트는 shebang(#!/usr/bin/env node) 덕분에 Node.js로 바로 구동됩니다. -
파이프 연결: 클라이언트는 자식 프로세스의
stdin,stdout,stderr를 파이프로 연결한 상태로 유지합니다. 이 세 스트림이 곧 전송 채널입니다:stdin(클라이언트 → 서버): 클라이언트가 요청을 씁니다. 서버는 들어오는 메시지를stdin에서 읽습니다.stdout(서버 → 클라이언트): 서버가 응답/알림을 씁니다. 이 채널은 프로토콜 메시지 전용이며, 다른 것을stdout에 출력하면 스트림이 손상됩니다.stderr(서버 → 클라이언트, 대역 외): 로깅/진단용입니다. 클라이언트가 캡처할 수는 있지만 프로토콜 데이터로 파싱하지 않습니다. 사람이 읽을 로그는stdout이 아니라 반드시 여기로 보내야 합니다.
-
메시지 프레이밍(JSON-RPC 2.0): MCP는 JSON-RPC 2.0으로 통신합니다. 각 메시지는 한 줄로 직렬화된 JSON 객체이며 개행(
\n)으로 끝나는 newline-delimited JSON입니다. 대표적인 교환 예시:- 클라이언트 →
stdin:{"jsonrpc":"2.0","id":1,"method":"initialize",...} - 서버 →
stdout:{"jsonrpc":"2.0","id":1,"result":{...}} - 이후
tools/list,tools/call등이 동일한 요청/응답 패턴을 따릅니다.
- 클라이언트 →
-
라이프사이클: 연결은 자식 프로세스가 살아있는 동안만 유지됩니다. 클라이언트가
stdin을 닫거나(EOF) 프로세스를 종료하면 서버도 종료됩니다. 상시 실행되는 데몬도, 관리할 포트도 없습니다 — 클라이언트가 파이프를 열어 두는 동안에만 서버가 존재합니다.
이 레포에서는 @modelcontextprotocol/sdk의 StdioServerTransport가 이 배관을 처리하므로, 도구 작성자는 stdin/stdout을 직접 다룰 필요 없이 async 도구 핸들러만 등록하면 됩니다. SDK가 표준 스트림 위에서 JSON-RPC 프레임의 직렬화/역직렬화를 대신 수행합니다.
왜 HTTP가 아닌 stdio인가? 포트 할당, 인증 계층, 네트워크 노출이 필요 없기 때문입니다. 클라이언트가 서버의 수명을 완전히 제어하고, OS 파이프는 안전한 로컬 채널입니다. 이것이 이 프로젝트가 stdio 전송만 사용하는 이유입니다(아래 비즈니스 제약 참고).
문서 사이트
apps/site/ 디렉토리에 Rspress 기반 문서 사이트가 운영됩니다:
- 패키지 README 자동 연동:
package-docs-plugin이packages/*/README.md를 탐색하여/packages페이지에 동적 렌더링 - static docs:
apps/site/docs/의 마크다운 파일이 정적 문서 페이지로 제공 - llms.txt 자동 생성:
@rspress/plugin-llms플러그인으로 LLM 친화적 사이트맵(llms.txt, llms-full.txt) 자동 생성 - 배포: Netlify (
netlify.toml설정)로 배포
향후 개선 방향
- 패키지 확장: 더 많은 도메인 영역의 MCP 서버 패키지 추가 가능
- 도구 확장: 각 패키지 내에서 더 다양한 도구 정의 및 추가
비즈니스 제약사항 및 금지 규칙
packages/common은 내부 공유 라이브러리로, 절대 npm에 배포되지 않음 (pnpm workspace에서!packages/common으로 제외)- 각 패키지는 독립적으로 release-please를 통해 버전 관리 및 배포됨
@modelcontextprotocol/sdk와zod는 모든 패키지의 핵심 외부 의존성으로, 함부로 버전을 올리거나 제거하지 않음- MCP 서버는 stdio 전송 방식만 사용 (HTTP/SSE 아직 미지원)
- 모든 도구는 비동기 핸들러(async handler)로 작성되어야 함
- 도구의 inputSchema는 Zod 스키마로만 정의 가능 (json-schema 등 다른 형식 불가)