본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 5. · 13 Views
MCP 통합 완벽 가이드
Model Context Protocol(MCP)을 활용하여 AI 에이전트와 외부 도구를 연동하는 방법을 알아봅니다. 로컬 서버부터 원격 서버까지, 실무에서 바로 적용할 수 있는 MCP 통합 기법을 단계별로 설명합니다.
목차
1. MCP란 무엇인가
김개발 씨는 요즘 AI 에이전트 개발에 푹 빠져 있습니다. 그런데 AI가 파일을 읽거나 데이터베이스를 조회하게 만들려니 막막했습니다.
"AI한테 어떻게 외부 도구를 쓰게 하지?" 선배 박시니어 씨가 웃으며 말했습니다. "MCP를 써보세요.
AI와 도구 사이의 통역사 같은 거예요."
**MCP(Model Context Protocol)**는 AI 모델이 외부 도구와 소통할 수 있게 해주는 표준 프로토콜입니다. 마치 USB가 다양한 기기를 컴퓨터에 연결하는 표준 규격인 것처럼, MCP는 AI가 파일 시스템, 데이터베이스, API 등 다양한 도구에 접근할 수 있는 표준 인터페이스를 제공합니다.
이를 통해 AI는 단순한 텍스트 생성을 넘어 실제 작업을 수행하는 에이전트로 진화할 수 있습니다.
다음 코드를 살펴봅시다.
// MCP의 기본 개념: AI와 도구의 소통 구조
interface MCPServer {
name: string; // 서버 이름
type: 'local' | 'remote'; // 서버 유형
tools: Tool[]; // 제공하는 도구 목록
}
interface Tool {
name: string; // 도구 이름 (예: read_file)
description: string; // 도구 설명
parameters: object; // 입력 파라미터 스키마
}
// AI가 MCP를 통해 도구를 호출하는 흐름
// AI 요청 -> MCP 서버 -> 도구 실행 -> 결과 반환 -> AI 응답
김개발 씨는 입사 6개월 차 주니어 개발자입니다. 최근 회사에서 AI 기반 자동화 프로젝트를 맡게 되었습니다.
Claude 같은 대형 언어 모델을 활용해 코드 리뷰를 자동화하고 싶었습니다. 문제는 AI가 단순히 텍스트만 생성할 수 있다는 점이었습니다.
"AI가 실제로 파일을 읽고, Git 명령어를 실행하려면 어떻게 해야 하지?" 김개발 씨는 고민에 빠졌습니다. 그때 선배 박시니어 씨가 다가왔습니다.
"MCP라는 게 있어요. AI와 외부 도구 사이의 통역사라고 생각하면 됩니다." 그렇다면 MCP란 정확히 무엇일까요?
쉽게 비유하자면, MCP는 마치 호텔의 컨시어지 서비스와 같습니다. 호텔 투숙객이 "맛있는 레스토랑 예약해주세요"라고 요청하면, 컨시어지가 대신 전화하고, 예약하고, 결과를 알려줍니다.
투숙객은 레스토랑의 전화번호나 예약 시스템을 몰라도 됩니다. MCP도 마찬가지입니다.
AI가 "파일을 읽어줘"라고 요청하면, MCP 서버가 대신 파일 시스템에 접근하고 결과를 전달합니다. MCP가 없던 시절에는 어땠을까요?
개발자들은 AI와 각 도구를 연결하는 코드를 일일이 작성해야 했습니다. 파일 시스템용 연결 코드, 데이터베이스용 연결 코드, API용 연결 코드...
도구가 늘어날 때마다 연결 코드도 기하급수적으로 늘어났습니다. 더 큰 문제는 표준이 없어서 각자 다른 방식으로 구현했다는 점입니다.
코드 재사용은 꿈도 못 꿨습니다. 바로 이런 문제를 해결하기 위해 Model Context Protocol이 등장했습니다.
MCP는 Anthropic에서 만든 오픈 표준입니다. 마치 HTTP가 웹 통신의 표준이 된 것처럼, MCP는 AI와 도구 간 통신의 표준을 목표로 합니다.
한 번 MCP 서버를 만들면 어떤 AI 클라이언트에서든 사용할 수 있습니다. MCP의 핵심 구성 요소는 세 가지입니다.
첫째, MCP 호스트는 AI 모델이 실행되는 환경입니다. Claude Desktop이나 VS Code 같은 애플리케이션이 여기에 해당합니다.
둘째, MCP 클라이언트는 호스트 내부에서 MCP 서버와 통신하는 부분입니다. 셋째, MCP 서버는 실제 도구를 제공하는 프로그램입니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 AI 기반 코드 에디터를 만든다고 가정해봅시다.
파일 읽기/쓰기 MCP 서버, Git 명령어 MCP 서버, 터미널 MCP 서버를 연결하면 AI가 실제로 코드를 수정하고 커밋까지 할 수 있습니다. Claude Code가 바로 이런 방식으로 동작합니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 눈이 반짝였습니다.
"아, 그러니까 MCP만 잘 이해하면 AI한테 뭐든 시킬 수 있겠네요!" MCP를 제대로 이해하면 AI의 능력을 무한히 확장할 수 있습니다. 여러분도 이제 MCP의 세계로 들어가 봅시다.
실전 팁
💡 - MCP는 AI와 도구 사이의 표준 통신 규약입니다
- 한 번 만든 MCP 서버는 여러 AI 클라이언트에서 재사용할 수 있습니다
- Claude Code, VS Code Copilot 등 많은 AI 도구가 MCP를 지원합니다
2. MCP 디렉토리 구조
김개발 씨는 MCP를 프로젝트에 적용하려고 합니다. 그런데 설정 파일을 어디에 두어야 할지 막막했습니다.
"프로젝트마다 다른 MCP 서버를 쓰고 싶은데, 전역 설정이랑 어떻게 구분하지?" 박시니어 씨가 mcp/ 디렉토리 구조를 설명해주기 시작했습니다.
mcp/ 디렉토리는 프로젝트별 MCP 서버 설정을 담는 공간입니다. 마치 package.json이 프로젝트의 의존성을 관리하듯, mcp/ 디렉토리는 해당 프로젝트에서 사용할 MCP 서버들을 정의합니다.
전역 설정과 분리되어 있어 프로젝트마다 다른 도구 세트를 구성할 수 있습니다.
다음 코드를 살펴봅시다.
// 프로젝트 디렉토리 구조
my-project/
├── .claude/
│ └── settings.json // Claude Code 프로젝트 설정
├── mcp/
│ ├── mcp.json // MCP 서버 목록 정의
│ ├── file-server/ // 로컬 MCP 서버 예시
│ │ ├── index.ts
│ │ └── package.json
│ └── database-server/ // 또 다른 로컬 서버
│ ├── index.ts
│ └── package.json
├── src/
└── package.json
// mcp/mcp.json 기본 구조
{
"mcpServers": {
"서버이름": { /* 서버 설정 */ }
}
}
김개발 씨는 회사에서 두 개의 프로젝트를 동시에 진행하고 있습니다. 하나는 쇼핑몰 프로젝트이고, 다른 하나는 내부 관리 시스템입니다.
쇼핑몰에서는 결제 API 도구가 필요하고, 관리 시스템에서는 데이터베이스 직접 접근 도구가 필요합니다. "전역으로 MCP 서버를 설정하면 두 프로젝트에서 같은 도구를 쓰게 되잖아요.
보안상으로도 문제가 될 수 있고요." 김개발 씨의 걱정에 박시니어 씨가 답했습니다. "그래서 프로젝트별 mcp/ 디렉토리가 있는 거예요." mcp/ 디렉토리는 마치 각 집의 창고와 같습니다.
아파트 단지에 공용 창고도 있지만, 각 집마다 개인 창고가 있죠. 공구가 필요하면 먼저 집 창고를 뒤지고, 없으면 공용 창고를 찾아봅니다.
MCP도 마찬가지입니다. 프로젝트의 mcp/ 디렉토리를 먼저 확인하고, 없으면 전역 설정을 참조합니다.
디렉토리 구조를 자세히 살펴봅시다. 프로젝트 루트에 mcp/ 폴더를 만듭니다.
이 안에 mcp.json 파일이 핵심입니다. 이 파일에서 어떤 MCP 서버들을 사용할지 선언합니다.
JSON 형식으로 서버 이름, 유형, 연결 정보를 정의합니다. 로컬 MCP 서버를 직접 만든다면 mcp/ 디렉토리 안에 서버별 폴더를 만듭니다.
예를 들어 파일 관리 서버라면 mcp/file-server/ 폴더를 만들고, 그 안에 index.ts와 package.json을 배치합니다. 이렇게 하면 서버 코드도 프로젝트와 함께 버전 관리됩니다.
.claude/settings.json과의 관계도 알아두면 좋습니다. Claude Code를 사용한다면 이 파일에서 mcp/ 디렉토리의 서버들을 자동으로 인식합니다.
별도의 연결 설정 없이도 mcp.json에 정의된 서버들을 바로 사용할 수 있습니다. 실무에서 권장하는 구조가 있습니다.
팀 프로젝트라면 mcp/ 디렉토리를 Git에 커밋하세요. 팀원 모두가 같은 MCP 환경에서 작업할 수 있습니다.
단, API 키 같은 민감한 정보는 환경 변수로 분리해야 합니다. 반대로 개인적인 도구나 실험적인 서버는 전역 설정에 두는 게 좋습니다.
홈 디렉토리의 ~/.claude/settings.json에서 전역 MCP 서버를 설정할 수 있습니다. 주의할 점도 있습니다.
mcp/ 디렉토리와 전역 설정에 같은 이름의 서버가 있으면 어떻게 될까요? 프로젝트 설정이 우선합니다.
이를 활용하면 전역 서버의 동작을 프로젝트별로 오버라이드할 수 있습니다. 다시 김개발 씨 이야기로 돌아가 봅시다.
이제 쇼핑몰 프로젝트의 mcp/ 폴더에는 결제 API 서버만, 관리 시스템의 mcp/ 폴더에는 데이터베이스 서버만 설정했습니다. "이렇게 하니까 프로젝트별로 딱 필요한 도구만 쓸 수 있네요!"
실전 팁
💡 - mcp.json 파일은 반드시 mcp/ 디렉토리 바로 아래에 위치해야 합니다
- 민감한 정보는 환경 변수로 분리하고 .env 파일은 .gitignore에 추가하세요
- 같은 이름의 서버가 있으면 프로젝트 설정이 전역 설정보다 우선합니다
3. 로컬 MCP 서버
김개발 씨는 회사 내부에서만 사용하는 특별한 도구가 필요했습니다. 외부 서비스에 맡기기엔 보안이 걱정되었고, 커스터마이징도 필요했습니다.
"직접 MCP 서버를 만들 순 없을까요?" 박시니어 씨가 고개를 끄덕였습니다. "로컬 MCP 서버를 만들면 됩니다.
생각보다 어렵지 않아요."
**로컬 MCP 서버(type: local)**는 사용자의 컴퓨터에서 직접 실행되는 MCP 서버입니다. 마치 집에서 직접 요리하는 것처럼, 외부에 의존하지 않고 필요한 도구를 직접 만들어 사용합니다.
표준 입출력(stdio)을 통해 AI 클라이언트와 통신하며, 보안이 중요하거나 네트워크가 없는 환경에서 유용합니다.
다음 코드를 살펴봅시다.
// mcp/mcp.json - 로컬 서버 설정
{
"mcpServers": {
"file-manager": {
"type": "local",
"command": "npx",
"args": ["ts-node", "mcp/file-server/index.ts"],
"env": {
"ROOT_DIR": "/home/user/projects"
}
},
"git-helper": {
"type": "local",
"command": "node",
"args": ["./mcp/git-server/dist/index.js"],
"cwd": "/home/user/my-project"
}
}
}
// 주요 속성 설명
// command: 서버를 실행할 명령어
// args: 명령어에 전달할 인자들
// env: 환경 변수 (선택)
// cwd: 작업 디렉토리 (선택)
김개발 씨는 회사의 레거시 시스템과 연동해야 하는 상황이었습니다. 이 시스템은 보안상 외부 접근이 차단되어 있고, 오직 내부 네트워크에서만 접근할 수 있습니다.
"외부 MCP 서버는 쓸 수 없겠네요. 어떻게 하죠?" 박시니어 씨가 설명을 시작했습니다.
"로컬 MCP 서버를 만들면 됩니다. 내 컴퓨터에서 직접 돌아가니까 보안 걱정도 없어요." 로컬 MCP 서버는 마치 집에서 직접 만드는 가정식과 같습니다.
레스토랑에서 사 먹으면 편하지만, 특별한 재료를 쓰거나 입맛에 맞게 조절하려면 직접 요리해야 하죠. 로컬 서버도 마찬가지입니다.
내 환경에 맞게, 내 필요에 맞게 도구를 만들 수 있습니다. mcp.json에서 type: local로 설정하면 로컬 서버로 인식됩니다.
핵심 설정 항목들을 살펴봅시다. command는 서버를 실행할 명령어입니다.
node, npx, python 등 어떤 명령어든 가능합니다. args는 그 명령어에 전달할 인자들입니다.
배열 형태로 작성합니다. env 속성으로 환경 변수를 전달할 수 있습니다.
API 키나 디렉토리 경로 같은 설정값을 외부에서 주입하면, 코드 수정 없이 동작을 바꿀 수 있습니다. cwd는 서버가 실행될 작업 디렉토리입니다.
파일 경로를 상대 경로로 처리해야 할 때 유용합니다. 지정하지 않으면 현재 프로젝트 디렉토리가 기본값이 됩니다.
로컬 서버의 통신 방식은 **stdio(표준 입출력)**입니다. AI 클라이언트가 서버의 stdin으로 요청을 보내고, 서버는 stdout으로 응답합니다.
복잡한 네트워크 설정 없이 프로세스 간 통신이 이루어집니다. 실행 흐름을 정리하면 이렇습니다.
AI 클라이언트가 MCP 서버를 시작하려고 합니다. mcp.json을 읽어서 command와 args를 확인합니다.
해당 명령어로 자식 프로세스를 생성합니다. 이후 stdin/stdout을 통해 JSON-RPC 메시지를 주고받습니다.
로컬 서버의 장점은 명확합니다. 첫째, 보안입니다.
데이터가 내 컴퓨터를 벗어나지 않습니다. 둘째, 커스터마이징입니다.
필요한 기능을 자유롭게 구현할 수 있습니다. 셋째, 오프라인 동작입니다.
네트워크가 없어도 작동합니다. 단점도 있습니다.
직접 서버를 만들고 관리해야 합니다. 버그가 생기면 직접 고쳐야 하고, 성능 최적화도 본인 몫입니다.
또한 각 개발자의 컴퓨터에 실행 환경을 세팅해야 합니다. 흔한 실수 중 하나는 경로 설정 오류입니다.
args에 상대 경로를 쓸 때 기준점이 어디인지 헷갈리기 쉽습니다. 확실하지 않다면 절대 경로를 사용하거나 cwd를 명시적으로 설정하세요.
김개발 씨는 로컬 MCP 서버로 레거시 시스템 연동 도구를 만들었습니다. "이제 AI한테 '고객 정보 조회해줘'라고 하면 바로 레거시 시스템에서 데이터를 가져오네요!"
실전 팁
💡 - TypeScript로 작성했다면 ts-node나 tsx로 직접 실행하거나, 먼저 빌드 후 node로 실행하세요
- 환경 변수에 민감한 정보를 넣을 때는 .env 파일을 활용하고 버전 관리에서 제외하세요
- 서버가 시작되지 않으면 command를 터미널에서 직접 실행해보며 디버깅하세요
4. 원격 MCP 서버
김개발 씨의 회사가 성장하면서 개발팀도 늘어났습니다. 각자 로컬에서 MCP 서버를 실행하다 보니 버전이 제각각이고, 설정도 미묘하게 달랐습니다.
"하나의 서버를 모두가 공유할 수 없을까요?" 박시니어 씨가 원격 MCP 서버를 제안했습니다.
**원격 MCP 서버(type: remote)**는 네트워크를 통해 접속하는 외부 MCP 서버입니다. 마치 클라우드 서비스처럼, 서버는 어딘가에서 실행되고 있고 우리는 URL로 접속만 하면 됩니다.
팀 전체가 동일한 도구를 사용하거나, 이미 구축된 서비스를 활용할 때 유용합니다.
다음 코드를 살펴봅시다.
// mcp/mcp.json - 원격 서버 설정
{
"mcpServers": {
"github-tools": {
"type": "remote",
"url": "https://mcp.github.example.com/sse",
"headers": {
"Authorization": "Bearer ${GITHUB_TOKEN}"
}
},
"shared-database": {
"type": "remote",
"url": "https://internal.company.com/mcp",
"transport": "sse"
},
"websocket-server": {
"type": "remote",
"url": "wss://realtime.example.com/mcp",
"transport": "websocket"
}
}
}
// 주요 속성 설명
// url: 원격 서버 주소 (https:// 또는 wss://)
// headers: 인증 헤더 (선택)
// transport: sse 또는 websocket (선택)
김개발 씨 팀은 10명으로 늘어났습니다. 모두가 같은 AI 도구를 사용하는데, 로컬 MCP 서버를 각자 관리하다 보니 문제가 생겼습니다.
"저는 되는데 왜 제 건 안 되죠?" "아, 최신 버전으로 업데이트 안 했구나." 박시니어 씨가 해결책을 내놓았습니다. "중앙에 MCP 서버를 하나 두고 모두가 접속하게 하면 어떨까요?
원격 서버를 쓰면 됩니다." 원격 MCP 서버는 마치 회사의 중앙 서버와 같습니다. 각자 컴퓨터에 파일을 저장하면 공유가 어렵지만, 공유 드라이브에 올리면 누구나 접근할 수 있죠.
MCP 서버도 중앙에 두면 팀 전체가 동일한 환경에서 작업할 수 있습니다. mcp.json에서 type: remote로 설정합니다.
가장 중요한 속성은 url입니다. 원격 서버의 주소를 적습니다.
HTTPS나 WSS 프로토콜을 사용하는 것이 보안상 안전합니다. headers 속성으로 인증 정보를 전달합니다.
API 키나 토큰을 헤더에 담아 보냅니다. 환경 변수 문법(${변수명})을 사용하면 실제 토큰 값을 코드에 노출하지 않을 수 있습니다.
원격 서버는 두 가지 통신 방식을 지원합니다. **SSE(Server-Sent Events)**는 HTTP 기반으로 서버가 클라이언트에게 이벤트를 푸시합니다.
단방향 통신에 적합하고, 설정이 간단합니다. WebSocket은 양방향 실시간 통신이 필요할 때 사용합니다.
transport를 명시하지 않으면 URL을 보고 자동 판단합니다. wss://로 시작하면 WebSocket, https://로 시작하면 SSE로 연결을 시도합니다.
원격 서버의 장점은 분명합니다. 첫째, 일관성입니다.
모든 팀원이 같은 버전의 도구를 사용합니다. 둘째, 유지보수입니다.
서버 한 곳만 업데이트하면 전체에 반영됩니다. 셋째, 리소스입니다.
무거운 작업을 서버에서 처리하면 클라이언트 부담이 줄어듭니다. 하지만 단점도 있습니다.
네트워크에 의존하므로 인터넷이 끊기면 사용할 수 없습니다. 서버 운영 비용이 발생하고, 보안 설정에도 신경 써야 합니다.
또한 네트워크 지연으로 로컬보다 응답이 느릴 수 있습니다. 실무에서는 둘을 조합해서 사용하는 경우가 많습니다.
민감한 작업은 로컬 서버로, 공통 도구는 원격 서버로 분리합니다. 네트워크가 끊겨도 기본 작업은 할 수 있도록 설계하는 것이죠.
주의할 점은 인증입니다. 원격 서버에 아무나 접속하면 안 됩니다.
API 키 인증, OAuth 토큰, 또는 내부 네트워크 제한 등 보안 장치를 반드시 마련해야 합니다. 김개발 씨 팀은 공통 도구들을 원격 MCP 서버로 이전했습니다.
이제 누가 언제 접속해도 같은 환경입니다. "드디어 '제 컴에서는 되는데요' 문제가 사라졌어요!"
실전 팁
💡 - 프로덕션 환경에서는 반드시 HTTPS/WSS를 사용하세요
- 환경 변수로 인증 토큰을 관리하고 절대 하드코딩하지 마세요
- 네트워크 지연을 고려해 타임아웃 설정을 적절히 조정하세요
5. MCP 도구 등록과 호출
김개발 씨는 MCP 서버 연결에 성공했습니다. 그런데 막상 사용하려니 막막했습니다.
"서버는 연결됐는데, AI한테 어떤 도구가 있는지 어떻게 알려주죠? 그리고 AI가 도구를 쓰려면 어떻게 해야 하나요?" 박시니어 씨가 도구 등록과 호출 과정을 설명하기 시작했습니다.
MCP에서 **도구(Tool)**는 AI가 호출할 수 있는 기능 단위입니다. 마치 리모컨의 버튼처럼, 각 도구는 이름, 설명, 입력 파라미터를 가지고 있습니다.
서버는 시작할 때 자신이 제공하는 도구 목록을 등록하고, AI는 필요할 때 적절한 도구를 선택해 호출합니다.
다음 코드를 살펴봅시다.
// MCP 서버에서 도구 등록하기 (TypeScript)
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
const server = new Server({ name: "my-tools", version: "1.0.0" });
// 도구 목록 제공
server.setRequestHandler("tools/list", async () => ({
tools: [
{
name: "read_file",
description: "파일의 내용을 읽어옵니다",
inputSchema: {
type: "object",
properties: {
path: { type: "string", description: "파일 경로" }
},
required: ["path"]
}
}
]
}));
// 도구 호출 처리
server.setRequestHandler("tools/call", async (request) => {
const { name, arguments: args } = request.params;
if (name === "read_file") {
const content = await fs.readFile(args.path, "utf-8");
return { content: [{ type: "text", text: content }] };
}
});
김개발 씨는 MCP 서버가 연결된 것을 확인했습니다. 하지만 한 가지 의문이 생겼습니다.
"AI가 이 서버에 뭘 요청할 수 있는지 어떻게 알죠? 메뉴판 같은 게 있어야 할 것 같은데..." 박시니어 씨가 고개를 끄덕였습니다.
"정확해요. MCP에서는 그걸 도구 등록이라고 합니다." **도구(Tool)**는 마치 스마트폰의 앱과 같습니다.
앱스토어에 가면 어떤 앱이 있는지, 각 앱이 무엇을 하는지 설명이 있죠. MCP 서버도 마찬가지입니다.
"나는 이런 도구들을 제공해요"라고 목록을 알려줍니다. 도구 등록에는 세 가지 정보가 필요합니다.
name은 도구의 고유 식별자입니다. AI가 이 이름으로 도구를 호출합니다.
description은 도구가 무엇을 하는지 설명합니다. AI는 이 설명을 보고 적절한 도구를 선택합니다.
inputSchema는 입력 파라미터의 구조를 정의합니다. JSON Schema 형식을 사용합니다.
위 코드를 자세히 살펴봅시다. tools/list 핸들러는 서버가 제공하는 도구 목록을 반환합니다.
AI 클라이언트가 서버에 연결하면 가장 먼저 이 목록을 요청합니다. 반환된 목록을 보고 AI는 "아, 이 서버에서는 파일을 읽을 수 있구나"라고 이해합니다.
tools/call 핸들러는 실제 도구 호출을 처리합니다. AI가 "read_file 도구를 path: '/home/user/test.txt' 인자로 호출해줘"라고 요청하면 이 핸들러가 실행됩니다.
request.params에서 도구 이름과 인자를 추출하고, 실제 작업을 수행한 뒤 결과를 반환합니다. 반환 형식도 중요합니다.
content 배열 안에 결과를 담습니다. type은 "text", "image", "resource" 등이 될 수 있습니다.
AI는 이 결과를 받아서 사용자에게 응답을 생성합니다. 실제 호출 흐름을 정리해봅시다.
사용자가 "test.txt 파일 내용 보여줘"라고 요청합니다. AI가 tools/list에서 받은 목록을 검토합니다.
read_file 도구가 적합하다고 판단합니다. tools/call로 도구 실행을 요청합니다.
서버가 파일을 읽어 결과를 반환합니다. AI가 결과를 정리해 사용자에게 보여줍니다.
좋은 도구 설계의 핵심은 description입니다. AI는 이 설명만 보고 도구를 선택합니다.
"파일 읽기"보다 "지정된 경로의 파일 내용을 텍스트로 읽어옵니다. 바이너리 파일은 지원하지 않습니다"처럼 구체적으로 작성하세요.
inputSchema도 꼼꼼하게 정의해야 합니다. required 배열로 필수 파라미터를 명시하고, 각 파라미터에 description을 달아주면 AI가 더 정확하게 인자를 전달합니다.
주의할 점이 있습니다. 도구 이름은 서버 내에서 유일해야 합니다.
또한 도구 실행 중 에러가 발생하면 적절한 에러 메시지를 반환해야 합니다. 그래야 AI가 사용자에게 "파일을 찾을 수 없습니다" 같은 의미 있는 응답을 할 수 있습니다.
김개발 씨는 자신만의 도구를 만들어 등록했습니다. "회사 내부 API 호출하는 도구를 만들었어요.
AI한테 '고객 목록 조회해줘'라고 하니까 알아서 API 호출하고 결과를 보여주네요!"
실전 팁
💡 - description은 AI가 도구를 선택하는 핵심 기준이므로 구체적이고 명확하게 작성하세요
- inputSchema의 required 배열로 필수 파라미터를 명시하면 호출 오류가 줄어듭니다
- 에러 상황에서도 구조화된 응답을 반환해야 AI가 적절히 처리할 수 있습니다
6. 커스텀 MCP 서버 연동하기
김개발 씨는 이제 MCP의 기본을 이해했습니다. 마지막 관문이 남았습니다.
회사의 특수한 요구사항에 맞는 커스텀 MCP 서버를 처음부터 끝까지 만들어 연동하는 것입니다. "직접 서버를 만들어서 Claude Code에 연결하고 싶어요." 박시니어 씨가 실전 가이드를 시작했습니다.
커스텀 MCP 서버는 특정 요구사항에 맞게 직접 구현하는 MCP 서버입니다. 공식 SDK를 사용하면 표준을 준수하면서도 원하는 기능을 자유롭게 구현할 수 있습니다.
파일 시스템, 데이터베이스, 외부 API 등 어떤 것이든 AI가 접근할 수 있는 도구로 만들 수 있습니다.
다음 코드를 살펴봅시다.
// mcp/custom-server/index.ts - 커스텀 MCP 서버 전체 구현
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
// 서버 인스턴스 생성
const server = new Server(
{ name: "custom-tools", version: "1.0.0" },
{ capabilities: { tools: {} } }
);
// 도구 목록 등록
server.setRequestHandler("tools/list", async () => ({
tools: [{
name: "get_weather",
description: "도시의 현재 날씨 정보를 조회합니다",
inputSchema: {
type: "object",
properties: {
city: { type: "string", description: "도시 이름" }
},
required: ["city"]
}
}]
}));
// 도구 호출 처리
server.setRequestHandler("tools/call", async (req) => {
if (req.params.name === "get_weather") {
const { city } = req.params.arguments;
// 실제로는 날씨 API 호출
return { content: [{ type: "text", text: `${city}: 맑음, 22°C` }] };
}
throw new Error(`Unknown tool: ${req.params.name}`);
});
// 서버 시작
const transport = new StdioServerTransport();
await server.connect(transport);
김개발 씨는 드디어 최종 미션에 도전합니다. 회사 내부 시스템과 연동하는 MCP 서버를 직접 만드는 것입니다.
"기존 서버들은 우리 요구사항에 안 맞아요. 직접 만들어야겠어요." 박시니어 씨가 차근차근 안내를 시작했습니다.
"걱정 마세요. SDK가 복잡한 부분을 다 처리해줍니다.
우리는 비즈니스 로직에만 집중하면 돼요." 커스텀 MCP 서버 구축은 마치 레고 조립과 같습니다. SDK가 기본 블록을 제공하고, 우리는 원하는 모양으로 조립만 하면 됩니다.
통신 프로토콜, 메시지 파싱 같은 복잡한 부분은 SDK가 처리합니다. 먼저 프로젝트를 세팅합니다.
mcp/ 디렉토리 안에 서버 폴더를 만들고, package.json을 생성합니다. 필요한 의존성은 @modelcontextprotocol/sdk입니다.
TypeScript를 사용한다면 ts-node나 tsx도 설치합니다. 코드를 살펴봅시다.
첫 번째 단계는 Server 인스턴스 생성입니다. name과 version으로 서버를 식별합니다.
capabilities에서 이 서버가 무엇을 제공하는지 선언합니다. tools: {}는 도구 기능을 제공한다는 의미입니다.
두 번째 단계는 도구 등록입니다. setRequestHandler로 "tools/list" 요청을 처리합니다.
앞서 배운 것처럼 name, description, inputSchema를 정의합니다. 여러 도구를 등록하려면 tools 배열에 추가하면 됩니다.
세 번째 단계는 도구 실행 로직입니다. "tools/call" 핸들러에서 실제 작업을 수행합니다.
req.params.name으로 어떤 도구가 호출되었는지 확인하고, req.params.arguments에서 인자를 추출합니다. 이 안에서 API 호출, 데이터베이스 조회 등 원하는 작업을 합니다.
네 번째 단계는 서버 시작입니다. StdioServerTransport는 표준 입출력으로 통신하는 전송 계층입니다.
로컬 서버라면 이것을 사용합니다. server.connect()로 서버를 시작합니다.
이제 mcp.json에 등록합니다. type을 local로 설정하고, command는 ts-node나 node로, args에 서버 파일 경로를 지정합니다.
저장하면 AI 클라이언트가 자동으로 서버를 시작합니다. 디버깅 팁도 알아두세요.
서버가 제대로 동작하는지 확인하려면 터미널에서 직접 실행해봅니다. 에러가 발생하면 스택 트레이스가 출력됩니다.
console.error로 디버그 로그를 찍을 수도 있습니다. stdout은 MCP 통신에 사용되므로 stderr로 로그를 출력해야 합니다.
실무에서 주의할 점이 있습니다. 도구 실행이 오래 걸리면 타임아웃이 발생할 수 있습니다.
무거운 작업은 비동기로 처리하거나, 진행 상황을 알려주는 방식을 고려하세요. 또한 에러 처리를 꼼꼼히 해야 합니다.
try-catch로 예외를 잡고, 의미 있는 에러 메시지를 반환하세요. 김개발 씨는 회사 내부 API를 호출하는 MCP 서버를 완성했습니다.
고객 정보 조회, 주문 상태 확인, 재고 조회까지 모두 AI로 할 수 있게 되었습니다. "이제 AI한테 '지난달 매출 상위 고객 10명 알려줘'라고 하면 바로 답이 나와요!" 박시니어 씨가 마지막으로 덧붙였습니다.
"MCP의 진짜 힘은 확장성에 있어요. 필요한 도구를 계속 추가하면 AI의 능력이 무한히 확장됩니다."
실전 팁
💡 - 디버깅 시 console.error를 사용하세요. stdout은 MCP 통신에 예약되어 있습니다
- 도구 실행 시간이 길면 타임아웃을 고려해 비동기 패턴을 적용하세요
- 에러 발생 시 구체적인 메시지를 반환해야 AI가 사용자에게 적절히 안내할 수 있습니다
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
마이크로서비스 배포 완벽 가이드
Kubernetes를 활용한 마이크로서비스 배포의 핵심 개념부터 실전 운영까지, 초급 개발자도 쉽게 따라할 수 있는 완벽 가이드입니다. 실무에서 바로 적용 가능한 배포 전략과 노하우를 담았습니다.
Application Load Balancer 완벽 가이드
AWS의 Application Load Balancer를 처음 배우는 개발자를 위한 실전 가이드입니다. ALB 생성부터 ECS 연동, 헬스 체크, HTTPS 설정까지 실무에 필요한 모든 내용을 다룹니다. 초급 개발자도 쉽게 따라할 수 있도록 단계별로 설명합니다.
고객 상담 AI 시스템 완벽 구축 가이드
AWS Bedrock Agent와 Knowledge Base를 활용하여 실시간 고객 상담 AI 시스템을 구축하는 방법을 단계별로 학습합니다. RAG 기반 지식 검색부터 Guardrails 안전 장치, 프론트엔드 연동까지 실무에 바로 적용 가능한 완전한 시스템을 만들어봅니다.
에러 처리와 폴백 완벽 가이드
AWS API 호출 시 발생하는 에러를 처리하고 폴백 전략을 구현하는 방법을 다룹니다. ThrottlingException부터 서킷 브레이커 패턴까지, 실전에서 바로 활용할 수 있는 안정적인 에러 처리 기법을 배웁니다.
AWS Bedrock Action Groups 완벽 가이드
AWS Bedrock의 Action Groups를 활용하여 AI 에이전트가 외부 API와 연동하는 방법을 배웁니다. OpenAPI 스키마 작성부터 파라미터 정의, 응답 형식 지정까지 실무에 필요한 모든 내용을 다룹니다.