アルアカ - Arcadia Academia

Arcadia Academiaは「エンジニアリングを楽しむ」を合言葉に日本のデジタル競争力を高めることをミッションとするテックコミュニティです。

Google Sheets MCPがCONNECTION_CLOSEDで繋がらない時の直し方

Featured image of the post

「Claude CodeにGoogle Sheets用のMCPサーバーを追加したら、さっきまで使えていたのに/mcpを開くと接続が切れている」「claude mcp listを叩くと急にFailedになった」「エラーメッセージはCONNECTION_CLOSEDとしか出ず、何が悪いのか分からない」。MCPサーバーはクライアント側に流れてくるエラーが抽象化されてしまい、サーバー内部で実際に何が起きているかが見えないことがよくあります。この記事では、Google Sheets向けのMCPサーバーが起動直後に落ちてCONNECTION_CLOSEDになる典型的な原因と、設定を1行直すだけで済む直し方をまとめます。

💡
30秒で要点
- CONNECTION_CLOSEDは結果であって原因ではない。まずサーバーを手動起動して本当のエラーメッセージを見る
- 今回の原因は依存ライブラリのバージョンが新しくなり、内部クラス名が変わったことによる非互換
- 設定の起動コマンドに依存バージョンを固定するオプションを足すだけで直る
- 認証エラー(権限・サービスアカウント設定)とは別物なので、まず切り分けてから直す

目次を開く

症状: /mcpを開くと接続が切れている

Claude Code(あるいは他のMCP対応クライアント)にGoogle Sheets操作用のMCPサーバーを登録しているのに、ある時から接続一覧に出てこなくなったり、CONNECTION_CLOSEDと表示されたりすることがあります。クライアントのログに残るのはこの一言だけで、サーバー側で何の例外が起きているかは分かりません。

まず手動起動して本当のエラーを見る

クライアント経由で判断する前に、登録しているコマンドをそのまま手元のターミナルで直接実行し、標準エラー出力を読みます。uvx経由でパッケージを起動している場合はこうなります。

uvx mcp-google-sheets@latest

このとき次のような例外が出ることがあります。

ModuleNotFoundError: No module named 'mcp.server.fastmcp'

クライアント側の表示がCONNECTION_CLOSEDしか返さないのに対し、手動起動だとPythonの例外がそのまま見えるため、原因の切り分けが一気に進みます。

原因: 依存するSDKのメジャーバージョンが上がり、内部クラス名が変わった

Python製のMCPサーバーの多くは、MCP公式のPython SDK(mcpパッケージ)に依存しています。このSDKが2系にアップデートされた際、サーバー実装によく使われていたFastMCPというクラスがMCPServerという名前に変わりました。サーバー側のパッケージがまだこの変更に追随していないバージョンだと、起動時にmcp.server.fastmcpを探しに行って見つからず、ModuleNotFoundErrorで落ちます。

uvx パッケージ名@latestのように常に最新版を取得する指定をしていると、サーバー側のバージョンは古いままなのに依存SDK側だけが新しくなり、ある日突然このエラーが出るようになります。

直し方: 依存SDKのバージョンを固定する

恒久的にはサーバー側のアップデートを待つのが筋ですが、それまでの応急処置として起動オプションに依存バージョンの上限を指定します。uv系のツールでは--withオプションで追加の依存を指定でき、ここで古いSDK系列に固定します。

Claude Codeの設定の場合、いったん既存の登録を削除してから、固定オプション付きで登録し直します。

claude mcp remove google-sheets -s user
claude mcp add-json -s user google-sheets '{
  "command": "uvx",
  "args": ["--with", "mcp<2", "mcp-google-sheets@latest"],
  "env": {
    "SERVICE_ACCOUNT_PATH": "/path/to/service-account.json"
  }
}'

ポイントはargsに"--with", "mcp<2"を挟んでいる部分です。これによりuvxがパッケージを解決する際、依存のmcpを2系未満(1系)に固定した状態で実行してくれます。envの中身(サービスアカウントの認証情報のパスなど)は元の設定からそのまま引き継いでください。

直った後の確認

