スライド資料は飛ばしてください。1つの repo をクローンし、コマンドを1つ実行して、デモのポンプ会社について動作するAIエージェントに質問します。次に裏側をのぞいてみてください。
MCPは未来です。みんなそう言います。実際に使った人はほとんどいません。
私はデジタル化コンサルタントです。今ではどのクライアントとの会話も、同じ質問で終わります。「それで……MCPをやるべきでしょうか?」私は同じ図を同じホワイトボードに100回描き、同じように100回目がとろんとしていくのを見てきました。だから説明するのをやめました。
代わりにデモ会社を作りました。顧客、受注、請求書、配送、クレームがあり、それらをすべて使いこなせるチャットエージェントがいます。repoを1つクローンしてコマンドを1つ実行し、数分待つだけで、あなたはそれと会話している状態になります。次に2つ目のタブを開いて、AIが行うすべての呼び出しをリアルタイムで確認します。そこでは、プロトコルが見ている同じ引数と回答がそのまま表示されます。
この記事は「MCPの話はよく聞くけど…」から「なるほど、あれはそういうことか」に至る、私が知っている最短ルートです。あなたの側で必要なのはコードなし。Dockerが入ったラップトップだけです。
MCP(Model Context Protocol)とは、AIがあなたのビジネスツールを、平易な言葉を通じて利用できるようにする標準的な契約です。CRMを読み取る、データベースを問い合わせる、チケットを起票する——といったことを、です。この投稿では、ローカルで5分以内に実行できる公開デモを手順付きで案内します。最後には、デモのB2B企業に質問し、その企業の自社バックエンドからデータを引き出す様子を見て、内蔵されたダッシュボードでツール呼び出しをすべて検査します。
デモに会いましょう:ポンプメーカー — そしてそのエージェント
ようこそ、Rheintal Pumpen GmbHへ。架空のドイツの工業用ポンプメーカーです。顧客は約60、受注は250件、クレーム、配送、サービスチケット——いわゆる「ミッドマーケットのB2B」が、何かのERPに入れて放置している、あの手のデータの形です。しかも、そのERPは触りたくないやつです。
デモはそのすべてをあなたのノートPC上で動かします。SQLiteデータベース、13個のツールを公開するMCPサーバ(製品検索、顧客の参照、未処理の請求書一覧、サービスチケットの起票など)、そしてその上にチャットUIがあります。
チャットUIはLibreChatです。オープンソースで、同じdocker-composeスタックで動作します。そしてLibreChatの中には「Rheintal Pumpen Demo」という設定済みのエージェントがあります。汎用のチャットボックスが見えるのではありません。会話のきっかけ、短いシステムプロンプト、さらにそれに配線されたMCPツールの厳選セットを備えた、名前付きのペルソナが見えます。
この違いは重要です。業界全体で見えてきたパターンはこうです。ツールはMCPから来る。パーソナリティとポリシーはエージェントから来る。MCPサーバは「できることはこれです」と言います。エージェントは「私は誰で、何のためにここにいて、何を使ってよいのか」を言います。このデモでは、エージェントはLibreChatネイティブの機能です。追加のサービスも追加のコンテナもありません。でも、プロダクションで使うのと同じアーキテクチャの考え方です。
質問を1つ投げて、何が起きるか見てみましょう。
ここがポイントです。
チャットを開いて、エージェントをクリックして、こう入力します:
「ステンレス製の筐体を持つ、潜水ポンプで在庫があるのはどれですか?」
回答が返ってきます。平易な英語、4つの型番名、在庫数、1行の要約。いいですね。
次に、ツール呼び出しカードを展開します——多くのチャットUIが隠している、あの小さなドロップダウンです。探しに行かないと見つかりません——そして、エージェントが実際に何をしたのかが見えます。
それは13個のうち正しいツールを選びました。固定されたenum(centrifugal_pump, submersible_pump, dosing_pump, accessory)の中から正しいカテゴリを選びました。そして「素材」は部分文字列フィルタであり、「stainless」は「stainless steel」と「cast iron / stainless steel」の両方にヒットすることを理解していました。これらのどれも、あなたのプロンプト内にはありませんでした。ツールの説明を読み、選び、実行したのです。
ここで、もう一度画像をひっくり返して考えてみましょう。MCPなしだと、同じ質問は開発チケットです。誰かがこれを書く必要があります:
SELECT * FROM products
WHERE category = ?
AND flow_rate_m3h >= ?
AND LOWER(material) LIKE ?
ORDER BY category, name
LIMIT 100;
次に、カテゴリが4つの値しか受け付けないこと、素材がLIKEによる部分文字列一致であること、そしてデータベースはどこかのVPNの裏側にあることを、誰かが把握していなければなりません。さらに、誰かがその問い合わせをSlackボット、ダッシュボード、あるいはリクエストフォームに組み込んで、5年間メンテナンスする必要があります。
MCPだと、この一連の鎖が1行に圧縮されます:
"ステンレス製の筐体を持つ、潜水ポンプで在庫があるのはどれですか?"
SQLはそのまま動きます。パラメータバインディングや境界チェックを伴って、正しく動きます。ただし、それが文章の下で動いているだけです。
これが、1拍で伝えたいすべてです。MCPはSQLのスキルを文に変えました。そしてSQLを安全に裏側に隠したままにしました。
さっき何が起きたのかを、4行で
MCPが実際に何か——マーケティングではなくプロトコル——を知りたいなら、ほんとうにそれは4行で収まります。
ツールは3つのことを広告します。名前、人間が読める説明、そしてパラメータ用のJSONスキーマです。モデルはそのカタログを読み取り、ツールを選び、パラメータを埋めて、呼び出します。これが契約のすべてです。
次は、上の質問に対してモデルが見たものです。これは、このrepoにおける search_products の説明文字列全体です:
"Search products. Filters: 'category' (centrifugal_pump, "
"submersible_pump, dosing_pump, accessory), 'min_flow_m3h' "
"(minimum flow rate), 'material' (substring, e.g. 'stainless')."
その段落——そして小さなJSONスキーマ——が、エージェントが作業するためのすべてでした。カテゴリenum、部分文字列のヒント、例の値:それが、見かけ上の賢さの源でした。マジックではありません。きちんと書かれた説明でした。
よく見ると設計のレバーが分かります。ツール説明が良いほど、エージェントも良くなる、ということです。これが新しいプログラマーの作法です。
この部分ではフタがきれいに持ち上がります。つまり、既存のスタックにあるあらゆる機能――CRMのルックアップ、SAPのRFC、Salesforceのクエリ――と同じ形のまま、MCPツールに変えられます。名前、説明、スキーマ。以上です。
実装の裏側をのぞく:インスペクタとアクティビティストリーム
チャットが見出しです。でも、その裏でちゃんと筋の通ったことが起きていると信じる必要があるだけだと、デモとしては説得力に欠けます。そこでリポジトリには、MCPサーバ自身から直接配信される、小さな2つのダッシュボードが同梱されています。これで、すべてを見ることができます。
MCPインスペクタ――ツールのためのSwagger UI
別のブラウザのタブでhttp://localhost:8765/を開いてください。そこにはMCPインスペクタがあります――サーバが公開しているすべてのツールを列挙する1ページで、モデルが見るのと同じメタデータが、人間向けに表示されているだけです。
各ツールの項目では、次の4つが一目で分かります:
- 何をするか――人間が読む説明の文字列(LLMがこのツールを呼ぶべきか判断するときに読む内容とまったく同一)。
- 何を受け取るか――パラメータのスキーマ。小さなフォーム風のブロックに展開されます。必須のフィールド、列挙型(許可される値が行内に一覧されます)、自由テキスト、デフォルト値。
- 誰が呼べるか――許可されたロールのチップ(admin, sales, accounting, service)。ロールベースのアクセス制御は、MCPに後付けされた「おまけ」ではありません。ツールの横に、プロトコルのレベルでちゃんと並んでいます。
- 何かを変えるかどうか――状態をミューテートするツールには小さなオレンジ色の書き込み(write)タグが付きます(このデモでは2つだけです)。読み取りツールにはタグがありません。このページを眺める誰でも、2秒で影響範囲(ブラストレディアス)を把握できます。
これは、顧客から「じゃあ、あなたのAIに何をつなげられるの?」と聞かれたときに私が送るページです。スライドなし、取り繕いなし、会議に同席する必要なしで答えられます。彼らは13個のツールをスクロールします。どのフィールドが型付きで、どれがゆるいのかを正確に見られます。書き込みツールが2つで、残りは読み取り専用であることも分かります。だいたい2分で、本来ならワークショップにした方がよい時間分の理解が進みます。つまり、その会議をもう取りに行かなくてよくなったんです。
ライブ・アクティビティ・ストリーム――すべての呼び出しをリアルタイムで
次にhttp://localhost:8765/activityを開いてください。これはライブ・アクティビティ・ストリームです。サーバが処理したすべてのツール呼び出しが、最新のものから順に表示され、チャットしながら更新されます。
それぞれのカードは1回の呼び出しです。1つクリックすると、左右に並ぶビューへ展開されます。左側には、モデルが選んだJSONの引数。右側には、ツールが返したJSONの結果です。呼び出しが失敗した場合――たとえば顧客が見つからない、フィルタが無効――カードは赤くなり、エラーがそのまま平文で表示されます。直近の10個の質問までさかのぼってスクロールでき、各質問について、モデルが何をする判断をしたのかがはっきり分かります。
これは、スライドを作らなくて済む2つ目のページです。「AIは実際に何をしているのか、どうやって分かるの?」――アクティビティ・ストリームが答えます。「昨日、あるエージェントがどの質問に答えたのかを監査したいんだけど?」――同じ答えです。イベントは永続化されているので、このページは最新のものを表示しているだけです。「Splunkに組み込みたいんだけど?」――/activity.jsonから同じJSONを読み取って流し込めばいいです。
より深いポイントは、自然言語でのツール利用を安全にデプロイできるようにする可視化レイヤーが、MCPとは別物ではないということです。可視化はMCPの薄いラッパーに過ぎません。インスペクタとアクティビティ・ストリームは合わせて、おそらくHTMLで200行程度と、1つのJSONエンドポイントだけです。重い処理はプロトコルが担っており、ダッシュボードはそこに既にあったものを見えるようにしているだけです。
不思議から実行へ――5分で
ここからが実践パートです。
前提条件(はい、必要なのは1つだけです):Docker。具体的にはComposeプラグイン付きのDockerです。
macOSまたはWindowsの場合:Docker Desktopをインストールしてください。必要なものがすべて詰まっています。
UbuntuまたはDebian Linuxの場合:リポジトリには、Dockerをインストールし、さらに少数のシステムツール(make、git、jq、python3)を用意するワンショットのヘルパーが付属しています。これはべき等――再実行しても安全です。
sudo ./scripts/install-prereqs.sh
これは、新しいLinux環境であなたのシステムに触れるのが最初の1回だけです。その後は、すべてコンテナの中に収まります。
そして、会社を動かすたった3行:
git clone git@github.com:dataAiOliver/rheintal-pumpen-mcp.git
cd rheintal-pumpen-mcp
make up
make upがセットアップすべてです。例から.envを書き出し、SQLiteのシードデータを生成し、4つのコンテナ(MCPサーバ、LibreChat、チャット履歴用のMongoDB、検索用のMeilisearch)を起動し、デモユーザをシードし、LibreChatのエージェントもシードするので、自分で配線する必要がありません。最初の実行は数分ほどかかります――主にイメージの取得です。
多くのチュートリアルはここで終わります。この記事は終わりません。というのも、壊れてしまう部分は通常、誰も検証しない部分だからです。そこで:
make smoke-test
これは、MCPサーバの/healthzを叩き、カタログが提供されていることを確認するために/tools.jsonを取得し、ポート3080のLibreChatルートにアクセスし、監査ログが生きていることを確認するために/activity.jsonを読み取ります。これらのどれかが失敗したら、「チャットが動かない」というだけでなく、どこが問題かが正確に分かります。(両方をつなげて実行したいなら、make up-verifyがあります。)
返却形式: {"translated": "翻訳されたHTML"}ブラウザで http://localhost:3080 を開きます。アカウントを登録してください(ローカルなので、メールはあなたのノートPCの外に出ません)。Rheintal Pumpen Demo エージェントを選び、何か質問してみましょう。利用可能な13個のツールはサイドパネルにそのまま表示されています。
最後のポイントがあります。このエージェントが実際に会話するには、LLMプロバイダが必要です。あなたの .env にそれがない場合、最後に大きなエラーブロックでうるさく止めて、やるべきことを正確に教えてくれます。つまり、.env に OPENAI_API_KEY=sk-... または ANTHROPIC_API_KEY=sk-ant-... を書き、もう一度 make up を実行してください。
スクリプトは冪等です。何も失われません。キーがないことは、壊れたチャットの3ステップ後ではなく、その瞬間に分かります。
監査ログは、インターフェースが会話になるからといって消えません。むしろ、より役に立つようになります。
なぜビジネスの読み手は気にすべきか
クライアントから私が最もよく聞く不安は、「AIが私たちのAPIを置き換える」です。このデモは、それより微妙で—そしてより役に立つ—別の事実を示します。APIはなくなりません。新しい入口ができるだけです。
このデモは、実際の企業が必要とするために、あえて次の3点をそのまま維持しています:
- ロールベースのアクセスは維持されます。このリポジトリの MCP サーバーには4つのロールがあります—admin、sales、accounting、service。各エージェントのペルソナはロールに紐づけられており、各ロールが見られるのは、そのロールにあるべきツールだけです。会計担当のエージェントは請求書をフラグ付けできますが、サービスチケットを起票できません。サービス担当のエージェントはチケットを開けますが、会計データを読むことはできません。RBACは自然言語の犠牲になりません。それはむしろ、それに含まれるパラメータです。このことはプロトコルレベルで確認できます。/tools.json の各エントリには、説明のすぐそばに allowed_roles 配列が付いており、それが Inspector ページがレンダリングする内容です。
- 監査ログは維持され、さらに充実します。すべてのツール呼び出しが、呼び出し元キーのロール、ツール名、引数、そして結果とともに記録されます。上で見た Live Activity ストリームは、そのログの人間が読める顔です。/activity.json は機械が読める側です。これは、CISOが求めていたコンプライアンスのストーリーであり、追加の統合作業なしに実現できます。
- バリデーションも維持されます。すべてのツール入力は、データベースに触れる前に厳密なスキーマを通過します。不正な入力は、SQLが実行される前に拒否されます。モデルには「drop」ツールがないため、誤って製品テーブルを削除してしまうことはありません。そしてこの制約は、Inspector ページを読むすべての人に見える形で提示されます。
それらをまとめて理解すると、戦略的な転換は小さいものの、確かに起こります。ボトルネックが「統合できるか?」から「どんな質問が価値あるのか?」へと移るのです。これははるかに良い課題です。
試してみる
リポジトリをクローンし、make up を実行して、エージェントに質問し、Activity タブを開いたままにしてください。これで記事は終わりです。
→ https://github.com/dataAiOliver/rheintal-pumpen-mcp
気になったなら拍手を。私がそうだったのと同じ質問を受けているコンサルタントなら、これをクライアントに共有してください。彼らは、より良い質問を持ち帰ってくるはずです。











