본문 바로가기
카테고리 없음

『개발자가 반드시 알아야 하는 MCP 지식』 전자책 실습용 소스코드

by Echinacea 2026. 7. 22.
반응형

전자책 『개발자가 반드시 알아야 하는 MCP 지식』 5장의 실습에 쓰이는 예제 소스코드를 이 글과 하단 첨부파일로 공개합니다. 책을 보며 그대로 따라 실행할 수 있도록, 복붙하면 바로 돌아가는 전체 코드를 담았습니다.

이 글은 무엇인가요

전자책 『개발자가 반드시 알아야 하는 MCP 지식』의 5장(실습 — 나의 첫 MCP 서버 만들기) 에서 사용하는 예제 코드입니다. 책에서는 각 코드가 왜 그렇게 동작하는지 개념과 함께 설명하고, 이 글에서는 그 실습 소스코드 전체를 제공합니다. 책을 읽는 분은 이 페이지를 열어두고 그대로 따라 하시면 됩니다.

아직 책을 보지 않으셨다면, 이 코드만으로도 "동작하는 MCP 서버 하나"를 만들어볼 수 있으니 편하게 따라 해보세요.

MCP를 잠깐만 짚고 가면

MCP(Model Context Protocol)는 AI를 외부 도구·데이터에 연결하는 공용 규격입니다. 2024년 11월 Anthropic이 공개한 뒤 OpenAI·Google·Microsoft가 모두 채택하고 리눅스 재단이 관리하는, 사실상의 업계 표준이 됐죠. 쉽게 말해 "AI 세계의 USB-C 포트"입니다. 자세한 개념과 배경은 전자책 1~4장에서 다루고, 여기서는 바로 실습으로 들어갑니다.

이 예제로 만드는 것

하나의 서버 안에 MCP의 핵심 4요소를 모두 담았습니다.

  • Tool add — 가장 기본적인 도구 (두 수를 더함)
  • Tool get_weather — 구조화된 출력을 반환하는 도구
  • Resource user-profile — URI로 데이터를 제공하는 리소스
  • Prompt review-code — 사용자가 고르는 프롬프트 템플릿

0. 준비물

  • Node.js 18 이상
  • 코드 에디터 (VS Code 등)
  • TypeScript / JavaScript 기초

1. 프로젝트 세팅

빈 폴더에서 프로젝트를 초기화하고, SDK와 Zod를 설치합니다. Zod는 도구의 입력 형식을 선언하는 검증 라이브러리로, MCP 서버 작성의 사실상 표준 짝꿍입니다.

 
bash
mkdir my-first-mcp && cd my-first-mcp
npm init -y
npm pkg set type=module
npm install @modelcontextprotocol/sdk zod
npm install -D typescript tsx @types/node

2. 실습 전체 코드 (src/index.ts)

src/index.ts 파일을 만들고 아래를 그대로 붙여넣으세요. 주석까지 그대로 두면 각 부분이 무슨 역할인지 바로 이해됩니다. (책 5장의 설명과 함께 보면 더 좋습니다.)

 
typescript
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

// 리소스가 돌려줄 가짜 데이터 소스.
// 실무에서는 이 자리에 실제 DB나 API 호출이 들어갑니다.
type User = { id: string; name: string; role: string };

async function getUser(userId: string): Promise<User> {
  const users: Record<string, User> = {
    "1": { id: "1", name: "Ada Lovelace", role: "engineer" },
    "42": { id: "42", name: "Grace Hopper", role: "admiral" },
  };
  return users[userId] ?? { id: userId, name: "Unknown", role: "guest" };
}

// 0) 서버 생성
const server = new McpServer({ name: "my-first-mcp", version: "1.0.0" });

// 1) Tool — add
//    주의: inputSchema는 Zod '필드들의 객체'(raw shape)로 준다.
//    z.object({...})로 감싸지 않는다!
server.registerTool(
  "add",
  {
    title: "더하기",
    description: "두 수를 더한다",
    inputSchema: { a: z.number(), b: z.number() },
  },
  async ({ a, b }) => ({
    content: [{ type: "text", text: String(a + b) }],
  })
);

