リモートMCPサーバー構築で学んだこと

5 min read

リモートMCPサーバー構築で学んだこと

私たちは数ヶ月をかけて、うまく機能するローカルMCPインテグレーションを構築しました — セットアップさえ乗り越えられれば。Node.js、npm、設定ファイル、環境変数。プロトコルにリモートサーバーのサポートが追加されたとき、すべてを単一のURLの背後に再構築しました。そこから得られた知見は、これまで構築したどんなものよりもLLMツール設計について多くのことを教えてくれました。

Ahmed BashirLuka Košeninaが2025年10月のDevRev LinkedIn Liveでこの現実について語りました。強力なリモートMCP体験は最初から自動的に得られるものではありません — 意図的なツール設計、反復、そしてクエリの形が曖昧な場合には追加のアノテーションやよりスコープの狭いツールが必要です。

この記事は、何がうまくいき、何が壊れ、なぜその違いが重要なのかについてです。

ローカルからリモートへ

私たちのローカルMCPサーバーはnpmパッケージとしてリリースされていました。開発者がインストールし、認証情報を設定し、Claude DesktopやCursorに接続します。これはうまく機能しました。なぜなら、私たちは正確に設計できたからです。各ツールはDevRevのAPIの狭い範囲にマッピングされていました。課題をリストするツール。記事を検索するツール。スプリントクエリ用のツール。それぞれが小さく、焦点が絞られ、LLMが推論しやすいものでした。

リモートMCPは契約を変えます。インストールのステップはありません。クライアントにURLを渡し、OAuth経由で認証すれば、接続完了です。摩擦はほぼゼロまで低下します。

しかし、ツールを再設計する必要がありました。ローカルツールは特定のユーザーの設定とスコープを前提にできました。リモートツールは、すべての組織のすべてのユーザーに、あらゆるクエリ形状で対応する必要があります。汎用性への圧力が、物事が壊れ始めるポイントでした。

mcp-04-local-vs-remote.png

うまくいくケース

シンプルで意図が明確なクエリは、リモートMCPで美しく機能します。「今日取り組むべき課題は?」は、認証されたユーザーにスコープされたフィルタ付き検索に、優先度と期限でソートされた状態でクリーンにルーティングされます。LLMは正しいツールを選び、パラメータを正確に埋め、有用な結果を返します。

スプリントフィルタ付きクエリも良好に機能します。「現在のスプリントのすべてを表示して」や「スプリント47で期限超過のものは?」は、有効なリクエストを構築するのに十分な構造をLLMに与えます。ツールスキーマにはスプリントパラメータがあり、LLMがそれを埋め、レスポンスが高速に返ってきます。

期限超過タスクの検出もうまく機能するケースです。「期限超過」の概念はシンプルな日付比較にマッピングされ、LLMは時間的推論を十分にこなして正しいフィルタを構築します。これらのクエリには共通のパターンがあります。明確なコンテキストから2〜3のパラメータが埋められる、単一のツール呼び出しにマッピングされることです。

796482513f65c2d408cf516de1220c1d1679b90e-1200x760.png

壊れるケース

同じクエリをローカルとリモートの両方のMCPに対して実行しました。「過去1日に更新され、MCPスプリント9に関連するすべての課題の要約をください。」ローカルでは正しい結果が返りました。リモートでは失敗しました — エラーではなく、間違った回答でした。LLMはクエリに一致しないデータを自信を持って返しました。

根本原因はツールスキーマの複雑さでした。リモートサーバーのハイブリッド検索ツールは約20のオブジェクトタイプにまたがります。課題、チケット、記事、カンバセーション、アカウント、コンタクト、パーツ、rev org — それぞれ独自のフィルタ可能フィールド、enum、リレーションシップを持ちます。単一ツールのスキーマが数百行に膨れ上がりました。

LLMがそのスキーマを受け取ると、どのパラメータを埋めるべきか推論する前に、構造全体を解析する必要があります。20のオブジェクトタイプとそれぞれのフィールドが掛け合わされると、モデルは1つのクエリを構築するためだけに、作業コンテキスト内でタクソノミー全体を保持しなければなりません。混乱が生じます。間違ったenum値を埋める。必須フィルタを省略する。正しそうに聞こえるが存在しないフィールド名をハルシネーションする。

