mcp-openapi-server
OpenAPI MCP Server
A Model Context Protocol (MCP) server that exposes OpenAPI endpoints as MCP tools, along with optional support for MCP prompts and resources. This server allows Large Language Models to discover and interact with REST APIs defined by OpenAPI specifications through the MCP protocol.
📖 문서
사용자 가이드 - Claude Desktop, Cursor 또는 기타 MCP 클라이언트에서 이 MCP 서버를 사용하려는 사용자용
라이브러리 사용 - 이 패키지를 라이브러리로 사용하여 사용자 정의 MCP 서버를 만드는 개발자용
개발자 가이드 - 코드베이스에서 작업하는 기여자와 개발자용
AuthProvider 가이드 - 상세 인증 패턴 및 예제
사용자 가이드
이 섹션에서는 최종 사용자로서 Claude Desktop, Cursor 또는 기타 MCP 호환 도구에서 MCP 서버를 사용하는 방법을 설명합니다.
개요
이 MCP 서버는 두 가지 방식으로 사용할 수 있습니다:
CLI 도구:
npx @ivotoby/openapi-mcp-server를 명령줄 인수와 함께 직접 사용하여 빠르게 설정라이브러리: 사용자 정의 구현을 위해 자체 Node.js 응용 프로그램에서
OpenAPIServer클래스를 가져와 사용
서버는 두 가지 전송 방식을 지원합니다:
Stdio 전송 (기본값): 표준 입력/출력을 통해 MCP 연결을 관리하는 Claude Desktop과 같은 AI 시스템과의 직접 통합용.
Streamable HTTP 전송: HTTP를 통해 서버에 연결하여 웹 클라이언트 및 기타 HTTP 지원 시스템이 MCP 프로토콜을 사용할 수 있게 합니다.
사용자 빠른 시작
옵션 1: Claude Desktop과 함께 사용 (Stdio 전송)
이 저장소를 클론할 필요가 없습니다. Claude Desktop이 이 MCP 서버를 사용하도록 설정하기만 하면 됩니다:
Claude Desktop 구성 파일을 찾거나 생성하세요:
macOS에서:
~/Library/Application Support/Claude/claude_desktop_config.json
다음 구성을 추가하세요:
{
"mcpServers": {
"openapi": {
"command": "npx",
"args": ["-y", "@ivotoby/openapi-mcp-server"],
"env": {
"API_BASE_URL": "https://api.example.com",
"OPENAPI_SPEC_PATH": "https://api.example.com/openapi.json",
"API_HEADERS": "Authorization:Bearer token123,X-API-Key:your-api-key"
}
}
}
}환경 변수를 실제 API 구성으로 바꾸세요:
API_BASE_URL: API의 기본 URLOPENAPI_SPEC_PATH: OpenAPI 명세의 URL 또는 경로API_HEADERS: API 인증 헤더용 쉼표로 구분된 key:value 쌍
옵션 2: HTTP 클라이언트와 함께 사용 (HTTP 전송)
HTTP 클라이언트에서 서버를 사용하려면:
설치가 필요 없습니다! npx로 패키지를 직접 실행하세요:
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json \
--headers "Authorization:Bearer token123" \
--transport http \
--port 3000HTTP 요청으로 서버와 상호작용하세요:
# Initialize a session (first request)
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl-client","version":"1.0.0"}}}'
# The response includes a Mcp-Session-Id header that you must use for subsequent requests
# and the InitializeResult directly in the POST response body.
# Send a request to list tools
# This also receives its response directly on this POST request.
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Mcp-Session-Id: your-session-id" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
# Open a streaming connection for other server responses (e.g., tool execution results)
# This uses Server-Sent Events (SSE).
curl -N http://localhost:3000/mcp -H "Mcp-Session-Id: your-session-id"
# Example: Execute a tool (response will arrive on the GET stream)
# curl -X POST http://localhost:3000/mcp \
# -H "Content-Type: application/json" \
# -H "Mcp-Session-Id: your-session-id" \
# -d '{"jsonrpc":"2.0","id":2,"method":"tools/execute","params":{"name":"yourToolName", "arguments": {}}}'
# Terminate the session when done
curl -X DELETE http://localhost:3000/mcp -H "Mcp-Session-Id: your-session-id"구성 옵션
서버는 환경 변수 또는 명령줄 인수를 통해 구성할 수 있습니다:
환경 변수
API_BASE_URL- API 엔드포인트의 기본 URLOPENAPI_SPEC_PATH- OpenAPI 명세의 경로 또는 URLOPENAPI_SPEC_FROM_STDIN- 표준 입력에서 OpenAPI 명세를 읽으려면 "true"로 설정OPENAPI_SPEC_INLINE- OpenAPI 명세 내용을 문자열로 직접 제공API_HEADERS- API 헤더용 쉼표로 구분된 key:value 쌍CLIENT_CERT_PATH- 상호 TLS용 클라이언트 인증서 PEM 파일 경로CLIENT_KEY_PATH- 상호 TLS용 클라이언트 개인 키 PEM 파일 경로CA_CERT_PATH- 사설/내부 CA용 사용자 정의 CA 인증서 PEM 파일 경로CLIENT_KEY_PASSPHRASE- 암호화된 클라이언트 개인 키의 암호REJECT_UNAUTHORIZED- 신뢰할 수 없는 서버 인증서를 거부할지 여부 (기본값:true)SERVER_NAME- MCP 서버 이름 (기본값: "mcp-openapi-server")SERVER_VERSION- 서버 버전 (기본값: "1.0.0")TRANSPORT_TYPE- 사용할 전송 유형: "stdio" 또는 "http" (기본값: "stdio")HTTP_PORT- HTTP 전송용 포트 (기본값: 3000)HTTP_HOST- HTTP 전송용 호스트 (기본값: "127.0.0.1")ENDPOINT_PATH- HTTP 전송용 엔드포인트 경로 (기본값: "/mcp")TOOLS_MODE- 도구 로딩 모드: "all"(모든 엔드포인트 기반 도구 로드), "dynamic"(메타 도구만 로드), 또는 "explicit"(includeTools에 지정된 도구만 로드) (기본값: "all")DISABLE_ABBREVIATION- 이름 최적화 비활성화 (이름이 64자를 초과하면 오류가 발생할 수 있음)VERBOSE- 운영 로깅 활성화 (기본값은true; 필수 외 로그를 억제하려면false로 설정)PROMPTS_PATH- 프롬프트 JSON/YAML 파일의 경로 또는 URLPROMPTS_INLINE- 프롬프트를 JSON 문자열로 직접 제공RESOURCES_PATH- 리소스 JSON/YAML 파일의 경로 또는 URLRESOURCES_INLINE- 리소스를 JSON 문자열로 직접 제공
명령줄 인수
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json \
--headers "Authorization:Bearer token123,X-API-Key:your-api-key" \
--exclude-tag admin \
--client-cert ./certs/client.pem \
--client-key ./certs/client-key.pem \
--name "my-mcp-server" \
--server-version "1.0.0" \
--transport http \
--port 3000 \
--host 127.0.0.1 \
--path /mcp \
--disable-abbreviation true \
--verbose false상호 TLS (mTLS)
업스트림 API가 클라이언트 인증서 인증을 요구하는 경우 TLS 자격 증명을 출력 요청에 직접 첨부할 수 있습니다.
npx @ivotoby/openapi-mcp-server \
--api-base-url https://secure-api.example.com \
--openapi-spec https://secure-api.example.com/openapi.json \
--client-cert ./certs/client.pem \
--client-key ./certs/client-key.pem \
--headers "Authorization:Bearer token123"이는 HTTP 수준 인증과 독립적이므로 mTLS를 정적 헤더나 AuthProvider와 결합할 수 있습니다.
TLS 관련 옵션은 --api-base-url이 https://를 사용할 때만 적용됩니다.
사설 CA 또는 암호화된 키의 경우:
npx @ivotoby/openapi-mcp-server \
--api-base-url https://internal-api.example.com \
--openapi-spec ./openapi.yaml \
--client-cert ./certs/client.pem \
--client-key ./certs/client-key.pem \
--client-key-passphrase "$CLIENT_KEY_PASSPHRASE" \
--ca-cert ./certs/internal-ca.pem \
--reject-unauthorized false--client-cert/CLIENT_CERT_PATH: 클라이언트 인증서 PEM 파일--client-key/CLIENT_KEY_PATH: 클라이언트 개인 키 PEM 파일--client-key-passphrase/CLIENT_KEY_PASSPHRASE: 암호화된 개인 키의 암호--ca-cert/CA_CERT_PATH: 사설/내부 인증 기관용 사용자 정의 CA 번들--reject-unauthorized/REJECT_UNAUTHORIZED: 의도적으로 자체 서명 또는 신뢰할 수 없는 서버 인증서를 허용하려는 경우에만false로 설정
스크립트나 임베디드 환경에서 서버를 조용히 유지하려면 --verbose false 또는 VERBOSE=false로 설정하세요.
OpenAPI 명세 로딩
MCP 서버는 OpenAPI 명세를 로드하는 여러 방법을 지원하여 다양한 배포 시나리오에 유연성을 제공합니다:
1. URL 로딩 (기본값)
원격 URL에서 OpenAPI 명세를 로드합니다:
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json2. 로컬 파일 로딩
로컬 파일에서 OpenAPI 명세를 로드합니다:
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec ./path/to/openapi.yaml3. 표준 입력 로딩
표준 입력에서 OpenAPI 명세를 읽습니다 (파이프 또는 컨테이너 환경에 유용):
# Pipe from file
cat openapi.json | npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--spec-from-stdin
# Pipe from curl
curl -s https://api.example.com/openapi.json | npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--spec-from-stdin
# Using environment variable
export OPENAPI_SPEC_FROM_STDIN=true
echo '{"openapi": "3.0.0", ...}' | npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com4. 인라인 명세
OpenAPI 명세 내용을 명령줄 인수로 직접 제공합니다:
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--spec-inline '{"openapi": "3.0.0", "info": {"title": "My API", "version": "1.0.0"}, "paths": {}}'
# Using environment variable
export OPENAPI_SPEC_INLINE='{"openapi": "3.0.0", ...}'
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com지원 형식
모든 로딩 방법은 JSON 및 YAML 형식을 모두 지원합니다. 서버는 형식을 자동으로 감지하여 그에 따라 파싱합니다.
Docker 및 컨테이너 사용
컨테이너 배포의 경우 OpenAPI 명세를 마운트하거나 stdin을 사용할 수 있습니다:
# Mount local file
docker run -v /path/to/spec:/app/spec.json your-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec /app/spec.json
# Use stdin with docker
cat openapi.json | docker run -i your-mcp-server \
--api-base-url https://api.example.com \
--spec-from-stdin오류 처리
서버는 명세 로딩 실패에 대한 상세한 오류 메시지를 제공합니다:
URL 로딩: HTTP 상태 코드 및 네트워크 오류
파일 로딩: 파일 시스템 오류 (파일 없음, 권한 등)
stdin 로딩: 빈 입력 또는 읽기 오류
인라인 로딩: 콘텐츠 누락 오류
파싱 오류: 상세한 JSON/YAML 구문 오류 메시지
유효성 검사
한 번에 하나의 명세 소스만 사용할 수 있습니다. 서버는 다음 중 정확히 하나가 제공되는지 검증합니다:
--openapi-spec(URL 또는 파일 경로)--spec-from-stdin--spec-inline
여러 소스가 지정되면 서버는 오류 메시지와 함께 종료됩니다.
도구 로딩 및 필터링 옵션
Stainless의 기사 "복잡한 OpenAPI 명세를 MCP 서버로 변환하면서 배운 것" (https://www.stainless.com/blog/what-we-learned-converting-complex-openapi-specs-to-mcp-servers)을 기반으로, 로드할 API 엔드포인트(도구)를 제어하기 위해 다음 플래그가 추가되었습니다:
--tools <all|dynamic|explicit>: 도구 로딩 모드를 선택합니다:all(기본값): OpenAPI 명세의 모든 도구를 로드하고 지정된 필터를 적용합니다.dynamic: 동적 메타 도구(list-api-endpoints,get-api-endpoint-schema,invoke-api-endpoint)만 로드합니다.--exclude-tag는 동적 엔드포인트 검색 및 호출에도 계속 적용됩니다.explicit:--tool옵션에 명시적으로 나열된 도구만 로드하고 포함 필터는 무시합니다.--exclude-tag는 거부 필터로 계속 적용됩니다.
--tool <toolId>: 지정된 도구 ID 또는 이름만 가져옵니다. 여러 번 사용할 수 있습니다.all모드에서는--tag,--resource,--operation을 우회하지만--exclude-tag는 우회하지 않습니다.--tag <tag>: 지정된 OpenAPI 태그가 있는 도구만 가져옵니다. 여러 번 사용할 수 있습니다.--exclude-tag <tag>: 지정된 OpenAPI 태그가 있는 도구를 제외합니다. 여러 번 사용할 수 있습니다. 제외된 태그는--tool보다 우선합니다.--resource <resource>: 지정된 리소스 경로 접두사 아래의 도구만 가져옵니다. 여러 번 사용할 수 있습니다.--operation <method>: 지정된 HTTP 메서드(get, post 등)에 대한 도구만 가져옵니다. 여러 번 사용할 수 있습니다.
태그 필터는 도구 표면 제어일 뿐 권한 부여가 아닙니다. 민감한 엔드포인트는 업스트림 API의 인증 모델로 계속 보호하세요. 태그가 없는 엔드포인트는 --exclude-tag의 영향을 받지 않습니다.
예시:
# Load only dynamic meta-tools
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --tools dynamic
# Load only explicitly specified tools (ignores other filters)
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --tools explicit --tool GET::users --tool POST::users
# Load only the GET /users endpoint tool (using all mode with filtering)
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --tool GET-users
# Load tools tagged with "user" under the "/users" resource
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --tag user --resource users
# Exclude admin and internal endpoints from any tool loading mode
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --exclude-tag admin --exclude-tag internal
# Load only POST operations
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --operation post프롬프트 및 리소스
이 서버는 OpenAPI 엔드포인트를 도구로 노출하는 것 외에도 MCP 프로토콜을 통해 프롬프트(재사용 가능한 템플릿)와 리소스(정적 콘텐츠)를 노출할 수 있습니다.
프롬프트와 리소스란 무엇인가요?
기능 | 용도 | 사용 사례 |
도구 | AI가 실행할 API 엔드포인트 | API 호출 |
프롬프트 | 인수 치환이 포함된 템플릿 메시지 | 재사용 가능한 워크플로 템플릿 |
리소스 | 컨텍스트용 읽기 전용 콘텐츠 | API 문서, 스키마 |
프롬프트 로딩
프롬프트는 파일, URL 또는 인라인 JSON에서 로드할 수 있습니다:
# Load from local file
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json \
--prompts ./prompts.json
# Load from URL
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json \
--prompts https://example.com/mcp/prompts.json
# Inline JSON
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json \
--prompts-inline '[{"name":"greet","title":"Greeting","template":"Hello {{name}}!"}]'프롬프트 파일 형식 (JSON):
[
{
"name": "api_request",
"title": "API Request Helper",
"description": "Helps generate API request templates",
"arguments": [
{ "name": "endpoint", "description": "API endpoint path", "required": true },
{ "name": "method", "description": "HTTP method", "required": false }
],
"template": "Create a {{method}} request to {{endpoint}} with proper parameters."
}
]리소스 로딩
리소스는 파일, URL 또는 인라인 JSON에서 로드할 수 있습니다:
# Load from local file
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json \
--mcp-resources ./resources.json
# Load from URL
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json \
--mcp-resources https://example.com/mcp/resources.json
# Inline JSON
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json \
--mcp-resources-inline '[{"uri":"docs://readme","name":"readme","text":"# Welcome"}]'리소스 파일 형식 (JSON):
[
{
"uri": "docs://api/overview",
"name": "api-overview",
"title": "API Overview",
"description": "Overview of the API",
"mimeType": "text/markdown",
"text": "# API Overview\n\nThis API provides..."
}
]도구, 프롬프트 및 리소스 결합
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json \
--prompts ./prompts.json \
--mcp-resources ./resources.json \
--transport http \
--port 3000이 구성으로 서버는 세 가지 모두에 대한 기능을 광고합니다:
{
"capabilities": {
"tools": { "list": true, "execute": true },
"prompts": {},
"resources": {}
}
}전송 유형
Stdio 전송 (기본값)
stdio 전송은 표준 입력/출력을 통해 MCP 연결을 관리하는 Claude Desktop과 같은 AI 시스템과의 직접 통합을 위해 설계되었습니다. 가장 간단한 설정이며 네트워크 구성이 필요 없습니다.
사용 시점: Claude Desktop 또는 stdio 기반 MCP 통신을 지원하는 다른 시스템과 통합할 때.
Streamable HTTP 전송
HTTP 전송을 사용하면 HTTP를 통해 MCP 서버에 접근할 수 있어 웹 애플리케이션 및 기타 HTTP 지원 클라이언트가 MCP 프로토콜과 상호작용할 수 있습니다. 세션 관리, 스트리밍 응답 및 표준 HTTP 메서드를 지원합니다.
주요 기능:
Mcp-Session-Id 헤더를 사용한 세션 관리
initialize및tools/list요청에 대한 HTTP 응답은 POST에서 동기적으로 전송됩니다.기타 서버에서 클라이언트로 전송되는 메시지(예:
tools/execute결과, 알림)는 SSE(Server-Sent Events)를 사용하여 GET 연결을 통해 스트리밍됩니다.POST/GET/DELETE 메서드 지원
사용 시점: MCP 서버를 stdio가 아닌 HTTP로 통신하는 웹 클라이언트나 시스템에 노출해야 할 때.
헬스 체크 엔드포인트
HTTP 전송을 사용할 때 모니터링 및 서비스 검색을 위해 /health에 헬스 체크 엔드포인트를 사용할 수 있습니다:
# Check server health
curl http://localhost:3000/health
# Response:
# {
# "status": "healthy",
# "activeSessions": 2,
# "uptime": 3600
# }헬스 응답 필드:
status: 서버가 실행 중일 때 항상 "healthy"를 반환합니다.activeSessions: 활성 MCP 세션 수uptime: 서버 가동 시간(초)
주요 기능:
인증 불필요
모든 HTTP 메서드(GET, POST 등)에서 작동
로드 밸런서, Kubernetes 프로브 및 모니터링 시스템에 적합
통합 예시:
# Kubernetes liveness probe
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 3
periodSeconds: 10
# Docker healthcheck
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:3000/health || exit 1보안 고려 사항
HTTP 전송은 DNS 리바인딩 공격을 방지하기 위해 Origin 헤더를 검증합니다.
기본적으로 HTTP 전송은 localhost(127.0.0.1)에만 바인딩됩니다.
다른 호스트에 노출하는 경우 추가 인증 구현을 고려하세요.
디버깅
디버그 로그를 보려면:
Claude Desktop에서 stdio 전송을 사용하는 경우:
로그는 Claude Desktop 로그에 표시됩니다.
HTTP 전송을 사용하는 경우:
npx @ivotoby/openapi-mcp-server --transport http &2>debug.log
라이브러리 사용
이 섹션은 이 패키지를 라이브러리로 사용하여 사용자 정의 MCP 서버를 만들려는 개발자를 위한 것입니다.
🚀 라이브러리로 사용하기
OpenAPIServer 클래스를 가져와 구성하면 특정 API를 위한 전용 MCP 서버를 만들 수 있습니다. 이 접근 방식은 다음과 같은 경우에 적합합니다:
사용자 정의 인증:
AuthProvider인터페이스로 복잡한 인증 패턴 구현API별 최적화: 엔드포인트 필터링, 오류 처리 사용자 정의, 특정 사용 사례에 맞는 최적화
배포: 서버를 독립 실행형 npm 모듈로 패키징하여 쉽게 공유
통합: 서버를 더 큰 애플리케이션에 포함하거나 사용자 정의 미들웨어 추가
기본 라이브러리 사용법
import { OpenAPIServer } from "@ivotoby/openapi-mcp-server"
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
const config = {
name: "my-api-server",
version: "1.0.0",
apiBaseUrl: "https://api.example.com",
openApiSpec: "https://api.example.com/openapi.json",
specInputMethod: "url" as const,
headers: {
Authorization: "Bearer your-token",
"X-API-Key": "your-api-key",
},
transportType: "stdio" as const,
toolsMode: "all" as const, // Options: "all", "dynamic", "explicit"
}
const server = new OpenAPIServer(config)
const transport = new StdioServerTransport()
await server.start(transport)도구 로딩 모드
toolsMode 구성 옵션은 OpenAPI 명세에서 로드할 도구를 제어합니다:
// Load all tools from the spec (default)
const config = {
// ... other config
toolsMode: "all" as const,
// Optional: Apply filters to control which tools are loaded
includeTools: ["GET::users", "POST::users"], // Only these tools
includeTags: ["public"], // Only tools with these tags
excludeTags: ["admin", "internal"], // Never expose tools with these tags
includeResources: ["users"], // Only tools under these resources
includeOperations: ["get", "post"], // Only these HTTP methods
}
// Load only dynamic meta-tools for API exploration
const config = {
// ... other config
toolsMode: "dynamic" as const,
// Provides: list-api-endpoints, get-api-endpoint-schema, invoke-api-endpoint
// excludeTags still hides matching operations from discovery and invocation
}
// Load only explicitly specified tools (include filters are ignored)
const config = {
// ... other config
toolsMode: "explicit" as const,
includeTools: ["GET::users", "POST::users"], // Only these exact tools
excludeTags: ["admin"], // Still applied as a deny filter
// includeTags, includeResources, includeOperations are ignored in explicit mode
}프롬프트 및 리소스 구성
API 도구와 함께 재사용 가능한 프롬프트와 정적 리소스를 노출합니다:
import { OpenAPIServer } from "@ivotoby/openapi-mcp-server"
const config = {
name: "my-api-server",
version: "1.0.0",
apiBaseUrl: "https://api.example.com",
openApiSpec: "https://api.example.com/openapi.json",
specInputMethod: "url" as const,
transportType: "stdio" as const,
toolsMode: "all" as const,
// Define prompts with argument templates
prompts: [
{
name: "api_request",
title: "API Request Helper",
description: "Helps generate API request templates",
arguments: [
{ name: "endpoint", description: "API endpoint path", required: true },
{ name: "method", description: "HTTP method", required: false },
],
template: "Create a {{method}} request to {{endpoint}} with proper parameters.",
},
],
// Define resources with static content
resources: [
{
uri: "docs://api/overview",
name: "api-overview",
title: "API Overview",
description: "Overview of the API capabilities",
mimeType: "text/markdown",
text: "# API Overview\n\nThis API provides...",
},
],
}
const server = new OpenAPIServer(config)추가 사용자 정의 도구 추가
OpenAPI 명세에서 생성된 도구와 함께 수작업으로 작성한 몇 가지 MCP 도구를 노출할 수 있습니다:
import { OpenAPIServer } from "@ivotoby/openapi-mcp-server"
const extraTools = [
{
id: "add",
tool: {
name: "add",
description: "Add two numbers",
inputSchema: {
type: "object",
properties: {
a: { type: "number" },
b: { type: "number" },
},
required: ["a", "b"],
},
},
handler: async (args) => {
const a = Number(args.a)
const b = Number(args.b)
const result = a + b
return {
content: [{ type: "text", text: JSON.stringify({ result }) }],
structuredContent: { result },
}
},
},
]
const server = new OpenAPIServer({
name: "my-api-server",
version: "1.0.0",
apiBaseUrl: "https://api.example.com",
openApiSpec: "https://api.example.com/openapi.json",
specInputMethod: "url",
transportType: "stdio",
toolsMode: "all",
extraTools,
})참고:
extraTools는 이 첫 번째 버전에서 라이브러리 전용입니다. 함수 핸들러를 위한 CLI 형식은 없습니다.추가 도구 ID와 MCP 도구 이름은 사용자 정의 도구와 OpenAPI 생성 도구 모두에서 고유해야 합니다.
추가 도구 핸들러는 일반 MCP
tools/call결과 객체를 반환해야 합니다.
동적 프롬프트 및 리소스 관리
서버 생성 후 프롬프트와 리소스를 동적으로 추가할 수도 있습니다:
const server = new OpenAPIServer(config)
// Add prompts dynamically
const promptsManager = server.getPromptsManager()
if (promptsManager) {
promptsManager.addPrompt({
name: "debug_error",
title: "Error Debugger",
template: "Debug this API error: {{error_message}}",
})
}
// Add resources dynamically
const resourcesManager = server.getResourcesManager()
if (resourcesManager) {
resourcesManager.addResource({
uri: "docs://changelog",
name: "changelog",
title: "API Changelog",
mimeType: "text/markdown",
text: "# Changelog\n\n## v1.0.0\n- Initial release",
})
}프롬프트 정의 형식
interface PromptDefinition {
name: string // Unique identifier
title?: string // Human-readable display title
description?: string // Description of the prompt
arguments?: {
// Template arguments
name: string
description?: string
required?: boolean
}[]
template: string // Template with {{argName}} placeholders
}리소스 정의 형식
interface ResourceDefinition {
uri: string // Unique URI identifier
name: string // Resource name
title?: string // Human-readable display title
description?: string // Description of the resource
mimeType?: string // Content MIME type
text?: string // Static text content
blob?: string // Static binary content (base64)
contentProvider?: () => Promise<string | { blob: string }> // Dynamic content
}AuthProvider를 사용한 고급 인증
토큰 만료, 갱신 요구 사항 또는 복잡한 인증이 있는 API의 경우:
import { OpenAPIServer, AuthProvider } from "@ivotoby/openapi-mcp-server"
import { AxiosError } from "axios"
class MyAuthProvider implements AuthProvider {
async getAuthHeaders(): Promise<Record<string, string>> {
// Called before each request - return fresh headers
if (this.isTokenExpired()) {
await this.refreshToken()
}
return { Authorization: `Bearer ${this.token}` }
}
async handleAuthError(error: AxiosError): Promise<boolean> {
// Called on 401/403 errors - return true to retry
if (error.response?.status === 401) {
await this.refreshToken()
return true // Retry the request
}
return false
}
}
const authProvider = new MyAuthProvider()
const config = {
// ... other config
authProvider: authProvider, // Use AuthProvider instead of static headers
}📁 전체 실행 가능한 예제는 examples/ 디렉터리에서 확인하세요. 다음을 포함합니다:
정적 인증을 사용한 기본 라이브러리 사용법
다양한 시나리오를 위한 AuthProvider 구현
실제 Beatport API 통합
프로덕션 준비가 된 패키징 패턴
🔐 AuthProvider를 사용한 동적 인증
AuthProvider 인터페이스는 정적 헤더로는 처리할 수 없는 정교한 인증 시나리오를 지원합니다:
주요 기능
동적 헤더: 각 요청에 대한 새로운 인증 헤더
토큰 만료 처리: 만료된 토큰 자동 감지 및 처리
인증 오류 복구: 복구 가능한 인증 실패에 대한 재시도 로직
사용자 정의 오류 메시지: 사용자에게 명확하고 실행 가능한 안내 제공
AuthProvider 인터페이스
interface AuthProvider {
/**
* Get authentication headers for the current request
* Called before each API request to get fresh headers
*/
getAuthHeaders(): Promise<Record<string, string>>
/**
* Handle authentication errors from API responses
* Called when the API returns 401 or 403 errors
* Return true to retry the request, false otherwise
*/
handleAuthError(error: AxiosError): Promise<boolean>
}일반적인 패턴
자동 토큰 갱신
class RefreshableAuthProvider implements AuthProvider {
async getAuthHeaders(): Promise<Record<string, string>> {
if (this.isTokenExpired()) {
await this.refreshToken()
}
return { Authorization: `Bearer ${this.accessToken}` }
}
async handleAuthError(error: AxiosError): Promise<boolean> {
if (error.response?.status === 401) {
await this.refreshToken()
return true // Retry with fresh token
}
return false
}
}수동 토큰 관리 (예: Beatport)
class ManualTokenAuthProvider implements AuthProvider {
async getAuthHeaders(): Promise<Record<string, string>> {
if (!this.token || this.isTokenExpired()) {
throw new Error(
"Token expired. Please get a new token from your browser:\n" +
"1. Go to the API website and log in\n" +
"2. Open browser dev tools (F12)\n" +
"3. Copy the Authorization header from any API request\n" +
"4. Update your token using updateToken()",
)
}
return { Authorization: `Bearer ${this.token}` }
}
updateToken(token: string): void {
this.token = token
this.tokenExpiry = new Date(Date.now() + 3600000) // 1 hour
}
}API 키 인증
class ApiKeyAuthProvider implements AuthProvider {
constructor(private apiKey: string) {}
async getAuthHeaders(): Promise<Record<string, string>> {
return { "X-API-Key": this.apiKey }
}
async handleAuthError(error: AxiosError): Promise<boolean> {
throw new Error("API key authentication failed. Please check your key.")
}
}📖 AuthProvider에 대한 자세한 문서와 예제는 docs/auth-provider-guide.md를 참조하세요.
OpenAPI 스키마 처리
참조 해석
이 MCP 서버는 API 스키마를 정확하게 표현하기 위해 강력한 OpenAPI 참조($ref) 해석을 구현합니다:
매개변수 참조: OpenAPI 명세의 매개변수 컴포넌트에 대한
$ref포인터를 완전히 해석합니다스키마 참조: 매개변수와 요청 본문 내의 중첩 스키마 참조를 처리합니다
재귀 참조: 순환 참조를 감지하고 처리하여 무한 루프를 방지합니다
중첩 속성: 모든 속성을 포함한 복잡한 중첩 객체 및 배열 구조를 보존합니다
입력 스키마 구성
서버는 각 도구에 대해 매개변수와 요청 본문을 지능적으로 병합하여 통합된 입력 스키마를 만듭니다:
매개변수 + 요청 본문 병합: 경로, 쿼리 및 본문 매개변수를 단일 스키마로 결합합니다
충돌 처리: 매개변수 이름과 충돌하는 본문 속성에 접두사를 붙여 이름 충돌을 해결합니다
타입 보존: 모든 스키마 요소에 대한 원래 타입 정보를 유지합니다
메타데이터 유지: 설명, 형식, 기본값, 열거형 및 기타 스키마 속성을 보존합니다
복잡한 스키마 지원
MCP 서버는 다양한 OpenAPI 스키마 복잡성을 처리합니다:
원시 타입 요청 본문: 객체가 아닌 요청 본문을 "body" 속성으로 감쌉니다
객체 요청 본문: 객체 속성을 도구의 입력 스키마로 평면화합니다
배열 요청 본문: 중첩된 항목 정의가 있는 배열 스키마를 올바르게 처리합니다
필수 속성: 어떤 매개변수와 속성이 필수인지 추적하고 보존합니다
개발자 정보
개발자를 위한
개발 도구
npm run build- TypeScript 소스 빌드npm run clean- 빌드 산출물 삭제npm test- Vitest 테스트 스위트 실행npm run typecheck- TypeScript 타입 검사 실행npm run lint-src/**/*.ts에 대해 타입 인식 ESLint 실행npm run dev- 소스 파일을 감시하고 변경 시 재빌드npm run inspect-watch- 변경 시 자동 리로드되는 인스펙터 실행
풀 리퀘스트 전 검증
PR을 열기 전에 전체 로컬 검증 스위트를 실행하세요:
npm run build
npm test
npm run typecheck
npm run lintnpm run build는 dist/를 갱신하여 CLI 실행 테스트가 최신 코드를 사용하도록 합니다. npm run lint는 의도적으로 타입 인식 방식이며 모든 소스 파일에서 린트 오류가 없어야 합니다.
개발 워크플로우
저장소를 클론합니다.
의존성을 설치합니다:
npm install개발 환경을 시작합니다:
npm run inspect-watchsrc/의 TypeScript 파일을 변경합니다.서버가 자동으로 재빌드되고 재시작됩니다.
기여하기
저장소를 포크합니다.
기능 브랜치를 생성합니다.
변경 사항을 적용합니다.
빌드, 테스트, 타입 검사 및 린트를 실행합니다:
npm run build && npm test && npm run typecheck && npm run lint풀 리퀘스트를 제출합니다.
📖 포괄적인 개발자 문서는 docs/developer-guide.md를 참조하세요.
FAQ
Q: "도구"란 무엇인가요? A: 도구는 OpenAPI 명세에서 파생된 단일 API 엔드포인트에 해당하며, MCP 리소스로 노출됩니다.
Q: 이 패키지를 내 프로젝트에서 어떻게 사용할 수 있나요?
A: OpenAPIServer 클래스를 가져와서 Node.js 애플리케이션에서 라이브러리로 사용할 수 있습니다. 이를 통해 특정 API를 위한 전용 MCP 서버를 사용자 정의 인증, 필터링 및 오류 처리와 함께 만들 수 있습니다. 전체 구현은 examples/ 디렉터리를 참조하세요.
Q: CLI 사용과 라이브러리 사용의 차이점은 무엇인가요?
A: CLI는 빠른 설정과 테스트에 유용하며, 라이브러리 방식은 특정 API를 위한 전용 패키지를 만들고, AuthProvider로 사용자 정의 인증을 구현하고, 사용자 정의 로직을 추가하며, 서버를 독립 실행형 npm 모듈로 배포할 수 있게 해줍니다.
Q: 만료 토큰이 있는 API는 어떻게 처리하나요?
A: 정적 헤더 대신 AuthProvider 인터페이스를 사용하세요. AuthProvider를 사용하면 토큰 갱신, 만료 처리 및 사용자 정의 오류 복구가 포함된 동적 인증을 구현할 수 있습니다. 다양한 패턴은 AuthProvider 예제를 참조하세요.
Q: AuthProvider란 무엇이며 언제 사용해야 하나요?
A: AuthProvider는 각 요청 전에 새로운 헤더를 가져오고 인증 오류를 처리하는 동적 인증용 인터페이스입니다. API에 만료 토큰이 있거나, 토큰 갱신이 필요하거나, 정적 헤더로 처리할 수 없는 복잡한 인증 로직이 필요한 경우 사용하세요.
Q: 로드할 도구를 어떻게 필터링하나요?
A: --tools all(기본값)과 함께 --tool, --tag, --exclude-tag, --resource, --operation 플래그를 사용하거나, 메타 도구만 사용하려면 --tools dynamic으로 설정하거나, --tool로 지정된 도구만 로드하려면 --tools explicit을 사용하세요. --exclude-tag는 거부 필터이며 dynamic 및 explicit 모드에서도 계속 적용됩니다.
Q: 동적 모드는 언제 사용해야 하나요?
A: 동적 모드는 모든 작업을 미리 로드하지 않고 엔드포인트를 검사하고 상호 작용할 수 있는 메타 도구(list-api-endpoints, get-api-endpoint-schema, invoke-api-endpoint)를 제공하므로 크거나 자주 변경되는 API에 유용합니다.
Q: 프롬프트와 리소스란 무엇인가요?
A: 프롬프트는 MCP prompts/get 메서드로 검색할 수 있는 인수 자리 표시자(예: {{name}})가 있는 재사용 가능한 메시지 템플릿입니다. 리소스는 MCP resources/read 메서드로 읽을 수 있는 정적 또는 동적 콘텐츠(텍스트 또는 바이너리)입니다. 둘 다 도구와 함께 구성할 수 있는 선택적 기능입니다.
Q: CLI에서 프롬프트와 리소스를 어떻게 노출하나요?
A: 프롬프트에는 --prompts <path|url>을, 리소스에는 --resources <path|url>을 사용하세요. 인라인 JSON에는 --prompts-inline과 --resources-inline을 사용할 수도 있습니다. 자세한 내용은 사용자 가이드의 "프롬프트 및 리소스" 섹션을 참조하세요.
Q: API 요청에 사용자 정의 헤더를 어떻게 지정하나요?
A: CLI 사용 시 --headers 플래그 또는 API_HEADERS 환경 변수에 쉼표로 구분된 key:value 쌍을 사용하세요. 라이브러리 사용 시 headers 구성 옵션을 사용하거나 동적 헤더를 위해 AuthProvider를 구현하세요.
Q: 어떤 전송 방법이 지원되나요? A: 서버는 AI 시스템 통합을 위한 stdio 전송(기본값)과 웹 클라이언트를 위한 HTTP 전송(SSE를 통한 스트리밍)을 지원합니다.
Q: 서버는 참조가 있는 복잡한 OpenAPI 스키마를 어떻게 처리하나요?
A: 서버는 매개변수와 스키마의 $ref 참조를 완전히 해석하여 중첩 구조, 기본값 및 기타 속성을 보존합니다. 참조 해석 및 스키마 구성에 대한 자세한 내용은 "OpenAPI 스키마 처리" 섹션을 참조하세요.
Q: 매개변수 이름이 요청 본문 속성과 충돌하면 어떻게 되나요?
A: 서버는 이름 충돌을 감지하고 본문 속성 이름에 자동으로 body_ 접두사를 붙여 충돌을 방지하므로 모든 속성에 액세스할 수 있습니다.
Q: MCP 서버를 배포용으로 패키징할 수 있나요?
A: 네! 라이브러리 방식을 사용하면 API 전용 npm 패키지를 만들 수 있습니다. npx your-api-mcp-server로 패키징하여 배포할 수 있는 전체 구현은 Beatport 예제를 참조하세요.
Q: 개발 및 기여 지침은 어디에서 찾을 수 있나요? A: 아키텍처, 핵심 개념, 개발 워크플로우 및 기여 지침에 대한 포괄적인 문서는 개발자 가이드를 참조하세요.
라이선스
MIT
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Point Gecko at an OpenAPI spec; get first-call-correct, auth-hidden agent tools.
MCP server for AI access to Swagger by SmartBear.
MCP server exposing the Backtest360 engine API as tools for AI agents.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/TuanLdv/mcp-openapi-server-demo'
If you have feedback or need assistance with the MCP directory API, please join our Discord server