// 2) Tool — 구조화된 출력(get_weather)
server.registerTool(
  "get_weather",
  {
    title: "날씨 조회",
    description: "도시의 현재 날씨를 반환한다",
    inputSchema: { location: z.string() },
    outputSchema: { tempC: z.number(), summary: z.string() },
  },
  async ({ location }) => {
    const data = { tempC: 20, summary: `${location}: 맑음` };
    return {
      content: [{ type: "text", text: JSON.stringify(data) }],
      structuredContent: data,
    };
  }
);

// 3) Resource — users://{userId}/profile
server.registerResource(
  "user-profile",
  new ResourceTemplate("users://{userId}/profile", { list: undefined }),
  { title: "사용자 프로필", mimeType: "application/json" },
  async (uri, { userId }) => ({
    contents: [
      { uri: uri.href, text: JSON.stringify(await getUser(String(userId)), null, 2) },
    ],
  })
);

// 4) Prompt — review-code
server.registerPrompt(
  "review-code",
  {
    title: "코드 리뷰",
    description: "코드의 문제점과 개선점을 점검한다",
    argsSchema: { code: z.string() },
  },
  ({ code }) => ({
    messages: [
      { role: "user", content: { type: "text", text: `다음 코드를 리뷰해줘:\n\n${code}` } },
    ],
  })
);

// stdio로 연결하고 대기.
// 로그는 반드시 console.error(stderr)로! console.log는 통신을 깨뜨린다.
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("[my-first-mcp] running on stdio");

3. 실행하고 눈으로 확인하기 (MCP Inspector)

호스트에 붙이기 전에, 공식 디버깅 도구 MCP Inspector로 서버 단독 테스트를 할 수 있습니다. 설치 없이 바로 실행됩니다.

 
bash
npx @modelcontextprotocol/inspector npx tsx src/index.ts

브라우저에 Inspector가 열리면, 왼쪽에서 서버에 연결한 뒤 Tools 탭에서 add를 골라 값을 넣고 실행해보세요. 결과가 나오면 성공입니다. (책 5.3절과 동일한 화면입니다.)

4. Claude Desktop에 연결하기

claude_desktop_config.json에 아래를 추가하고(경로는 절대경로로), Claude Desktop을 완전히 재시작하세요.

 
json
{
  "mcpServers": {
    "my-first-mcp": {
      "command": "npx",
      "args": ["tsx", "/절대/경로/my-first-mcp/src/index.ts"]
    }
  }
}
  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

자주 걸리는 함정 3가지

  1. console.log 쓰지 말 것. stdout은 MCP 메시지 통로입니다. 디버그 로그는 반드시 console.error(stderr)로 찍으세요. 초보자가 가장 많이 겪는 오류입니다.
  2. inputSchema는 필드 객체. { a: z.number() } 형태여야 하며, z.object({...})로 감싸면 안 됩니다.
  3. 경로는 절대경로 + 재시작. 호스트 설정에 상대경로를 쓰거나, 설정 후 재시작을 안 하면 연결되지 않습니다.

마치며

여기까지 따라오셨다면, AI가 실제로 호출할 수 있는 도구·리소스·프롬프트를 가진 MCP 서버를 직접 만든 것입니다. 이제 getUser 자리에 진짜 API를 붙이고 도구를 늘려가면, 그게 바로 실전 MCP 서버예요.


개념까지 제대로 이해하고 싶다면

이 코드는 전자책 『개발자가 반드시 알아야 하는 MCP 지식』 의 실습 부분입니다. 책에서는 이 코드가 왜 이렇게 동작하는지를 포함해 다음을 비유로 쉽게, 실습으로 확실하게 다룹니다.

  • 호스트·클라이언트·서버의 관계와 메시지 흐름
  • stdio와 Streamable HTTP, 언제 무엇을 쓰나
  • 프롬프트 인젝션·토큰 패스스루 같은 보안 원칙과 OAuth
  • 스펙·SDK 로드맵과 "나는 어디까지 알아야 하나"

React·TypeScript 개발자가 하루이틀이면 "아, 이게 MCP구나"를 체감하도록 만들었습니다. 미리보기와 목차는 아래에서 확인하세요.

 

소스코드 다운로드

 

 

반응형

댓글