1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude Code の MCP サーバー設定を .mcp.json でチームに配る実装手順 — local/project/user スコープの優先順位・${VAR} 展開で起動失敗・プロジェクトサーバーが承認待ちで出てこない、3つのハマりどころ【2026】

1
Posted at

はじめに / 対象と前提

Claude Code で MCP サーバーをいくつか使い始めると、次に必ずぶつかるのが「この設定、チームメンバーにどう配るか」だ。自分の手元では claude mcp add で動いていたのに、リポジトリを clone した同僚の環境では MCP ツールが一切見えない。あるいは .mcp.json をコミットしたら API キーまで一緒に push しそうになった。

この記事はそのあたりを、どこに保存されているか → どう配るか → どこでハマるか の順で整理する。

  • 想定読者:Claude Code を個人で使えていて、MCP サーバーの設定をリポジトリ経由でチームに共有したい Web エンジニア
  • 前提知識:MCP(Model Context Protocol、Claude に外部ツールを渡す共通規格)の概念と、claude mcp add を一度は叩いたことがある程度
  • 検証環境:macOS 15 / Claude Code 2.x 系(2026 年 10 月時点)/ Node.js 22.x。MCP サーバーのサンプルは @modelcontextprotocol/server-filesystem と自作の stdio サーバー

TL;DR

  • MCP サーバー設定には local / project / user の 3 スコープ があり、保存先ファイルが違う。チーム共有は project スコープ = リポジトリ直下の .mcp.json 一択
  • .mcp.json に秘密情報を直書きせず ${VAR} 展開 を使う。ただし 未定義かつデフォルト無し の変数があると設定ファイル全体の読み込みに失敗する
  • project スコープのサーバーは 初回に承認プロンプト が出る。一度「拒否」を選ぶとそのサーバーは黙って無効になり、claude mcp reset-project-choices を叩くまで復活しない

手順 / 動かし方

1. まず今どこに何が入っているか確認する

claude mcp list

実行結果(自分の環境):

Checking MCP server health...

filesystem: npx -y @modelcontextprotocol/server-filesystem /Users/me/work - ✓ Connected
notion: npx -y @notionhq/notion-mcp-server - ✓ Connected

ここで注目すべきは どのスコープに入っているかは list では分からない こと。個別に get で見る。

claude mcp get filesystem
filesystem:
  Scope: Local config (private to you in this project)
  Status: ✓ Connected
  Type: stdio
  Command: npx
  Args: -y @modelcontextprotocol/server-filesystem /Users/me/work

Scope: Local config と出ている時点で、この設定は 同僚の環境には存在しない。

2. 3 スコープの保存先と優先順位

スコープ 指定方法 保存先 共有範囲
local(既定) --scope local または省略 ~/.claude.json 内の「そのプロジェクトパス」の項 自分のみ・そのディレクトリのみ
project --scope project リポジトリ直下の .mcp.json git に乗る=チーム全員
user --scope user ~/.claude.json のグローバル項 自分のみ・全プロジェクト

同じ名前のサーバーが複数スコープにあるときは local > project > user の順で勝つ。つまり「チームの .mcp.json にある github サーバーを、自分だけ別トークンで動かしたい」なら、同名で local に登録すれば個人側が優先される。

3. project スコープで登録して .mcp.json を生成する

claude mcp add --transport stdio --scope project filesystem \
  -- npx -y @modelcontextprotocol/server-filesystem ./docs

生成された .mcp.json:

{
  "mcpServers": {
    "filesystem": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "./docs"],
      "env": {}
    }
  }
}

ポイントは パスを相対で書いていること。local スコープのときに /Users/me/work と絶対パスで書いていたものをそのまま project に移すと、他人の環境では存在しないパスになる。相対パスは Claude Code を起動したカレントディレクトリ基準で解決される。

4. 秘密情報は ${VAR} で外出しする

API キーが必要なサーバーはこう書く。

{
  "mcpServers": {
    "notion": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@notionhq/notion-mcp-server"],
      "env": {
        "NOTION_TOKEN": "${NOTION_TOKEN}",
        "NOTION_API_VERSION": "${NOTION_API_VERSION:-2025-09-03}"
      }
    }
  }
}
  • ${VAR}:シェルの環境変数をそのまま埋め込む
  • ${VAR:-default}:未定義ならデフォルト値を使う

展開が効くのは command / args / env / url / headers の各フィールド。HTTP 型のリモート MCP なら "headers": {"Authorization": "Bearer ${MY_TOKEN}"} と書ける。

