StackMap
Subscribe
Explore / claude-secrets
vaultry

claude-secrets

Encrypted secrets store for Claude Code: macOS-Keychain-backed vault with MCP server, CLI, commit-safe secret:// .env placeholders and a native input dialog.

6 2 JavaScript NOASSERTIONupdated 3 months ago
Curator's take

Fixes a real leak: tokens pasted into chat live forever in transcripts and API logs — here they go dialog-to-Keychain-vault without the model ever seeing them, gated per-project by an allowlist. macOS-only, source-available (not OSI), 6 stars: adopt as a personal utility, not team infrastructure.

Mapped by ShipWithAI editors · links verified
README.md

Claude Secrets

@vaultry/claude-secrets

Encrypted token store for Claude Code sessions and your shell/apps. macOS Keychain backed · MCP server · CLI · .env placeholder expansion.

npm version npm downloads license platform node

Stop pasting tokens into every new Claude session. Store them once, reference them everywhere — including commit-safe .env files.


Quick install (one line)

curl -fsSL https://raw.githubusercontent.com/vaultry/claude-secrets/main/install.sh | bash

Or via npm:

npm install -g @vaultry/claude-secrets
claude-secrets-setup
claude mcp add claude-secrets --scope user -- claude-secrets-mcp

Three interfaces

Interface Who uses it Policy-gated
MCP server Claude Code sessions Yes (per-project allowlist)
CLI claude-secrets Your shell, apps, scripts No (user has Keychain access)
.env placeholders Any tool that reads .env Via CLI

Store secrets

Store demo

Pipe from stdin (keeps the value out of shell history):

echo "ghp_xxxxx" | claude-secrets set GITHUB_TOKEN
op read "op://Private/Gitea/token" | claude-secrets set GITEA_TOKEN
claude-secrets set DB_PASSWORD              # interactive — type, Ctrl-D

Encrypted with AES-256-GCM, master key stored in macOS Keychain (syncs between Macs via iCloud Keychain).


Commit-safe .env files

dotenv demo

Replace real values with secret://NAME references. The .env file can now be committed to git safely — it contains only names, no credentials.

# .env
API_KEY=secret://GITHUB_TOKEN
DB_URL=postgres://app:secret://DB_PASSWORD@db.local/app
PORT=3000

Placeholder syntax: secret://NAME — URI-style, avoids bash parameter-expansion collisions. Names can contain A-Z, 0-9, _, ., -.


Expand placeholders

export demo

Resolve placeholders to real values at runtime:

eval "$(claude-secrets export)"                    # into current shell
claude-secrets export --format json > resolved.json
claude-secrets export --format dotenv > .env.resolved

claude-secrets export --file .env.staging         # different file
claude-secrets export --on-missing empty          # empty for missing refs
--on-missing Behavior
throw (default) Exit 1 with list of missing names
empty Placeholder becomes empty string
keep Placeholder left literal (secret://NAME)

Run a command with secrets

exec demo

claude-secrets exec -- pnpm dev                    # inject then run
claude-secrets exec -- node build.js
claude-secrets exec --file .env.prod -- npm run deploy

Secrets live only in the child process — not in the parent shell's environment, history, or ps output.

package.json scripts work seamlessly:

{
  "scripts": {
    "dev": "claude-secrets exec -- ts-node src/index.ts",
    "test": "claude-secrets exec --file .env.test -- vitest",
    "deploy": "claude-secrets exec --file .env.prod -- node deploy.js"
  }
}

MCP server (for Claude Code)

After registering with claude mcp add, Claude Code gets 6 tools under mcp__claude-secrets__*:

| Tool | Policy