はじめに
私は普段、Devcontainer環境で開発環境を構築し、VSCodeの拡張機能(anthropic.claude-code)経由でClaude Codeを使っていました。
やはり話題になっているだけあって、Claude Codeのすごさは日々実感しています。コードの生成・修正はもちろん、プロジェクト全体を理解した上での提案や、ファイル横断でのリファクタリングなど、開発体験が大きく変わりました。
そうなると欲が出てくるもので、次はMCPサーバーの導入をしたいと思うようになりました。MCPサーバーを使えば、外部サービスと連携したりと、できることの幅がさらに広がります。
しかし、今まで「VSCode拡張機能を入れるだけ」で済んでいた自分にとって、MCPサーバーの導入は意外とハードルが高いものでした。
- MCPサーバーによってはNode.jsが必要だと知らなかった
- Devcontainerを
RebuildするたびにClaude Codeの認証が消えてしまう - ClaudeCodeの導入方法が複数あってどれを選択したらいいか迷う
...といった具合に、細かいところでつまずきました。
いろいろ調べて試行錯誤した結果、現時点での個人的ベストプラクティスがまとまったので、GitHub MCPサーバーの導入を具体例として、環境構築手順を共有します。
始める前に知っておきたいこと
MCPサーバーをDevcontainer上で動かすには、いくつか事前に理解しておくべきポイントがあります。自分がつまずいた点を先に整理しておきます。
MCPサーバーの通信方式とランタイム
MCPサーバーには主に2つの通信方式があり、方式によって必要な準備が異なります。
| 方式 | 概要 | ランタイム |
|---|---|---|
| stdio |
npxやuvxでプロセスを起動し、標準入出力で通信する。 |
必要(Node.js, Python等) |
| HTTP (SSE) | URLを指定してHTTPサーバーと通信する | 不要 |
stdio方式の場合、起動コマンドに応じたランタイムが必要です。
| ランタイム | 起動コマンド | 代表的なMCPサーバー |
|---|---|---|
| Node.js | npx |
GitHub, Slack, Filesystem など多数 |
| Python | uvx |
一部のPython製サーバー |
この記事で扱うGitHub MCPサーバーはstdio方式でnpxで起動するため、Node.jsが必要です。(MCPサーバー自体がNode.jsで実装されているため)
Claude Codeの導入方法と設計判断
Devcontainer上でClaude Codeを使う方法は複数あります。
| 方法 | 概要 |
|---|---|
| Dockerfileでインストール |
curl -fsSL https://claude.ai/install.sh | bash をDockerfileに記述 |
| Devcontainer Featureで導入 | 公式のClaude Code Featureを宣言的に追加 |
| コンテナ起動後に手動インストール | 毎回手動で実行 |
など
本記事ではDockerfileに書く方式を採用しています。理由は、Claude Codeはプロジェクトの開発ツールとして中心的な存在であり、「コンテナのベース環境の一部」として扱うのが自然だと考えたためです。
ぶっちゃけDevcontainer Featureを活用しても全く問題ないと思います
(優先順位が低いのか、更新がかなり前だったので、なんとなく敬遠してしまったというのが本音)
一方、Node.jsのような汎用ツールはDevcontainer Featuresで導入しています。
Claude Codeはこの開発環境の中心的なツールであるためDockerfileに含め、Node.jsは汎用ランタイムとしてDevcontainer Featureに追加する形にしました。
Devcontainerを Rebuildすると認証が消える
Claude Codeの設定や認証情報は~/.claudeディレクトリに保存されます。DevcontainerはRebuildするとコンテナが作り直されるため、何もしないと毎回認証からやり直しです。これをDocker Named Volumeで解決します。
最終的なファイル構成
your-project/
├── .devcontainer/
│ ├── Dockerfile
│ └── devcontainer.json
├── .mcp.json # MCPサーバー設定
├── .env # APIトークン(Git管理外)
├── .gitignore
└── (ソースコード)
Dockerfile
FROM nvidia/cuda:12.8.1-cudnn-devel-ubuntu24.04
ENV DEBIAN_FRONTEND=noninteractive \
PIP_ROOT_USER_ACTION=ignore \
PYTHONPATH=/workspace \
PATH=/opt/venv/bin:/root/.local/bin:${PATH} \
LANG=en_US.UTF-8 \
LANGUAGE=en_US:en \
LC_ALL=en_US.UTF-8
RUN apt-get update && apt-get install -y --no-install-recommends \
python3 \
python3-pip \
python3-dev \
python3-venv \
curl \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /workspace
RUN python3 -m venv /opt/venv
# Python パッケージ(プロジェクトに応じて変更)
RUN /opt/venv/bin/python -m pip install --upgrade pip && \
/opt/venv/bin/python -m pip install \
numpy pandas scikit-learn ...
# Claude Code
RUN curl -fsSL https://claude.ai/install.sh | bash
CMD ["bash"]
ベースイメージはプロジェクトに応じて自由に変更してください。ここではGPU利用の機械学習プロジェクトを例にnvidia/cudaを使っています。
今回はCUDAベースイメージを使用しているため rootユーザーのまま運用しています。
ポイントは最後の部分です。
RUN curl -fsSL https://claude.ai/install.sh | bash
Claude Codeの公式インストールスクリプトを実行しています。これにより、コンテナ起動後すぐにターミナルでclaudeコマンドが使えるようになります。
devcontainer.json
{
"name": "your-project-devcontainer",
"build": {
"dockerfile": "Dockerfile",
"context": ".."
},
"features": {
"ghcr.io/atsushi11o7/devcontainer-features/base-utils:1": {},
"ghcr.io/devcontainers/features/node:1": {
"version": "24"
}
},
"workspaceFolder": "/workspace",
"workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind",
"runArgs": [
"--env-file", "${localWorkspaceFolder}/.env"
],
"mounts": [
"source=claude-config,target=/root/.claude,type=volume"
],
"containerEnv": {
"CLAUDE_CONFIG_DIR": "/root/.claude"
},
"customizations": {
"vscode": {
"extensions": [
"anthropic.claude-code",
"ms-python.python",
"ms-toolsai.jupyter"
],
"settings": {
"terminal.integrated.defaultProfile.linux": "bash",
"python.defaultInterpreterPath": "/opt/venv/bin/python"
}
}
},
"remoteUser": "root"
}
各セクションを順番に解説していきます。
Devcontainer Featuresについて
"features": {
"ghcr.io/atsushi11o7/devcontainer-features/base-utils:1": {},
"ghcr.io/devcontainers/features/node:1": {
"version": "24"
}
}
GitHub MCPサーバーを含む多くのMCPサーバーは、npxやuvxなどのコマンドでプロセスを起動し、標準入出力(stdio)経由でClaude Codeと通信します。npxはNode.jsに付属するパッケージランナーです。つまり、MCPサーバーを使うにはNode.jsが必要です。
PythonやCUDAベースのDockerイメージにはNode.jsが入っていないため、何らかの方法でインストールする必要があります。
Dockerfileに書き込んでもいいのですが、Node.jsはプロジェクト固有ではなく、MCPサーバー起動などに使う汎用ランタイムであるため、Devcontainer Featureで追加しています。
Devcontainer Features とは
Devcontainer Featuresは、Dockerfileで構築したベースイメージの上に、追加のツールや設定を宣言的にインストールできる仕組みです。
「Dockerfileに直接書くのと何が違うの?」と思うかもしれません。主な違いは以下の通りです。
| Dockerfileに書く | Devcontainer Featuresを使う | |
|---|---|---|
| 記述量 | インストール手順を自分で書く | 数行の宣言で済む |
| 再利用性 | プロジェクトごとにコピペ | 複数プロジェクトで使い回しやすい |
| ベースイメージとの分離 | Dockerfileが長くなりがち | 関心の分離ができる |
| バージョン管理 | 自分でバージョン指定を管理 | Feature側でメンテされる |
要するに、「Dockerfileはプロジェクト固有の環境構築に集中し、Git・Node.jsなどの汎用ツールはFeaturesに任せる」という役割分担ができます。
今回導入したFeature
ghcr.io/devcontainers/features/node:1 — 公式提供のNode.js Feature
Microsoft/Devcontainersが公式に提供しているFeatureです。versionパラメータでNode.jsのバージョンを指定できます。これにより、コンテナ内でnodeコマンドとnpxコマンドが使えるようになり、MCPサーバーの起動が可能になります。
"ghcr.io/devcontainers/features/node:1": {
"version": "24"
}
ghcr.io/atsushi11o7/devcontainer-features/base-utils:1 — 自作のFeature
こちらは筆者が自作したDevcontainer Featureです。複数のプロジェクトで共通して使いたいツール(Git、GitHub CLI、基本的なユーティリティなど)を1つのFeatureにまとめています。
今回の記事にはあまり関係ないです。
mounts + containerEnv — Claude Code設定の永続化
"mounts": [
"source=claude-config,target=/root/.claude,type=volume"
],
"containerEnv": {
"CLAUDE_CONFIG_DIR": "/root/.claude"
}
これを設定しないと、Devcontainerを再作成するたびにClaude Codeの認証がリセットされます。
Claude Codeの設定や認証情報は~/.claudeディレクトリに保存されます。DevcontainerはRebuildすると中身がまっさらになるため、何もしないと毎回/loginからやり直しです。地味にストレスが溜まります。
これを防ぐために、Docker Named Volumeを使って~/.claudeを永続化しています。
コンテナ内の /root/.claude
↕ マウント
Docker Named Volume "claude-config"(ホスト側で永続管理)
Named VolumeはDevcontainerを作り直しても消えません。docker volume lsで確認でき、明示的にdocker volume rm claude-configしない限り残り続けます。
containerEnvのCLAUDE_CONFIG_DIRは、Claude Codeに設定ディレクトリの場所を明示的に教えるための環境変数です。
runArgs + .env — APIトークンの安全な管理
"runArgs": [
"--env-file", "${localWorkspaceFolder}/.env"
]
MCPサーバーにはAPIトークンが必要なものもあります。しかし、トークンを.mcp.jsonやDockerfileに直接書くのはセキュリティ上危険です。Git管理下のファイルにトークンをハードコードしてしまうと、リポジトリを公開した瞬間に漏洩します。
そこで、.envファイルにトークンを分離し、Dockerの--env-fileオプションでコンテナに注入する方式を採っています。
.envファイルの作成
プロジェクトルートに.envファイルを作成します。
GITHUB_PERSONAL_ACCESS_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx
必ず.gitignoreに追加してください。
# .gitignore
.env
GitHub Personal Access Tokenの取得
GitHubの Settings → Developer settings → Personal access tokens → Tokens (classic) から発行します。
MCPサーバー用途ではrepoとread:orgスコープがあれば十分かと思います。
customizations — VSCode拡張機能の自動インストール
"customizations": {
"vscode": {
"extensions": [
"anthropic.claude-code",
"ms-python.python",
"ms-toolsai.jupyter"
],
"settings": {
"terminal.integrated.defaultProfile.linux": "bash",
"python.defaultInterpreterPath": "/opt/venv/bin/python"
}
}
}
anthropic.claude-codeを指定しておくと、Devcontainer起動時にClaude CodeのVSCode拡張機能が自動インストールされます。
これにより、ターミナルからのclaudeコマンドに加え、VSCodeのサイドバーからもClaude Codeを利用可能になります。
.mcp.json — MCPサーバーの設定
プロジェクトルートに.mcp.jsonを配置します。Claude Codeはこのファイルを自動検出します。
{
"mcpServers": {
"github": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-github"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}"
}
}
}
}
各キーの意味は以下の通りです。
| キー | 値 | 説明 |
|---|---|---|
type |
"stdio" |
標準入出力で通信 |
command |
"npx" |
Node.jsのパッケージランナー(Node.jsが必要な理由) |
args |
["-y", "@modelcontextprotocol/server-github"] |
-yで確認プロンプトをスキップし、GitHubサーバーパッケージを指定 |
env |
${GITHUB_PERSONAL_ACCESS_TOKEN} |
.envから注入されたコンテナの環境変数を参照 |
動作確認
1. Devcontainerの起動
VSCodeでプロジェクトを開き、コマンドパレット(Ctrl+Shift+P)から 「Dev Containers: Rebuild and Reopen in Container」 を実行します。
初回はDockerイメージのビルドとFeaturesのインストールが走るため、少し時間がかかります。
2. Claude Codeの起動
ターミナルでclaudeを実行します。初回は認証が必要なので、表示される指示に従って/loginを行ってください。
コンテナ内でClaude Codeが起動した様子。Named Volumeで~/.claudeを永続化しているため、2回目以降のRebuildでは認証不要です。
3. MCPサーバーの認識確認
Claude Code起動時に.mcp.jsonが検出されると、以下のようなプロンプトが表示されます。
「New MCP server found in .mcp.json: github」と表示されます。「Use this and all future MCP servers in this project」を選択すると、以降は自動で読み込まれます。
4. MCPサーバーの動作確認
Claude Code内でmcp listと入力すると、接続中のMCPサーバーを確認できます。
GitHub MCPサーバーが正常に接続されている状態。
これで環境構築は完了です。Claude Codeに「このリポジトリのIssueを一覧して」「PRを作成して」といった指示が通るようになります。
まとめ
MCPサーバー導入を前提としたDevcontainer + Claude Code環境のポイントをまとめます。
| 課題 | 解決策 | 設定箇所 |
|---|---|---|
| MCPサーバーの実行にNode.jsが必要 | Devcontainer Featureで導入 |
devcontainer.json の features
|
| APIトークンを安全に管理したい |
.env + --env-fileで注入 |
devcontainer.json の runArgs
|
| Rebuild後もClaude Codeの認証を保持 | Named Volumeで~/.claudeを永続化 |
devcontainer.json の mounts
|
| MCPサーバーの設定 | プロジェクトルートに.mcp.jsonを配置 |
.mcp.json |
一度この構成を作ってしまえば、あとは.mcp.jsonにMCPサーバーを追加していくだけで拡張できます。GitHub以外にもさまざまなMCPサーバーが公開されているので、ぜひ試してみてください。