そのライブセッションは同じアイデアを中心にタイトルが付けられていました。バリデーションなしに「初日から何かがそのまま動く」ことはない。複雑な集計クエリ — 「前四半期にコンポーネント別にグループ化されたP0バグは何件あったか」— は、LLMが複数のフィルタを組み合わせ、正しいオブジェクトタイプを選択し、データモデルのグルーピングセマンティクスを理解することを要求します。メガツールスキーマは、それらのステップの各々をモデルが静かに失敗する場所にします。

ツール設計がすべて

核心的な教訓は率直です。ツール設計は、MCP実装の他のどの部分よりも重要です。認証よりも。トランスポートよりも。選択するサーバーフレームワークよりも。

私たちは、ツールは入力が少なくdescriptionに多くの情報を持つ方がパフォーマンスが良いことを発見しました。3つの必須パラメータと、何をするか、いつ使うか、各パラメータの意味についてのリッチな自然言語descriptionを持つツールは、15のオプションパラメータと簡潔なdescriptionを持つツールを上回ります。LLMはツールを呼び出すかどうかを決定するためにdescriptionを読みます。パラメータの埋め方を決定するためにパラメータのdescriptionを読みます。どちらかが曖昧であれば、精度は低下します。

オブジェクトタイプごとの焦点を絞ったツールは、1つのメガツールを一貫して上回ります。search_issuesツール(priority、assignee、sprint、date rangeを受け付ける)は、hybrid_searchツール(オブジェクトタイプのdiscriminatorとすべてのタイプのすべてのフィールドのunionを受け付ける)よりも、モデルにとって使いやすいものです。LLMにかかる認知的負荷は、同じスキーマを読む人間にかかる認知的負荷を映し出します。人間がフォームを正しく埋めるのに苦労するなら、LLMも同様です。

パラメータのdescriptionはパラメータ名よりも重みが大きいことも学びました。qという名前のパラメータに「タイトル、説明、コメント本文に対してマッチするフルテキスト検索クエリ」というdescriptionがある場合は、search_queryという名前でdescriptionがまったくないパラメータよりも、はるかに良くモデルを導きます。

コンテキストウィンドウの飽和

スケールするにつれて、ほとんどのMCP実装が直面するバジェットの問題があります。LLMに公開するすべてのツールはコンテキストウィンドウのスペースを消費します。クライアントは各カンバセーションの開始時に、利用可能なすべてのツールの完全なスキーマを送信します。複雑なスキーマを持つ30のツールを公開すると、ユーザーが質問する前にコンテキストウィンドウの30〜40%を消費する可能性があります。

問題はドメインオブジェクトで複合化します。DevRevはすべてのオブジェクトタイプでカスタムフィールドをサポートしており、一部の顧客はこれを積極的に活用しています。「contact」オブジェクトだけで200以上のカスタムフィールドを持つ顧客がいました。contactに触れるすべてのツール — 作成、更新、検索、一覧 — が、入力と出力の定義で200以上のすべてのフィールドの完全なスキーマを持っていました。ツールスキーマは爆発的に膨張し、LLMの精度は急落しました。コンテキストウィンドウの大部分が、特定のクエリでは決して使われないフィールド定義で占められていたためです。

これにより、実際のカンバセーション、取得されたデータ、そして重要なことにモデルの推論のための余地が少なくなります。ツール数とスキーマの複雑さが増すにつれて、以前はうまく機能していたクエリでもレスポンスの品質が低下することを観察しました。モデルが失敗していたのはツールが間違っていたからではありません。考えるための余地がなくなっていたからです。

これに対処するため、ツールセット全体を再考する必要がありました。すべてのフィールドをすべてのツールスキーマに焼き込む代わりに、オブジェクト管理のための汎用ツールセット — 作成、読み取り、更新、削除、一覧 — に移行しています。ここではオブジェクトスキーマはオンデマンドで取得されます。LLMはまず必要なオブジェクトにどのフィールドが存在するかを発見し、次に関連するフィールドのみをコンテキストに含めてクエリを構築します。これにより、ツールごとのスキーマが小さく保たれ、複雑さがモデルがうまく処理する2ステップのインタラクションパターンに押し込まれます。

