GraphQL MCPサーバーでClaudeにAPIを叩かせる — mcp-graphqlの使い方
mcp-graphqlを使ってGraphQL APIをMCPサーバー化し、Claude CodeにスキーマIntrospectionとクエリ実行を任せる手順を、環境変数の設計とMutation許可の判断まで解説します。
GraphQL APIはRESTと違い、1つのエンドポイントの背後にスキーマという「使い方の説明書」を持っています。モデルがまずスキーマを調べてからクエリを組み立てるという2段階の動きと、噛み合いやすい構造です。この記事では代表的なOSS実装mcp-graphqlを使って、GraphQL APIをMCPサーバー化しClaude Codeから叩けるようにする手順を扱います。
MCPプロトコル自体の仕組みはMCPとは、claude mcp addの構文やスコープの詳細はClaude Code MCP設定ガイドが対応します。スキーマから型を生成する開発側の設定はClaude CodeでGraphQL Codegenを使うにあります。
mcp-graphqlが提供するツールとリソース
mcp-graphqlとは、GraphQL APIへのスキーマIntrospectionとクエリ実行をツール化するModel Context Protocolサーバーです。個人の開発者が公開しているOSS実装で、npmパッケージmcp-graphqlとして配布されています。npmの最新版は2.0.4(2025年5月27日公開)です。設定方式がコマンドライン引数から環境変数に変わった1.0.0は、2025年4月8日に公開されています。
提供されるツールは2つだけです。
| ツール | できること |
|---|---|
introspect-schema | できることGraphQLのIntrospectionクエリでスキーマを取得する(ローカルのスキーマファイルやSCHEMAで指定したURLがあればそちらを優先) |
query-graphql | できること実際にクエリを実行する。既定ではMutationは無効 |
スキーマはgraphql-schemaという名前のMCPリソースとしても公開されます。READMEには、introspect-schemaは「スキーマをリソースとして使えないときに最初に呼ぶもの」と書かれています。
Claude Codeでは、MCPリソースを@server:protocol://resource/pathの形式でプロンプトから参照できます。プロンプトで@を入力すると、接続中のサーバーのリソースがファイルと並んで候補に出ます。graphql-schemaの具体的なURIはREADMEに載っていないため、候補に出るかどうかを見て、出なければintrospect-schemaを呼ばせる流れが手堅くなります。
環境変数でエンドポイントと権限を決める
現行版ではすべて環境変数で構成します。
| 環境変数 | 役割 | 既定値 |
|---|---|---|
ENDPOINT | 役割接続先のGraphQLエンドポイントURL | 既定値http://localhost:4000/graphql |
HEADERS | 役割リクエストヘッダーをJSON文字列で指定(認証トークン等) | 既定値{} |
ALLOW_MUTATIONS | 役割Mutation操作を許可するか | 既定値false |
SCHEMA | 役割ローカルのスキーマファイルパスまたはURL(指定するとIntrospectionを省略) | 既定値未指定 |
NAME | 役割MCPサーバーの表示名 | 既定値mcp-graphql |
ALLOW_MUTATIONSが既定でfalseになっている点が、このサーバーの設計思想を表しています。READMEはその理由を「LLMがデータベースやサービスのデータを書き換えるのを防ぐため」と説明しています。読み取り専用から始めて、必要になったら明示的に開ける構成です。
導入手順
Claude Codeにmcp-graphqlを繋ぐ流れ
- 1
claude mcp addで登録する
ENDPOINTと、認証が要るAPIならHEADERSを--envで渡します。ローカルの開発サーバーならENDPOINTだけで足ります。 - 2
スキーマを取らせる
「利用可能なGraphQLのクエリとタイプを教えて」のように聞くと、
introspect-schemaが呼ばれてスキーマが返ります。 - 3
クエリを実行させる
以降はそのスキーマをもとに、Claudeが
query-graphqlでクエリ文字列を組み立てて実行します。
Claude Codeへの追加はclaude mcp addで完結します。認証付きのAPIに繋ぐ場合は次のとおりです。
claude mcp add --env ENDPOINT=https://api.example.com/graphql \
--env HEADERS='{"Authorization":"Bearer YOUR_TOKEN"}' \
--transport stdio graphql -- npx mcp-graphqlローカル向けは次の1行です。
claude mcp add --env ENDPOINT=http://localhost:3000/graphql --transport stdio graphql -- npx mcp-graphqlSmitheryから導入する場合
サードパーティのMCPサーバー配布サービスSmitheryにも登録されています。READMEが案内しているのは、Claude Desktop向けに設定を書き込むコマンドです。
npx -y @smithery/cli install mcp-graphql --client claudeClaude Codeに入れる場合は、上のclaude mcp addで直接登録します。チームで設定を.mcp.jsonにコミットして共有したいときも、この方式のほうが構成をバージョン管理に残しやすくなります。
トークンを.mcp.jsonに直書きしない
チームで共有する.mcp.jsonに、トークンをそのまま書くわけにはいきません。Claude Codeの.mcp.jsonは${VAR}形式の環境変数展開に対応していて、展開できる場所はcommand・args・env・url・headersです。HEADERSはenvの中の値なので、${GRAPHQL_TOKEN}のように参照だけを書けます。
Claude Code v2.1.289で--scope project付きで実行すると、次の出力と.mcp.jsonが得られます。
claude mcp add --env ENDPOINT=https://api.example.com/graphql \
--env 'HEADERS={"Authorization":"Bearer ${GRAPHQL_TOKEN}"}' \
--transport stdio --scope project graphql -- npx mcp-graphql
# Added stdio MCP server graphql with command: npx mcp-graphql to project config生成される.mcp.jsonは次のとおりです。
{
"mcpServers": {
"graphql": {
"type": "stdio",
"command": "npx",
"args": ["mcp-graphql"],
"env": {
"ENDPOINT": "https://api.example.com/graphql",
"HEADERS": "{\"Authorization\":\"Bearer ${GRAPHQL_TOKEN}\"}"
}
}
}
}JSON文字列の中のダブルクォートは\"にエスケープされ、${GRAPHQL_TOKEN}は展開されないままファイルに残ります。展開はClaude Codeが設定を読む側で行われます。トークン本体は各自のシェルの環境変数に置きます。
注意点が2つあります。1つ目は、環境変数が未設定で:-defaultもないときです。設定自体は読み込まれ、${GRAPHQL_TOKEN}という文字列がそのまま渡されます。警告はclaude mcp listと/mcpに出ます。APIから認証エラーが返ったら、先にこの警告を見ます。
2つ目は、プロジェクトスコープのサーバーは初回に承認が求められる点です。.mcp.jsonをチームに配ったあと、各メンバーは対話セッションで承認を済ませる必要があります。
複数のGraphQL APIを同時に繋ぐ
社内に複数のGraphQL APIがある場合、claude mcp addを繋ぎたいAPIの数だけ実行し、それぞれ別の名前を付けて登録します。区別は登録名(users-graphqlなど)で付き、NAME環境変数はサーバー自身が名乗る名前です。
claude mcp add --env ENDPOINT=https://users-api.example.com/graphql --env NAME=users-graphql \
--transport stdio users-graphql -- npx mcp-graphql
claude mcp add --env ENDPOINT=https://billing-api.example.com/graphql --env NAME=billing-graphql \
--transport stdio billing-graphql -- npx mcp-graphqlサーバーごとにプロセスが独立するため、一方のエンドポイントでALLOW_MUTATIONS=trueにしても、もう一方には影響しません。APIごとに書き込み権限を個別に設計できる点は、単一のMCPサーバーで複数エンドポイントを切り替える設計より、書き込みの事故をAPI単位に閉じ込められる構成です。
JSONで直接書きたいときはclaude mcp add-jsonも使えます。add-jsonに{"command":"npx","args":["mcp-graphql"],"env":{...}}を渡すと、渡した内容のまま.mcp.jsonに保存されます。claude mcp addが補う"type": "stdio"は入りません。
Mutationを許可するかどうかの判断
ALLOW_MUTATIONS=trueを付けない限り、Claudeは読み取り専用のクエリしか実行できません。許可する前に、次の3点を見ます。
Mutationを開ける前の3つの問い
接続先はどの環境か
検証環境限定でMutationを開け、本番は読み取り専用に留めるという分離が現実的です。
API側の認可はどこまで効くか
HEADERSで渡すトークンの権限スコープが、リゾルバレベルで書き込み範囲を制限しているかを見ます。READMEは、このサーバーを「Introspectionも、Mutationを含む何でもできる」汎用実装と位置付けています。削除系のMutationはあるか
スキーマに削除系が含まれるなら、
ALLOW_MUTATIONS=trueは削除操作も同時に許可します。環境変数は真偽値のこの1つだけで、Mutationを名前で絞る設定はREADMEの一覧にありません。
もう一段細かく制御したい場合は、Claude Code側の許可ルールでmcp__graphql__query-graphqlをaskにします。ルール名はmcp__<サーバー名>__<ツール名>の形で、サーバーをgraphqlの名前で登録していれば次のように書けます。
{
"permissions": {
"ask": ["mcp__graphql__query-graphql"]
}
}ただし、この方法はクエリとMutationを区別しません。許可ルールの仕様では、mcp__ルールに括弧で引数条件を付けても、設定ファイルの読み込み時に読み飛ばされます。askにすると読み取りクエリも毎回確認になるため、読み取り用と書き込み用でサーバーを2つ登録して、書き込み側だけをaskにする分け方が現実的です。許可ルール全般の書き方はMCPセキュリティガイドにあります。
RESTのMCP連携との違い
業務SaaSをMCP経由で自作接続する場合、多くはREST APIをエンドポイントごとにツール化します。GraphQLはこれと発想が異なります。
RESTのMCP化とGraphQLのMCP化
REST APIのMCP化
エンドポイントごとに個別のツールを用意します。新しいエンドポイントが増えたらツール定義を足す必要があり、権限はエンドポイント単位で絞りやすい構成です。
GraphQLのMCP化
introspect-schemaとquery-graphqlの2つで完結します。スキーマが変われば取得結果が変わるので、ツール定義の書き直しは要りません。権限の粒度は、クエリとMutationの二択が基本です。
REST寄りの自作手順は業務SaaS MCP連携ガイドで扱っています。スキーマの変化が速い社内GraphQL APIや、そもそもREST層を持たないAPIでは、mcp-graphqlのような汎用実装のほうが保守の手間を抑えやすくなります。
独自のMCPサーバーを作る選択肢
mcp-graphqlのREADMEには「Customize for your own server」という節があります。ここに書かれているのは、この実装はIntrospectionも各種操作も丸ごと許可する非常に汎用的なものだ、という点です。もっと限定した実装が要るなら、クライアントに入力させるクエリのフィールドや変数を絞った専用のMCPサーバーを自作し、mcp-graphqlはその参考にするよう勧めています。
汎用実装をそのまま使うか自作するかの判断は、公開するAPIの性質に依存します。社内ツール向けで利用者を信頼できるならmcp-graphqlで十分です。外部公開のAPIや機密性の高いスキーマを扱うなら、ツールの入力スキーマ自体を絞り込んだ専用実装が選択肢になります。
たとえば、query-graphqlのような汎用クエリ実行ツールを置き換え、あらかじめ用意した固定のクエリ文字列に対して変数だけを受け取るツールを複数並べる設計です。この方式なら、モデルが任意のフィールドを組み合わせてクエリを組み立てる自由度がなくなります。
よくあるつまずき
登録時に「Invalid environment variable format」と出る
claude mcp add --envはキーと値のペアを複数受け取るため、サーバー名を--envの直後に置くと、名前も環境変数として読まれます。次のように、サーバー名の直前に--envを置いた場合です。
claude mcp add --env ENDPOINT=http://localhost:3000/graphql graphql -- npx mcp-graphql
# Invalid environment variable format: graphql, environment variables should be added as: -e KEY1=value1 -e KEY2=value2Claude Code v2.1.289では、この2行目のメッセージが出ます。公式ドキュメントにも同じ注意があり、--envとサーバー名のあいだに--transport stdioのような別のオプションを挟めば避けられます。この記事の登録コマンドが--transport stdioをサーバー名の前に置いているのは、そのためです。
Introspectionが無効化されているAPIに繋げない
本番運用のGraphQL APIでは、セキュリティ上の理由でIntrospectionを無効にしている例があります。その場合はintrospect-schemaでスキーマを取れません。SCHEMA環境変数でスキーマファイルまたはスキーマを公開しているURLを別途指定します。
認証ヘッダーのJSON文字列がシェルでエスケープされる
HEADERSはJSON文字列として渡す仕様のため、シェルの引用符処理でクォートが崩れやすい箇所です。HEADERS='...'のように値をシングルクォートで囲めば、JSONの"はそのまま渡せます。.mcp.jsonにサーバー定義を直接書く方式であれば、この問題を避けられます。
Mutationを許可したのにエラーになる
ALLOW_MUTATIONS=trueにしてもMutationが失敗するときは、API側の認可が拒否している可能性を疑います。HEADERSで渡しているトークンにMutation実行の権限があるかを、GraphQL API側のドキュメントで調べます。
スキーマが大きすぎて結果が会話に入らない
Claude Codeは、MCPツールの出力が10,000トークンを超えると警告を出し、既定では25,000トークンを上限にします。テキストの結果が上限を超えると会話には入らず、ファイルに保存されて、そのパスだけが会話に残ります。
大きなスキーマをintrospect-schemaで取ると、この上限に当たる可能性があります。上限はMAX_MCP_OUTPUT_TOKENSで引き上げられます。
まとめ
繋ぐAPIの数と、書き込みを許すかどうかで、サーバーを何個に分けて登録するかが決まります。読み取りだけのAPIはまとめて1つ、書き込みを開けるAPIは単独で登録しておくと、権限の線引きが後から崩れにくくなります。