Skip to main content
Glama
TuanLdv

mcp-openapi-server

by TuanLdv

OpenAPI MCP Server

OpenAPI エンドポイントを MCP ツールとして公開し、オプションで MCP プロンプトとリソースをサポートする Model Context Protocol (MCP) サーバーです。このサーバーを使用すると、大規模言語モデルが MCP プロトコルを通じて OpenAPI 仕様で定義された REST API を検出して操作できるようになります。

📖 ドキュメント

  • ユーザーガイド - この MCP サーバーを Claude Desktop、Cursor、または他の MCP クライアントで使用したいユーザー向け

  • ライブラリの使用 - このパッケージをライブラリとして使用してカスタム MCP サーバーを作成する開発者向け

  • 開発者ガイド - コードベースに取り組むコントリビューターおよび開発者向け

  • AuthProvider ガイド - 詳細な認証パターンと例


ユーザーガイド

このセクションでは、エンドユーザーとして Claude Desktop、Cursor、またはその他の MCP 互換ツールで MCP サーバーを使用する方法について説明します。

Related MCP server: cod-api MCP Server

概要

この MCP サーバーは、次の 2 つの方法で使用できます。

  1. CLI ツール: npx @ivotoby/openapi-mcp-server をコマンドライン引数とともに直接使用して、すばやくセットアップする

  2. ライブラリ: 独自の Node.js アプリケーションで OpenAPIServer クラスをインポートして使用し、カスタム実装を行う

サーバーは 2 つのトランスポート方式をサポートしています。

  1. Stdio トランスポート (デフォルト): 標準入出力を通じて MCP 接続を管理する Claude Desktop などの AI システムとの直接統合用。

  2. ストリーミング対応 HTTP トランスポート: HTTP 経由でサーバーに接続し、Web クライアントやその他の HTTP 対応システムが MCP プロトコルを使用できるようにする。

ユーザー向けクイックスタート

オプション 1: Claude Desktop で使用する (Stdio トランスポート)

このリポジトリをクローンする必要はありません。Claude Desktop がこの MCP サーバーを使用するように設定するだけです。

  1. Claude Desktop の設定ファイルを探すか作成します:

    • macOS の場合: ~/Library/Application Support/Claude/claude_desktop_config.json

  2. 次の設定を追加します:

{
  "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"
      }
    }
  }
}
  1. 環境変数を実際の API 設定に置き換えます:

    • API_BASE_URL: API のベース URL

    • OPENAPI_SPEC_PATH: OpenAPI 仕様の URL またはパス

    • API_HEADERS: API 認証ヘッダー用のカンマ区切りの key:value ペア

オプション 2: HTTP クライアントで使用する (HTTP トランスポート)

HTTP クライアントでサーバーを使用するには:

  1. インストールは不要です。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 3000
  1. HTTP リクエストを使用してサーバーとやり取りします:

# 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 エンドポイントのベース URL

  • OPENAPI_SPEC_PATH - OpenAPI 仕様へのパスまたは URL

  • OPENAPI_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 ファイルへのパスまたは URL

  • PROMPTS_INLINE - プロンプトを JSON 文字列として直接指定します

  • RESOURCES_PATH - リソースの JSON/YAML ファイルへのパスまたは URL

  • RESOURCES_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.json

2. ローカルファイルからの読み込み

ローカルファイルから OpenAPI 仕様を読み込みます:

npx @ivotoby/openapi-mcp-server \
  --api-base-url https://api.example.com \
  --openapi-spec ./path/to/openapi.yaml

3. 標準入力からの読み込み

標準入力から 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.com

4. インライン仕様

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 構文エラーメッセージ

検証

一度に使用できる仕様ソースは 1 つだけです。サーバーは、次のいずれか 1 つだけが指定されていることを検証します。

  • --openapi-spec (URL またはファイルパス)

  • --spec-from-stdin

  • --spec-inline

複数のソースが指定された場合、サーバーはエラーメッセージを表示して終了します。

ツールの読み込みとフィルタリングオプション

