mcpField
O
openapi-to-mcp

openapi-to-mcp

github.com/mcp-use開発10.8k192 回インストール1 日前に更新
リポジトリ

openapi-to-mcp について

OpenAPI 3.x または Swagger 2.0 の API 仕様から MCP サーバーを構築するスキルです。操作の選定、型付きツールの生成、認証設定、テスト、デプロイを開発者向けに案内します。

主な機能

  1. 01OpenAPI・Swagger 仕様の取り込み
  2. 02API 操作を MCP ツールに変換
  3. 03Zod 引数スキーマの生成
  4. 04環境変数による認証設定
  5. 05サーバーのテストとデプロイ

活用シーン

  1. 01既存 REST API の LLM ツール化
  2. 02大規模 API 仕様からのエンドポイント選定
  3. 03HTTP ベース MCP サーバーの構築と検証

MCP 対応

選択した API 操作をそれぞれツールとして公開する MCP サーバーの構築を案内します。ワークフローでは Streamable HTTP トランスポートを使用します。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mcp-use/mcp-use --skill openapi-to-mcp

インストール後、Claude Code で/openapi-to-mcpを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE.txt
references/
auth.md
code-templates.md
deploy.md
mapping-rules.md
testing.md

詳細

OpenAPI 仕様書から MCP サーバーを構築する

既存の REST API(OpenAPI 3.x または Swagger 2.0 ドキュメントで記述)を MCP サーバーに変換します。仕様書内の各操作が、LLM が呼び出せる 1 つの MCP ツールになります。サーバーはテスト用にローカルで実行でき、1 つのコマンドで Manufact / mcp-use クラウドにデプロイできます。

このスキルでは、スコープの決定 → 仕様書の取り込み → 操作のマッピング → スキャフォールドの作成 → ツールの生成 → 認証の設定 → テスト → デプロイまで、エンドツーエンドの手順を説明します。

基本理念:仕様書が契約です

OpenAPI ドキュメントが信頼できる唯一の情報源です。ツール名、説明、パラメーターの形式、認証要件はすべて仕様書に基づいており、独自に作るべきではありません。これは次の理由で重要です。

  • LLM は説明を信頼します。 仕様書に summary: "Get current weather for a city" と書かれていれば、ツールを呼び出すかどうかを判断する際に、LLM はその内容をそのまま読み取ります。手作業で作成した要約は仕様書とのずれが生じますが、仕様書から生成した要約は API の変更に応じて同期されます。
  • Zod スキーマは OpenAPI スキーマを反映します。 パラメーター(パス、クエリ、本文)はすべて、1 つの zod オブジェクト内のフィールドになります。必須/任意、列挙値、最小値/最大値、説明もすべて引き継がれます。LLM はこのスキーマを使って、ユーザーに何を尋ねるべきかを判断します。
  • 認証情報は仕様書の外で管理します。 OpenAPI には認証方式が記載されていますが、シークレットは記載されません。シークレットは環境変数から取得し、必須とする環境変数は仕様書をもとに判断します。

迷ったときは、創意工夫よりも仕様書への機械的な忠実さを優先してください。創造的な部分は、ユーザーと会話する LLM が担います。LLM に必要なのは、API を忠実かつ型安全に扱う手段だけです。

手順

1. 依頼の範囲を決める(AskUserQuestion を使用)

