Claude Media
claude mcp add-jsonでMCPサーバーをJSONのまま登録する手順

claude mcp add-jsonでMCPサーバーをJSONのまま登録する手順

claude mcp add-jsonにClaude Desktopの設定を貼るときは、mcpServersの外枠を外して中身だけを渡します。typeの補い方とstreamable-httpの扱い、失敗メッセージの読み方まで扱います。

claude mcp add-json は、MCPサーバーの設定をJSON文字列のままClaude Codeに登録するコマンドです。READMEや他のクライアント向けの手順に載っているJSONを、フラグに分解し直さずに使えます。ただし、貼る前に直す点が2つあります。mcpServers の外枠を外すことと、url だけのエントリに type を足すことです。

add-jsonの基本形は名前とJSONの2引数

構文は、サーバー名のあとにJSONを1つ渡すだけです。

claude mcp add-json <name> '<json>'

JSONには claude mcp add のフラグに相当する内容が入ります。リモートHTTPなら type と url、ヘッダーが要るなら headers、ローカルのstdioなら command と args と env です。WebSocketサーバーは claude mcp add --transport が ws を受け付けないため、.mcp.json か add-json でしか登録できません。

成功すると Added ... MCP server <name> to local config の形の1行が出ます。v2.1.295で試した出力は次のとおりです。

claude mcp add-json example '{"command":"npx","args":["-y","@example/mcp-server"]}'
# Added stdio MCP server example to local config

add との違いは、入力の形が違うだけです。保存先のスコープの選び方は同じで、省略すればlocalスコープに入り、--scope project なら .mcp.json、--scope user ならユーザー設定に書かれます。スコープの仕組みはClaude Code MCP設定ガイドで扱っています。

Claude Desktopの設定は外枠を外して渡す

他のクライアント向けの手順書には、次のような mcpServers ブロックが載っていることがよくあります。

{
  "mcpServers": {
    "example": {
      "command": "npx",
      "args": ["-y", "@example/mcp-server"]
    }
  }
}

このブロック全体を add-json に渡してはいけません。渡すのは、サーバー名の下にあるオブジェクトだけです。サーバー名は第1引数に出します。

手順

mcpServersブロックをコマンドに直す

  1. 1

    サーバー名を取り出す

    mcpServers の直下のキー(上の例なら example)が、add-json の第1引数になります。

  2. 2

    中身のオブジェクトだけをJSONにする

    {"command":"npx","args":["-y","@example/mcp-server"]} の部分です。mcpServers の外枠は付けません。

  3. 3

    シングルクォートで囲んで実行する

    JSONの中のダブルクォートをシェルに解釈させないため、全体をシングルクォートで包みます。

claude mcp add-json example \
  '{"command":"npx","args":["-y","@example/mcp-server"]}'

外枠を付けたまま渡すとどうなるかも、同じバージョンで確かめました。

claude mcp add-json bad '{"mcpServers":{"example":{"command":"npx"}}}'
# Invalid configuration: : Invalid input

どのキーが悪いのかは出ません。貼り付けて拒否されたら、まず外枠が残っていないかを疑うのが近道です。

サーバーが複数あるときは1つずつ登録する

add-json の構文は、名前1つにJSON1つです。mcpServers に複数のサーバーが並んでいる場合は、キーごとに名前と中身のオブジェクトを取り出して、コマンドを分けて実行します。チームで共有したいなら、プロジェクト直下の .mcp.json の mcpServers に書き足してコミットする方法もあります。

Desktopの設定はまとめて取り込むこともできる

Claude Desktopにすでに登録済みのサーバーが多いなら、JSONを1件ずつ貼らずに、専用のコマンドで一括して取り込めます。

claude mcp add-from-claude-desktop
claude mcp list

実行すると選択式の画面が開き、取り込むサーバーを選べます。終わったら claude mcp list で登録結果を確かめます。ユーザー設定に入れたいときは --scope user を付けます。

使い分けは次のとおりです。

場面向いているコマンド
Desktopに登録済みのサーバーをまとめて移したい向いているコマンドadd-from-claude-desktop
手順書に載っているJSONの1件だけを入れたい向いているコマンドadd-json
url だけのエントリのように、直してから入れたい向いているコマンドadd-json(type を足してから貼る)

