Apidog

올인원 협업 API 개발 플랫폼

API 설계

API 문서

API 디버깅

API 모킹

API 자동화 테스트

클라우드 데스크탑에 연결된 MCP 서버를 타입스크립트로 구축한 방법

Young-jae

Young-jae

Updated on April 9, 2025

모델 컨텍스트 프로토콜(MCP)은 AI 어시스턴트가 외부 도구 및 데이터 소스와 상호 작용하는 방식에서 중요한 발전을 나타냅니다. Anthropic에 의해 개발된 MCP는 Claude가 맞춤형 서버와 원활하게 통신할 수 있도록 하여 실시간 정보에 접근하고, 복잡한 워크플로를 실행하며, 대화 문맥을 벗어나지 않고 API와 상호작용할 수 있게 합니다. 이 기능은 Claude를 독립적인 LLM에서 외부 기능을 활용하면서도 대화의 일관성을 유지할 수 있는 다재다능한 어시스턴트로 변모시킵니다.

이 포괄적인 가이드에서는 TypeScript MCP 서버를 처음부터 구축하고 이를 Claude Desktop과 연결하는 과정을 안내합니다. 이 통합을 구현함으로써 Claude는 실시간 데이터를 검색하거나, 계산을 수행하거나, 맞춤형 비즈니스 논리를 대화 내에서 직접 상호작용하도록 할 수 있습니다.

MCP 서버 구현에 들어가기 전에 API 개발 도구의 선택이 워크플로의 효율성에 상당한 영향을 미칠 수 있다는 점을 언급할 가치가 있습니다.

  • Postman이 오랫동안 업계 표준으로 자리잡았지만, Apidog는 우리가 구축하고 있는 현대적인 개발 워크플로에 완벽하게 보완하는 우수한 대안으로 부상했습니다.
  • 개발 중인 API에 대한 Postman의 제한과 달리, Apidog는 API 사양과 요청 간에 실시간 동기화를 제공하여 API가 발전함에 따라 문서와 테스트가 자동으로 최신 상태를 유지합니다.
  • 비주얼 API 사양 작성, 무제한 수집 실행(Postman의 경우 월 25회 제한 비교), 자동 생성된 요청 및 모의 응답과 같은 강력한 기능으로 Apidog는 전체 API 생애 주기를 간소화합니다. 시각적 테스트 생성 및 자체 호스팅 러너를 포함한 종합적인 테스트 기능은 저희 MCP 서버와 같은 복잡한 통합을 구현하는 팀에 이상적입니다.

TypeScript MCP 서버를 구축하면서 Apidog의 협업 기능과 개발 중심의 접근 방식이 팀의 생산성을 향상하고 API가 일관되며 잘 테스트되고 철저하게 문서화되도록 하는 방법을 고려해 보시기 바랍니다.

버튼

모델 컨텍스트 프로토콜 이해하기

모델 컨텍스트 프로토콜은 Claude가 외부 서비스와 통신하는 표준화된 방법을 정의합니다. Claude가 외부 소스에서 정보가 필요하다고 판단하면, 특별히 포맷된 JSON 요청을 통해 MCP 서버를 호출할 수 있습니다. 서버는 이 요청을 처리하고 요청된 데이터를 반환하며, Claude는 이를 응답에 통합할 수 있습니다.

MCP는 기존 AI 통합 접근 방식에 비해 여러 가지 장점을 제공합니다:

  • 문맥 인식: Claude는 요청을 할 때 전체 대화 기록을 유지합니다
  • 양방향 통신: 프로토콜은 Claude와 귀하의 서버 간의 복잡한 상호작용을 지원합니다
  • 보안 및 제어: 어떤 기능을 노출할지 및 요청을 처리하는 방법을 결정할 수 있습니다
  • 원활한 경험: 사용자는 하위 통합에 대해 알 필요 없이 자연스럽게 Claude와 상호작용합니다

전제 조건

MCP 서버를 구축하기 전에 다음이 준비되었는지 확인하십시오:

  • Node.js (v18 이상) 설치됨
  • Visual Studio Code와 같은 코드 편집기
  • TypeScript에 대한 기본 지식
  • Claude Desktop 애플리케이션 설치됨
  • 서버 엔드포인트 구축을 위한 Express.js에 대한 익숙함

TypeScript 프로젝트 설정하기

MCP 서버를 위한 새로운 TypeScript 프로젝트를 생성해 보겠습니다:

