MCP サーバーに鍵を安全に渡す設定
4 分で読む
AI エージェントは、MCP サーバーを使うと、kintone や freee などの外のサービスのデータを読んだり書いたりできます。MCP サーバーは、AI エージェントが起動する別のプログラムで、外のサービスに接続するために、鍵(API キーやアクセストークン)を受け取ります。MCP そのものは MCP とは何か で説明しています。
このページは、MCP サーバーに鍵を渡すときに、その MCP サーバーに要る鍵だけを届け、ほかの鍵を届けない設定のしかたです。
MCP サーバーに鍵が届く 3 つの道
鍵は、多くの場合、環境変数で MCP サーバーに渡します。環境変数は、プログラムを起動するときにプログラムに渡される「名前」と「中身(文字列)」の組です。編集部は 2026 年 10 月に、Claude Code・Codex・Antigravity の CLI で、MCP サーバーにどの環境変数が届くかを測りました。MCP サーバーに鍵が届く道は、次の 3 つでした。
| 鍵が届く道 | 測った結果 |
|---|---|
| AI エージェントの環境変数を受け継ぐ | Claude Code と Antigravity の CLI は、初期設定で、自分の環境変数を全部 MCP サーバーに渡した。Codex は、決まった 11 個の名前の環境変数と、設定で名前を書いた環境変数だけを渡した |
MCP の設定ファイルの env |
設定ファイルの env に書いた鍵は、3 つの AI エージェントのどれでも MCP サーバーに届いた。鍵の中身は、設定ファイルに文字のまま保存された |
AI エージェントの設定ファイルの env |
Claude Code の設定ファイル(settings.json)の env に書いた鍵は、Claude Code が起動するすべてのプログラムに届く Claude Code Docs(Settings reference)原文Values here are plain text in the settings file and reach every subprocess Claude Code starts.出典を開く確認 2026-10-18 |
1 つ目の道があるので、パソコンの環境変数に鍵を入れたまま Claude Code や Antigravity の CLI を起動すると、その鍵は、その鍵を使わない MCP サーバーにも届きます。
要る鍵だけを届ける 4 つの決まり
| 決まり | 理由 |
|---|---|
| ① MCP の設定ファイルには、鍵の中身を書かず、環境変数の名前で参照する | 設定ファイルは文字のまま保存され、プロジェクトの設定ファイルは git でほかの人と共有されることがある |
| ② AI エージェントを起動するときに、作業に要る環境変数だけを渡す | MCP サーバーが AI エージェントの環境変数を受け継ぐ道を、渡す時点で絞る |
| ③ MCP サーバーに受け継がせる環境変数を絞る設定を入れる | Claude Code は設定で絞れる。Codex は初期設定で絞られている。Antigravity の CLI には、この設定が無い |
| ④ 使う MCP サーバーだけを、使うプロジェクトにだけ登録する | 登録した MCP サーバーは、AI エージェントを起動するたびに起動される |
MCP の公式の文書も、鍵をシェルの設定ファイルで export せずに、MCP サーバーごとに渡すよう勧めています。 出典を開く確認 2026-10-18Model Context Protocol Docs(Local Server Security)原文
Use the per-server environment configuration in your client's config file rather than exporting secrets in your shell profile, so each server sees only its own credentials.
鍵の要らない MCP サーバーを選べば、渡す鍵そのものが減ります。編集部が公開している MCP サーバーは読み取り専用で、鍵を受け取らない作りです(編集部の MCP は何を開き何を閉じるか)。
製品ごとの設定
| AI エージェント | ① 鍵を名前で参照する書き方 | ③ MCP サーバーに受け継がせる環境変数を絞る設定 |
|---|---|---|
| Claude Code | MCP の設定ファイルの env に "${EXAMPLE_API_KEY}" と書く |
起動するときに CLAUDE_CODE_MCP_ALLOWLIST_ENV=1 を渡す |
| Codex | Codex の設定ファイルの env_vars に "EXAMPLE_API_KEY" と書く |
初期設定で絞られている |
| Antigravity の CLI | 書き方が無い。MCP サーバーを起動するコマンドの中で、鍵を読み込む | 設定が無い。起動するときに env -i で絞る |
EXAMPLE_API_KEY は、例として付けた環境変数の名前です。設定ファイルの例と、MCP サーバーに届いた環境変数の確かめ方は、調査の詳細 にあります。
チェック
| 確かめること | 詳しく |
|---|---|
| MCP の設定ファイルに、鍵の中身を書いていないか | 設定ファイル |
| プロジェクトの設定ファイルを git で共有する前に、鍵の中身が入っていないことを確かめたか | 設定ファイル |
| AI エージェントを、作業に要る環境変数だけを渡して起動しているか | Claude Code・Codex・Antigravity の CLI |
| 使っていない MCP サーバーを、登録から外したか | — |
| MCP サーバーに届いた環境変数の名前を、確かめ用の MCP サーバーで確かめたか | 確かめ方 |
AI エージェントを起動するときの環境変数の絞り方は AI エージェントを起動する前に に、MCP サーバーを追加してよいかの確かめ方は MCP サーバーを追加する前に、何を確かめるか にあります。
ここから先は調査の詳細です(約 17 分)。上のカードだけで決められます。調べた 1 件ずつの記録は IT連携マップ に、出典 URL と調査日つきで公開しています。
調査の詳細
このページの設定は、編集部が 2026 年 10 月 18 日に、Claude Code 2.1.251・Codex 0.162.1・Antigravity の CLI 1.4.1 で、このページのとおりに書いて動かし、MCP サーバーに届いた環境変数の名前を確かめたものです。鍵には、ダミーの文字列を使いました。どの AI エージェントが、どの環境変数を MCP サーバーに渡すかの測定と、MCP の仕様・各社の文書・ソースコードとの照合は、AI エージェントを起動する前に の調査の詳細にあります。
MCP の設定ファイルは、どこにあり、どう書くか
MCP の設定ファイルは、AI エージェントが MCP サーバーを起動するときの、コマンド、コマンドに渡す引数、環境変数を書くファイルです。
| AI エージェント | 設定ファイルの場所 | 形式 | 登録するコマンド |
|---|---|---|---|
| Claude Code | プロジェクトで共有する設定は、プロジェクトのフォルダの .mcp.json。自分だけの設定は ~/.claude.json |
JSON | claude mcp add・claude mcp add-json |
| Codex | ~/.codex/config.toml |
TOML | コマンドを使わず、ファイルを書く |
| Antigravity の CLI | ~/.gemini/config/mcp_config.json |
JSON | agy mcp add |
claude mcp add の --env と agy mcp add の --env は、渡した鍵の中身を、設定ファイルに文字のまま書き込みます。たとえば、次のコマンドを実行すると、.mcp.json に鍵の中身が書き込まれます(編集部が確かめました)。この書き方は使いません。
# 使わない書き方: 鍵の中身が .mcp.json に文字のまま書き込まれる
claude mcp add example --scope project --env EXAMPLE_API_KEY=鍵の中身 -- node server.js
編集部のパソコンでは、.mcp.json と ~/.gemini/config/mcp_config.json は、同じパソコンのほかの利用者も読める権限(644)、~/.claude.json と ~/.codex/config.toml は、自分だけが読める権限(600)で保存されていました。.mcp.json は、プロジェクトのフォルダに置かれるので、git でほかの人と共有されることもあります。
Claude Code で、MCP サーバーに要る鍵だけを渡す
手順は 4 つです。
1 つ目に、鍵を、macOS のキーチェーン(パスワードを保存する macOS の機能)に保存します。-w を最後に置くと、鍵の中身を入力するよう聞かれるので、そこで入力します。鍵の中身をコマンドに書かないので、コマンドの記録(履歴)に鍵の中身が残りません。
security add-generic-password -a "$USER" -s example-api-key -w
2 つ目に、MCP サーバーを、鍵の環境変数の名前で登録します。
cd ~/work/project # MCP サーバーを使うプロジェクトのフォルダに移る
claude mcp add-json example '{"type":"stdio","command":"node","args":["server.js"],"env":{"EXAMPLE_API_KEY":"${EXAMPLE_API_KEY}"}}' --scope project
${EXAMPLE_API_KEY} を単引用符(')の中に書くのは、シェルが先に ${EXAMPLE_API_KEY} を鍵の中身に置き換えないようにするためです。このコマンドで、.mcp.json に次の内容が書き込まれます。鍵の中身は書き込まれません。
{
"mcpServers": {
"example": {
"type": "stdio",
"command": "node",
"args": [
"server.js"
],
"env": {
"EXAMPLE_API_KEY": "${EXAMPLE_API_KEY}"
}
}
}
}
3 つ目に、作業に要る環境変数だけを渡して、Claude Code を起動します。
env -i HOME="$HOME" USER="$USER" LANG="$LANG" TERM="$TERM" PATH="$PATH" \
CLAUDE_CODE_MCP_ALLOWLIST_ENV=1 \
EXAMPLE_API_KEY="$(security find-generic-password -a "$USER" -s example-api-key -w)" \
claude
env -iは、環境変数を空にしてから、後ろに並べた環境変数だけを渡して claude を起動します。CLAUDE_CODE_MCP_ALLOWLIST_ENV=1は、Claude Code が自分の環境変数を MCP サーバーに受け継がせず、最低限の環境変数と、MCP の設定ファイルのenvだけを MCP サーバーに渡す設定です Claude Code 鍵(API キー)の扱い 。$(security find-generic-password … -w)は、キーチェーンから鍵の中身を取り出して、EXAMPLE_API_KEY に入れます。鍵の中身は画面に表示されません。- Claude Code は、.mcp.json の
${EXAMPLE_API_KEY}を、起動したときに渡された EXAMPLE_API_KEY の中身に置き換えて、MCP サーバーに渡します。EXAMPLE_API_KEY を渡さずに起動すると、${EXAMPLE_API_KEY}という文字がそのまま MCP サーバーに渡ります。 - 対話の画面で起動すると、Claude Code は、プロジェクトの設定ファイルの MCP サーバーを使ってよいかを聞きます Claude Code MCP サーバーを追加するときの注意 。
4 つ目に、MCP サーバーに届いた環境変数を確かめます。確かめ用の MCP サーバー を同じ設定で登録して起動すると、次の名前が記録されました(2026 年 10 月 18 日、Claude Code 2.1.251)。EXAMPLE_API_KEY は届き、起動するときに一緒に渡したダミーの鍵(OTHER_SERVICE_TOKEN)と LANG は届きませんでした。
CLAUDECODE
CLAUDE_CODE_SESSION_ID
CLAUDE_PROJECT_DIR
EXAMPLE_API_KEY
HOME
PATH
TERM
USER
__CF_USER_TEXT_ENCODING
Codex で、MCP サーバーに要る鍵だけを渡す
1 つ目に、鍵を、Claude Code の手順 の 1 つ目と同じコマンドで、キーチェーンに保存します。
2 つ目に、Codex の設定ファイル(~/.codex/config.toml)に、MCP サーバーを書きます。
[mcp_servers.example]
command = "node"
args = ["server.js"]
env_vars = ["EXAMPLE_API_KEY"]
出典を開く確認 2026-10-18env_vars は、Codex の環境変数のうち、MCP サーバーに渡してよい環境変数の名前を並べる項目です。OpenAI Codex Docs(Model Context Protocol)原文
Environment variables to allow and forward.
env_vars に名前を書いたものだけが MCP サーバーに届きます。
3 つ目に、同じ設定ファイルに、Codex が実行するコマンド(スクリプトなど)に渡す環境変数も書きます。Codex は、初期設定で、Codex が実行するコマンドに環境変数を全部渡し、名前に KEY・SECRET・TOKEN を含む環境変数も取り除きません Codex(OpenAI) 鍵(API キー)の扱い 。さらに、Codex は作業の始めに ~/.zshrc を読み込み、そこで export された環境変数も、Codex が実行するコマンドに渡します(測定)。
[shell_environment_policy.filters]
"PATH" = "include"
"HOME" = "include"
"USER" = "include"
"LANG" = "include"
"TERM" = "include"
"EXAMPLE_API_KEY" = "include"
出典を開く確認 2026-10-18filters に "include" と書いた名前の環境変数だけが、Codex が実行するコマンドに渡ります。OpenAI Codex Docs(Configuration Reference)原文
Include entries create an allowlist and can't restore excluded values.
~/.zshrc で export された環境変数にも、この絞り込みが効きました。Codex が実行するコマンドが鍵を使わないなら、"EXAMPLE_API_KEY" の行は書きません。
4 つ目に、作業に要る環境変数だけを渡して、Codex を起動します。
env -i HOME="$HOME" USER="$USER" LANG="$LANG" TERM="$TERM" PATH="$PATH" \
EXAMPLE_API_KEY="$(security find-generic-password -a "$USER" -s example-api-key -w)" \
codex
確かめ用の MCP サーバーを同じ設定で登録して起動すると、MCP サーバーには次の名前が記録されました(2026 年 10 月 18 日、Codex 0.162.1)。起動するときに一緒に渡したダミーの鍵(OTHER_SERVICE_TOKEN)は届きませんでした。Codex が実行したスクリプトにも、OTHER_SERVICE_TOKEN と、.zshrc に書いたダミーの環境変数(測定では、一時ディレクトリに置いた .zshrc を読ませた)は届きませんでした。
EXAMPLE_API_KEY
HOME
LANG
PATH
TERM
USER
__CF_USER_TEXT_ENCODING
Antigravity の CLI で、MCP サーバーに要る鍵だけを渡す
Antigravity の文書は、MCP の設定ファイルの 出典を開く確認 2026-10-18env を、stdio で動く MCP サーバーのプロセスに渡す環境変数と説明しています。Google Antigravity Docs(MCP)原文
Environment variables for the `stdio` server process.
~/.gemini/config/mcp_config.json)の env に ${EXAMPLE_API_KEY} と書いても、Antigravity の CLI 1.4.0 は鍵の中身に置き換えず、${EXAMPLE_API_KEY} という文字をそのまま MCP サーバーに渡しました(測定)。
そこで、MCP サーバーを起動するコマンドの中で、キーチェーンから鍵を読み込みます。鍵は、Claude Code の手順 の 1 つ目と同じコマンドで、キーチェーンに保存しておきます。
agy mcp add example -- /bin/sh -c 'EXAMPLE_API_KEY="$(security find-generic-password -a "$USER" -s example-api-key -w)" exec node server.js'
/bin/sh -c '…'は、単引用符の中のコマンドを、シェルに実行させます。Antigravity の CLI は、MCP サーバーを起動するたびに、このコマンドを実行します。- このコマンドは、キーチェーンから鍵の中身を取り出して EXAMPLE_API_KEY に入れ、
execで MCP サーバー(node server.js)を起動します。鍵の中身は、この MCP サーバーの環境変数にだけ入り、設定ファイルには書き込まれません。 - 設定ファイルには、
"command": "/bin/sh"と、-cの後ろのコマンドの文字だけが書き込まれました。
Antigravity の CLI は、自分の環境変数を全部 MCP サーバーに渡すので、Antigravity の CLI を起動するときも、作業に要る環境変数だけを渡します。$USER は、キーチェーンの鍵を探すときに使うので、渡す環境変数に入れます。
env -i HOME="$HOME" USER="$USER" LANG="$LANG" TERM="$TERM" PATH="$PATH" agy
確かめ用の MCP サーバーを同じ書き方で登録して起動すると、MCP サーバーには次の名前が記録されました(2026 年 10 月 18 日、Antigravity の CLI 1.4.1)。EXAMPLE_API_KEY は、キーチェーンから読み込まれて届きました。この回は、Antigravity の CLI を起動するときにダミーの鍵(OTHER_SERVICE_TOKEN)も渡したので、OTHER_SERVICE_TOKEN も MCP サーバーに届きました。Antigravity の CLI に渡した環境変数は、MCP サーバーにも届くということです。
EXAMPLE_API_KEY
HOME
LANG
OTHER_SERVICE_TOKEN
PATH
PWD
SHLVL
TERM
USER
__CF_USER_TEXT_ENCODING
遠隔の MCP サーバーに鍵を渡す
遠隔の MCP サーバーは、AI エージェントが起動するのではなく、インターネットの向こうで動いている MCP サーバーです。AI エージェントは、鍵を HTTP のヘッダー(Authorization)に入れて、遠隔の MCP サーバーに送ります。
Claude Code では、ヘッダーにも ${…} で環境変数の名前を書けます。
claude mcp add-json remote-example '{"type":"http","url":"https://example.com/mcp","headers":{"Authorization":"Bearer ${EXAMPLE_API_KEY}"}}' --scope project
Codex では、 出典を開く確認 2026-10-18bearer_token_env_var に、鍵が入っている環境変数の名前を書きます。OpenAI Codex Docs(Model Context Protocol)原文
Environment variable name for a bearer token to send in Authorization
[mcp_servers.remote-example]
url = "https://example.com/mcp"
bearer_token_env_var = "EXAMPLE_API_KEY"
編集部は、手元のパソコンで動かした遠隔の MCP サーバー(127.0.0.1)を使って、Claude Code と Codex が、EXAMPLE_API_KEY の中身を Authorization ヘッダーに入れて送ったことを確かめました。そのとき、遠隔の MCP サーバーは、ヘッダーが期待どおりかどうかだけを記録し、鍵の中身は記録していません。
Antigravity の文書の設定ファイルの例は、遠隔の MCP サーバーの headers に、鍵の中身を直接書いています。Antigravity の CLI で、利用者の設定ファイルの headers に ${…} と書いたときに置き換えられるかは、測っていません。
確かめ用の MCP サーバー
次のプログラムは、起動したときに受け取った環境変数の名前だけを、同じフォルダの mcp-env-names.txt に書く MCP サーバーです。環境変数の中身は書きません。ツールは持たないので、AI エージェントから使われることはありません。
// 確かめ用の MCP サーバー: 起動したときに受け取った環境変数の「名前」だけを、ファイルに書く(中身は書かない)
import { writeFileSync } from 'node:fs';
import { createInterface } from 'node:readline';
const names = Object.keys(process.env).sort();
writeFileSync(new URL('./mcp-env-names.txt', import.meta.url), names.join('\n') + '\n');
const send = (message) => process.stdout.write(JSON.stringify(message) + '\n');
createInterface({ input: process.stdin }).on('line', (line) => {
const m = JSON.parse(line);
if (m.id === undefined) return; // 通知には返事をしない
if (m.method === 'initialize') {
send({ jsonrpc: '2.0', id: m.id, result: { protocolVersion: m.params.protocolVersion, capabilities: { tools: {} }, serverInfo: { name: 'env-names', version: '1.0.0' } } });
} else if (m.method === 'tools/list') {
send({ jsonrpc: '2.0', id: m.id, result: { tools: [] } });
} else {
send({ jsonrpc: '2.0', id: m.id, error: { code: -32601, message: 'not supported' } });
}
});
使い方は 3 つの手順です。
1 つ目に、このプログラムを mcp-env-names.mjs という名前で、プロジェクトのフォルダに保存します。
2 つ目に、確かめたい MCP サーバーと同じ環境変数の設定で、このプログラムを登録します。Claude Code では次のコマンドです。Codex では、設定ファイルに、command を "node"、args を mcp-env-names.mjs の場所(/ から始まる形)にした項目を足します。Antigravity の CLI では、node server.js を node "$PWD/mcp-env-names.mjs" に変えて登録します。
claude mcp add-json env-names '{"type":"stdio","command":"node","args":["mcp-env-names.mjs"],"env":{"EXAMPLE_API_KEY":"${EXAMPLE_API_KEY}"}}' --scope project
3 つ目に、いつもと同じように AI エージェントを起動して、記録された名前を見ます。確かめ終わったら、登録から外します。
cat mcp-env-names.txt
claude mcp remove env-names --scope project
Antigravity の CLI では、agy mcp remove env-names で登録から外します。