取り込みには条件があります。対応するのはmacOSとWindows Subsystem for Linux(WSL)で、Desktopの設定ファイルは標準の保存場所から読まれます。Desktop側のサーバー名に使えない文字(スペースなど)が含まれていると、そのサーバーは取り込まれず、名前が報告されます。選んだ残りのサーバーは取り込まれます。v2.1.205より前は、最初の不正な名前で全体が止まっていました。

名前が使える形なら、Desktopと同じ名前で入ります。同じ名前のサーバーがすでにある場合は、server_1 のように数字の接尾辞が付きます。

urlだけのエントリはtypeを足さないと通らない

リモートサーバーの設定では、url だけを書いて type を省いた形をよく見かけます。Claude Codeは type のないエントリをstdioサーバーとして読みます。そのため、url があっても type がなければ設定ミスです。

add-json では、この形は登録の時点で弾かれます。v2.1.295で試した結果です。

claude mcp add-json remote1 '{"url":"https://mcp.example.com/mcp"}'
# Invalid configuration: : Invalid input
 
claude mcp add-json remote2 \
  '{"type":"http","url":"https://mcp.example.com/mcp"}'
# Added http MCP server remote2 to local config

type に入れる値は、エンドポイントの種類に合わせて選びます。

手順書に書かれているもの足す type
https:// のMCPエンドポイント足す typehttp
SSEと明記されたエンドポイント足す typesse
wss:// のエンドポイント足す typews

.mcp.json などの設定ファイルにこの形が残っている場合は、読み込み時にそのサーバーがスキップされ、MCP server "<name>" has a "url" but no "type"; add "type": "http" (or "sse" / "ws") to this entry というメッセージが出ます。v2.1.202より前は、同じ問題が command: expected string, received undefined と報告されていたため、古い記事やissueで見かけたら原因は同じです。

streamable-httpはhttpの別名として受け付けられる

MCPの仕様書は、このトランスポートを streamable-http と呼びます。サーバー側のドキュメントがそのまま "type": "streamable-http" と書いていても、書き換えは要りません。.mcp.json、~/.claude.json、claude mcp add-json では、streamable-http が http の別名として扱われます。

手元で登録して保存先を見ると、別名のまま残るわけではないことが分かりました。

claude mcp add-json remote3 \
  '{"type":"streamable-http","url":"https://mcp.example.com/mcp"}'
# Added http MCP server remote3 to local config

出力は http サーバーとして追加されたと表示します。~/.claude.json に書かれた別のサーバーの type も http でした。設定を見比べるときは、別名の違いを気にしなくて済みます。

名前の規則とシェルのエスケープ

サーバー名には、英数字、ハイフン、アンダースコアしか使えません。Desktop側の設定でスペースやドットを含むキーを使っていた場合は、名前を付け直してから登録します。

claude mcp add-json 'my server' '{"command":"npx"}'
# Invalid name my server. Names can only contain letters, numbers, hyphens, and underscores.

予約されている名前も使えません。workspace、claude-in-chrome、computer-use、Claude Preview、Claude Browser は組み込みサーバーの名前で、claude mcp add は拒否します。設定ファイルにこの名前のサーバーを書くと、読み込み時にスキップされて、名前を変えるよう警告が出ます。Desktopの設定からキーを持ってくるときは、この名前とぶつかっていないかも見ておきます。

同じ名前を別のスコープに、異なる接続先で登録した場合は、claude mcp list と /mcp に競合の警告が出ます。OAuthのサインインは接続先ごとに保存されるため、読み込まれる定義が変わると、サインインし直しが必要になります。残したい定義を決めて、ほかは claude mcp remove <name> --scope <scope> で消します。

JSONの中に認証ヘッダーなどが入ると、1行が長くなって貼り間違えやすくなります。その場合は、JSONをファイルに書いておき、コマンド置換で読み込ませる手もあります。トークンは直書きせず、環境変数の参照にしておきます。s.json の中身は次の形です(空の設定ディレクトリで登録まで通ることを確かめた例です)。

{
  "type": "http",
  "url": "${API_BASE_URL:-https://api.example.com}/mcp",
  "headers": {
    "Authorization": "Bearer ${API_KEY}"
  }
}
claude mcp add-json --scope project shared "$(cat s.json)"
# Added http MCP server shared to project config

