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 configadd との違いは、入力の形が違うだけです。保存先のスコープの選び方は同じで、省略すれば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
サーバー名を取り出す
mcpServersの直下のキー(上の例ならexample)が、add-jsonの第1引数になります。 - 2
中身のオブジェクトだけをJSONにする
{"command":"npx","args":["-y","@example/mcp-server"]}の部分です。mcpServersの外枠は付けません。 - 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 configtype に入れる値は、エンドポイントの種類に合わせて選びます。
| 手順書に書かれているもの | 足す 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 と書かれていれば、そのまま使えます。