🪐

GraphQL APIをMCP Serverとして使えるApollo MCP Server

に公開

GraphQL APIが好きなみなさんこんにちは。

Apollo Clientや Apollo Serverでお馴染みのApollo GraphQLからGraphQL APIを簡単にMCP Serverとして実行できるツールがリリースされていたので使ってみました。

https://www.apollographql.com/docs/apollo-mcp-server

Apollo MCP Serverとは

Apollo MCP Serverは、既存のGraphQL APIをそのままに、特別な開発や大きな変更を加えることなく、MCP Serverとして動かすことができ、AIとの連携が実現できます。

Apollo MCP Server自体はRustで作成されており、バイナリを実行する際にオプションでGraphQLの設定を渡すだけで起動します。

https://github.com/apollographql/apollo-mcp-server

仕組みについては公式ドキュメントをご参照ください。

https://www.apollographql.com/docs/apollo-mcp-server#how-apollo-mcp-server-works

GraphQL APIをMCP Serverとして実行する

インストール

公式ドキュメントのQuikstartには Apolloが提供する多機能な CLIツールのrover を使った例もありますが、nix cli を使ってバイナリをダウンロードするのが手軽です。

https://www.apollographql.com/docs/apollo-mcp-server/guides

curl -sSL https://mcp.apollo.dev/download/nix/latest | sh

GraphQL Queryを指定して起動

Apollo MCP ServerはGraphQL QueryがそのままMCPのToolsとして使うことができます。

この記事では、SpaceXの宇宙飛行士やロケット情報が公開されているGraphQL APIを例としてMCP Serverにしてみます。そして、企業情報を取得するQueryとロケットの打ち上げ情報を検索するQueryの二つを用意しました。

https://studio.apollographql.com/public/SpaceX-pxxbxen/variant/current/home

企業情報を取得するQuery

query GetCompanyInfo {
  company {
    name
    founder
    founded
    employees
    vehicles
    launch_sites
    test_sites
    valuation
    summary
    headquarters {
      address
      city
      state
    }
    links {
      website
      twitter
      elon_twitter
    }
  }
}

ロケットの打ち上げ情報を検索するQuey