${VAR} は設定ファイルを読み込むときに環境変数の値へ展開され、${VAR:-default} は変数が未設定のときに default を使います。v2.1.295で --scope project を付けて登録したところ、.mcp.json にも url と headers が ${...} のままの文字列で書き込まれました。コミットしてもトークン自体は載りません。展開できる場所は command、args、env、url、headers です。

stdioサーバーなら、env に環境変数の参照を置く形になります。

{
  "command": "npx",
  "args": ["-y", "@example/mcp-server"],
  "env": {
    "EXAMPLE_TOKEN": "${EXAMPLE_TOKEN}"
  }
}

こちらも add-json の第2引数にそのまま渡せます。チームで .mcp.json を共有する場合、各自のシェルに EXAMPLE_TOKEN を設定しておけば、同じファイルで動きます。

注意が2つあります。

  • 変数が未設定でデフォルトもないと、設定は読み込まれますが ${VAR} の文字列がそのまま使われ、claude mcp list に警告が出ます
  • リモートサーバーの url と headers では、ANTHROPIC_API_KEY や ANTHROPIC_AUTH_TOKEN、NPM_TOKEN のような認証情報の変数は空として扱われます。Bearer ${ANTHROPIC_AUTH_TOKEN} と書くと空のトークンが送られ、多くは401で失敗します。API_KEY のように別の名前を付けた変数に値を写して参照します

空として扱われたかどうかは、claude --debug-file /tmp/claude-debug.log で起動し、ログの中の never expanded toward a remote server を探すと分かります。401が返るときの切り分けに使えます。

OAuthの設定もJSONに含められる

事前に登録したOAuthクライアントがあるサーバーは、oauth オブジェクトをJSONに含めて渡せます。クライアントシークレットはJSONに入れず、--client-secret を別のフラグとして付けると、入力を求められます。

claude mcp add-json my-server \
  '{"type":"http","url":"https://mcp.example.com/mcp","oauth":{"clientId":"your-client-id","callbackPort":8080}}' \
  --client-secret

コールバックポートだけを固定して、クライアント登録はClaude Codeに任せることもできます。その場合は "oauth":{"callbackPort":8080} だけを書きます。

登録できたかを確かめる

登録後は claude mcp get <name> で内容と状態を見ます。

claude mcp get shared
# shared:
#   Scope: Project config (shared via .mcp.json)
#   Status: ⏸ Pending approval (run `claude` to approve)
#   Type: http

--scope project で入れたサーバーは、対話セッションで承認するまで接続されません。Pending approval はエラーではなく、承認待ちの表示です。接続に失敗しているときの再接続は/mcp reconnect allの記事が詳しく、ここでは登録の段階に絞ります。

同じ名前を同じスコープに2回登録すると、2回目は MCP server dup already exists in local config と表示されて追加されません。上書きしたいときは、先に claude mcp remove <name> を実行します。

user か local スコープの書き込みに失敗した場合は、MCP server "<name>" was not saved to ... というエラーで終了します。どちらも ~/.claude.json に保存されるため、そのファイルが読み取り専用か、サンドボックスに保護されていると起きます。ファイルを書き込み可能にするか、サンドボックスの外で同じコマンドを再実行します。v2.1.283より前は、保存に失敗しても成功と表示されていました。

つまずきの早見表

症状原因直し方
Invalid configuration: : Invalid input原因mcpServers の外枠が残っている、または url に type がない直し方外枠を外す、type を足す
Invalid name ...原因名前に使えない文字が含まれる直し方英数字・ハイフン・アンダースコアに直す
already exists in local config原因同じ名前が同じスコープにある直し方claude mcp remove で消してから登録する
was not saved to ...原因~/.claude.json に書き込めない直し方ファイルの権限かサンドボックスを見直す
Pending approval原因--scope project のサーバーを未承認直し方claude を対話で起動して承認する

まとめ

add-json に渡すのは、サーバー名と、その下のオブジェクトだけです。Claude Desktopの設定を貼るときは外枠を外し、url のエントリには type を足します。streamable-http と書かれていれば、そのまま使えます。

この記事を共有:XはてブLinkedIn