MCP Server 만들기 일단 첫 목표로는 코드리뷰 기능이 아니라, 단순하게 hello라고 출력되는 tool을 가진 MCP server를 만들어본다
// server.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({
name: "code-review-agent",
version: "0.1.0",
description: "코드 리뷰 에이전트",
});
server.registerTool(
"hello",
{
title: "Hello",
description: "Say hello to a user",
inputSchema: {
name: z.string().describe("User name"),
},
},
async ({ name }) => {
return {
content: [
{
type: "text",
text: `Hello, ${name}`,
},
],
};
},
);
const transport = new StdioServerTransport();
await server.connect(transport);
각 코드의 개념으로는 McpServer - MCP tool들을 등록하는 서버 객체
registerTool - agent나 client가 호출할 수 있는 tool을 등록
inputSchema - tool이 어떤 입력값을 받는지 정의
StdioServerTransport - 표준입력/표준출력을 통해 MCP client와 통신하는 transport
server.connect - MCP server를 transport에 연결하고 실행 상태로 만든다
server를 실행하는 경우에는 'npm run dev:server'를 터미널에 입력한다. 아무것도 나오지 않는것이 정상이다. MCP stdio server는 웹 서버처럼 포트를 열고 로그를 출력하는 방식이 아니라, MCP client가 표준입력으로 요청을 보낼 때까지 기다리는 구조이기 떄문이다.
MCP Client 만들기 다음으로 client.ts를 만드는데, 이 client는server.ts를 자식 프로세스로 실행하고, MCP 프로토콜로 연결한 뒤 tool 목록을 조회한다.
// client.ts
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
const client = new Client({
name: "test-client",
version: "0.1.0",
});
const transport = new StdioClientTransport({
command: "npx",
args: ["tsx", "src/server.ts"],
});
await client.connect(transport);
const tools = await client.listTools();
console.log(tools);
여기서의 개념은 Client - MCP server에 요청을 보내는 클라이언트 객체
StdioClientTransport - MCP server 프로세스를 실행하고 stdio로 연결하는 transport
client.connect - client와 server를 MCP로 연결
client.listTools - server가 제공하는 tool 목록을 조회 이후에 터미널에 'npm run dev:client' 를 입력한다면 이렇게 출력된다!
이것의 의미는 - server.ts가 정상 실행되었다 - hello tool이 MCP server에 등록되었다 - client.ts가 MCP server에 연결되었다 - client가 server의 tool 목록을 성공적으로 조회했다 이렇게이다.
2. 구조와 흐름
지금까지의 구조는 이러하다.
server.ts - MCP server - hello tool 제공 - stdio transport 사용
client.ts - MCP client - server.ts를 자식 프로세스로 실행 - tool 목록 조회
그리고 전체 흐름은 npm run dev:client 입력 → client.ts 실행 → StdioClientTransport가 server.ts 실행 → MCP 연결 → client.listTools() → hello tool 정보 출력
3. 해야할 일
여기까지 함으로써, MCP server/client의 최소 구조는 완성된 것 같다.
이 다음부터는 단순하게 hello를 출력하는 대신, 코드리뷰나 분석에 필요한 tool을 하나씩 추가해볼 예정이다.