mkdir claude-mcp-server
cd claude-mcp-server
npm init -y
npm install typescript @types/node ts-node express @types/express cors @types/cors
npx tsc --init

다음으로, tsconfig.json을 다음 설정으로 업데이트하십시오:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "outDir": "./dist",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  }
}

MCP 서버 구현하기

프로젝트 루트 디렉토리에 server.ts라는 새 파일을 만드세요. 이것이 MCP 서버의 진입점이 될 것입니다:

import express from 'express';
import cors from 'cors';
import { Request, Response } from 'express';

// MCP 프로토콜에 대한 타입 정의
interface MCPRequest {
  query: string;
  conversation_id: string;
  request_id: string;
  parameters?: Record<string, any>;
}

interface MCPResponse {
  response: string;
  status: 'success' | 'error';
  error?: string;
}

const app = express();
app.use(cors());
app.use(express.json());

// 헬스 체크 엔드포인트
app.get('/health', (req: Request, res: Response) => {
  res.status(200).json({ status: 'healthy' });
});

// MCP 엔드포인트
app.post('/mcp', (req: Request, res: Response) => {
  try {
    const mcpRequest = req.body as MCPRequest;
    console.log('수신된 MCP 요청:', JSON.stringify(mcpRequest, null, 2));

    // 쿼리를 기반으로 요청 처리
    const response = processQuery(mcpRequest);
    
    res.status(200).json({
      status: 'success',
      response
    } as MCPResponse);
  } catch (error) {
    console.error('MCP 요청 처리 중 오류 발생:', error);
    res.status(500).json({
      status: 'error',
      error: error instanceof Error ? error.message : '알 수 없는 오류',
      response: '죄송합니다. 요청 처리 중 오류가 발생했습니다.'
    } as MCPResponse);
  }
});

// 서로 다른 쿼리 유형을 처리하는 함수
function processQuery(request: MCPRequest): string {
  const { query, parameters } = request;

  // 예시 쿼리 처리 - 귀하의 사용 사례에 맞게 사용자 정의하십시오
  switch (query) {
    case 'getCurrentTime':
      return `현재 시간은 ${new Date().toLocaleTimeString()}입니다.`;
    
    case 'getWeather':
      const location = parameters?.location || '알 수 없음';
      // 실제 앱에서는 여기에서 날씨 API를 호출할 것입니다.
      return `${location}의 날씨는 현재 맑고 72°F입니다.`;
    
    case 'calculateSum':
      if (parameters?.numbers && Array.isArray(parameters.numbers)) {
        const sum = parameters.numbers.reduce((a: number, b: number) => a + b, 0);
        return `숫자의 합은 ${sum}입니다.`;
      }
      return '합계를 계산하기 위한 잘못된 매개변수입니다.';

    default:
      return `인식할 수 없는 쿼리: ${query}`;
  }
}

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`MCP 서버가 포트 ${PORT}에서 실행 중입니다.`);
});

MCP 서버 실행하기

서버를 실행하려면 다음을 실행하십시오:

npx ts-node server.ts

귀하의 MCP 서버는 이제 포트 3000(또는 지정한 포트)에서 실행되고 있어야 합니다.

Claude Desktop에 연결하기

MCP 서버가 실행 중이므로 Claude Desktop을 구성하여 서버에 연결해야 합니다. 방법은 다음과 같습니다:

  1. Claude Desktop 애플리케이션을 엽니다
  2. 설정으로 이동(보통 오른쪽 상단 구석에 있습니다)
  3. "실험적 기능" 섹션으로 이동합니다
  4. "모델 컨텍스트 프로토콜" 토글을 활성화합니다
  5. URL http://localhost:3000/mcp로 새 MCP 엔드포인트를 추가합니다
  6. 설정을 저장합니다

이제 Claude Desktop은 귀하의 맞춤형 MCP 서버와 통신할 수 있습니다.

통합 테스트하기

Claude와 함께 MCP 서버를 테스트하려면, 구현한 특정 쿼리를 유발하는 질문을 Claude에게 해보십시오. 예를 들어:

  • "지금 몇 시인가요?" (여기서는 getCurrentTime 쿼리를 유발해야 함)
  • "샌프란시스코의 날씨는 어떤가요?" (여기서는 위치 매개변수로 "샌프란시스코"가 포함된 getWeather 쿼리를 유발해야 함)
  • "5, 10, 15, 20의 합계를 계산해 줄 수 있나요?" (여기서는 calculateSum 쿼리를 유발해야 함)