設定を変えたら、再度/mcpやクライアントの一覧コマンドで状態を確認します。

claude mcp list

対象のサーバーがConnected(あるいはそれに相当する正常表示)になっていれば直っています。念のため、もう一度手動起動でもエラーが出ないか確認しておくと確実です。

uvx --with "mcp<2" mcp-google-sheets@latest

エラーなく待機状態に入れば成功です(終了する場合はCtrl+Cで止めます)。

認証エラーと混同しないための切り分け表

CONNECTION_CLOSED系のエラーは原因が複数あり得るため、手動起動で出るメッセージごとに切り分けます。

手動起動で出るメッセージ 原因 対処
ModuleNotFoundError: No module named 'mcp.server.fastmcp' 依存SDKの2.x化による非互換 本記事のmcp<2固定
PermissionError / 権限不足を示す例外 サービスアカウントにスプレッドシートの共有権限が無い 対象シートをサービスアカウントのメールアドレスに共有し直す
認証情報ファイルが見つからないという例外 envに指定したパスが間違っている、またはファイルが存在しない パスをlsなどで実際に存在するか確認する
何も出ずに即終了する コマンド自体のパスが通っていない(uvxが無い等) which uvxでコマンドの実体を確認する

一番上の行以外はバージョン非互換とは無関係なので、まずは手動起動でどのメッセージが出るかを見てから、該当する行の対処に進んでください。

将来この固定を外すタイミング

mcp<2固定はあくまで応急処置です。サーバー側のパッケージが依存SDKの2系に対応したバージョンをリリースしたら、--with "mcp<2"の指定を外し、uvx パッケージ名@latestだけの元の設定に戻せます。手元の版が対応済みかどうかは、固定を外した状態で一度uvx パッケージ名@latestを手動起動し、同じModuleNotFoundErrorが再発しないかで確認できます。

まとめ

MCPサーバーの接続エラーは、クライアント側ではCONNECTION_CLOSEDのような抽象的な表示にまとめられてしまい、そこから原因を推測するのは困難です。登録しているコマンドを手元で直接実行し、標準エラー出力に出るPythonの例外をそのまま読むのが最短の切り分け方法です。今回のように依存SDKのメジャーバージョンアップによる非互換が原因であれば、起動オプションに依存バージョンの上限を指定して固定することで、サーバー側の対応を待たずに復旧できます。

よくある質問(FAQ)

他のMCPサーバーでも同じ症状が起きますか?

uvxやPythonのパッケージマネージャ経由で動かしているPython製のMCPサーバー全般で起こり得ます。まずクライアント経由ではなく手動でサーバーのコマンドを直接実行し、標準エラー出力を確認してください。

mcp<2に固定すると、今後ずっとこのままで良いですか?

いいえ、応急処置です。サーバー側のパッケージが依存SDKの2系に対応したら、固定を外して最新版に追従する設定に戻してください。

Claude Code以外のクライアントでも同じ直し方で良いですか?

考え方は同じです。クライアントごとのMCPサーバー設定ファイルで、起動コマンドのargsに依存バージョンを固定するオプションを追加すれば同じく直ります。設定ファイルの場所や書式はクライアントごとに異なるので、各自の設定ドキュメントでargsやcommandに相当する項目を確認してください。

認証系のエラーと見分けがつきません

本文の切り分け表の通り、まず手動起動で出るメッセージを確認してください。ModuleNotFoundErrorであれば依存バージョンの問題、権限やファイルパスに関する例外であれば認証・共有設定の問題です。

プログラミング学習でお悩みですか?

現役エンジニアがあなたの学習をマンツーマンでサポートします。

  • 学習の進め方がわからない
  • ポートフォリオの作り方を知りたい
  • 現場で使える技術を学びたい
まずは30分の無料相談

相談は完全無料・オンラインで気軽に

あなたを爆速で成長させるメンタリングプログラムはこちら

メンタープログラムバナー

学習・開発のお悩みは現役エンジニアに相談

メンタープログラムの詳細を見る

エンジニアの基礎学習ゲーム

プログラミング学習支援

無料相談はこちら