OpenAPI仕様からMCPサーバーを自動生成する3つの方法
OpenAPI仕様をFastMCP・AWS製openapi-mcp-server・openapi-mcp-generatorで自動的にMCPサーバー化する手順と、3ツールの使い分けを扱います。
既存のREST APIをMCPサーバー化するとき、エンドポイントを1つずつ手作業でツール定義に書き起こす必要はありません。OpenAPI仕様さえあれば、FastMCP・AWS製のopenapi-mcp-server・openapi-mcp-generatorのいずれかが、エンドポイントをMCPツールへ自動変換します。3つはそれぞれ言語・配布形態・カスタマイズ性が異なり、選び方次第で運用の手間が変わります。
MCPツールを手作業で1つずつ定義する自作の基本はMCPサーバー自作ガイド、生成したサーバーの動作確認はMCP Inspectorの使い方が扱っています。
OpenAPIからのMCPサーバー自動生成とは
OpenAPI仕様からのMCPサーバー自動生成とは、既存のOpenAPI 3.x定義(JSON/YAML)を読み込み、各エンドポイントをMCPのツールやリソースへ機械的に変換する手法です。ツール定義のコードを人手で書く代わりに、変換ツールがOpenAPIのパス・パラメータ・レスポンススキーマから必要な情報を抽出します。
3ツールとも「既存APIをすぐAIエージェントから叩けるようにする」という目的は共通ですが、実行環境(Python/Node.js)、配布形態(ライブラリ/CLIパッケージ)、ルーティングの制御方法が異なります。
FastMCPでPythonのMCPサーバーを生成する
FastMCPはFastMCP.from_openapi()にOpenAPI仕様とHTTPクライアントを渡すだけでMCPサーバーを構築するPythonライブラリです。
import httpx
from fastmcp import FastMCP
# APIへのHTTPクライアントを作成
client = httpx.AsyncClient(base_url="https://api.example.com")
# OpenAPI仕様を取得
openapi_spec = httpx.get("https://api.example.com/openapi.json").json()
# MCPサーバーを作成
mcp = FastMCP.from_openapi(
openapi_spec=openapi_spec,
client=client,
name="My API Server",
)
if __name__ == "__main__":
mcp.run()既定では、OpenAPI仕様に含まれるすべてのエンドポイントがMCPのツールに変換されます。これは互換性を最大化するための実用的な既定値で、ほとんどのMCPクライアントがツールにしか対応していないためです。認証が必要なAPIでは、httpx.AsyncClient側にヘッダーとして認証情報を設定します。
AWS製のopenapi-mcp-serverを使う
AWS Labsが公開するopenapi-mcp-serverは、OpenAPI仕様からMCPのツールとリソースを動的に生成するPython製サーバーです。pipで直接インストールして使います。
pip install "awslabs.openapi-mcp-server"環境変数でAPI名・ベースURL・仕様の取得先を指定して起動します。主な特徴は次のとおりです。
- GETをTOOLとして扱う — クエリパラメータ付きのGETリクエストは、リソースではなくツールにマッピングされ、検索・フィルタリング系のエンドポイントをLLMが扱いやすくなる
- タグベースのフィルタリング —
--include-tags pet,storeや--exclude-tags admin,internalのようにCLI引数か環境変数(INCLUDE_TAGS/EXCLUDE_TAGS)で公開範囲を絞れる - 複数仕様の合成 —
--additional-specsで複数のOpenAPI仕様を1つのMCPサーバーにまとめられる。各仕様は個別の認証設定を持てる - SSRF対策 — 仕様取得前にURLをDNS解決とIPアローリストで検証する
- 認証方式 — Basic・Bearer Token・APIキー・Cognitoに対応
YAML形式の仕様を読み込む場合や、Prometheusでのメトリクス収集を使う場合は、拡張パッケージを追加でインストールします。
pip install "awslabs.openapi-mcp-server[yaml]"
pip install "awslabs.openapi-mcp-server[prometheus]"さらに、OpenAPI仕様からAPI操作ごとの自然言語プロンプトや、API全体のドキュメント用プロンプトを動的に生成する機能も備えており、ツールだけでなくプロンプト面でもAPI構造を活用します。
Node.js/TypeScriptで生成するopenapi-mcp-generator
openapi-mcp-generatorは、OpenAPI仕様から独立したNode.jsプロジェクト一式(TypeScriptコード・package.json・テスト用HTMLクライアント)を出力するCLIツールです。生成後のサーバーは既存APIへのプロキシとして動作し、リクエスト構造をZodスキーマで実行時検証します。認証情報を扱う際は既定でTLS証明書の検証を行い、自己署名証明書を使う開発環境向けには--insecureで検証を無効化できます。
npm install -g openapi-mcp-generator
openapi-mcp-generator --input path/to/openapi.json --output path/to/output/dir主なCLIオプションは次のとおりです。
| オプション | 説明 | 既定値 |
|---|---|---|
--transport / -t | 説明stdio / web / streamable-httpのいずれか | 既定値stdio |
--base-url / -b | 説明APIのベースURL(OpenAPIのserversが無い・曖昧な場合は必須) | 既定値自動検出 |
--max-tool-name-length | 説明ツール名の最大文字数(Claude Desktopの上限は64) | 既定値64 |
--custom-auth | 説明組み込み認証の前に呼ばれるsrc/auth.tsを編集可能な形で生成 | 既定値false |
--allow-external-refs | 説明$refでの外部URL参照解決を許可(既定は無効、パース時のSSRF対策) | 既定値false |
生成されたサーバーはstdio(ローカルのMCPクライアント向け)に加え、Server-Sent EventsのWebサーバーやStreamableHTTPとしても起動できます。後者2つはブラウザで動くテストクライアントが同梱されており、生成直後に動作確認ができます。
ツール名を制御する
自動生成したツール名がAPIのoperationIdをそのまま反映するだけだと、AIエージェントにとって選びにくい名前になることがあります。FastMCPはoperationIdを最初の二重アンダースコア(__)までで自動的に名付け、さらにスラッグ化(記号除去)・56文字までの切り詰め・重複時の連番付与を行います。個別に名前を制御したい場合はmcp_names辞書でoperationIdごとの表示名を指定できます。
mcp = FastMCP.from_openapi(
openapi_spec=spec,
client=client,
mcp_names={
"list_users__with_pagination": "user_list",
"create_user__admin_required": "create_user",
},
)AWS製のopenapi-mcp-serverは逆に、ツールの説明文を充実させる方向でLLMの選択精度を上げています。OpenAPI仕様に含まれるレスポンスコードやパラメータの例をツールの説明に自動的に追記し、あわせてプロンプトのトークン効率を高める最適化で70〜75%のトークン削減を達成していると案内されています。
openapi-mcp-generatorにはCLIとは別にプログラム的なAPIもあり、Node.jsアプリケーションからツール定義だけを抽出することもできます。
import { getToolsFromOpenApi } from 'openapi-mcp-generator';
const tools = await getToolsFromOpenApi('./petstore.json', {
baseUrl: 'https://api.example.com',
excludeOperationIds: ['deletePet'],
filterFn: (tool) => tool.method.toLowerCase() === 'get',
});生成プロジェクト一式ではなく、既存のNode.jsサーバーにツール定義だけを組み込みたい場合はこちらが向きます。
3つのツールをどう使い分けるか
| ツール | 実行環境 | 出力形態 | 向くケース |
|---|---|---|---|
| FastMCP | 実行環境Python(ライブラリ) | 出力形態コード内でサーバーを構築 | 向くケースPythonプロジェクトに組み込み、ルーティングを細かくカスタマイズしたい |
| openapi-mcp-server(AWS) | 実行環境Python(pipパッケージ) | 出力形態起動可能なサーバー本体 | 向くケース複数API仕様の合成、タグベースの公開範囲制御、AWS系の認証(Cognito)が要る |
| openapi-mcp-generator | 実行環境Node.js(CLIツール) | 出力形態独立したTypeScriptプロジェクト一式 | 向くケース生成後のコードを編集・配布したい、複数トランスポート(Web/StreamableHTTP)で動かしたい |
いずれも「まず全エンドポイントをツール化し、不要な範囲を後から絞る」という設計思想は共通しています。既存のPythonバックエンドに寄せるならFastMCP、複数のAPIをまとめて1つのMCPサーバーにしたいならAWS製、生成後のコードを手元で編集・デプロイしたいならopenapi-mcp-generatorという判断が妥当です。
ルーティングをカスタマイズする(FastMCPの例)
既定の「全ルートをツール化」から外れたい場合、route_mapsにカスタムルールを渡します。
from fastmcp import FastMCP
from fastmcp.server.providers.openapi import RouteMap, MCPType
mcp = FastMCP.from_openapi(
openapi_spec=spec,
client=client,
route_maps=[
# /admin/ 配下は除外
RouteMap(pattern=r"^/admin/.*", mcp_type=MCPType.EXCLUDE),
# internal タグが付いたルートも除外
RouteMap(tags={"internal"}, mcp_type=MCPType.EXCLUDE),
],
)カスタムルールは既定ルールより先に評価されるため、除外したいルートだけを列挙すれば残りは既定どおりツール化されます。AWS製の--exclude-tagsも考え方は同じで、タグ単位で公開範囲を絞る点が共通しています。
よくあるつまずき
自動変換したツールの質がそのまま使えるとは限らない
FastMCPの開発元は、自動変換したMCPサーバーよりも、手作業で設計・選別したMCPサーバーのほうがLLMの性能が明確に高くなると案内しています。特にエンドポイント数やパラメータが多い複雑なAPIほど差が出やすいため、自動生成はプロトタイピングの起点として使い、本番でAIエージェントに使わせるツールはroute_mapsや--include-tagsで絞り込む前提で運用するのが妥当です。
Claude Desktopでツール名が長すぎて弾かれる
Claude Desktopにはツール名の文字数上限があり、openapi-mcp-generatorは既定で64文字を超える名前をハッシュ付きで切り詰めます。他のツールで自動生成したサーバーをClaude Desktopに接続する場合も、operationIdが長いAPIでは同様の問題が起きやすい点に注意します。
外部$ref参照でSSRFの注意が要る
OpenAPI仕様が外部URLへの$refを含む場合、両ツールとも既定では解決を無効にしています。openapi-mcp-generatorの--allow-external-refsやAWS製のSSRF検証は、信頼できない仕様ファイルを扱う際の安全策なので、必要な場合だけ明示的に有効化します。
認証をどこで設定するか迷う
FastMCPはhttpxクライアント側にヘッダーとして設定、AWS製は環境変数やauth_type/auth_token、openapi-mcp-generatorは環境変数か--custom-authで生成したsrc/auth.tsという具合に、認証の設定場所がツールごとに異なります。生成後にAPIキーが漏れないよう、いずれのツールでも認証情報はコード直書きではなく環境変数側に置きます。
まとめ
OpenAPI仕様からMCPサーバーを自動生成する選択肢は、Pythonプロジェクトに組み込むならFastMCP、複数API仕様をまとめて1つのサーバーにしたいならAWS製のopenapi-mcp-server、生成後のコードを編集・配布したいならopenapi-mcp-generatorという順で絞り込めます。どのツールでも、まず全エンドポイントを機械的にツール化してから、タグやパターンで公開範囲を絞り込む流れは共通です。ただし自動生成はあくまで出発点で、本番投入前には不要なツールを削り、ツール名や説明文をLLMが選びやすい形に整える一手間が要ります。