
Vaultshell
io.github.SoWhatIPublished by GitHub account SoWhatIv0.1.2Updated Oct 24, 2026
Injects secrets into shell commands at exec time; plaintext never reaches the LLM context
Overview
Local MCP server that stores secrets on your machine and injects them into shell commands at exec time, keeping plaintext out of the model context.
- What you can do
- Run one-shot shell commands with rule-based secret injection, dry-run previews, timeouts and output truncation
- Open, send to, list, close and revoke persistent shell sessions whose secrets die with the process
- Start and stop loopback credential-injecting reverse proxies that add auth headers in memory only
- List, set, delete and probe secrets in backends such as encrypted file, keychain, env, file, 1Password, Vault, Infisical and Doppler
- List and statically validate injection rules, flagging unknown secrets, unreachable or inject-everywhere rules
- Query the redacted audit log of commands, injected names and flags
- When to use it
- Useful when an assistant needs to run shell commands that require API keys or tokens but the secrets must not appear in the conversation, logs or audit records. Also fits workflows that want per-command injection, short-lived sessions or a local proxy instead of exporting credentials into the environment.
- Requirements
- Runs as a local process; Node.js 20+ for the npm/git install, or the published container image. A MASTER_KEY environment variable (64 hex characters) for the encrypted-file backend, or a macOS keychain. Config and rules files under the data directory, which VAULTSHELL_HOME can override. Optional node-pty native build for real PTY sessions; external CLI backends need their own authenticated CLIs. Desktop only.
Installation
In SourceWeft
- Open Vaultshell in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
vaultshell
English | 简体中文
Available on the official MCP Registry: io.github.SoWhatI/vaultshell
An MCP server that stores secrets in local secure storage, injects them into shell child processes at exec time based on rules, and guarantees secret plaintext never reaches the model context — not in tool responses, not in logs, not in audit records.
The closed loop: reference-based storage + conditional injection + mandatory output redaction.
Status: M3 — one-shot commands + persistent sessions + credential proxy + external CLI backends. See CHANGELOG and docs/design-spec.md.
The iron rule
- No MCP tool returns secret plaintext — ever. Responses contain only names,
masks (
[REDACTED:NAME]), and redacted output. - Resolvers are only invoked inside the launcher; values go straight into the
child process
envand never pass through the tool layer. shell_exechas no free-formenvparameter. Secrets enter by rule reference only.- Redactor failures are fail-closed: output is discarded, never returned raw.
Quick start
Requires Node.js 20+.
Install from GitHub (no npm registry account needed)
This is the same code as the npm registry package, installed from git —
npm clones the repo, runs prepare (→ npm run build) and links the
vaultshell bin. Pin a tag for reproducibility:
npx -y github:SoWhatI/vaultshell#v0.1.1.
Docker (ghcr.io)
MCP client config using Docker:
The image runs as the non-root node user (HOME=/home/node), so the data
volume mounts at /home/node/.vaultshell. node-pty is excluded from the
image — sessions automatically fall back to pipe mode (pty: false) in
containers; injection and redaction are unchanged. The web subcommand
passes through (docker run … ghcr.io/sowhati/vaultshell web — loopback
inside the container, of limited use).
No Smithery distribution: Smithery has gone hosted-only (it only accepts servers deployed to its own infrastructure). vaultshell's secrets must stay on the user's machine by design — third-party hosting is incompatible with its threat model, so we deliberately do not publish there.
From source
Claude Desktop (claude_desktop_config.json):
Full setup, configuration reference, rule-writing guide, client integration, and FAQ: docs/user-guide.md.
MCP tools
Execution limits (M3)
dryRun: trueonshell_execreports the would-beruleId,injectednames, final env key list (never values) and the deny-list verdict — without executing anything.timeoutSeconds(defaultdefaults.execTimeoutSeconds= 120, capped at 3600) kills the command and returnstimedOut: true.defaults.maxOutputBytes(default 1 MiB) truncates each output stream and setstruncated: true. Truncation happens after the Redactor — it can never bypass redaction.defaults.maxConcurrentExecs(default 8) rejects excess concurrentshell_execcalls with a clear error (no queue).- All of the above are recorded in the audit log (
dryRun/timedOut/truncatedflags).
Web config UI
Prints a one-time-token URL like http://127.0.0.1:5317/?token=… — open it
to manage secrets (write-only), edit rules with live static-validation
warnings and a matcher dry-run, edit config, and browse the redacted audit
log. The token dies with the process; every API call needs it, mutations
require same-origin application/json requests, and no endpoint can ever
return a secret value. Do not port-forward it. Design & threat model:
docs/web-config-ui-design.md.
Credential proxy (M3)
For high-sensitivity API tokens, prefer not landing the secret in env at
all. Declare a proxy in config.yaml:
Then shell_proxy_start { "id": "stripe" } → { port, expiresAt }, and
commands call http://127.0.0.1:<port>/v1/charges instead of
https://api.stripe.com/v1/charges. The proxy injects the header in
memory only and auto-stops after its TTL (default 300s). Audit records the
host and secret name, never the header value.
Boundaries: http:///https:// upstreams only (proxy→upstream TLS is
properly validated; no CONNECT tunneling, no TLS termination); the
client→proxy leg is plaintext on 127.0.0.1, which inherits the same-UID
local-process boundary from the threat model.
Persistent sessions (M2)
shell_session_open spawns a long-lived shell with the matched rule's
secrets injected at creation. The session is recycled after an idle TTL
(defaults.sessionTtlSeconds, default 900s, overridable per rule via
ttlSeconds or per call) — when the process dies, the secrets die with it.
shell_session_revoke kills a possibly-compromised session immediately and
rebuilds one without any secrets.
Sessions use a real PTY via node-pty
(an optional dependency — native build, needs Xcode CLT on macOS /
build-essential + python3 on Linux). If node-pty cannot be loaded or spawned,
vaultshell automatically falls back to a plain child_process shell and the
shell_session_open response says pty: false; injection and redaction
behave identically, only interactivity is degraded. Session output merges
stdout/stderr (PTY semantics) and passes through the same Redactor.
Backend support matrix
Details, per-backend setup, and how to register a plugin resolver: docs/backends.md.
Threat model
Full discussion: docs/design-spec.md §7. Report vulnerabilities privately per SECURITY.md.
Data layout
VAULTSHELL_HOME overrides the data directory (used by tests).
Development
See CONTRIBUTING.md — including the security red lines every PR must respect.
License
MIT © 2026 vaultshell contributors
Source: README.md at commit b4a2017
Tools
0Version history
1- v0.1.2LatestSep 30, 2026
Score
50% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts