AI 에이전트 API 테스트 능력 부여하는 MCP 서버 구축 방법

Ashley Innocent

Ashley Innocent

19 March 2026

AI 에이전트 API 테스트 능력 부여하는 MCP 서버 구축 방법

Apidog 엔터프라이즈

온프레미스 배포

SSO & RBAC

SOC 2 준수

Apidog Enterprise 살펴보기

요약 (TL;DR)

run_test, validate_schema, list_environments 세 가지 도구를 노출하는 TypeScript MCP 서버를 구축하세요. Claude Code의 경우 ~/.claude/settings.json에, Cursor의 경우 .cursor/mcp.json에 구성합니다. 그러면 AI 에이전트가 채팅 인터페이스를 벗어나지 않고도 Apidog 테스트를 실행하고, OpenAPI 스키마를 검증하며, 환경을 가져올 수 있습니다. 전체 소스 코드는 약 150줄이며 @modelcontextprotocol/sdk 패키지를 사용합니다.

Claude Code, Cursor 및 기타 AI 에이전트가 채팅 인터페이스를 벗어나지 않고 Apidog API 테스트를 실행하고, 스키마를 검증하고, 응답을 비교할 수 있도록 하는 MCP 서버를 구축하세요.

💡
코딩 세션 중입니다. AI 에이전트가 방금 API 엔드포인트 구축을 마쳤습니다. 코드를 복사하고, Apidog을 열고, 테스트 컬렉션을 만들고, 수동으로 유효성 검사를 실행하는 대신, 하나의 명령을 입력하여 결과를 받고 싶을 것입니다.
버튼

이것이 바로 Model Context Protocol (MCP)이 가능하게 하는 것입니다. MCP는 AI 에이전트가 표준화된 인터페이스를 통해 외부 도구에 접근할 수 있도록 합니다. Apidog용 MCP 서버를 구축하면 AI 에이전트가 컨텍스트 전환 없이 테스트를 실행하고, 스키마를 검증하며, 환경을 가져올 수 있습니다.

MCP란 무엇인가요?

MCP (Model Context Protocol)는 AI 에이전트가 외부 도구 및 데이터 소스에 접근하기 위한 프로토콜입니다. Claude Code, Cursor 및 기타 MCP 호환 클라이언트에서 작동하는 플러그인 시스템으로 생각할 수 있습니다.

MCP 서버는 도구 (에이전트가 호출할 수 있는 함수)와 리소스 (에이전트가 읽을 수 있는 데이터)를 노출합니다. Apidog MCP 서버는 API 테스트를 위한 도구를 노출할 것입니다.

┌─────────────────┐         ┌──────────────────┐         ┌─────────────┐
│  AI 에이전트    │         │  MCP 서버        │         │  Apidog     │
│  (Claude Code)  │◄───────►│  (사용자 코드)   │◄───────►│  API        │
└─────────────────┘   JSON  └──────────────────┘  HTTP   └─────────────┘

1단계: 프로젝트 설정

새로운 TypeScript 프로젝트를 생성하세요:

mkdir apidog-mcp-server
cd apidog-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node

tsconfig.json을 생성하세요:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

package.json에 빌드 스크립트를 추가하세요:

{
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js"
  }
}

2단계: MCP 서버 스켈레톤 생성

src/index.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: "apidog",
  version: "1.0.0",
  description: "AI 에이전트를 위한 Apidog API 테스트 도구"
});

// 도구는 여기에 정의됩니다

const transport = new StdioServerTransport();
await server.connect(transport);

이 스켈레톤은 MCP 서버를 생성하고 이를 stdio 트랜스포트에 연결합니다. 트랜스포트는 표준 입출력을 통해 AI 에이전트와 서버 간의 통신을 처리합니다.

3단계: run_test 도구 정의

src/index.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: "apidog",
  version: "1.0.0",
  description: "AI 에이전트를 위한 Apidog API 테스트 도구"
});

// 도구: run_test
server.tool(
  "run_test",
  {
    projectId: z.string().describe("Apidog 프로젝트 ID (프로젝트 URL에서 찾을 수 있음)"),
    environmentId: z.string().optional().describe("테스트 실행을 위한 선택적 환경 ID"),
    testSuiteId: z.string().optional().describe("특정 테스트 스위트를 실행하기 위한 선택적 테스트 스위트 ID")
  },
  async ({ projectId, environmentId, testSuiteId }) => {
    const apiKey = process.env.APIDOG_API_KEY;
    if (!apiKey) {
      return {
        content: [{
          type: "text",
          text: "오류: APIDOG_API_KEY 환경 변수가 설정되지 않았습니다"
        }]
      };
    }

    // API URL 구축
    let url = `https://api.apidog.com/v1/projects/${projectId}/tests/run`;
    const params = new URLSearchParams();
    if (environmentId) params.append("environmentId", environmentId);
    if (testSuiteId) params.append("testSuiteId", testSuiteId);
    if (params.toString()) url += `?${params.toString()}`;

    try {
      const response = await fetch(url, {
        method: "POST",
        headers: {
          "Authorization": `Bearer ${apiKey}`,
          "Content-Type": "application/json"
        }
      });

      if (!response.ok) {
        const error = await response.text();
        return {
          content: [{
            type: "text",
            text: `API 오류: ${response.status} ${error}`
          }]
        };
      }

      const results = await response.json();
      return {
        content: [{
          type: "text",
          text: JSON.stringify(results, null, 2)
        }]
      };
    } catch (error) {
      return {
        content: [{
          type: "text",
          text: `요청 실패: ${error instanceof Error ? error.message : String(error)}`
        }]
      };
    }
  }
);

const transport = new StdioServerTransport();
await server.connect(transport);

도구 정의는 세 부분으로 구성됩니다:

  1. 이름run_test (에이전트는 이름으로 도구를 선택하므로 설명적으로 만드세요)
  2. 스키마 — 설명이 포함된 파라미터에 대한 Zod 유효성 검사
  3. 핸들러 — Apidog API를 호출하는 비동기 함수

4단계: validate_schema 도구 추가

배포 전에 OpenAPI 오류를 포착하기 위해 스키마 유효성 검사를 추가하세요:

// 도구: validate_schema
server.tool(
  "validate_schema",
  {
    schema: z.object({}).describe("유효성 검사할 OpenAPI 3.x 스키마 객체"),
    strict: z.boolean().optional().default(false).describe("추가 검사를 위해 엄격 모드 활성화")
  },
  async ({ schema, strict }) => {
    const apiKey = process.env.APIDOG_API_KEY;
    if (!apiKey) {
      return {
        content: [{
          type: "text",
          text: "오류: APIDOG_API_KEY 환경 변수가 설정되지 않았습니다"
        }]
      };
    }

    try {
      const response = await fetch("https://api.apidog.com/v1/schemas/validate", {
        method: "POST",
        headers: {
          "Authorization": `Bearer ${apiKey}`,
          "Content-Type": "application/json"
        },
        body: JSON.stringify({ schema, strict })
      });

      const result = await response.json();

      if (!response.ok) {
        return {
          content: [{
            type: "text",
            text: `유효성 검사 실패: ${JSON.stringify(result.errors, null, 2)}`
          }]
        };
      }

      return {
        content: [{
          type: "text",
          text: result.valid
            ? "스키마가 유효한 OpenAPI 3.x입니다"
            : `경고: ${JSON.stringify(result.warnings, null, 2)}`
        }]
      };
    } catch (error) {
      return {
        content: [{
          type: "text",
          text: `유효성 검사 실패: ${error instanceof Error ? error.message : String(error)}`
        }]
      };
    }
  }
);

5단계: list_environments 도구 추가

사용 가능한 테스트 환경을 가져오는 도구를 추가하세요:

// 도구: list_environments
server.tool(
  "list_environments",
  {
    projectId: z.string().describe("Apidog 프로젝트 ID")
  },
  async ({ projectId }) => {
    const apiKey = process.env.APIDOG_API_KEY;
    if (!apiKey) {
      return {
        content: [{
          type: "text",
          text: "오류: APIDOG_API_KEY 환경 변수가 설정되지 않았습니다"
        }]
      };
    }

    try {
      const response = await fetch(
        `https://api.apidog.com/v1/projects/${projectId}/environments`,
        {
          headers: {
            "Authorization": `Bearer ${apiKey}`
          }
        }
      );

      if (!response.ok) {
        const error = await response.text();
        return {
          content: [{
            type: "text",
            text: `API 오류: ${response.status} ${error}`
          }]
        };
      }

      const environments = await response.json();
      return {
        content: [{
          type: "text",
          text: environments.length === 0
            ? "이 프로젝트에 대한 환경을 찾을 수 없습니다"
            : environments.map((e: any) =>
                `- ${e.name} (ID: ${e.id})${e.isDefault ? " [기본값]" : ""}`
              ).join("\n")
        }]
      };
    } catch (error) {
      return {
        content: [{
          type: "text",
          text: `요청 실패: ${error instanceof Error ? error.message : String(error)}`
        }]
      };
    }
  }
);

6단계: 빌드 및 테스트

서버를 빌드하세요:

npm run build

간단한 MCP 클라이언트로 테스트하세요. test-client.js를 생성하세요:

import { spawn } from "child_process";

const server = spawn("node", ["dist/index.js"], {
  env: { ...process.env, APIDOG_API_KEY: "your-api-key" }
});

server.stdout.on("data", (data) => {
  console.log(`서버 출력: ${data}`);
});

server.stderr.on("data", (data) => {
  console.error(`서버 오류: ${data}`);
});

// 테스트 메시지 전송
const message = {
  jsonrpc: "2.0",
  id: 1,
  method: "initialize",
  params: {
    protocolVersion: "2024-11-05",
    capabilities: {},
    clientInfo: { name: "test-client", version: "1.0.0" }
  }
};

server.stdin.write(JSON.stringify(message) + "\n");

7단계: Claude Code 구성

Claude Code 구성에 MCP 서버를 추가하세요:

~/.claude/settings.json을 생성하거나 편집하세요:

{
  "mcpServers": {
    "apidog": {
      "command": "node",
      "args": ["/absolute/path/to/apidog-mcp-server/dist/index.js"],
      "env": {
        "APIDOG_API_KEY": "your-api-key-here"
      }
    }
  }
}

Claude Code를 다시 시작하세요. API 테스트 지원을 요청하면 Apidog 도구가 이제 나타나야 합니다.

Claude Code에서 사용법:

run_test 도구를 사용하여 Apidog 프로젝트에서 테스트를 실행하세요.
프로젝트 ID: proj_12345
환경: staging
이 OpenAPI 스키마를 Apidog 규칙에 따라 검증하세요:
[스키마 붙여넣기]
proj_12345 프로젝트의 모든 환경을 나열하세요

8단계: Cursor 구성

Cursor는 유사한 MCP 구성을 사용합니다. 프로젝트의 .cursor/mcp.json을 생성하세요:

{
  "mcpServers": {
    "apidog": {
      "command": "node",
      "args": ["/absolute/path/to/apidog-mcp-server/dist/index.js"],
      "env": {
        "APIDOG_API_KEY": "your-api-key-here"
      }
    }
  }
}

Cursor에서 사용법:

@apidog run_test projectId="proj_12345" environmentId="staging"

완전한 소스 코드

전체 src/index.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: "apidog",
  version: "1.0.0",
  description: "AI 에이전트를 위한 Apidog API 테스트 도구"
});

// 도구: run_test
server.tool(
  "run_test",
  {
    projectId: z.string().describe("Apidog 프로젝트 ID"),
    environmentId: z.string().optional().describe("환경 ID"),
    testSuiteId: z.string().optional().describe("테스트 스위트 ID")
  },
  async ({ projectId, environmentId, testSuiteId }) => {
    const apiKey = process.env.APIDOG_API_KEY;
    if (!apiKey) {
      return {
        content: [{
          type: "text",
          text: "오류: APIDOG_API_KEY가 설정되지 않았습니다"
        }]
      };
    }

    let url = `https://api.apidog.com/v1/projects/${projectId}/tests/run`;
    const params = new URLSearchParams();
    if (environmentId) params.append("environmentId", environmentId);
    if (testSuiteId) params.append("testSuiteId", testSuiteId);
    if (params.toString()) url += `?${params.toString()}`;

    try {
      const response = await fetch(url, {
        method: "POST",
        headers: {
          "Authorization": `Bearer ${apiKey}`,
          "Content-Type": "application/json"
        }
      });

      const results = await response.json();
      return {
        content: [{
          type: "text",
          text: JSON.stringify(results, null, 2)
        }]
      };
    } catch (error) {
      return {
        content: [{
          type: "text",
          text: `요청 실패: ${error instanceof Error ? error.message : String(error)}`
        }]
      };
    }
  }
);

// 도구: validate_schema
server.tool(
  "validate_schema",
  {
    schema: z.object({}).describe("OpenAPI 스키마"),
    strict: z.boolean().optional().default(false)
  },
  async ({ schema, strict }) => {
    const apiKey = process.env.APIDOG_API_KEY;
    if (!apiKey) {
      return {
        content: [{
          type: "text",
          text: "오류: APIDOG_API_KEY가 설정되지 않았습니다"
        }]
      };
    }

    const response = await fetch("https://api.apidog.com/v1/schemas/validate", {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${apiKey}`,
        "Content-Type": "application/json"
      },
      body: JSON.stringify({ schema, strict })
    });

    const result = await response.json();
    return {
      content: [{
        type: "text",
        text: result.valid
          ? "스키마가 유효합니다"
          : `문제: ${JSON.stringify(result.errors || result.warnings, null, 2)}`
      }]
    };
  }
);

// 도구: list_environments
server.tool(
  "list_environments",
  {
    projectId: z.string().describe("Apidog 프로젝트 ID")
  },
  async ({ projectId }) => {
    const apiKey = process.env.APIDOG_API_KEY;
    if (!apiKey) {
      return {
        content: [{
          type: "text",
          text: "오류: APIDOG_API_KEY가 설정되지 않았습니다"
        }]
      };
    }

    const response = await fetch(
      `https://api.apidog.com/v1/projects/${projectId}/environments`,
      {
        headers: { "Authorization": `Bearer ${apiKey}` }
      }
    );

    const environments = await response.json();
    return {
      content: [{
        type: "text",
        text: environments.map((e: any) =>
          `- ${e.name} (${e.id})${e.isDefault ? " [기본값]" : ""}`
        ).join("\n")
      }]
    };
  }
);

const transport = new StdioServerTransport();
await server.connect(transport);

구축한 것

구성 요소 목적
MCP 서버 AI 에이전트를 Apidog API에 연결
run_test 테스트 컬렉션을 프로그램적으로 실행
validate_schema 배포 전 OpenAPI 오류 포착
list_environments 사용 가능한 테스트 환경 검색
Zod 유효성 검사 타입 안정성 파라미터 처리
Stdio 트랜스포트 Claude Code, Cursor, 모든 MCP 클라이언트와 호환

다음 단계

서버 확장:

운영 고려 사항:

팀과 공유:

일반적인 문제 해결

Claude Code에서 MCP 서버가 로드되지 않음:

구성 후 도구가 나타나지 않음:

API 요청이 401 오류로 실패함:

Zod 유효성 검사 오류:

TypeScript 컴파일 오류:

MCP 서버 로컬에서 테스트하기

운영 환경에 배포하기 전에 서버를 로컬에서 테스트하세요:

stdio를 사용한 수동 테스트:

# 서버 시작
node dist/index.js

# 다른 터미널에서 테스트 메시지 전송
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | node dist/index.js

예상 출력:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      { "name": "run_test", "description": "...", "inputSchema": {...} },
      { "name": "validate_schema", "description": "...", "inputSchema": {...} },
      { "name": "list_environments", "description": "...", "inputSchema": {...} }
    ]
  }
}

도구 호출 테스트:

echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_environments","arguments":{"projectId":"your-project-id"}}}' | node dist/index.js

이제 AI 에이전트가 Apidog의 테스트 기능에 직접 접근할 수 있습니다. 채팅과 브라우저 간에 더 이상 복사-붙여넣기를 할 필요가 없습니다. 더 이상 수동 테스트 실행도 필요 없습니다. 명령을 입력하고 결과를 받으세요.

이것이 MCP의 힘입니다: AI 에이전트를 도메인별 도구로 확장하고, 그들이 해야 할 일 — 더 빠르게 배포할 수 있도록 돕는 일 —을 하도록 하세요.

핵심 요약

버튼

자주 묻는 질문 (FAQ)

AI에서 MCP란 무엇인가요?MCP (Model Context Protocol)는 AI 에이전트가 외부 도구 및 데이터 소스에 접근할 수 있도록 하는 표준화된 프로토콜입니다. AI 에이전트를 위한 플러그인 시스템으로 생각할 수 있습니다.

Apidog용 MCP 서버는 어떻게 생성하나요?@modelcontextprotocol/sdk를 설치하고, Zod 유효성 검사를 사용하여 도구를 정의하고, Apidog API를 호출하는 핸들러를 구현하고, StdioServerTransport를 통해 연결합니다.

Cursor와 함께 사용할 수 있나요?네. 프로젝트 루트에 있는 .cursor/mcp.json에 MCP 서버 구성을 추가하세요. 동일한 서버가 Claude Code, Cursor 및 다른 MCP 클라이언트와 함께 작동합니다.

어떤 도구를 노출해야 하나요?테스트 컬렉션 실행을 위한 run_test, OpenAPI 유효성 검사를 위한 validate_schema, 사용 가능한 환경 가져오기를 위한 list_environments로 시작하세요.

Apidog MCP 서버는 운영 환경에 준비되었나요?튜토리얼 코드는 시작점입니다. 운영 환경에서 사용하기 전에 재시도 로직, 속도 제한, 적절한 오류 처리 및 안전한 API 키 저장을 추가하세요.

Apidog API 키가 필요한가요?네. APIDOG_API_KEY를 환경 변수로 설정하세요. 서버는 런타임에 이를 읽어 API 요청을 인증합니다.

이 MCP 서버를 팀과 공유할 수 있나요?네. 비공개 패키지로 npm에 게시하고, 필요한 환경 변수를 문서화하고, MCP 구성 예시를 포함하세요.

Apidog에서 API 설계-첫 번째 연습

API를 더 쉽게 구축하고 사용하는 방법을 발견하세요