MCP란?
Model Context Protocol(MCP)은 Claude가 외부 서비스에 안전하고 표준화된 방식으로 접근할 수 있게 해주는 프로토콜입니다. 한 번 만든 MCP 서버는 Claude Code, Claude Desktop, MCP를 지원하는 다른 IDE에서 그대로 사용할 수 있습니다.
트랜스포트 선택
세 가지 주요 트랜스포트가 있습니다.
| 트랜스포트 | 적합한 경우 | 인증 |
|---|---|---|
| HTTP | 원격 호스팅 SaaS, 다중 사용자 | OAuth, API 키 |
| stdio | 로컬 CLI 도구, 시스템 접근 | 환경변수, 토큰 |
| SSE | 일부 레거시 원격 서버 | OAuth |
신규 원격 서버는 보통 HTTP를 선택합니다.
시작 준비
필요한 것:
- Node.js 18 이상 (또는 Python 3.10 이상)
- Claude Code 설치 완료
- 연결하고 싶은 서비스나 데이터 소스
프로젝트 초기화 (TypeScript 예시)
mkdir my-mcp-server && cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk
npm install -D typescript @types/node
npx tsc --init
기본 구조
MCP 서버는 세 가지 요소로 구성됩니다.
- Tools — Claude가 호출할 수 있는 함수
- Resources — Claude가 읽을 수 있는 데이터 (파일·DB 행 등)
- Prompts — 미리 정의된 프롬프트 템플릿
대부분의 서버는 Tools만 있어도 충분합니다.
Tool 정의 (예: 날씨 조회)
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
const server = new McpServer({
name: "weather-server",
version: "1.0.0",
});
server.registerTool(
"get-weather",
{
title: "Get current weather",
description: "Returns current weather for a city",
inputSchema: {
city: z.string().describe("City name in English"),
},
},
async ({ city }) => {
const weather = await fetchWeather(city);
return {
content: [{ type: "text", text: JSON.stringify(weather, null, 2) }],
};
}
);
도구 설명(description)은 Claude가 도구를 언제 호출할지 결정하는 핵심 정보입니다. 명확하고 구체적으로 작성합니다.
stdio 트랜스포트로 실행
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const transport = new StdioServerTransport();
await server.connect(transport);
빌드 후 실행:
npx tsc
node dist/index.js
Claude Code에 연결
1. 로컬 stdio 서버 추가
claude mcp add weather -- node /absolute/path/to/dist/index.js
--scope user를 붙이면 모든 프로젝트에서, --scope project를 붙이면 .mcp.json을 통해 팀 전체와 공유할 수 있습니다.
2. 원격 HTTP 서버 추가
claude mcp add --transport http weather https://mcp.example.com/mcp
OAuth가 필요한 경우 /mcp 명령으로 인증 링크를 받습니다.
3. 프로젝트 단위 공유 (.mcp.json)
.mcp.json을 프로젝트 루트에 두면 팀원이 동일한 MCP 설정을 공유할 수 있습니다.
{
"mcpServers": {
"weather": {
"type": "http",
"url": "https://mcp.example.com/mcp"
}
}
}
Claude Desktop에 연결
Claude Desktop은 자체 설정 파일로 stdio MCP 서버를 로드합니다. Claude Code의 claude mcp add가 아니라 직접 JSON 파일을 편집해야 합니다.
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
파일이 없으면 새로 만듭니다.
{
"mcpServers": {
"weather": {
"command": "node",
"args": ["/absolute/path/to/dist/index.js"]
}
}
}
저장한 후 Desktop 앱을 완전히 종료(Cmd+Q) 하고 다시 실행해야 적용됩니다. 창을 닫는 것만으로는 프로세스가 종료되지 않습니다. 다시 실행한 뒤 채팅 입력창 아래 도구 패널에서 노출된 도구 목록을 확인할 수 있습니다.
권한 민감한 도구 디자인
셸 실행·파일 시스템·외부 네트워크처럼 권한이 강한 작업을 노출할 때는 도구를 좁게 쪼개는 것이 핵심입니다. Claude Desktop의 권한 모델은 도구 단위 허용/거부이므로, 한 도구의 입력 스키마가 넓을수록 사용자가 “항상 허용”을 누르는 순간의 위험이 커집니다.
나쁜 예 — 범용 셸 노출
server.registerTool("run_shell", {
description: "Runs an arbitrary shell command",
inputSchema: { command: z.string() },
}, async ({ command }) => { /* ... */ });
이 한 도구는 ls부터 rm -rf·curl까지 모든 작업을 같은 권한 단위로 묶습니다. 사용자가 한 번 “항상 허용”을 누르면 사실상 무제한 셸 접근이 됩니다.
좋은 예 — 의도별 분리
server.registerTool("list_files", {
description: "Lists files in a directory",
inputSchema: { path: z.string() },
}, /* ... */);
server.registerTool("read_file", {
description: "Reads a text file",
inputSchema: { path: z.string() },
}, /* ... */);
server.registerTool("git_status", {
description: "Returns git status for the current repo",
inputSchema: {},
}, /* ... */);
각 도구가 좁은 입력 스키마를 가지므로 의도하지 않은 작업이 끼어들 여지가 줄고, 사용자가 도구별로 다른 허용 정책을 세울 수 있습니다.
설계 원칙
- 프롬프트가 아니라 스키마로 제약 —
description에 “위험한 명령 금지”를 적기보다 inputSchema에서 허용 범위를 좁힘 - 부수효과가 있는 도구(쓰기·실행)와 읽기 전용 도구를 이름과 반환값으로 명확히 구분
- 경로·URL 인자는 서버 측에서 화이트리스트로 한 번 더 검증 — Claude가 전달하는 값을 신뢰하지 않음
테스트
claude
/mcp
추가한 서버 상태와 노출된 도구 목록이 보입니다. 그 후 일반 대화로 도구를 호출하도록 요청해 동작을 확인합니다.
배포 패턴
- 공식 SaaS — 자체 도메인에 HTTP MCP 서버 배포 (예:
https://mcp.notion.com/mcp). 사용자가 OAuth로 인증. - 개인용 도구 — npm 패키지로 배포하고 README에
claude mcp add명령 제공. - 마켓플레이스 등록 — claude.com/plugins에 등록하면 발견성과 설치 경험이 크게 개선됩니다.
다음 단계
- Notion MCP, GitHub MCP, Slack MCP 구현을 참고하여 실전 패턴 학습
- MCP 공식 문서에서 Resources·Prompts·OAuth Provider 등 고급 기능 확인
- 토큰 사용량과 응답 속도가 중요하므로 도구 응답은 가능한 짧고 구조화된 JSON으로 반환
자주 묻는 질문
MCP 서버는 무엇인가요?
Claude가 외부 서비스(DB·API·SaaS)에 표준화된 방식으로 접근할 수 있게 해주는 서버입니다. Tools(함수)·Resources(데이터)·Prompts(템플릿)를 정의하면 Claude가 호출할 수 있습니다.
어떤 트랜스포트를 선택해야 하나요?
원격 서비스라면 HTTP, 로컬 도구라면 stdio가 일반적입니다. 원격 호스팅 가능하고 다중 사용자가 사용할 거면 HTTP, 개인 환경에서만 쓰는 도구나 시스템 권한이 필요한 경우에는 stdio가 적합합니다.
Claude Code에 어떻게 연결하나요?
원격 HTTP 서버는 `claude mcp add --transport http <name> <url>`, 로컬 stdio 서버는 `claude mcp add <name> -- <command>`로 추가합니다. 프로젝트 단위 공유는 `.mcp.json`에 정의합니다.
Claude Desktop에서도 같은 서버를 쓸 수 있나요?
stdio MCP 서버라면 macOS는 `~/Library/Application Support/Claude/claude_desktop_config.json`, Windows는 `%APPDATA%\Claude\claude_desktop_config.json`에 동일한 `mcpServers` 블록을 추가하면 됩니다. 저장 후 Desktop 앱을 완전히 종료하고 다시 실행해야 적용됩니다.
OAuth 인증은 어떻게 처리하나요?
MCP SDK가 OAuth 2.1 흐름을 표준화해 제공합니다. 서버에서 `/.well-known/oauth-authorization-server` 메타데이터를 노출하면, `/mcp` 명령으로 인증 링크를 받아 브라우저에서 로그인할 수 있습니다.
기존 도구를 MCP로 만들어 배포하면 무엇이 좋은가요?
Claude Code, Claude Desktop, 그리고 MCP를 지원하는 다른 IDE에서 같은 도구를 그대로 쓸 수 있습니다. 도구별로 IDE 통합을 따로 만들 필요가 없어 배포·유지보수 비용이 줄어듭니다.