【ITニュース解説】How long does claude.ai wait for your MCP server? I measured it
2026年10月15日に「Dev.to」が公開したITニュース「How long does claude.ai wait for your MCP server? I measured it」について初心者にもわかりやすく解説しています。
ITニュース概要
Claude.aiとMCPサーバーの接続時間を測定した。サーバーが起動に時間がかかる設定だと、Claudeの接続タイムアウト(約10秒)を超え、接続エラーになることが判明。常にサーバーを稼働させる設定で解決。また、遅い正規表現処理を改善し、パフォーマンスを向上させた。
ITニュース解説
この記事では、AIアシスタントのClaudeが外部ツールと連携する際に発生した接続問題と、その原因、そして解決策について詳しく解説している。筆者は、自身が開発したClaude用ツールサーバーが「Couldn't connect to the server.(サーバーに接続できませんでした)」というエラーを出す一方で、サーバー自身の状態を確認するヘルスチェック(/healthz)はすぐに成功するという矛盾した現象に直面した。このサーバーは、Claudeの機能拡張プロトコルであるMCP(Model Connector Protocol)を使って、ユーザーが複数のNotionワークスペースにアクセスできるようにする役割を担っており、MicrosoftのクラウドサービスであるAzure Container Apps上で動作する.NET 10製のアプリケーションである。
この問題の主な原因は、Azure Container Appsの「スケール・トゥ・ゼロ」という機能にあった。スケール・トゥ・ゼロとは、アプリケーションへのリクエストがないアイドル状態の時に、費用を節約するためにサーバーのインスタンス(レプリカ、つまりサーバーの複製)を自動的に0にまで減らす仕組みを指す。この機能自体はコスト削減に非常に有効だが、次にリクエストが来た際には、停止していたサーバーを起動する必要があるため、その分の時間がかかるというデメリットがある。筆者のサーバーの場合、リクエストが来てから実際にアプリケーションが応答できるようになるまで、少なくとも23秒もの時間がかかっていたことがログから判明した。これは、コンテナ(アプリケーションの実行環境)の起動やアプリケーション自体の初期化に時間を要するためである。
一方、Claude側には、外部サーバーとの接続を待つ時間に上限(タイムアウト)が設定されている。筆者が独自に計測した結果、Claudeが新しいコネクタを追加する際には、サーバーからの応答を5秒未満しか待たないことが分かった。具体的なテストでは、4.5秒や4.7秒で接続を諦めて「Couldn't check the server.(サーバーを確認できませんでした)」というエラーを出した。既存のコネクタで接続を試みる場合(ClaudeのUIで「Connect」ボタンを押すなど)はもう少し長く、約10秒がタイムアウトの目安だった。さらに、Claudeが実際に外部ツールに対して処理を依頼する「ツール呼び出し」の場合、公式ドキュメントでは最長240秒(4分)まで待つとされている。つまり、サーバーの起動に23秒かかる状況では、コネクタの追加や接続時の初期チェックにおいて、Claudeのタイムアウトを確実に超えてしまい、接続エラーが発生していたのである。
この接続問題に対する最も直接的な解決策は、Azure Container Appsの設定を変更し、常に最低1つのサーバーインスタンスが稼働するようにすることだった。具体的には、「--min-replicas 1」という設定を適用することで、アイドル状態でもサーバーが停止しなくなり、新しいリクエストが来た際にすぐに応答できるようになる。筆者もこの方法を採用した結果、サーバーの起動待ち時間は解消され、Claudeからの接続エラーは発生しなくなった。しかし、この設定にはコストが伴う。サーバーが常に稼働するため、アイドル状態であってもコンピューティング資源に対する費用が発生するようになる。もしスケール・トゥ・ゼロの利点である費用節約を維持したいのであれば、サーバーの起動時間を極めて短く、特にコネクタ追加時は5秒未満、それ以外でも10秒未満に抑える必要がある。筆者のサーバーは、起動プロセスの大半がコードが実行される前段階で発生しており、その短縮には限界があった。
接続問題の解決後も、別の重要なパフォーマンス上の課題が浮上した。それは、Markdown形式のテキストをNotionで表示できる形式に変換するコードの中に含まれる「正規表現」の処理速度に関する問題だ。特定の入力パターン、例えば「**a **a a」のように閉じタグがない「」が連続する非常に長い行が与えられると、正規表現の処理が著しく遅くなることが判明した。このような問題は「ReDoS(Regular Expression Denial of Service)」と呼ばれ、悪意のある、あるいはたまたまそのような形式の入力によって、サーバーの応答が極端に遅れたり、サーバーが停止したりする可能性がある。筆者のテストでは、20万文字の入力で7秒、100万文字では約3分も処理に時間がかかることが明らかになり、Claudeからのリクエスト上限である2 MiB(約200万文字)に近いデータが送られた場合、理論上13分近くかかる可能性も示唆された。これは、単一の小さなサーバーで動いている場合、他のすべてのリクエスト処理にも影響を及ぼす重大な問題だった。
この正規表現の問題を解決するため、複数の対策が講じられた。まず、個々の正規表現のマッチ処理に対して100ミリ秒のタイムアウトを設定した。さらに、最初のマッチでタイムアウトが発生した場合は、それ以降の同じ変換処理におけるフォーマット(太字やリンクなど)を中止し、プレーンテキストとして扱うようにした。また、一つの変換処理全体に対しても約1秒のタイムアウトを設け、Claudeから送られるMarkdownテキストの最大文字数を10万文字に制限した。これらの変更により、以前は1秒以上かかっていた8万文字の長い行の処理が、わずか0.1秒程度にまで短縮された。正規表現は非常に強力なツールだが、このように悪意のある入力に対して脆弱になる可能性があるため、入力元が制御できない場合は、タイムアウト設定が不可欠であることを筆者は強く推奨している。
開発プロセスにおいても、いくつかの学びがあった。例えば、コードの品質を検査するツール(Analyzer)がDockerコンテナ内では意図せず有効になり、ビルドが失敗するという問題が発生した。これは、プロジェクト全体でコードスタイルを統一する設定ファイル(.editorconfig)がDockerイメージのビルド時にコピーされていなかったためだ。このような問題は、開発時のテストでは見落とされがちだが、継続的インテグレーション・継続的デリバリー(CI/CD)のパイプラインに組み込むことで、より早期に発見できるようになった。筆者のサーバーは、公式のC# MCP SDKを使用せず、必要最小限の機能を手動で実装している。これは、SDKが認証サーバーの機能を提供しないため、結局多くの部分を自作する必要があることと、対応するMCPメソッドが少なかったため、シンプルな構成を保つことを優先した結果である。サーバーはデータベースを持たず、ユーザーの認証情報やトークンは暗号化された形式で安全に管理されるように設計されており、ステートレスな運用が可能となっている。
まだ完全に解明されていない点もいくつか残されている。例えば、クラウドサービスが追加するクライアントのIPアドレス情報(X-Forwarded-Forヘッダ)の正確な挙動や、低スペックなコンテナ環境で正規表現のタイムアウトが意図せず発生する可能性などだ。また、悪意のあるユーザーがモデルを通じて問題のあるテキストを送ろうとする可能性に対する対策も検討されている。現状では、Notion連携の書き込み権限を制限したり、読み取り専用のワークスペースを設定したりするなどの防御策が導入されている。
この一連の経験は、AIとの連携やクラウド環境でのアプリケーション開発において、単に機能を実現するだけでなく、パフォーマンス、セキュリティ、そして運用コストといった多角的な視点からシステムを設計・改善していくことの重要性を示している。特に、外部サービスとの連携では、それぞれのサービスの内部的な挙動やタイムアウト設定を理解し、それに合わせて自作のシステムを最適化する必要がある。