첫 번째 MCP 서버 만들기: TypeScript 프로젝트 설정
요약
Model Context Protocol(MCP) 서버 구축을 위한 첫 단계로, Node.js, TypeScript, Express.js를 활용한 프로젝트 환경 설정 방법을 안내합니다. 개발자가 MCP 서버 로직을 구현하기 전 필요한 기술 스택의 역할과 준비 사항을 다룹니다.
핵심 포인트
- Node.js를 활용한 서버 측 런타임 환경 구축
- TypeScript 도입을 통한 타입 안전성 및 개발 생산성 확보
- Express.js를 이용한 경량 웹 프레임워크 구성
- MCP 서버 개발을 위한 필수 사전 준비 사항 안내
첫 번째 MCP 서버 만들기: TypeScript 프로젝트 설정
이전 기사에서 Model Context Protocol (MCP) 이론을 이해하셨나요? 완벽합니다! 이제 코드로 직접 실습해 볼 시간입니다. 우리는 함께 기능적인 MCP 서버의 기초를 구축할 것입니다. 당황하지 마세요. 집을 짓는 것처럼 단계별로 진행할 것입니다. 먼저 기초를 다지고, 그다음 벽을 세우고, 마지막으로 지붕을 올릴 것입니다.
서론 (Introduction)
개발자로서의 커리어 동안, 저는 이론이 현실이 되는 그 마법 같은 순간에 항상 매료되어 왔습니다. 여러분의 첫 "Hello World"를 기억하시나요? 우리가 함께 경험할 것이 바로 그것입니다. 다만 MCP 버전일 뿐이죠. 이 기사에서는 Node.js, TypeScript, 그리고 Express.js를 사용하여 개발 환경을 준비할 것입니다. 복잡한 것은 없으며, 단지 적절한 도구를 적절한 위치에 배치할 뿐입니다.
목표는 간단합니다. 이 튜토리얼이 끝날 때쯤, 여러분은 MCP 서버 로직을 호스팅할 준비가 된 완벽하게 구성된 프로젝트를 갖게 될 것입니다. 이것을 DIY 프로젝트를 시작하기 전에 작업실을 준비하는 과정이라고 생각하세요. 도구를 정리하고, 필요한 것이 모두 있는지 확인한 다음, 평온하게 창작을 시작할 수 있습니다.
왜 이 기술들을 사용하는가? (Why These Technologies?)
명령어를 무작정 입력하기 전에, 우리의 기술적 선택을 이해하기 위해 잠시 시간을 가져봅시다. 반드시 이 스택을 사용해야 하는 것은 아니지만, 초보자에게 제가 이를 추천하는 이유는 다음과 같습니다.
Node.js: 런타임 환경 (The Runtime Environment)
Node.js는 JavaScript를 서버 측에서 실행할 수 있게 해줍니다. 거대한 커뮤니티와 수천 개의 사용 가능한 패키지를 보유한 업계 표준이 되었습니다. 우리의 MCP 서버를 위해, Node.js는 파일 시스템, 네트워크 관리, 그리고 AI와 여러분의 데이터 사이에 가교를 만드는 데 필요한 모든 것에 대한 접근 권한을 제공합니다.
TypeScript: 타입 안전성 (Type Safety)
TypeScript는 안전망이 있는 JavaScript와 같습니다. 정적 타입 (Static types)을 추가하여 많은 어처구니없는 오류로부터 우리를 구해줍니다. AI 요청을 처리하고 잠재적으로 민감한 데이터를 조작하는 서버를 구축할 때, 이 정도 수준의 검증을 갖추는 것은 안심이 됩니다. 게다가, TypeScript를 사용하면 에디터의 자동 완성 (Auto-completion) 기능이 마법처럼 변합니다.
Express.js: 미니멀리스트 웹 프레임워크 (The Minimalist Web Framework)
Express는 Node.js 웹 개발의 스위스 아미 나이프 (Swiss Army knife)입니다. 이를 통해 라우트 (routes)를 생성하고, HTTP 요청 (HTTP requests)을 처리하며, 서버를 적절하게 구조화할 수 있습니다. Express는 가볍고 빠르며, JSON 명령을 수신할 우리의 MCP 서버에 완벽하게 적합합니다.
시작 전 준비 사항 (Prerequisites Before Starting)
다음 항목들이 컴퓨터에 설치되어 있는지 확인하세요:
- Node.js 버전 16 이상: 터미널에서
node --version으로 확인하세요. Node.js가 설치되어 있지 않다면, 공식 nodejs.org 웹사이트에서 다운로드하세요. - npm (Node Package Manager): Node.js와 함께 자동으로 설치됩니다.
npm --version으로 확인하세요. - 코드 에디터 (A code editor): Visual Studio Code는 TypeScript에 매우 훌륭하지만, 본인이 편하게 사용하는 것을 사용해도 좋습니다.
- 터미널 (A terminal): Bash, Zsh, PowerShell 등 무엇이든 상관없습니다. 명령어를 실행할 수만 있으면 됩니다.
모든 준비가 되었나요? 좋습니다, 이제 터미널을 열어봅시다!
1단계: 폴더 생성 및 초기화 (Step 1: Folder Creation and Initialization)
워크스페이스 (workspace)를 만드는 것부터 시작해 보겠습니다. 터미널을 열고 다음 명령어들을 입력하세요:
<span class="nb">mkdir </span>mcp-server
<span class="nb">cd </span>mcp-server
npm init <span class="nt">-y</span>
...
방금 어떤 일이 일어났나요?
첫 번째 줄은 mcp-server라는 이름의 새 폴더를 생성합니다. 이것은 우리의 집이자 프로젝트입니다. 두 번째 줄은 해당 폴더로 들어갑니다. 세 번째 줄은 npm init -y를 통해 Node.js 프로젝트를 초기화합니다.
-y 플래그는 "모두 예 (yes to all)"를 의미합니다. 즉, 모든 기본 옵션을 자동으로 수락합니다. 이 플래그가 없다면, npm은 일련의 질문들(프로젝트 이름, 버전, 설명 등...)을 던질 것입니다. 지금은 기본값으로도 충분합니다.
이 명령어는 매우 중요한 파일인 package.json을 생성합니다. 이것은 프로젝트의 신분증과 같습니다. 모든 의존성 (dependencies), 사용 가능한 스크립트 (scripts), 그리고 프로젝트 메타데이터 (metadata)를 나열합니다. 이 파일을 열어보면 다음과 같은 내용을 볼 수 있습니다:
<span class="p">{</span><span class="w">
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mcp-server"</span><span class="p">,</span><span class="w">
</span><span class="nl">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1.0.0"</span><span class="p">,</span><span class="w">
...
기본적인 내용이지만, 진행하면서 계속 발전시켜 나갈 것입니다.
2단계: TypeScript 설치하기
이제 프로젝트에 TypeScript를 갖춰보겠습니다. 다음 명령어를 입력하세요:
npm <span class="nb">install </span>typescript ts-node @types/node <span class="nt">--save-dev</span>
이 명령어를 자세히 살펴보겠습니다:
npm install은 매우 명시적입니다. 패키지를 설치한다는 의미입니다. --save-dev는 이 패키지들이 개발 의존성 (development dependencies)임을 나타내며, 프로덕션 (production) 환경이 아닌 개발 단계에서만 필요함을 의미합니다.
각 패키지의 역할은 다음과 같습니다:
- typescript: TypeScript 컴파일러 (compiler) 그 자체입니다. 작성한 TypeScript 코드를 Node.js에서 실행할 수 있는 JavaScript로 변환합니다.
- ts-node: 수동으로 컴파일할 필요 없이 TypeScript 코드를 직접 실행할 수 있게 해주는 마법 같은 도구입니다. 개발 과정에서 엄청난 시간을 절약해 줍니다.
- @types/node: Node.js 환경을 위한 타입 정의 (Type definitions)입니다. 덕분에 TypeScript는
fs.readFile,path.join등과 같은 Node.js 네이티브 함수들을 이해할 수 있습니다.
설치가 완료되면 package.json을 확인해 보세요. 새로운 섹션이 나타났을 것입니다:
<span class="nl">"devDependencies"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"@types/node"</span><span class="p">:</span><span class="w"> </span><span class="s2">"^20.10.0"</span><span class="p">,</span><span class="w">
</span><span class="nl">"ts-node"</span><span class="p">:</span><span class="w"> </span><span class="s2">"^10.9.2"</span><span class="p">,</span><span class="w">
...
버전은 이 글을 읽는 시점에 따라 다를 수 있지만, 원리는 동일합니다.
Step 3: TypeScript 설정하기
TypeScript는 코드를 어떻게 컴파일할지 알기 위해 설정 파일이 필요합니다. 다음 명령어로 파일을 생성해 봅시다:
npx tsc <span class="nt">--init</span>
작은 기술적 참고 사항: npx는 패키지를 전역(globally)으로 설치하지 않고 실행합니다. 여기서는 --init 옵션과 함께 TypeScript 컴파일러 (tsc)를 실행하여 설정 파일을 생성합니다.
이 명령은 각 옵션을 설명하는 수많은 주석이 포함된 tsconfig.json 파일을 생성합니다. 내용이 방대하지만 학습에 도움이 됩니다! 우리 프로젝트에서 가장 중요한 옵션들은 다음과 같습니다:
<span class="p">{</span><span class="w">
</span><span class="nl">"compilerOptions"</span><span class="p">:</</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"target"</span><span class="p">:</</span><span class="w"> </span><span class="s2">"ES2020"</span><span class="p">,</span><span class="w">
...
간단한 설명:
- target: 대상 JavaScript 버전입니다. ES2020은 현대적이며 지원이 잘 됩니다.
- module: 모듈 시스템입니다. CommonJS는 Node.js의 표준입니다.
- outDir: 컴파일된 JavaScript 파일이 위치할 디렉토리입니다 (이 폴더는 나중에 생성할 것입니다).
- rootDir: TypeScript 소스 코드가 위치하는 곳입니다.
- strict: 모든 TypeScript 엄격 검사 (strict checks)를 활성화합니다. 다소 까다롭지만 버그를 방지해 줍니다.
지금은 생성된 기본값만으로도 충분합니다. 나중에 필요에 따라 세부적으로 조정할 수 있습니다.
Step 4: Express.js 설치하기
기초를 다지는 마지막 벽돌는 우리의 HTTP 요청을 처리할 프레임워크인 Express.js입니다. 다음 명령어로 설치하세요:
npm <span class="nb">install </span>express
npm <span class="nb">install</span> @types/express <span class="nt">--save-dev</span>
왜 명령어가 두 개인가요?
- express: 라이브러리 자체이며, 프로덕션(production) 환경에서 필요합니다. 따라서
--save-dev를 붙이지 않습니다. - @types/express: Express를 위한 타입 정의 (Type definitions)이며, 개발 단계에서만 필요합니다. 그래서
--save-dev를 사용합니다.
이제 최종적인 package.json은 다음과 같은 모습이어야 합니다:
<span class="p">{</span><span class="w">
</span><span class="nl">"name"</span><span class="p">:</</span><span class="w"> </span><span class="s2">"mcp-server"</span><span class="p">,</span><span class="w">
</span><span class="nl">"version"</span><span class="p">:</</span><span class="w"> </span><span class="s2">"1.0.0"</span><span class="p">,</span><span class="w">
...
버전 번호는 약간 다를 수 있지만, 필수적인 요소들은 모두 포함되어 있습니다.
설치 확인 (Installation Verification)
더 진행하기 전에, 모든 것이 제대로 작동하는지 확인해 봅시다. src 폴더와 테스트 파일을 생성합니다:
<span class="nb">mkdir </span>src
다음의 간단한 내용으로 src/index.ts 파일을 생성합니다:
<span class="k">import</span> <span class="nx">express</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">express</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">app</span> <span class="o">=</span> <span class="nx">express</span><span class="p">();</span>
...
이 코드는 무엇을 하나요?
Express를 임포트(import)하고 애플리케이션을 생성합니다. / 경로에 간단한 JSON 메시지를 반환하는 GET 라우트(route)를 정의합니다. 그리고 3000번 포트에서 서버를 실행합니다.
이 코드를 실행하기 위해, package.json에 스크립트를 추가해 봅시다. scripts 섹션을 다음과 같이 수정합니다:
<span class="nl">"scripts"</span><span class="p">:</</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"dev"</span><span class="p">:</</span><span class="w"> </span><span class="s2">"ts-node src/index.ts"</span><span class="p">,</span><span class="w">
</span><span class="nl">"test"</span><span class="p">:</</span><span class="w"> </span><span class="s2">"echo </span><span class="se">\"</span><span class="s2">Error: no test specified</span><span class="se">\"</span><span class="s2"> && exit 1"</span><span class="w">
...
이제, 실행합니다:
npm run dev
모든 설정이 올바르게 되었다면, 터미널에 다음과 같은 내용이 표시될 것입니다:
✅ Server launched on http://localhost:3000
브라우저를 열고 http://localhost:3000으로 이동하세요. 다음과 같은 내용을 볼 수 있을 것입니다:
<span class="p">{</span><span class="w">
</span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"MCP server operational!"</span><span class="w">
</span><span class="p">}</span><span class="w">
...
축하합니다! 환경 설정이 완벽하게 완료되었습니다.
프로젝트 구성 (Project Organization)
마치기 전에, 프로젝트를 조금 정리해 봅시다. 제가 권장하는 구조는 다음과 같습니다:
mcp-server/
├── src/
│ ├── index.ts # 서버 진입점 (Server entry point)
...
또한, 불필요한 파일이 버전 관리되는 것을 방지하기 위해 .gitignore 파일을 생성하세요:
node_modules/
dist/
*.log
...
다음 단계 (Next Steps)
이제 탄탄한 기초를 마련했습니다! 이 시리즈의 다음 글들에서는 다음과 같은 내용이 기다리고 있습니다:
- Part 3: AI가 로컬 파일을 읽을 수 있도록 하는 첫 번째 MCP
readFile도구(tool) 만들기 - Part 4: 도구 탐색 시스템 (그 유명한 "메뉴") 구현하기
- Part 5: 권한(permissions) 및 보안 관리하기
- Part 6: Claude 또는 ChatGPT로 서버 테스트하기
결론 (Conclusion)
우리는 방금 MCP 서버의 견고한 토대를 마련했습니다. 물론 지금은 많은 일을 하지 않지만, 모든 도구가 갖춰져 있습니다. 이는 복잡한 요리를 시작하기 전에 주방을 준비해 두는 것과 같습니다. 모든 것이 정리되어 있고 접근하기 쉬우며, 우리는 본질적인 것에 집중할 수 있습니다.
다음 글에서는 첫 번째 실제 MCP 도구인 readFile 함수를 만들 것입니다. 이 함수는 AI가 사용자의 컴퓨터에 있는 파일을 읽을 수 있게 해줍니다. 여기서부터 진짜 마법이 시작됩니다!
이 설정으로 이것저것 실험해 보는 것을 주저하지 마세요. 다른 Express 라우트를 추가해 보거나, TypeScript를 다뤄보며 환경에 익숙해지세요. 이러한 기초가 익숙해질수록 나머지 과정도 더 자연스럽게 느껴질 것입니다.
함께 읽어보세요:
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기