機能

共有MCPサーバー

最終更新日: 2026年10月19日
ccam 0.6.0とClaude Code 2.1.302で確認済み

このページは英語から機械翻訳されています。修正を歓迎します。 GitHubでこのページを編集

このページの内容

Claude CodeはユーザーのMCPサーバーを.claude.jsonに保存します。これはアカウントのログインを保持するのと同じファイルなので、アカウント間で共有できません。ccamは共有サーバーをグループのファイルmcp.jsonに保存し、起動時にグループのすべてのアカウントに渡します。ccam mcpを使うと、サーバーを一度追加するだけですべてのアカウントで使えます。あるセッション内で追加したサーバーをほかのアカウントに移すには、ccam mcp importを使います。

使い方

ccam mcp add fs -- npx -y @modelcontextprotocol/server-filesystem ~/code   # a local (stdio) server
ccam mcp add ctx --url https://mcp.context7.com/mcp --header 'Authorization: Bearer …'
ccam mcp add docs --url https://example.com/sse --transport sse
ccam mcp add db -e PGHOST=localhost -- pg-mcp                    # with an environment variable
ccam mcp add-json gh '{"type":"http","url":"https://api.githubcopilot.com/mcp/"}'
ccam mcp add tools -g team -- tools-mcp                           # into the group team
ccam mcp list                                                     # every group, and servers only one account has
ccam mcp remove ctx
ccam mcp import work                                              # move work's own servers into its group
ccam mcp import work gh --force                                   # replace the group's different gh

変更は各アカウントの次の起動から適用されます。実行中のセッションは、起動時のサーバーを使い続けます。

$ ccam mcp add fs -- npx -y @modelcontextprotocol/server-filesystem ~/code
✓ fs added in group default — applies from the next launch
$ ccam mcp list
group default (work, side)
  ctx                  http https://mcp.context7.com/mcp
  fs                   stdio npx -y @modelcontextprotocol/server-filesystem /home/me/code
only in account work: pg

グループにすでにある名前を追加すると、その定義が置き換えられ、addedではなくupdatedと表示されます。サーバーがアカウントに届くのは、そのアカウントがそのグループとMCPを共有している場合(ccam share <name> --mcp on)だけです。MCPを共有しているアカウントがまだない場合は、addがその旨を表示します。

オプション

オプション 効果 デフォルト
-g、--group <group> add、add-json、removeの対象グループ いずれかのアカウントがMCPを共有しているグループが1つだけならそのグループ、それ以外はdefault
-- <command> [args…](add) このコマンドをstdioサーバーとして実行します
--url <url>(add) リモートサーバーのURL(http/sse)
--transport <stdio|http|sse>(add) --urlサーバーのトランスポート http
--header <'Name: value'>(add) HTTPヘッダー。複数回指定できます なし
-e、--env <KEY=VALUE>(add) stdioサーバーの環境変数。複数回指定できます なし
--force(import) 同じ名前で内容の異なるグループのサーバーを置き換えます。以前のmcp.jsonはバックアップされます オフ
--keep-local(import) アカウントの.claude.jsonの項目を残します オフ
-h、--help 各コマンドのヘルプ
--dry-run(グローバル) mcp listだけが対応します。add、add-json、remove、importは拒否し、何も変更しません オフ

addには、--の後のコマンドか--urlのどちらかが必要です。どちらもない場合はa command to run (after --) or --url is requiredで失敗します。--headerは--urlサーバーに、--envはコマンドのサーバーに適用されます。add-jsonはclaude mcp add-jsonと同じJSONを受け取り、定義はcommandかurlを持つオブジェクトでなければなりません。importは常にアカウントがMCPを共有しているグループを使い、listはすべてのグループを表示するので、-gで変わることはありません。

しくみ

関係するファイルは次のとおりです。

  • ~/.local/share/ccam/groups/<group>/mcp.json: 共有サーバーです。形式は{"mcpServers": {…}}で、--mcp-configが読む形式です。サーバーの項目にはAPIキーが含まれることが多いため、fsutil.AtomicWriteを使ってモード0600で書き込まれます。
  • ~/.local/share/ccam/profiles/<name>/.claude.json: アカウントのサーバーを保持する、Claude Code自身のファイルです。ccamはprofile.TopLevelValueスキャナーでそのmcpServersの値だけを読み、起動経路でファイル全体を解析することはありません。
  • ~/.local/state/ccam/mcp/<name>/: seenファイル、sync-stamp、.claude.jsonのバックアップです。

戦略は2つあり、~/.config/ccam/config.tomlのmcp_strategyで設定します。デフォルトはフラグ戦略です。

  1. launcher.applyMCPがアカウントのMCPグループを見つけます。mcp.FlagArgsは、グループのmcp.jsonがあるかどうかを、解析せずに1回のstatで確認します。
  2. Plan.InsertArgsが、--mcp-config=<path>をclaudeの直後、自分で指定した引数より前に置きます。そのため、自分で指定した--mcp-configや--strict-mcp-configも、その上に追加で適用されます。
  3. mcp.NewLocalが、前回の起動以降にアカウントの.claude.jsonが変更されたかを確認し、変更があった場合だけそのサーバーを解析します。
  4. syscall.ExecがccamをClaude Codeに置き換えます。

パスは2つではなく、--mcp-config=<path>という1つの引数で渡されます。Claude Codeの--mcp-configは複数の値を取るため、claude --mcp-config a.json "prompt"ではプロンプトが2つ目の設定ファイルとして読まれ、MCP config file not foundで失敗します。1つの引数の形式ならそこで区切られるので、続くプロンプトやmcp listのようなサブコマンドも動作します。Claude Codeは、アカウント自身のサーバーに加えて--mcp-configのサーバーを読み込みます。名前が重なった場合は.claude.jsonの項目が優先されます。フラグ戦略が.claude.jsonに書き込むのは、Remote Controlの場合だけです。

