はじめに
本記事は CyberAgent Developers Advent Calendar 2025 14日目の記事です❄️
こんにちは、AI事業本部の極予測TDの大友寛之です。
私が所属する極予測TDはレスポンシブ検索広告を扱うプロダクトであり、広告効果を高めるためにさまざまな機能を開発しています。例えば、広告文の品質を判定する機能などを開発しており、それらの一部はWeb APIとしても開発しています。
昨今AIエージェントの開発が盛んになる中、これらのWeb APIをAIエージェントから容易に呼び出せる状態 (Agent-ready) にすることで、より広告効果の高い広告文を生成できるのではないかと考えました。
本記事では、FastMCPの機能を活用することで、これまでプロダクトで開発してきた複数のWeb APIをModel Context Protocol (MCP) 経由でAIエージェントから利用できるようにした話をご紹介します。
なお、本記事で言及するWeb APIはOpenAPI仕様に準拠していることを前提としておりますので、あらかじめご承知おきください。
対象読者
- 複数のWeb APIを運用しており、それらをAIエージェントから簡単に呼び出せるようにしたい方
TL;DR
- FastMCPを使うことでOpenAPI準拠のAPIサーバーを簡単にMCPサーバーに変換できる
- さらにFastMCPのComposition機能を使うと複数のAPIサーバーのGatewayとなるMCPサーバーを構築できる
背景
極予測TDでは広告文の品質を判定するようなAPI含め複数のAPIを開発しています。そういったAPIがAIエージェントから呼び出せるようになると、広告文の生成と品質判定のプロセスをイテレーティブに繰り返すことで、より品質の高い広告文を生成することが期待できます。

これらのAPIを呼び出すロジックを実装することでAIエージェントから直接APIを呼び出すことも可能ですが、AIエージェントごとに各APIを呼び出すロジックを実装する必要があったり、APIの仕様変更が発生した場合に呼び出すロジックを修正する必要があったりと、開発や運用に手間がかかります。
MCPサーバーを導入する
そこで、私が所属するチームではMCPサーバーを開発することにしました。MCPを用いて機能を提供できるようになると、個別でAPIを呼び出すロジックの実装が不要になり、またAPIの仕様変更時にもMCPサーバーを修正するだけでよいといった恩恵があります。
今回MCPサーバーを導入するにあたり、以下の2つのパターンを検討しました。
- 各APIサーバーに対応するMCPサーバーを開発する
- APIサーバーのGatewayとなるようなMCPサーバーを開発する

まず1つ目の「各APIサーバーに対応するMCPサーバーを開発する」というパターンです。このパターンでは、既存のAPIと同じようなインターフェイスのMCPサーバーを開発するイメージですが、個別にMCPサーバーを開発するコストやMCPホスト側でも個別にMCPサーバーを登録する手間が発生します。

続いて、「APIサーバーのGatewayとなるようなMCPサーバーを開発する」というパターンです。こちらのパターンは、APIサーバーの前段にGatewayの役割を持つMCPサーバー (以下、MCP Gateway) を配置するイメージで、一つのMCPサーバーを構築するだけなので開発・運用にかかるコストが小さいです。一方で、MCP Gateway経由でAPIサーバーにリクエストを送るため、通信のオーバーヘッドが増えます。
私たちのケースでは、MCPサーバーの開発・運用コストを抑えたかった、通信のオーバーヘッドを無視できるユースケースだった、という理由で二つ目のパターンを採用しました。
FastMCPでMCP Gatewayを開発する
今回はFastMCPを用いてMCPサーバーを構築しました。FastMCPはMCPサーバーやクライアントを構築するためのPython向けフレームワークです。
FastMCPの2つの機能を利用することで、MCP Gatewayを構築できます。
1つ目はOpenAPI統合機能です。すでにOpenAPI準拠のサーバーがある場合、OpenAPI SpecificationをもとにMCPサーバーを構築してくれます。
import httpx
from fastmcp import FastMCP
client = httpx.AsyncClient(base_url="https://api.example.com")
# OpenAPI Specを取得する
openapi_spec = httpx.get("https://api.example.com/openapi.json").json()
# OpenAPI統合機能を用いて、既存のAPIからMCPサーバーを作成する
mcp = FastMCP.from_openapi(
openapi_spec=openapi_spec,
client=client,
name="My API Server"
)
この機能を用いることで、手動でMCPツールやリソースを構築する必要がなくなり、簡単にAPIをMCP化することができます。
2つ目はServer Composition機能です。この機能を使うことで、複数のMCPサーバーを一つにまとめることができます。
Server Composition機能の中でも二つの選択肢があり、一つがimport_server、もう一つがmountです。import_serverはサブサーバー (統合したいMCPサーバー) を一度だけメインサーバーに読み込むのに対して、mountはサブサーバーとメインサーバーとの間にライブリンクを作成することで、メインサーバーへのリクエストをサブサーバーに委譲するような流れになっています。
今回の私たちのケースでは「MCPサーバーの開発・運用コストを抑えたい」、「通信のオーバーヘッドは多少無視できる」という理由のため、mountを採用しました。
# 以下は`mount`のサンプルコードです
from fastmcp import FastMCP, Client
# サブのMCPサーバーを定義する
sub_mcp = FastMCP(name="SubMcp")
# メインのMCPサーバーにサブサーバーをマウントする
main_mcp = FastMCP(name="MainMcp")
main_mcp.mount(sub_mcp, prefix="sub")
ここまでにご紹介したOpenAPI統合機能とServer Composition機能を組み合わせることで、MCP Gatewayを構築することができます。
import httpx
from fastmcp import FastMCP
api1_client = httpx.AsyncClient(base_url="https://api1.example.com")
api2_client = httpx.AsyncClient(base_url="https://api2.example.com")
api1_openapi_spec = httpx.get("https://api1.example.com/openapi.json").json()
api2_openapi_spec = httpx.get("https://api2.example.com/openapi.json").json()
mcp1 = FastMCP.from_openapi(
openapi_spec=api1_openapi_spec,
client=api1_client,
name="Mcp1"
)
mcp2 = FastMCP.from_openapi(
openapi_spec=api2_openapi_spec,
client=api2_client,
name="Mcp2"
)
# MCP Gatewayを定義する
gateway = FastMCP("MCPGateway")
# Sever Composition機能を用いて、MCP Gatewayに複数のMCPサーバーをマウントする
gateway.mount(mcp1)
gateway.mount(mcp2)
gateway.run()
Claude Code等のAIエージェントにこちらのMCPサーバーを登録するだけで、複数のWeb APIを利用することが可能になります。
補足: 本記事でご紹介したMCP Gatewayは、Amazon Bedrock AgentCore Gatewayを参考にしています。筆者が所属するプロダクトではAmazon Bedrock AgentCoreを利用しておりませんでしたが、Gatewayのような機能を使いたいと思い、自前で開発したのがこの取り組みの経緯になります。
おわりに
本記事では、FastMCPのOpenAPI統合機能とServer Composition機能を組み合わせることでGatewayの役割を持つMCPサーバーを構築し、複数のWeb APIを簡単にMCP化できる話をご紹介しました。
今回ご紹介したパターンは構築のしやすさや、Web APIとAIエージェントとの連携のしやすさが魅力です。一方でOpenAPI SpecからMCPツール・リソースを自動生成するときの単位がエンドポイントのため、エンドポイントの数が多いとツール・リソースの定義が膨大になり、結果的にLLMのコンテキストを圧迫してしまうのが注意点です。最近はAnthropic社からtool searchといったツールも発表されており、こういったツールを組み合わせるとLLMのコンテキストを圧迫せず既存のWeb APIと連携できるかもしれません。
最後までご覧いただきありがとうございました!