query FindLaunches(
  $apoapsis_km: Float
  $block: Int
  $cap_serial: String
  $capsule_reuse: String
  $core_flight: Int
  $core_reuse: String
  $core_serial: String
  $customer: String
  $eccentricity: Float
  $end: Date
  $epoch: Date
  $fairings_recovered: String
  $fairings_recovery_attempt: String
  $fairings_reuse: String
  $fairings_reused: String
  $fairings_ship: String
  $gridfins: String
  $id: ID
  $inclination_deg: Float
  $land_success: String
  $landing_intent: String
  $landing_type: String
  $landing_vehicle: String
  $launch_date_local: Date
  $launch_date_utc: Date
  $launch_success: String
  $launch_year: String
  $legs: String
  $lifespan_years: Float
  $longitude: Float
  $manufacturer: String
  $mean_motion: Float
  $mission_id: String
  $mission_name: String
  $nationality: String
  $norad_id: Int
  $orbit: String
  $payload_id: String
  $payload_type: String
  $periapsis_km: Float
  $period_min: Float
  $raan: Float
  $reference_system: String
  $regime: String
  $reused: String
  $rocket_id: String
  $rocket_name: String
  $rocket_type: String
  $second_stage_block: String
  $semi_major_axis_km: Float
  $ship: String
  $side_core1_reuse: String
  $side_core2_reuse: String
  $site_id: String
  $site_name_long: String
  $site_name: String
  $start: Date
  $tbd: String
  $tentative_max_precision: String
  $tentative: String
) {
  launches(
    find: {
      apoapsis_km: $apoapsis_km
      block: $block
      cap_serial: $cap_serial
      capsule_reuse: $capsule_reuse
      core_flight: $core_flight
      core_reuse: $core_reuse
      core_serial: $core_serial
      customer: $customer
      eccentricity: $eccentricity
      end: $end
      epoch: $epoch
      fairings_recovered: $fairings_recovered
      fairings_recovery_attempt: $fairings_recovery_attempt
      fairings_reuse: $fairings_reuse
      fairings_reused: $fairings_reused
      fairings_ship: $fairings_ship
      gridfins: $gridfins
      id: $id
      inclination_deg: $inclination_deg
      land_success: $land_success
      landing_intent: $landing_intent
      landing_type: $landing_type
      landing_vehicle: $landing_vehicle
      launch_date_local: $launch_date_local
      launch_date_utc: $launch_date_utc
      launch_success: $launch_success
      launch_year: $launch_year
      legs: $legs
      lifespan_years: $lifespan_years
      longitude: $longitude
      manufacturer: $manufacturer
      mean_motion: $mean_motion
      mission_id: $mission_id
      mission_name: $mission_name
      nationality: $nationality
      norad_id: $norad_id
      orbit: $orbit
      payload_id: $payload_id
      payload_type: $payload_type
      periapsis_km: $periapsis_km
      period_min: $period_min
      raan: $raan
      reference_system: $reference_system
      regime: $regime
      reused: $reused
      rocket_id: $rocket_id
      rocket_name: $rocket_name
      rocket_type: $rocket_type
      second_stage_block: $second_stage_block
      semi_major_axis_km: $semi_major_axis_km
      ship: $ship
      side_core1_reuse: $side_core1_reuse
      side_core2_reuse: $side_core2_reuse
      site_id: $site_id
      site_name_long: $site_name_long
      site_name: $site_name
      start: $start
      tbd: $tbd
      tentative_max_precision: $tentative_max_precision
      tentative: $tentative
    }
  ) {
    id
    mission_name
    launch_year
    launch_success
    details
    rocket {
      rocket_name
    }
  }
}

また、GraphQL Schemaファイルも必要なので、次の画面からRow Fileとしてダウンロードします。

https://studio.apollographql.com/public/SpaceX-pxxbxen/variant/current/schema/sdl?selectedSchema=%23%40!api!%40%23

GraphQL SchemaとToolsとして使うQueryが揃ったら、次のようにオプションを渡して起動します。http-addressやportは好みで変更できます。

./apollo-mcp-server --schema ./space_x_schema.graphql  --endpoint https://spacex-production.up.railway.app/ --http-port 5000 --http-address 127.0.0.1 -o FindLaunches.graphql GetCompanyInfo.graphql

MCP Inspectorでデバッグ

次に、MCP ServerののToolが正しく動いているか検証します。
MCP Toolをデバッグするには、AI経由の呼び出しではなく、手動で実行できるMCP Inspectorが便利です。
次のコマンドで起動できるので、Streamable HTTPとしてApollo MCP Serverに接続できます。

npx @modelcontextprotocol/inspector

MCP InspectorでToolが認識されており、実行を確認できます。

MCP Inspector Screen

MCP Clientから使う

今回はRoo Codeを使いました。Copilot AgentやClineでもstreamable-httpに対応していればそれぞれ設定を追加すれば使えるかと思います。

また、LLMのモデルはgemini-2.5-proを使っています。

プロジェクトMCPの設定例

Roo Code MCP Settings Screen

GetCompanyInfoが使われるような質問を投げかけてみると、GetCompanyInfo Toolsが選択されて、GraphQL API Responseの情報をもとに答えてくれていますね!

また、打ち上げ情報に関する質問を聞くと、これも同じようにToolsを使って答えてくれています。

まとめ

Apollo MCP Serverを使えば既存のGraphQL APIをとても簡単にMCP ServerとしてCoding AgentやMCP Clientから使うことができることがわかりました。

自社サービスやGraphQL APIを提供しているサービスとのAI活用がより進みそうですね。

参考

Discussion