MCP サーバをローカルで動かす際に気をつけていること
はじめに
2025 年も終わろうとしているが、ここ 1 年は LLM 搭載の IDE から MCP サーバを使って開発することが増えた。
MCP サーバはローカルで Docker コンテナ として立てて動かすことが現状多いので、その状況においていくつか意識していることを書いてみる。なお、本記事では VS Code の Roo Code 拡張を前提として説明するが、他の LLM 機能搭載の IDE を使っている方は脳内で置き換えて考えてくれればと思う(おそらく大した違いはないように記載できているはず)。
MCP(Model Context Protocol)とは
MCP は、LLM アプリケーションが外部ツールやデータソースと標準化された方法で連携するためのプロトコルである。これにより、AI エージェントがファイルシステム、データベース、API などに安全にアクセスできるようになる。標準入出力(stdio)を使った通信方式が基本となっており、Docker コンテナとの相性も良い。
What is the Model Context Protocol (MCP)? - Model Context Protocol
modelcontextprotocol.io
GitHub - modelcontextprotocol/servers: Model Context Protocol Servers
Model Context Protocol Servers. Contribute to modelcontextprotocol/servers development by creating an account on GitHub.
github.com
ネイティブ実行 VS Docker コンテナ実行
MCP サーバをローカルで動作させる際、個人的にはコンテナで実行したい。理由としては簡単でコンテナの特性を活かして下記のようなメリットを享受したいからである。
- 環境の分離: ホストマシンに特定のランタイムや依存ライブラリをインストールする必要がない。
- セキュリティ: ホストマシンと隔離した環境で動作させることによって MCP サーバがアクセスできる範囲を限定できる。
- ポータビリティ: 環境構築などの手間がはぶけるためポータビリティが非常に高い。つまりチーム内で同じ環境を再現しやすく使い回しも容易。
それぞれの場合の mcp.json の書き方を示す。ここでは Playwright MCP1 を例にしている。
ネイティブ実行の場合
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest"
]
}
}
}
コンテナ実行の場合
{
"mcpServers": {
"playwright": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"--init",
"--pull=always",
"mcr.microsoft.com/playwright/mcp"
]
}
}
}
ネイティブ実行ではホスト上で直接コマンドを実行するのに対し、コンテナ実行では docker run コマンドでコンテナを起動する点が異なる。
MCP サーバ起動時によく使うオプション
MCP サーバをコンテナで実行する際によく使うオプションを説明する。
-i: 標準入力を開いたまま(MCP の stdio 通信に必須)
--init: PID 1 プロセスとして init を使用(ゾンビプロセス対策)
--mount / -v: ボリュームマウント(ファイルアクセス用)
-p: ポートフォワード(ホストからコンテナへ直接にアクセス)
これらについて一つずつ説明する。
-i(--interactive) オプション
MCP の通信プロトコルは標準入出力を使用するため、Docker 実行時に -i を指定しないとクライアントとコンテナ間の通信パイプが確立されず、接続エラー(Timeout)になる。常に -i を付けて標準入力を開いたままにしておくことが重要である。
--init オプション
PID 1 プロセスとして init を使用することで、ゾンビプロセスの発生を防ぐ。Docker コンテナ内で実行されるプロセスは通常 PID 1 として起動されるが、PID 1 には特別な責任があり、子プロセスの終了処理を適切に行う必要がある。--init フラグを指定することで、軽量な init プロセス(tini)が PID 1 として起動され、シグナルの転送やゾンビプロセスの刈り取りを自動的に処理してくれる。長時間実行するコンテナや、子プロセスを生成する可能性がある MCP サーバでは特に推奨される。
下記の記事がとても参考になるので詳しく知りたければこちらも読んでもらうと良い。
Dockerの--initフラグについて - Carpe Diem
概要 dockerのコンテナは指定したコマンドがPID 1で起動されており、使い方によってはシグナルハンドリングできないことがありますよ、という話です。 それによってプロセスをGracefulに終了できなかったりリソースリークが起きたりするので注意する必要があります。 環境 docker v18.09.0 どんな問題が起きる? こちらでとてもわかり易く説明されてます。 Unix プロセスと Docker の罠 - けちゃぶろぐ Dockerケースを要約すると、親、子、孫の3プロセスが起動している状態で ケース 何が起きる 問題点 親が死ぬ 子も孫も強制的に死ぬ 処理中リクエストをハンドリングで…
christina04.hatenablog.com
docker --init (Tini) が PID 1 問題を解決している様子を調べてみた - Qiita
はじめに docker --init は PID 1 として動作させることを想定してないプロセスを適切に処理するために、軽量の init を PID 1 で実行する Docker 1.13 で追加されたオプションです。内部的には Tini が使用されています。Tini の...
qiita.com
--mount と -v(--volume) オプション
ホストのディレクトリやファイルをコンテナ内にマウントするオプションである。MCP サーバがファイルシステムにアクセスする際に必要となる。
例えば、Playwright MCP サーバでスクリーンショットをローカルマシン上に保存したい場合や、SQLite MCP サーバでデータをローカルに永続化したい場合に使用する。また、ログファイルやドキュメントを読み取り専用で MCP サーバに提供する場合にも活用できる。
Docker では、ストレージのマウントに --mount と -v(--volume) の 2 つのオプションが用意されているが、公式としては前者を推奨している2 ため理由がなければ前者を使うと良い。
下記の通り、key=value 形式で可読性が高く、マウントの種類を type=volume で明示的に指定する。
# Volume の場合
$ docker run --mount type=volume,source=myvolume,target=/app/data image
# 読み取り専用にする場合
$ docker run --mount type=volume,source=myvolume,target=/app/data,readonly image
LLM に読み書きを許可するマウントを最小限に絞ることで、誤操作のリスクを減らせる。必要最小限のディレクトリのみをマウントし、可能な限り読み取り専用にすることを推奨する。
Volumes
Learn how to create, manage, and use volumes instead of bind mounts for persisting data generated and used by Docker.
docs.docker.com
-p(--publish) オプション
コンテナ内のポートをホスト側に公開するオプションである。SSE(Server-Sent Events) 接続など、MCP サーバを HTTP サーバとして常時起動する特定のケースで使用する。 この記事で扱っている stdio 接続(Roo Code など)では通常不要という認識である。
基本的な構文は以下の通りである。
$ docker run -p <ホストのポート>:<コンテナのポート>
# 例: コンテナ内のポート 9000 をホストの 9000 番ポートに公開
# -p 9000:5432
一方、コンテナからホスト側へのアクセス(MCP サーバからホスト上の DB や API へのアクセス)の場合は、host.docker.internal をエンドポイントに指定する。これにより、ホスト側つまり localhost に到達できる。
なお、host.docker.internal は Docker Desktop や Rancher Desktop で利用可能な機能である。Linux でネイティブに Docker Engine を使用している場合は、代わりに --add-host=host.docker.internal:host-gateway オプションを指定するか、ホストのネットワークインターフェースの IP アドレスを直接指定する必要がある。
まとめ
以上が MCP サーバを Docker コンテナで動作させる際に個人的に意識していることだった。
まず Docker コンテナを使うことで、ローカル環境を汚すことなく、さまざまな MCP サーバを簡単に起動できる。
そして、紹介した MCP サーバ起動時のオプションの使い方とその意図を理解した上で活用することで、安全かつ効率的に MCP サーバを利用できると思う。
MCP についてはまだまだ発展途上の技術ではあるので、動向をキャッチアップしていきたい。より深く学びたい方は、おすすめの書籍を掲載しているのでぜひ参照してもらえればと思う。
参考
やさしいMCP入門
AIエージェント時代の標準規格MCP(モデル コンテキスト プロトコル)の入門書。
大バズりしたスライド「やさしいMCP入門」の著者が新技術の基礎をやさしく解説。
Chapter 1 MCPとは
Chapter 2 MCPの仕組み
Chapter 3 MCPを実際に触ってみよう
Chapter 4 MCP対応クライアント紹介
Chapter 5 MCPサーバー紹介
Chapter 6 MCPサーバー紹介(開発者向け)
Chapter 7 MCPがもたらすビジネスインパクト
Chapter 8 MCPの展望と今後の発展
※この商品は固定レイアウトで作成されており、タブレットなど大きいディスプレイを備えた端末で読むことに適しています。また、文字列のハイライトや検索、辞書の参照、引用などの機能が使用できません。
続きを読む
amazon.co.jp
MCPサーバー開発大全――独自サーバーの実装から自動テストの構築まで エンジニア選書
(概要)
※この商品はリフロー型epubで作成されております。デバイスに合わせて文字の大きさやレイアウトが変更可能です。また,電子書籍内で検索をかけたり,マーカーを引いたり,自動読み上げを行うことも可能です。
MCP(Model Context Protocol)は、LLM(大規模言語モデル)とツールを連携させる革新的なプロトコルとして急速に普及しています。MCPによってAIエージェントに各種のタスクを任せることが現実になりました。同時に重要性を増しているのが、自サービスのMCPサーバーを完備してAIフレンドリーにすることです。サービスやデータベースは「AIから使えるかどうか」によってその価値が大きく変わります。
本書はMCPの基礎概念からMCPサーバー開発のための環境構築、基本的な実装、複雑なドメインヘの応用、そして品質保証を扱います。書籍内では実例として、初歩的な天気予報サーバーや、実践的な社内ドキュメントサーバーを作成します。また、著者が独自に考案した「4層テスト戦略」は、従来のAPIテストでは対応困難なMCP特有の課題に対する解決策を提示します。さらにはCI/CDおよび自動テストの構築という運用面まで、MCPサーバー開発のすべてを学べる1冊です!
(こんな方におすすめ)
・実践的なMCPサーバーを作りたい方
・自身や自社の持つデータ資源をAIエージェントに活用させたい方
・LLMが介在するシステムのテストや品質保証に関心のある方
(目次)
第1章 MCPサーバー開発の基礎知識
1.1 MCPとは何か
1.2 MCPサーバーの基本アーキテクチャ
1.3 開発環境の構築
1.4 まとめ
第2章 MCPアーキテクチャの理解
2.1 MCPプロトコルの全体像
2.2 MCPサーバーの設計パターン
2.3 MCPサーバーのスケーラビリティ
2.4 セキュリティアーキテクチャ
2.5 他のプロトコル・アーキテクチャとの比較
2.6 まとめ
第3章 基本的なサーバー実装
3.1 公式サンプルの解析
3.2 HTTP APIとの連携
3.3 天気予報MCPサーバーの構築
3.4 まとめ
第4章 複雑なサーバー設計
4.1 複雑な処理フローの設計
4.2 実例:過ごし方提案MCPサーバー
4.3 応用:社内ドキュメントサーバー
4.4 スケーラビリティとパフォーマンス
4.5 設定管理とデプロイメント
4.6 まとめ
第5章 MCPサーバーのテスト戦略
5.1 4層テスト戦略
5.2 Layer 1:単体テストの実装
5.3 Layer 2:プロトコルテストの実装
5.4 Layer 3:カスケードテストの実装
5.5 Layer 4:E2Eテストの実装
5.6 まとめ
第6章 CI/CD統合
6.1 GitHub Actionsでの自動テスト
6.2 テストカバレッジの測定と改善
6.3 デプロイメント自動化
6.4 その他の品質保証のベストプラクティス
6.5 まとめ
続きを読む
amazon.co.jp
AIエージェント開発/運用入門 [生成AI深掘りガイド]
「AIエージェント」の基本・作り方・活用方法が、
この一冊でぜんぶ学べる!
※この電子書籍は、「固定レイアウト型」で配信されております。説明文の最後の「固定レイアウト型に関する注意事項」を必ずお読みください。
昨今話題の「AIエージェント」について、基礎の基礎から1つずつ丁寧に、しっかりと解説した本格入門書です。
基礎知識はもとより、AIエージェントの作り方や実際の活用事例、さらにはAIエージェントを語るうえで欠かせないLLMについても解説しています。
また、本書の後半では、開発後の運用フェーズ(LLMOps)の技法についてもLangfuseを用いて解説するなど、企業の開発現場で活用できる、実践的なレベルまで主要な技術をいっきに紹介しています。
★★本書の特徴★★
(1)フロントエンドの実装までハンズオンで学べる
「推論を行うシンプルなAIエージェント」
「MCPを用いたAIエージェント」
「複数のエージェントが協業するマルチエージェント」 など
(2)AIエージェントの開発と運用がよくわかる
「開発フレームワークと便利なツール」
「プロンプトの管理手法」
「AIエージェントのトレーシング」
「AIエージェントの評価と改善」 など
(3)最新の関連知識を盛りだくさんに解説
「AIエージェントの動作を人が制御するHuman-in-the-Loop」
「Strands Agents」「Mastra」「Amazon Bedrock AgentCore」
「Amazon Bedrock Guardrails」 などなど
【読者特典】
サンプルコード配布
※カバー画像が異なる場合があります。
●目次
第1章 LLMとAIエージェントの基本
第2章 LLMのAPIを使ってみよう
第3章 主要フレームワークの紹介
第4章 LangGraphでAIエージェントを作ってみよう
第5章 MastraでフルスタックWebアプリを作ろう
第6章 高度なAIエージェントの開発に挑戦しよう
第7章 LangfuseでLLMOpsに挑戦しよう
第8章 ガードレールとRagas評価でAIエージェントの品質を高めよう
付録
固定レイアウト型に関する注意事項(必ずお読みください)
この電子書籍は、全ページ画像の「固定レイアウト型」で配信されております。以下の点にご注意し、購入前にプレビュー表示をご確認の上、ご購入ください。
■使用できない機能
・文字拡大(ピンチイン・ピンチアウトは可能ですが、画面におさまらない場合は画面をスワイプ)/文字のコピー/マーク/ハイライト/文字列検索/辞書の参照/Web検索/引用
■推奨環境
・タブレットなど大きいディスプレイを備えた端末
・Wi-Fiネットワーク経由でのダウンロード(Kindle端末の場合)
続きを読む
amazon.co.jp