FastAPIで作成したAPI エンドポイントをモデル コンテキスト プロトコル (MCP) ツールとして公開してみる

FastAPIで作成したAPI エンドポイントをモデル コンテキスト プロトコル (MCP) ツールとして公開してみる

Clock Icon2025.04.30

はじめに

データ事業本部のkobayashiです。FastAPIを使ったアプリ開発を業務で行っているのですが、FastAPIをMCPサーバーとして使えるPythonモジュールがあり試してみたのでまとめます。

https://fastapi.tiangolo.com/ja/

FastAPIとfastapi_mcpとは

FastAPIは、Pythonで高速なAPIを構築するためのWebフレームワークです。Pythonの型ヒント(Type Hints)を活用し、自動的にAPIドキュメントを生成する特徴があります。

モジュール名の通り最大の特徴は速さにあり、内部でStarletteとPydanticを使用することで、NodeJSやGoに匹敵する高いパフォーマンスを実現し、Python製フレームワークの中でもトップクラスの処理速度を実現しています。
開発効率も大きなメリットです。直感的なAPI設計により開発速度が200〜300%向上し、型ヒントによる自動バリデーションでバグを約40%削減できるとされています。コードは簡潔に書け、エディタの自動補完機能との相性も良好です。
また、OpenAPIやJSON Schemaといった業界標準に準拠しており、自動生成される対話型ドキュメントによりAPI仕様の共有が容易になります。これにより、フロントエンドとバックエンドの連携もスムーズに進められます。

https://github.com/fastapi/fastapi

fastapi_mcpはそのFastAPIフレームワークを拡張し、Model Context Protocol (MCP) を実装したライブラリです。MCPは、LLMアプリケーションが外部リソース(ツール、情報、プロンプト)と標準化された方法で連携するためのプロトコルです。
この実装の最大の特徴は、FastAPIとの完全な統合で既存のFastAPI依存関係システムを活用した認証機能が組み込まれており、追加設定をほとんど必要とせず、FastAPIアプリを指定するだけで動作します。単なるOpenAPI変換ツールではなく、FastAPIのネイティブ機能として設計されています。
リクエストモデルとレスポンスモデルのスキーマを保持し、Swaggerと同様にすべてのエンドポイントのドキュメントを自動生成します。これにより、開発者はLLMアプリケーションのAPIを簡単に理解し、テストできます。
デプロイも柔軟で、MCPサーバーを同じアプリにマウントすることも、個別に展開することも可能です。また、FastAPIのASGIインターフェースを直接使用することで、効率的な通信を実現し、高いパフォーマンスを維持しています。

https://github.com/tadata-org/fastapi_mcp/tree/main

では早速使ってみたいと思います。

FastAPIとfastapi_mcpを使ってみる

あらかじめ普段使うようなエンドポイントをすでに実装してあるアプリケーションコード「full-stack-fastapi-template」がFastAPIの公式に用意されているのでこれにfastapi_mcpモジュールを追加してMCPサーバを組み込みたいと思います。

https://github.com/fastapi/full-stack-fastapi-template/tree/master

余談ですが、こちらのリポのコードはFastAPIを使ったウェブアプリでバックエンドからフロントエンドまでをモノリポで実装しているもので個人的にもFastAPIを使ったアプリを作る際には重宝しています。

エンドポイントは以下のようなものがあらかじめ設定されています。

スクリーンショット 2025-04-27 7.49.05

今回使うのはbackend側だけになり、fastapi_mcpを組み込むためにfastapi-mcpをpyproject.tomlのdependenciesに追加します。

[project]
name = "app"
version = "0.1.0"
description = ""
requires-python = ">=3.10,<4.0"
dependencies = [
    "fastapi[standard]<1.0.0,>=0.114.2",
    "python-multipart<1.0.0,>=0.0.7",
    "email-validator<3.0.0.0,>=2.1.0.post1",
    "passlib[bcrypt]<2.0.0,>=1.7.4",
    "tenacity<9.0.0,>=8.2.3",
    "pydantic>2.0",
    "emails<1.0,>=0.6",
    "jinja2<4.0.0,>=3.1.4",
    "alembic<2.0.0,>=1.12.1",
    "httpx<1.0.0,>=0.25.1",
    "psycopg[binary]<4.0.0,>=3.1.13",
    "sqlmodel<1.0.0,>=0.0.21",
    # Pin bcrypt until passlib supports the latest
    "bcrypt==4.0.1",
    "pydantic-settings<3.0.0,>=2.2.1",
    "sentry-sdk[fastapi]<2.0.0,>=1.40.6",
    "pyjwt<3.0.0,>=2.8.0",
    "fastapi-mcp",  # 追加
]

この状態でuvを使って必要なパッケージをインストールします。

$ uv sync

それでは必要なパッケージは組み込めたので次にbackend/app/main.pyファイルにfastapi_mcpを組み込んでみます。

backend/app/main.py
import sentry_sdk
from fastapi import FastAPI
from fastapi_mcp import FastApiMCP # 追加
from fastapi.routing import APIRoute
from starlette.middleware.cors import CORSMiddleware

from app.api.main import api_router
from app.core.config import settings

def custom_generate_unique_id(route: APIRoute) -> str:
    return f"{route.tags[0]}-{route.name}"

if settings.SENTRY_DSN and settings.ENVIRONMENT != "local":
    sentry_sdk.init(dsn=str(settings.SENTRY_DSN), enable_tracing=True)

app = FastAPI(
    title=settings.PROJECT_NAME,
    openapi_url=f"{settings.API_V1_STR}/openapi.json",
    generate_unique_id_function=custom_generate_unique_id,
)

# Set all CORS enabled origins
if settings.all_cors_origins:
    app.add_middleware(
        CORSMiddleware,
        allow_origins=settings.all_cors_origins,
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )

app.include_router(api_router, prefix=settings.API_V1_STR)

mcp = FastApiMCP(app) # 追加
mcp.mount() # 追加

とても簡単で以下の3行を追加するだけで既存のFastAPIを使ったAPIサーバーにMCPサーバーを組み込むことができます。

from fastapi_mcp import FastApiMCP
...
mcp = FastApiMCP(app)
mcp.mount()

修正したmain.pyを実行したところで実際にMCPホストからこのAPIを利用してみます。

Cursorから実行してみる

full-stack-fastapi-templateは8000のローカルポートを使用しているのでこの情報を下にCursor SettingsMCP設定にfastapi_mcpの設定を追加します。

{  
  "mcpServers": {
    "fastapi-mcp": {
      "command": "npx",
      "args": ["mcp-remote", "http://127.0.0.1:8000/mcp"]
    }
 }
}

これでCursorからfastapi_mcpを使う準備は整ったのでCursorのchatから使用してみます。

コマンド(エンドポイント)の確認

はじめに利用できるエンドポイント一覧を表示するよう指示を出してみます。

fastapi-mcpで実行できるコマンドを教えて

するとfastapi_mcpを通じてエンドポイント一覧を表示してくれます。

スクリーンショット 2025-04-28 3.58.01
次にヘルスチェックのエンドポイントにリクエストを送ってみます。

ヘルスチェックを実行してみて

スクリーンショット 2025-04-27 8.03.11

リクエストを送る際は一度実行してよいのかの確認が入るのでCmd + Enterを押下すると実際にリクエストを送ります。

スクリーンショット 2025-04-27 8.03.31

ヘルスチェックリクエストが通りその結果も表示してくれています。

ログイン処理

次にユーザー一覧を取得してみますがログインしてアクセストークンを取得する必要がありますので先にログイン処理を行います。

admin@example.com
abcd1234
でログインして

スクリーンショット 2025-04-28 4.16.48

ログインを試みますが、「full-stack-fastapi-template」で作成したエンドポイントではうまくログインできないようでした。
スクリーンショット 2025-04-28 4.35.30
色々試しましたがうまくログインできなかったので一旦curlでログイン処理を行っておきます。

curlで実行してログインしてトークンを取得して
curl -X 'POST' \
  'http://0.0.0.0:8000/api/v1/login/access-token' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=password&username=admin%40example.com&password=abcd1234&scope=&client_id=string&client_secret=string'

スクリーンショット 2025-04-28 4.24.19

ログイン処理が終わったのでユーザー情報を取得してみます。

現在のユーザー情報を取得して

スクリーンショット 2025-04-28 4.26.24

次にユーザー一覧を取得します。

ユーザー一覧を取得して

スクリーンショット 2025-04-28 4.29.14

ユーザー一覧を取得できました。

アイテムのCRUD操作を行う

アイテムのCRUD操作を行ってみます。

まずはアイテムを作成します。

サンプルアイテムを3つ適当に登録して

スクリーンショット 2025-04-28 4.40.07

次にアイテムを確認してみます。

アイテム一覧を取得して

スクリーンショット 2025-04-28 4.41.39

アイテムの更新を行ってみます。

サンプルアイテム1をサンプルアイテム01に変更して説明はテスト用アイテム更新済みにして

スクリーンショット 2025-04-28 4.43.51

最後にアイテムの削除を行ってみます。

サンプルアイテム2を削除してからアイテム一覧を取得して削除できてことを確認したい

スクリーンショット 2025-04-28 4.45.14

まとめ

FastAPIで作成したAPIエンドポイントをMCPサーバーとして利用できる「fastapi_mcp」を使ってみました。このライブラリは非常に簡単にFastAPIアプリケーションに組み込むことができ、MCPホストから自然言語で操作を行える点がとても興味深いです。この直感的な操作性は実に魅力的で、現在開発中のアプリケーションにも積極的に組み込んでいきたいと感じる優れた使い勝手でした。

最後まで読んで頂いてありがとうございました。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.