5. 同僚側での動作確認

clone 直後に claude を起動すると、次のプロンプトが出る。

This project contains MCP servers defined in .mcp.json.
Do you want to use them?
  ❯ Yes, use these servers
    No, skip

ここで Yes を選び、セッション内で /mcp を打つと接続状態が一覧で出る。✓ connected になっていれば完了。

ハマりどころ

ハマりどころ 1:${VAR} が未定義だと .mcp.json 全体が読まれない

症状:.mcp.json に 3 つサーバーを書いたのに、/mcp に 1 つも出てこない。エラーも特に見えない。

原因:${NOTION_TOKEN} を書いた同僚の環境でその変数が未定義だった。Claude Code は デフォルト値のない未定義変数を含む設定ファイルをパースできない 扱いにするので、その 1 行のために ファイル全体 が無効になる。巻き添えで他のサーバーも消える。

回避策:

  • 秘密情報以外の変数には必ず ${VAR:-default} でデフォルトを付ける
  • 秘密情報は README に「export NOTION_TOKEN=... を .zshrc に書け」と明記する。.env ファイルは読まれない(Claude Code 自身は dotenv を読まない。シェルの環境変数だけが見える)
  • 詰まったら claude --debug で起動し、MCP 関連のログを確認する。パース失敗はここに出る

ハマりどころ 2:一度「No」を選ぶと、そのサーバーは黙って無効のまま

症状:初回プロンプトで間違えて「No, skip」を押した。以降 .mcp.json を直しても claude を再起動しても一切出てこない。

原因:project スコープの承認結果は プロジェクト単位で ~/.claude.json に記憶 される。拒否はそのまま永続化され、再プロンプトは出ない。

回避策:

claude mcp reset-project-choices

を叩いて次回起動時にプロンプトを出し直す。CI や共有マシンで毎回プロンプトを出したくない場合は、.claude/settings.json に明示的に書く。

{
  "enableAllProjectMcpServers": true
}

逆に「この 1 つだけは使いたくない」なら disabledMcpjsonServers: ["notion"]、「この 2 つだけ許可」なら enabledMcpjsonServers: ["filesystem", "github"] と書ける。チーム用途は enabledMcpjsonServers でホワイトリストにしておくのが安全。

ハマりどころ 3:-- を忘れるとサーバー側の引数を claude が食う

症状:

claude mcp add --scope project filesystem npx -y @modelcontextprotocol/server-filesystem ./docs

と打ったら、error: unknown option '-y' で止まる。あるいは止まらずに登録されたが、起動すると npx が対話プロンプトで固まる。

原因:claude mcp add は -- より後ろをサーバーコマンドとして丸ごと扱う。-- が無いと -y を自分のオプションだと解釈する。

回避策:サーバーコマンドの前には必ず -- を置く。環境変数を渡すときの -e KEY=value と HTTP ヘッダの --header は -- の 前 に置く。

claude mcp add --transport stdio --scope project -e NOTION_TOKEN='${NOTION_TOKEN}' notion \
  -- npx -y @notionhq/notion-mcp-server

シングルクォートで囲わないとその場でシェルが展開してしまい、.mcp.json に 実トークンが直書き される。commit 前に git diff .mcp.json で ${ が残っているか必ず目視すること。

背景・補足

なぜ project スコープだけ承認プロンプトが入るのか。.mcp.json は リポジトリに同梱される=第三者が書いた設定を自分のマシンで実行する ことになるため、悪意ある command が仕込まれていても自動実行されないようにしている。OSS を clone して claude を起動した瞬間に任意コマンドが走る、を防ぐための安全装置だ。

逆に local / user スコープは自分で claude mcp add した前提なのでプロンプト無しで即有効になる。この非対称性を知っていると「自分の環境では動くのに同僚で動かない」の 9 割は説明がつく。

まとめ

  • チーム共有は project スコープ(.mcp.json)、個人上書きは local スコープ。同名なら local が勝つ
  • 秘密情報は ${VAR}、それ以外は ${VAR:-default}。未定義変数 1 つでファイル全体が無効になる
  • 初回承認で「No」を押したら claude mcp reset-project-choices。チームでは enabledMcpjsonServers でホワイトリスト化
  • claude mcp add は -- の後ろがサーバーコマンド。-e でトークンを渡すときはシングルクォートで展開を防ぐ
  • 詰まったら claude mcp get <name> でスコープ確認、claude --debug でパースエラー確認
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?