品質が低下し始める前の実用的な上限は、よく設計されたツール10〜15個前後でした。それを超える場合は戦略的である必要があります。関連する操作をグループ化し、オプションパラメータを積極的に削減し、ツールが本当にMCPサーフェスにある必要があるのか、別のインターフェースの背後に属するのかを検討してください。

mcp-04-tool-design-context-window.png

snap-inによるカスタムMCPツール

私たちがリリースしたより興味深いパターンの1つは、チームが私たちのコードに触れることなく、組織のリモートMCPサーバーを拡張できるようにすることです。DevRevのsnap-inフレームワークを使えば、開発者はTypeScriptで関数を書き、MCPツールとしてマークし、組織のサーバーにデプロイできます。

関数は私たちのインフラストラクチャで実行されます。ツールスキーマは自動的に組織のMCPサーバーにマージされます。ユーザーが組織のリモートMCP URLに接続すると、DevRevの組み込みツールとチームがデプロイしたカスタムツールの両方が表示されます。

これが重要なのは、すべてのチームに汎用ツールでは予測できないドメイン固有のクエリがあるためです。セキュリティチームは脆弱性とオープンチケットを照合するツールが欲しいかもしれません。サポートチームはチケットステータスと顧客のセンチメントを一緒に引き出すツールが欲しいかもしれません。これらのツールは狭く、焦点が絞られ、特定的です — まさにLLMで最もうまく機能する設計パターンです。

snap-inアプローチは、偶発的に良いツール設計を強制します。単一の目的のために単一の関数を書く開発者は、明確な入力と明確なdescriptionを持つツールを作成する傾向があります。デプロイの単位が単一の関数である場合、メガツールを構築する誘惑は低くなります。

6c5249b6585d9a1aeb299294f8d920459272944d-800x600.png

正直なフレーミング

MCPは常に情報を得るための最速かつ最も正確な方法ではありません。多くのクエリでは、よく構築されたダッシュボードや直接のAPIコールが、速度と信頼性の両方でLLMを介したツール呼び出しを上回ります。MCPの価値は柔軟性にあります — 新しいビューを構築したり新しいクエリを書いたりすることなく、自然言語でアドホックな質問ができる能力です。

しかし、その柔軟性には代償があります。MCPを通じて一貫して優れた結果を得るためには、多くの実験と多くの検証が必要です — 修正が「よりスマートなモデル」ではなく「新しい、またはより良くdescriptionされたツール」であるケースを含みます。私たちはすべてのツールを代表的なクエリのスイートに対してテストしています。ツールがデータを返すかどうかだけでなく、同じ意図の異なる表現でLLMがツールを正しく呼び出すかどうかを測定しています。パラメータの埋め精度をファーストクラスのメトリクスとして追跡しています。

MCPから最大の価値を引き出すチームは、ツール設計をプロダクトの規律として扱い、後付けにしないチームです。APIを初めて見るジュニア開発者に向けてドキュメントを書くように、descriptionを書いてください。敵対的な表現でテストしてください。可用性だけでなく精度を測定してください。そして、冗長に感じても、複雑なツールを3つのシンプルなツールに分割する意志を持ってください。

リモートMCPはセットアップの障壁をゼロにします。これは本当に価値があります。しかし、難しい問題を「どうやってインストールするか」から「LLMが確実に使えるツールをどう設計するか」にシフトさせます。私たちはまだ学んでおり、ツーリングは成熟し続けています。今MCPサーバーを構築しているチームは、AIエージェントがソフトウェアシステムとどのように対話するかのプレイブックを書いています。ツール設計を正しくすることが、そのスタックにおいて最も高いレバレッジの仕事です。

詳しくはこちら

MCPツールを構築している方、またはDevRevのリモートMCPサーバーを試したい方は、https://developer.devrev.ai/mcp でセットアップの詳細とベストプラクティスをご確認ください。

---

まだうまくいかない部分も含めて、オープンに共有してくれたDevRev MCPチームに感謝します。Ahmed BashirとLuka Košeninaによるライブウォークスルー「DevRev Remote MCP – Real use cases for builders」(2025年10月)もご覧ください:

Cursor向けの以前のMCPデモは、AhmedとShivamのセッションで確認できます:

DEVREV

See Computer work for you

Your AI teammate that finds answers, takes action, and gets work done across every tool.