You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
How the Inspector chooses a secret store is only explained in the Docker guide (docs/docker.md, "Where secrets go, and how to make them survive (#1950)"). That covers the keychain probe, the memory/file fallback, the secrets.json location, encryption with MCP_INSPECTOR_SECRET_KEY, the 0600 mode and cross-process locking.
The automatic fallback isn't specific to containers, though. In core/auth/node/secret-store-selection.ts, any host where the keychain probe fails falls back to the file store. That includes a Linux box without libsecret or a Secret Service, a headless server or SSH session with no D-Bus, and Android/Termux (#1905). None of those users would think to open a Docker guide.
What non-container users see today:
docs/environment-variables.md → "Secret store": a reference table of the three variables and one paragraph on container detection, which points back to the Docker guide for the details.
The startup banner and the settings-dialog footer, which tell them a fallback happened but not what it means or how to change it.
Proposal
Move the store-selection material out of docs/docker.md into its own user-facing guide, e.g. docs/secret-storage.md, written for every runtime:
The selection order: MCP_INSPECTOR_SECRET_STORE explicit override → keychain probe → fallback (memory in an unmounted container, file otherwise), with the same "which store do I get" table extended with host rows.
The file store: path lookup (MCP_INSPECTOR_SECRET_FILE → MCP_STORAGE_DIR → ~/.mcp-inspector), plaintext vs MCP_INSPECTOR_SECRET_KEY encryption, what happens when the passphrase changes or is lost, 0600 re-tightening, locking.
Getting a keychain back: installing libsecret moves secrets.json into the keychain on the next start (absorbFileSecretsIntoKeyring), with the keychain winning on conflict and the file deleted only if every value was copied.
Where the active store is reported: startup banner, GET /api/config, the Client Settings / Server Settings footers.
Then:
docs/docker.md keeps only what is container-specific: mount the volume to get a durable store, the upgrade chown, and passing -e MCP_INSPECTOR_SECRET_KEY. It links to the new guide for everything else.
docs/environment-variables.md "Secret store" links to the new guide instead of the Docker guide.
Add the new guide to the Documentation table in the root README.md.
Consider linking to it from the startup fallback banner (warnAboutSecretStorage) so the message tells users where to read more.
Notes
Documentation only, no behavior change. Follow-up to #1950 (PR #2076), #2082 and #2365.
This is no longer documentation-only. The only way to supply the file store's passphrase was MCP_INSPECTOR_SECRET_KEY. In a container that value is readable through docker inspect, docker exec and the process environment, and Docker and Compose secrets, which deliver a file, could not supply it at all. So this issue also covers:
MCP_INSPECTOR_SECRET_KEY_FILE: reads the passphrase from a file, with trailing line breaks stripped.
Both variables set is an error.
Missing, unreadable or empty key file: the store refuses to read or write rather than falling back to plaintext, and reports it through the existing "File (unreadable)" warning and settings footer.
Docs: a loud Docker warning that mounting the volume turns on plaintext file storage unless a key is supplied, plus a written threat model for the file store.
Problem
How the Inspector chooses a secret store is only explained in the Docker guide (
docs/docker.md, "Where secrets go, and how to make them survive (#1950)"). That covers the keychain probe, the memory/file fallback, thesecrets.jsonlocation, encryption withMCP_INSPECTOR_SECRET_KEY, the0600mode and cross-process locking.The automatic fallback isn't specific to containers, though. In
core/auth/node/secret-store-selection.ts, any host where the keychain probe fails falls back to the file store. That includes a Linux box without libsecret or a Secret Service, a headless server or SSH session with no D-Bus, and Android/Termux (#1905). None of those users would think to open a Docker guide.What non-container users see today:
docs/environment-variables.md→ "Secret store": a reference table of the three variables and one paragraph on container detection, which points back to the Docker guide for the details.Proposal
Move the store-selection material out of
docs/docker.mdinto its own user-facing guide, e.g.docs/secret-storage.md, written for every runtime:env:values) and why it is kept out ofmcp.json(Move oauthClientSecret out of mcp.json into the OS keychain #1356).MCP_INSPECTOR_SECRET_STOREexplicit override → keychain probe → fallback (memoryin an unmounted container,fileotherwise), with the same "which store do I get" table extended with host rows.MCP_INSPECTOR_SECRET_FILE→MCP_STORAGE_DIR→~/.mcp-inspector), plaintext vsMCP_INSPECTOR_SECRET_KEYencryption, what happens when the passphrase changes or is lost,0600re-tightening, locking.secrets.jsoninto the keychain on the next start (absorbFileSecretsIntoKeyring), with the keychain winning on conflict and the file deleted only if every value was copied.GET /api/config, the Client Settings / Server Settings footers.Then:
docs/docker.mdkeeps only what is container-specific: mount the volume to get a durable store, the upgradechown, and passing-e MCP_INSPECTOR_SECRET_KEY. It links to the new guide for everything else.docs/environment-variables.md"Secret store" links to the new guide instead of the Docker guide.README.md.warnAboutSecretStorage) so the message tells users where to read more.Notes
Documentation only, no behavior change. Follow-up to #1950 (PR #2076), #2082 and #2365.
Rescoped (2026-09-22): add
MCP_INSPECTOR_SECRET_KEY_FILEThis is no longer documentation-only. The only way to supply the file store's passphrase was
MCP_INSPECTOR_SECRET_KEY. In a container that value is readable throughdocker inspect,docker execand the process environment, and Docker and Compose secrets, which deliver a file, could not supply it at all. So this issue also covers:MCP_INSPECTOR_SECRET_KEY_FILE: reads the passphrase from a file, with trailing line breaks stripped.The docs-site follow-up is #2450.