claude remote-control(rc)は--mcp-configを受け付けず、そのセッションは.claude.jsonからしかサーバーを読みません。ccam work rcでは、ccamはこのフラグを付けず、ターミナル上であれば、sync戦略と同じようにバックアップを取ってグループのサーバーを.claude.jsonにコピーするかどうかを確認します。コピーができるまで確認し、その後はグループのmcp.jsonが変わったときにだけ再び確認します(Remote Control)。このコピーは名前が重なった場合に--mcp-configより優先されるため、ccam mcp add、add-json、remove、importは、グループのほかのアカウントが持つコピーも更新します。

$ ccam mcp add ctx --url https://mcp.context7.com/mcp
✓ ctx added in group default — applies from the next launch
✓ Updated the copy in account side's .claude.json (made for Remote Control)

セッション内でclaude mcp addを使って追加したサーバーは、そのアカウントの.claude.jsonにだけ保存されます。その時点ではccamはClaude Codeに置き換えられていて検出できないため、次の起動時に確認します。seenファイルには、.claude.jsonの更新日時と、すでに通知したサーバー名が保存されています。日時が異なる場合、ccamは名前をグループと比較し、新しいサーバーごとにヒントを一度だけ、入力を待たずに表示します。

ccam: MCP servers only account work has: pg
      To share them with other accounts: ccam mcp import work pg

mcp_strategy = "sync"の場合、サーバーはclaude mcp listや/mcpに通常のユーザーサーバーとして表示されます。ccamは起動前に、各アカウントの.claude.jsonにサーバーを書き込みます。

  1. mcp.Syncが、グループのmcp.jsonの更新日時をsync-stampと比較します。変更がなければ、アカウントの.claude.jsonは開きません。
  2. Claude Code自身のロックを取得します。これはファイルの隣にある.claude.json.lockというフォルダーで、mkdirで作成します。最大2秒待ち、Claude Codeのロックライブラリと同じく、10秒より古いロックは古くなったものとして扱います。
  3. 現在の.claude.jsonを状態フォルダーのbackups/に保存し、新しいものを5つ残します。
  4. mcpServersにグループのすべてのサーバーを設定し、以前に自分が書き込んだサーバーのうちグループにもうないものを削除し、アカウント自身のサーバーは残して、元のモードのままファイルをアトミックに書き込みます。
  5. 新しいスタンプと、自分が管理するサーバー名を記録します。Claude Codeは--mcp-configなしで起動します。

アカウントのセッションが実行中の場合は、ccam: account work is already running, skipping MCP syncと表示して同期をスキップします。Claude Codeは実行中に.claude.jsonを書き換えるためです。同期に失敗するとccam: MCP sync failed (launching anyway): …と表示され、そのまま起動します。セッション内で追加したサーバーのヒントは、フラグ戦略だけの機能です。

ccam mcp importは、アカウント自身のサーバーをそのグループに移動します。

ccamはmcp.LocalServersでアカウントのサーバーを読み、mcp.SameDefを使って、それぞれをグループの同じ名前のサーバーと比較します。この比較は、キーの順序や空白を無視します。グループにないサーバーと、グループに同じ定義で存在するサーバーはコピーされます。定義が異なるサーバーはスキップされます。グループの定義は、ほかのすべてのアカウントが使っているためです。

Skipped gh: group default already has a different gh (`ccam mcp import work gh --force` replaces it)
✓ Copied to group default: pg
✓ Removed account work's own entries (.claude.json backed up)

--forceを付けるとグループのサーバーが置き換えられ、以前のmcp.jsonは先にグループのフォルダー内の.ccam-backup/<time>/mcp.jsonに保存されます。続いてmcp.RemoveLocalが、同じロックのもとで、状態フォルダーにバックアップを取った後、コピーした項目をアカウントの.claude.jsonから削除します。名前が重なるとアカウントの項目がグループのものより優先されてしまうため、この処理が必要です。--keep-localを付けると項目を残します。

安全性と特殊なケース

  • サインイン。 OAuthでサインインするサーバーは、トークンをサーバーの一覧ではなく各アカウントの.credentials.json(mcpOAuth)に保存します。そのため、サーバーを共有してもサインインは共有されません。各アカウントで一度ずつ/mcpでサインインするか、ccam migrateで~/.claudeからサインイン情報をコピーしてください。グループがログインファイルを受け取ることはありません。
  • 実行中のアカウント。 importはグループにコピーしますが、実行中のアカウント自身の項目は残し、その旨を表示します。セッションが終了した後にもう一度実行してください。同期は実行中のアカウントをスキップします。
  • Remote Control用のコピー。 実行中のアカウントのコピーには触れず、次のように表示します。Note: account side is running, so the copy in its .claude.json stays as it was until its next Remote Control launch. mcp_strategy = "sync"の場合は、起動のたびに同期するため、更新は必要ありません。
  • 壊れたファイル。 .claude.jsonが有効なJSONでない場合、同期はファイルに触れずにエラーを報告します。2秒以内にロックを取得できない場合、ccamはcould not lock … (Claude Code is writing the file)と報告します。
  • MCPを共有していないアカウント。 importは拒否し、先にccam share side --mcp onを実行するよう案内します。
  • グループ名。 -gはグループ名だけを受け取ります。名前はgroups/の下のフォルダーになるため、../xのような名前は拒否されます。