コードを書く前に、AskUserQuestion ツールを使って次の 5 項目を確定します。5 項目はいずれも API と構築するものについての質問です。デプロイについては、実際に動作するサーバーを評価できるようになるステップ 10 で、別途確認します。

  • 仕様書の場所:ワークスペース内のファイルパス、URL(例:https://api.example.com/openapi.json)、またはチャットへの貼り付けです。貼り付けられた場合は、まず openapi.yaml または openapi.json に保存します。
  • サーバーのベース URL:仕様書に servers[0].url があればその値を使用し、なければユーザーに確認します。servers エントリが複数あることはよくあります(本番/ステージング)。どれを使うか確認してください。
  • 認証方式:components.securitySchemes を確認します。複数ある場合は、どれを使うか尋ねます。API キーまたはトークンが必要な場合は、それを格納する環境変数(API_KEY、OPENAI_API_KEY など)を尋ねます。シークレット自体は尋ねないでください。会話に含めたり、コミットしたりしてはいけません。
  • 操作のフィルター:Stripe や GitHub などの大規模な仕様書には、数百ものエンドポイントがあります。すべての操作を公開するか、タグ(pets、users)で絞り込むか、操作を個別に選ぶかを尋ねます。操作が約 30 個未満の仕様書では、既定で「すべて」を選び、それ以上の場合は尋ねてください。フィルターパターンについては references/mapping-rules.md を参照してください。
  • ウィジェット:チャット内でウィジェット(LLM の返信の横にインライン表示する React コンポーネント)を表示する操作があるか、ツールのみのサーバーにするかを尋ねます。OpenAPI ラッパーの既定は ツールのみ です。LLM は JSON を読み取って会話します。特定の応答にリッチな UI を求める場合(ジオコーディングのエンドポイントに地図、メトリクスのエンドポイントにグラフ、検索結果にカード一覧など)に限り、ウィジェットを選びます。この回答に応じてステップ 3 のスキャフォールドテンプレートが決まります。ツールのみの場合は --template blank、ウィジェットを使う場合は resources/ のウィジェット基盤があらかじめ設定された --template mcp-apps を選びます。ほとんどの操作でウィジェットを使いたい場合は、このスキルよりも mcp-apps-builder スキルが適しています。その旨を伝え、続行する前に確認してください。

このステップを省略しないでください。ユーザーが必要としていないツールを 200 個生成すると、LLM のツール一覧が煩雑になり、応答も遅くなります。

2. 仕様を取得して参照を解決する

仕様を、参照解決済みの単一の JSON オブジェクトとしてディスクに保存します。参照を解決すると $ref がインライン化されるため、後続のコードでポインターをたどる必要がなくなります。

# In the scaffolded project root
npm install @apidevtools/swagger-parser
// scripts/load-spec.ts (run once, manually or as a build step)
import SwaggerParser from "@apidevtools/swagger-parser";
import { writeFileSync } from "node:fs";

const spec = await SwaggerParser.dereference("./openapi.yaml");
writeFileSync("./openapi.dereferenced.json", JSON.stringify(spec, null, 2));

URL の仕様の場合、swagger-parser は URL を直接受け付けます。貼り付けた YAML の場合は、まず openapi.yaml に書き込んでから参照を解決します。仕様が Swagger 2.0 の場合は、先に swagger2openapi を実行します(npx swagger2openapi --outfile openapi.yaml swagger.yaml)。

参照解決済みファイルを簡単に確認します。ファイルを開いて "$ref" を検索し、何も見つからないことを確認してください。見つかった場合、その仕様には循環参照があり、swagger-parser はそれらをそのまま保持しています。その参照は zod で不透明なオブジェクト型として扱ってください。

3. create-mcp-use-app でひな形を作成する

ステップ 1 のウィジェットに関する回答に基づいて、テンプレートを選びます。

# Tools-only (the default for an OpenAPI wrapper)
npx create-mcp-use-app@latest <project-name> --template blank

# Any widgets at all
npx create-mcp-use-app@latest <project-name> --template mcp-apps

ひな形に依存関係のインストールと git init を任せてください。どちらも役立ちます(npm install の postinstall で mcp-use generate-types が実行され、後で npm run deploy を実行するには git リポジトリが必要です)。このスキルは、コンパニオンとなるコーディングエージェント用スキルもデフォルトでインストールしますが、問題ありません。

しばらく確認していない場合は、npx create-mcp-use-app@latest --list-templates でテンプレートカタログを確認してください。執筆時点で利用できるのは blank、mcp-server、mcp-apps です。OpenAPI ファーストのサーバーには blank を使ってください。mcp-server には削除することになるサンプルツールが含まれています。

ひな形の作成後、OpenAPI フローに必要な追加の依存関係を 2 つインストールします。

cd <project-name>
npm install @apidevtools/swagger-parser dotenv

blank で作成されるもの(mcp-apps は resources/ とウィジェットのインフラストラクチャを含む上位互換です):

  • ルートに設定済みの MCPServer インスタンス(name、title、version、description)を含む index.ts。ツール、リソース、プロンプトのコメントアウトされた例も含まれています。process.env.PORT(デフォルトは 3000)でリッスンします。
  • mcp-use CLI に接続されたスクリプトを含む package.json:dev(ホットリロードとインスペクター)、build、start、deploy。tsx、zod、typescript はすでに dev/通常の依存関係に含まれているため、再インストールしないでください。
  • ESM 用に事前設定された tsconfig.json("type": "module")。
  • 静的アセットとして配信される favicon と SVG アイコンを含む public/。
  • .git ディレクトリと初回コミット。

ひな形では、環境変数 MCP_URL を MCP サーバー自体の公開ベース URL 用に予約しています(ウィジェットのアセット URL などで使用されます)。これは上流 API のベース URL ではありません。競合を避けるため、上流の変数には BASE_URL(明示したい場合は API_BASE_URL)という名前を付けてください。

4. プロジェクト構成を計画する

ディレクトリ構成は浅く、予測しやすいものにします。初めてプロジェクトを読む人が、OpenAPI クライアント、ツールの配線、認証を、ひと目でわかる 3 つのファイルから見つけられるようにすることが目的です。

<project>/
├── index.ts                         # MCPServer + server.tool() registration loop
├── openapi.yaml                     # The original spec (committed)
├── openapi.dereferenced.json        # Dereferenced spec (gitignored; regenerated)
├── src/
│   ├── client.ts                    # fetch-based HTTP client (base URL + auth + error handling)
│   ├── auth.ts                      # Reads env vars, builds the auth header
│   ├── operations.ts                # Loads dereferenced spec, exposes operation metadata
│   └── schema.ts                    # OpenAPI schema → zod converter
├── scripts/
│   └── load-spec.ts                 # Dereference helper (step 2)
├── .env.example                     # Document required env vars (API_KEY, BASE_URL, etc.)
└── package.json

小規模な仕様(操作が 10 未満)の場合は、client.ts、auth.ts、operations.ts を index.ts にまとめてもかまいません。それより大きい場合は分割してください。各ファイルの役割を 1 つにすると、LLM の性能が向上します。

5. 操作をツールに対応付ける

仕様内の各操作について、server.tool({...}, handler) の呼び出しを 1 つ作成します。対応付けは機械的に行えます。

OpenAPI フィールドMCP ツールのフィールド
operationId(優先)またはスラッグ化した ${method}_${path}ツールの name(snake_case)
summary + descriptionツールの description
parameters(path + query)+ requestBody.content."application/json".schema統合された zod オブジェクト → ツールの schema
responses.200.content."application/json".schema任意の zod オブジェクト → ツールの outputSchema
security(またはルートレベルのフォールバック)ハンドラーが付加する認証ヘッダー

完全なルールについては references/mapping-rules.md を参照してください。operationId がない場合のツール名の付け方、zod での oneOf/anyOf/nullable 型の扱い、複数のコンテンツを持つリクエストボディのフラット化、レスポンス形状に関する注意点(バイナリダウンロード、ストリーミング、ページ分割されたリスト)などを説明しています。

6. zod スキーマを生成する

OpenAPI の型は次のように zod に対応付けます。完全なコンバーターは src/schema.ts にあります。実装については references/code-templates.md を参照してください。主な選択肢は次のとおりです。

  • type: string と enum → z.enum([...])。LLM が認識できるように、OpenAPI の description を .describe() の引数に使用します。
  • type: integer / type: number → z.number().int() / z.number()。minimum、maximum、multipleOf を引き継ぎます。
  • type: array → z.array(<itemType>)。minItems / maxItems がある場合は、.min() / .max() をチェーンします。
  • type: object → z.object({...})。必須のプロパティは非オプショナルにし、それ以外は .optional() でラップします。
  • oneOf / anyOf → z.union([...])。オブジェクトのみをメンバーに持つ allOf は、1つの z.object にマージします。
  • nullable: true(OpenAPI 3.0)または type: ["string", "null"](3.1)→ .nullable()。

LLM が引数を入力する際に人間が読めるヒントを得られるよう、すべてのフィールドで常に .describe(openapi.description ?? openapi.summary ?? "") を呼び出してください。

7. HTTP クライアントと認証レイヤーを構築する

src/client.ts は、callOperation(operationId, args) → Promise<unknown> という関数を1つ公開します。内部では次の処理を行います。

  1. 参照を解決した仕様からオペレーションを検索します。
  2. パスパラメーターを URL テンプレートに置換します(/users/{id} + {id: 42} → /users/42)。
  3. クエリパラメーターを ?key=value として追加します。
  4. src/auth.ts から認証ヘッダーを追加します。
  5. リクエストボディを JSON としてシリアライズします(仕様で指定されている場合は application/x-www-form-urlencoded を使用します)。
  6. リクエストを送信し、2xx 以外のレスポンスではサーバーのエラーボディを含む例外をスローします。
  7. 解析した JSON を返します(JSON 以外のレスポンスの場合はテキストを返します)。

src/auth.ts は、仕様の securitySchemes に基づいて process.env から値を読み取ります。一般的な4種類の方式と、それぞれがどのようにヘッダーになるかについては references/auth.md を参照してください。必須の環境変数は .env.example に記載します。これは、後でサーバーを実行する人との取り決めになります。

8. index.ts でツールを接続する

登録ループは簡潔です。擬似コード:

import "dotenv/config";
import { MCPServer, text } from "mcp-use";
import { operations } from "./src/operations";
import { callOperation } from "./src/client";
import { operationToZod } from "./src/schema";

// Keep the MCPServer fields from the example (title, favicon, icons).
// Just adjust `name`, `title`, and `description` to match the API you're wrapping.
const server = new MCPServer({
  name: "<api-name>",
  title: "<API name>",
  version: "1.0.0",
  description: "MCP server wrapping the <API name> REST API",
  favicon: "favicon.ico",
  icons: [{ src: "icon.svg", mimeType: "image/svg+xml", sizes: ["512x512"] }],
});

for (const op of operations) {
  server.tool(
    {
      name: op.toolName,
      description: op.description,
      schema: operationToZod(op),
    },
    async (args) => {
      const result = await callOperation(op.operationId, args);
      return text(typeof result === "string" ? result : JSON.stringify(result, null, 2));
    },
  );
}

// Streamable HTTP transport — the only supported transport for this skill.
// MCP endpoint: POST http://localhost:<port>/mcp
// Inspector:    http://localhost:<port>/mcp/inspector
const PORT = process.env.PORT ? Number(process.env.PORT) : 3000;
server.listen(PORT);

トランスポートには stdio ではなく、ストリーミング可能な HTTP を使用する必要があります。 mcp-use の server.listen(port) は /mcp でストリーミング可能な HTTP トランスポートを設定します。これは、このスキルで生成するすべてのサーバーに適した選択肢です。stdio に置き換えないでください。stdio サーバーは Manufact/mcp-use cloud にデプロイできず(クラウドではトラフィックの転送先となる HTTP エンドポイントが必要です)、オンラインインスペクターでテストできず、ChatGPT のカスタム MCP サーバーや Claude のカスタムコネクターとして追加できず(どちらも HTTPS 経由で接続します)、references/testing.md の curl テストでもアクセスできません。stdio はローカル CLI ツール用の MCP サーバー向けであり、ここで構築するものとは異なります。

各ファイルの完全なテンプレートは references/code-templates.md にあります。

9. サーバーをテストする

まず開発サーバーを起動してください。このステップのすべてのテストは、サーバーが実行中であることを前提としています。

npm run dev

ログにはポート番号(デフォルトは 3000。使用中の場合は 3001 に切り替わります)、MCP URL(http://localhost:<port>/mcp)、インスペクターの URL が表示されます。1 つ目のターミナルでこのまま実行し、2 つ目のターミナルで以下のテストコマンドを実行してください。

次に、2 つのレイヤーでテストします。両方に合格するまでは「完了」としないでください。詳しい手順は references/testing.md を参照してください。

レイヤー 1 — mcp-use client CLI。 まずはこれを試してください。mcp-use パッケージには、ストリーミング可能な HTTP で通信し、セッションと認証の管理を処理する CLI が含まれています。ターミナルから直接 tools list/tools call/interactive のループを実行できます。コードも、curl の計算も不要です。

# Save the dev server under a short name
npx mcp-use client connect dev http://localhost:3000/mcp

# List and describe tools
npx mcp-use client dev tools list
npx mcp-use client dev tools describe <tool_name>

# Call a tool — args are key=value, or pass JSON for complex shapes
npx mcp-use client dev tools call <tool_name> limit=5
npx mcp-use client dev tools call <tool_name> '{"limit": 5, "filter": "active"}'

# REPL mode for fast iteration
npx mcp-use client dev interactive

CI/スクリプトによるテストでは、--json を追加して jq に渡してください。tools list が何も返さない場合は、index.ts の操作フィルターですべてが除外されているか、openapi.dereferenced.json がありません。connect 自体が失敗する場合は、開発サーバーが実行されていないか、別のポートで実行されています。curl に切り替えて(references/testing.md の「Raw protocol debugging」セクションを参照)、エンドポイントが応答するかどうかを確認してください。

レイヤー 2 — インスペクターのチャット(実際の LLM ループ)。 レイヤー 1 ではサーバーが動作することを確認できます。インスペクターでは、LLM がサーバーを使えることを確認します。つまり、モデルが適切なツールを選べるほどツールの説明が明確か、引数を正しく入力するためのヒントが Zod スキーマに十分あるか、レスポンス形式がモデルによる要約を妨げるほど特殊ではないかを確認できます。

http://localhost:<PORT>/mcp/inspector?server=http%3A%2F%2Flocalhost%3A<PORT>%2Fmcp&tab=chat

強制呼び出し(「list_pets を limit 5 で使用してください。」)と、自由形式の探索(「ストアにある最初の 5 匹のペットを表示してください。」)の両方をテストしてください。後者のほうが難しく、説明の品質を確認するのに適しています。

両方のレイヤーでエラー経路もテストしてください。必須引数の不足(Zod による拒否)、誤った認証(上流の 401)、上流の 5xx(BASE_URL に応答しないポートを指定)を試します。どちらのレイヤーも、サーバーがクラッシュするのではなく、明確なエラーを返す必要があります。

どちらかのレイヤーで「Failed to resolve import」や古いツール定義が表示された場合は、rm -rf .mcp-use && npm run dev を実行してください。

10. デプロイする(ユーザーに確認する)

サーバーはローカルで動作しています。次に、AskUserQuestion を使って、mcp-use cloud にデプロイするか、ローカルにとどめるかを確認してください。選択肢は 2 つだけです。他の選択肢を列挙する必要はありません。

  • mcp-use cloud にデプロイ — サーバーを https://<name>.run.mcp-use.com/mcp の URL で公開します。この URL は ChatGPT、Claude、その他の MCP クライアントから利用できます。開発者自身の開発マシン以外でもサーバーを使う場合に最適です。
  • ローカルにとどめる — 開発サーバーの URL を伝えて終了します。内部 API に対するプロトタイプ作成や、公開 URL を確定する前に出力を評価したい場合に最適です。

ユーザーが ローカルにとどめる を選んだ場合は、これで完了です。ステップ 9 のインスペクター URL と /mcp URL を伝え、このステップの残りはスキップしてください。デプロイを開始しないでください。時期尚早なデプロイは認証情報の漏えいや、古い公開エンドポイントの作成につながります。

ユーザーが デプロイ を選んだ場合、blank のスキャフォールドでは、すでに npm run deploy が mcp-use deploy を実行するよう設定されています。ログイン後に実行するコマンドは 2 つです。

npx mcp-use login
npm run deploy

現在、これには GitHub リポジトリが必要です。プロジェクトがまだ GitHub にない場合は、以下を実行してください。

gh repo create <org>/<name> --private --source=. --push

デプロイ後は、https://<name>.run.mcp-use.com/mcp のような URL が発行されます。本番サーバーでローカルと同じ認証を使えるように、Manufact ダッシュボードで同じ環境変数を設定してください(デプロイ CLI がプロジェクトページへのリンクを表示します)。

環境変数をダッシュボードで設定する方法、ログの確認方法、ブランチデプロイの設定方法を含む詳しいデプロイ手順は、references/deploy.md を参照してください。

11. リリース前のチェックリスト

完了とする前に、以下を確認してください。

  • .env.example に必要な環境変数がすべて、簡単なコメント付きで記載されている。
  • openapi.dereferenced.json が .gitignore に含まれている(openapi.yaml から再生成します)。
  • npm run build が成功し、npx tsc --noEmit でエラーがない。
  • インスペクターで、必要なすべてのツールを実際の API に対して少なくとも 1 回実行した。
  • デプロイ済み URL に対して curl https://<name>.run.mcp-use.com/mcp を実行すると、有効な MCP レスポンスが返る。
  • コミットしてプッシュする。

重要な参考資料

該当する手順に進んだら、以下を読んでください。各ファイルは特定のテーマを詳しく解説しています。最初にすべて読み込まないでください。

  • references/mapping-rules.md — オペレーションからツールへのマッピングルール:命名、パラメーターの統合、レスポンスの処理、スキーマの特殊ケース(oneOf/anyOf/allOf、nullable、再帰参照)、大きな仕様のフィルタリング。
  • references/code-templates.md — index.ts、src/client.ts、src/auth.ts、src/operations.ts、src/schema.ts、scripts/load-spec.ts、.env.example、tsconfig.json のコピーしてすぐ使えるひな形。各ファイルには注釈が付いています。
  • references/auth.md — よく使われる4つの認証方式(apiKey、http bearer、http basic、OAuth2 bearer)と、それぞれをヘッダーに変換する方法。OAuthのリフレッシュトークンを使うパターンも含みます。
  • references/testing.md — Inspector の手順、.mcp-use の古いキャッシュによる落とし穴、ツールを強制的に呼び出す方法、ツールのレスポンスで確認する項目、よくある4xx/5xxのデバッグ方法。
  • references/deploy.md — mcp-use deploy、GitHub のセットアップ、Manufact ダッシュボードでの環境変数、ブランチのデプロイ、オブザーバビリティのタブ、デプロイした URL を ChatGPT のカスタム MCP サーバーまたは Claude のカスタムコネクターとして追加する方法。

トリガーワードと別名

ユーザーが次のいずれかに該当する表現を使った場合は、このスキルを使用してください。

  • 「この OpenAPI 仕様/Swagger ドキュメントから MCP サーバーを構築する」
  • 「この API/swagger.json/openapi.yaml を MCP ツールに変換する」
  • 「[API 名] を MCP サーバーとしてラップする」
  • 「[Stripe/GitHub/社内 API] を Claude から呼び出せるようにする」
  • 「これらのエンドポイントを LLM に公開する」
  • 「OpenAPI 仕様があるので、MCP サーバーを生成する」
  • MCP 用のバージョンを求める .yaml/.json ファイルを貼り付ける、または添付する
  • 既存の REST API(キー、ベース URL、ドキュメントへのリンクのいずれかを含む)について説明し、LLM からアクセスできるようにしたいと求める

このスキルを使用しない場合

  • ユーザーが、ほとんどまたはすべてのツールでチャット内にカスタム UI を表示するウィジェット主導型 MCP Appを求めている場合 → 代わりに mcp-apps-builder を使用してください。このスキルでも特定の1つか2つのツールにウィジェットを追加できますが、ウィジェットが主目的なら、もう一方のスキルを出発点にするのが適切です。手順1でユーザーに確認してください。
  • ユーザーがまだ API を持っておらず、ゼロから設計したい場合 → これは API 設計のタスクであり、MCP でラップするタスクではありません。
  • ユーザーが MCP サーバーをクライアントとして利用したい(構築するのではない)場合 → 別のスキルを使用してください。このスキルは対象外です。
  • 仕様の対象が OpenAPI ではなく、GraphQL または gRPC サービスである場合 → このスキルは OpenAPI 専用です。パターンは応用できますが、スキーマコンバーターは使用できません。

コメント