Stainless の記事「What We Learned Converting Complex OpenAPI Specs to MCP Servers」(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

この構成により、サーバーは 3 つすべての機能をアドバタイズします。

{
  "capabilities": {
    "tools": { "list": true, "execute": true },
    "prompts": {},
    "resources": {}
  }
}

トランスポートの種類

Stdio トランスポート (デフォルト)

stdio トランスポートは、標準入出力を通じて MCP 接続を管理する Claude Desktop などの AI システムとの直接統合向けに設計されています。これは最もシンプルなセットアップで、ネットワーク構成は必要ありません。

使用するタイミング: Claude Desktop または stdio ベースの MCP 通信をサポートする他のシステムと統合する場合。

ストリーミング対応 HTTP トランスポート

HTTP トランスポートを使用すると、MCP サーバーに HTTP 経由でアクセスできるようになり、Web アプリケーションやその他の HTTP 対応クライアントが MCP プロトコルとやり取りできるようになります。セッション管理、ストリーミング応答、標準的な HTTP メソッドをサポートしています。

主な機能:

  • Mcp-Session-Id ヘッダーによるセッション管理

  • initialize および tools/list リクエストの HTTP 応答は POST 上で同期的に送信されます。

  • その他のサーバーからクライアントへのメッセージ (例: tools/execute の結果、通知) は、Server-Sent Events (SSE) を使用して GET 接続でストリーミングされます。

  • POST/GET/DELETE メソッドのサポート

使用するタイミング: MCP サーバーを、stdio ではなく HTTP で通信する Web クライアントやシステムに公開する必要がある場合。

ヘルスチェックエンドポイント

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) にのみバインドされます

  • 他のホストに公開する場合は、追加の認証の実装を検討してください

デバッグ

デバッグログを確認するには:

  1. Claude Desktop で stdio トランスポートを使用する場合:

    • ログは Claude Desktop のログに表示されます

  2. HTTP トランスポートを使用する場合:

    npx @ivotoby/openapi-mcp-server --transport http &2>debug.log

ライブラリの使用

このセクションは、このパッケージをライブラリとして使用してカスタム MCP サーバーを作成したい開発者向けです。

🚀 ライブラリとして使用する

特定のAPI向けの専用MCPサーバーは、OpenAPIServerクラスをインポートして設定することで作成できます。このアプローチは以下に最適です:

  • カスタム認証: 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サーバーは、堅牢なOpenAPI参照($ref)解決を実装し、APIスキーマの正確な表現を保証します:

  • パラメータ参照: 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 lint

npm run buildはdist/を更新し、CLI実行テストが現在のコードを使用するようにします。npm run lintは意図的に型認識であり、すべてのソースファイルでクリーンである必要があります。

開発ワークフロー

  1. リポジトリをクローン

  2. 依存関係をインストール: npm install

  3. 開発環境を起動: npm run inspect-watch

  4. src/内のTypeScriptファイルに変更を加える

  5. サーバーが自動的に再ビルドされ再起動されます

コントリビューション

  1. リポジトリをフォーク

  2. フィーチャーブランチを作成

  3. 変更を加える

  4. ビルド、テスト、型チェック、リントを実行: npm run build && npm test && npm run typecheck && npm run lint

  5. プルリクエストを送信

📖 包括的な開発者ドキュメントについては、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: dynamicモードはいつ使用すべきですか? A: dynamicモードは、すべての操作をプリロードせずにエンドポイントを検査および操作するためのメタツール(list-api-endpoints、get-api-endpoint-schema、invoke-api-endpoint)を提供します。これは、大規模または頻繁に変更されるAPIに役立ちます。

Q: プロンプトとリソースとは何ですか? A: プロンプトは、引数プレースホルダー(例:{{name}})を持つ再利用可能なメッセージテンプレートで、MCP prompts/getメソッドで取得できます。リソースは、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トランスポート(デフォルト)と、Webクライアント用のHTTPトランスポート(SSEによるストリーミング付き)をサポートしています。

Q: 参照を含む複雑なOpenAPIスキーマはどのように処理されますか? A: サーバーはパラメータとスキーマの$ref参照を完全に解決し、ネストされた構造、デフォルト値、その他の属性を保持します。参照解決とスキーマ合成の詳細については、「OpenAPIスキーマ処理」セクションを参照してください。

Q: パラメータ名がリクエストボディのプロパティと衝突するとどうなりますか? A: サーバーは名前の競合を検出し、衝突を避けるためにボディプロパティ名に自動的にbody_プレフィックスを付けて、すべてのプロパティにアクセスできるようにします。

Q: MCPサーバーを配布用にパッケージ化できますか? A: はい!ライブラリアプローチを使用する場合、API専用のnpmパッケージを作成できます。npx your-api-mcp-serverとしてパッケージ化して配布できる完全な実装については、Beatportの例を参照してください。

Q: 開発とコントリビューションのガイドラインはどこにありますか? A: アーキテクチャ、主要な概念、開発ワークフロー、コントリビューションガイドラインに関する包括的なドキュメントについては、開発者ガイドを参照してください。

ライセンス

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Exposes REST API endpoints defined in an OpenAPI Specification as MCP tools, allowing AI models to call them via the ModelContext Protocol.
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Exposes any REST API as MCP tools, enabling AI agents to discover and call existing HTTP endpoints without modifying the original API.
    -