Claude가 이러한 질문에 대답하기 위해 외부 정보가 필요함을 인식하면, 자동으로 MCP 요청을 귀하의 서버로 보내고 응답을 자신의 대답에 통합합니다.

MCP 서버 확장하기

우리가 구축한 기본 서버는 시작점에 불과합니다. 기능을 확장하기 위한 몇 가지 아이디어는 다음과 같습니다:

인증 추가하기

MCP 서버를 보호하기 위해 인증을 추가하십시오:

// 기본 인증을 위한 미들웨어
const authenticateMCP = (req: Request, res: Response, next: Function) => {
  const apiKey = req.headers['x-api-key'];
  if (!apiKey || apiKey !== process.env.MCP_API_KEY) {
    return res.status(401).json({
      status: 'error',
      error: 'Unauthorized',
      response: '인증에 실패했습니다.'
    });
  }
  next();
};

// MCP 엔드포인트에 미들웨어 적용
app.post('/mcp', authenticateMCP, (req: Request, res: Response) => {
  // 기존 핸들러 코드
});

데이터베이스 통합 구현하기

귀하의 MCP 서버를 데이터베이스에 연결하여 정보를 검색하거나 저장하십시오:

import { MongoClient } from 'mongodb';

// 데이터베이스 연결 초기화
const dbClient = new MongoClient('mongodb://localhost:27017');
let db: any;

async function connectToDb() {
  await dbClient.connect();
  db = dbClient.db('mcpDatabase');
  console.log('데이터베이스에 연결되었습니다.');
}

connectToDb().catch(console.error);

// 데이터베이스 상호작용을 위한 쿼리 핸들러 추가
case 'getUserData':
  if (parameters?.userId) {
    const user = await db.collection('users').findOne({ id: parameters.userId });
    return user ? JSON.stringify(user) : '사용자를 찾을 수 없습니다.';
  }
  return '잘못된 사용자 ID입니다.';

웹훅 지원 추가하기

외부 서비스에 알리기 위해 웹훅 기능을 구현하십시오:

case 'sendNotification':
  if (parameters?.message && parameters?.destination) {
    // 외부 알림 서비스 호출
    await fetch('https://your-webhook-url.com', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ message: parameters.message })
    });
    return `${parameters.destination}에 알림이 전송되었습니다.`;
  }
  return '잘못된 알림 매개변수입니다.';

MCP 서버 개발을 위한 모범 사례

  1. 오류를 우아하게 처리하기: 항상 예외를 포착하고 유익한 오류 메시지를 반환하십시오
  2. 로깅 구현하기: 디버깅 및 감사용으로 모든 요청과 응답을 기록하십시오
  3. TypeScript 인터페이스 사용하기: 모든 데이터 구조에 대해 명확한 인터페이스를 정의하십시오
  4. 타임아웃 설정하기: 멈춘 작업을 방지하기 위해 요청 타임아웃을 구현하십시오
  5. 입력 검증하기: 모든 입력 매개변수를 처리하기 전에 신중하게 검증하십시오
  6. 단위 테스트 추가하기: 신뢰성을 보장하기 위해 쿼리 핸들러를 철저히 테스트하십시오

결론

TypeScript MCP 서버를 구축하는 것은 Claude의 기능을 확장할 수 있는 신나는 가능성을 열어 줍니다. 이 가이드를 따라 Claude를 귀하의 서비스 및 데이터와 통합하기 위한 기반을 마련했습니다. 모델 컨텍스트 프로토콜은 대화 흐름을 깨뜨리지 않고 Claude가 외부 정보에 접근할 수 있는 원활한 사용자 경험을 제공합니다.

MCP가 계속 진화함에 따라 대규모 언어 모델과 외부 시스템 간의 더욱 정교한 통합을 기대할 수 있습니다. 생산성 도구, 지식 관리 시스템 또는 맞춤형 비즈니스 애플리케이션을 구축하든, MCP는 Claude의 지능과 귀하의 전문 기능을 결합할 수 있는 강력한 방법을 제공합니다.

귀하의 사용 사례에 맞게 추가 쿼리 핸들러로 서버를 확장하는 가능성을 탐색하기 시작하고, MCP 개발자의 증가하는 커뮤니티와 경험을 공유하십시오.