MCP 서버 직접 만들어서 Claude에 연결하기 — 나만의 도구 자동화
지난주 금요일 오후 3시, 저는 Slack에서 "긴급" 라벨이 붙은 멘션 12개를 확인하느라 20분을 썼습니다. 각 메시지를 열어서 맥락을 파악하고, 스프레드시트에 옮기고, 우선순위를 정리했죠. "Claude한테 시켜볼까?" 싶었지만 LLM은 제 Slack 워크스페이스에 접근할 수 없었습니다. Model Context Protocol로 커스텀 서버를 만들고 나니, "오늘 긴급 멘션 정리해줘"라고 치면 30초 만에 요약본이 나옵니다.
이 글을 읽고 나면 반복 작업을 자연어 한 줄로 처리하는 나만의 도구를 Claude에 연결할 수 있게 됩니다.
준비물
- Node.js 18 이상 (제 환경은 20.11.0)
- Claude Desktop 앱 (MCP 서버 연결 지원)
- 텍스트 에디터 (VS Code 추천)
- 기본적인 JavaScript 지식
MCP 서버는 여러 언어로 만들 수 있지만, 공식 SDK가 TypeScript 우선으로 제공되므로 Node.js로 시작하는 게 가장 빠릅니다. 로컬 프로세스로 실행되므로 추가 비용이 들지 않아요.
MCP 서버는 왜 필요한가요?
Claude 같은 LLM은 텍스트 생성은 잘하지만, 파일 시스템 접근·API 호출·데이터베이스 조회 같은 실제 작업은 직접 못 합니다. 프롬프트에 "이 파일 읽어줘"라고 써도 LLM은 파일 경로를 보지 못하죠.
MCP는 이 간극을 메우는 다리입니다. 여러분이 만든 서버가 Claude와 시스템 사이에서 중개자 역할을 합니다. 공식 사양상 Claude가 "파일 읽기 도구를 써야겠다"고 판단하면 서버에 요청을 보내고, 서버가 실제로 파일을 읽어서 결과를 돌려줍니다.
저는 Slack API를 MCP 서버로 감싼 뒤 "오늘 받은 멘션 정리해줘"라고 요청했습니다. 서버가 실제 데이터를 가져와서 Claude에 전달하니, 프롬프트만으로는 불가능했던 작업이 가능해졌어요.
첫 번째 MCP 서버 만들기
가장 단순한 형태의 MCP 서버를 만들어보겠습니다. 현재 시각을 돌려주는 도구 하나만 제공하는 서버예요.
1단계: 프로젝트 초기화
터미널에서 새 디렉토리를 만들고 npm 프로젝트를 시작합니다.
mkdir my-mcp-server
cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk
이렇게 입력하면 package.json이 생성되고 MCP SDK가 설치됩니다. 설치에는 보통 10~20초 정도 걸려요.
2단계: 서버 코드 작성
index.js 파일을 만들고 아래 코드를 입력합니다.
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = new Server({
name: 'my-time-server',
version: '1.0.0',
}, {
capabilities: {
tools: {},
},
});
server.setRequestHandler('tools/list', async () => {
return {
tools: [{
name: 'get_current_time',
description: '현재 시각을 ISO 형식으로 반환합니다',
inputSchema: {
type: 'object',
properties: {},
},
}],
};
});
server.setRequestHandler('tools/call', async (request) => {
if (request.params.name === 'get_current_time') {
return {
content: [{
type: 'text',
text: new Date().toISOString(),
}],
};
}
throw new Error('Unknown tool');
});
const transport = new StdioServerTransport();
await server.connect(transport);
이 코드는 MCP 서버의 뼈대입니다. 공식 사양 기준으로 tools/list는 도구 목록을 반환하고, tools/call은 실제로 도구를 실행합니다. inputSchema 필드는 빈 객체라도 반드시 포함해야 Claude가 도구를 인식해요.
입력: Claude가 "현재 시간 알려줘"라고 요청 → 출력: 서버가 2026-07-11T14:23:01.234Z 형식으로 반환
3단계: Claude Desktop에 연결
package.json에 "type": "module"을 추가하고, Claude Desktop 설정 파일을 엽니다.
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%\Claude\claude_desktop_config.json
MCP 문서 기준으로 설정 파일의 mcpServers 객체에 서버 정보를 등록하면 됩니다.
{
"mcpServers": {
"my-time-server": {
"command": "node",
"args": ["/절대경로/my-mcp-server/index.js"]
}
}
}
/절대경로/ 부분을 실제 프로젝트 경로로 바꿔야 합니다. 상대 경로는 작동하지 않아요.
Claude Desktop을 재시작하면 왼쪽 하단에 연결된 MCP 서버 아이콘이 나타납니다. 채팅창에 "지금 몇 시야?"라고 물어보세요.
입력: "지금 몇 시야?" → 출력: Claude가 get_current_time 도구를 호출해서 "2026년 7월 11일 오후 2시 23분입니다" 같은 답변 생성
실무에서 써먹기 — 업무 자동화 워크플로우
시간 출력만으로는 실감이 안 나죠. 제가 실제로 쓰는 시나리오를 공유합니다. 우리 팀은 매일 아침 GitHub 이슈를 확인하고 우선순위를 정리하는 게 일과였는데, MCP 서버에 이슈 조회 기능을 추가한 뒤 "우리 레포 긴급 이슈 있어?"라고 물으면 바로 답이 나옵니다. 아침마다 5분 걸리던 일이 30초로 줄었어요.
입력: "anthropics/anthropic-sdk-python 레포에서 'bug' 라벨 달린 이슈 중 지난 7일간 닫힌 건 몇 개야?" → MCP 서버가 GitHub API 쿼리 실행 → Claude가 "총 12개의 버그 이슈가 해결되었습니다" 같은 요약 제공
핵심은 한 번 만들어두면 계속 쓴다는 점입니다. 저는 Notion 검색, Slack 통계, 사내 DB 쿼리까지 전부 MCP 서버로 연결했습니다.
흔한 실수와 해결법
1. 서버가 Claude에 안 보여요
제가 처음 3시간 날린 실수입니다. claude_desktop_config.json에 상대 경로(./index.js)를 썼거든요. 절대 경로로 바꾸니까 바로 인식됐습니다. 설정 파일 저장 후 Claude Desktop을 완전히 종료하고 다시 켜야 해요.
2. 도구는 보이는데 호출이 안 돼요
inputSchema를 빼먹었을 가능성이 큽니다. MCP 사양상 JSON Schema 형식의 inputSchema 필드가 필수인데, 빈 객체라도 반드시 넣어야 Claude가 도구를 호출할 수 있어요.
3. 결과가 이상하게 나와요
tools/call에서 반환하는 형식이 틀렸을 겁니다. 공식 문서 기준으로 반드시 { content: [{ type: 'text', text: '...' }] } 구조여야 합니다.
자주 묻는 질문
Q. MCP 서버는 항상 로컬에서만 실행되나요? A. 아닙니다. 기본 예제는 stdio 전송 방식(로컬 프로세스)이지만, MCP 사양은 HTTP 전송 방식도 정의하고 있어서 원격 서버를 연결할 수도 있습니다. 다만 Claude Desktop은 현재 stdio만 공식 지원합니다.
Q. 여러 MCP 서버를 동시에 연결할 수 있나요? A. 가능합니다. claude_desktop_config.json의 mcpServers 객체에 여러 서버를 나열하면 됩니다. 저는 GitHub용·Slack용·DB용 3개를 동시에 띄워놓고 씁니다. 각 서버의 name 필드가 고유하면 충돌 없이 작동합니다.
Q. 도구 이름은 어떻게 짓는 게 좋나요? A. 동사_명사 형태를 추천합니다. fetch_issues, send_message 형태죠. Claude가 의도를 파악할 때 명확한 동사가 있으면 정확도가 올라갑니다.
Q. MCP 서버 디버깅은 어떻게 하나요? A. 서버 코드에 console.error()를 추가하고 Claude Desktop을 터미널에서 실행하면 로그를 볼 수 있습니다. macOS는 /Applications/Claude.app/Contents/MacOS/Claude, Windows는 설치 경로의 Claude.exe를 직접 실행하세요. stdio 방식은 표준 입출력을 쓰므로 stderr로 디버그 메시지를 내보내야 합니다.
Q. 인증이 필요한 API는 어떻게 연결하나요? A. 환경변수나 설정 파일에서 API 키를 읽어오는 방식을 쓰면 됩니다. process.env.GITHUB_TOKEN 형태로 서버 코드에서 직접 참조하고, Claude에게는 토큰을 노출하지 않습니다. 서버가 중개자 역할을 하므로 민감 정보는 서버 내부에만 둬도 충분합니다.
다음 단계
MCP 서버를 만들고 나면 할 수 있는 게 정말 많아집니다. 제가 추천하는 순서는 이렇습니다.
첫째, 가장 자주 반복하는 작업부터 자동화하세요. 저는 Slack 멘션 정리부터 시작했습니다. 하루에 3번 이상 하는 일이면 MCP 서버로 만들 가치가 있어요.
둘째, 여러 도구를 조합하는 워크플로우로 확장하세요. 한 서버에 3~5개 도구를 만들어두면 Claude가 알아서 순서를 조합합니다. "지난주 고객 문의 중 긴급 건만 추려서 Slack으로 보내줘" 같은 요청을 처리할 수 있죠.
셋째, 팀원과 공유하세요. 제 경우 서버 코드를 팀 레포에 올려두니까, 동료들이 같은 설정 파일로 5분 만에 연결했습니다. 한 사람이 만들면 팀 전체가 쓸 수 있다는 게 MCP의 장점입니다.