Local-first .env and secrets manager, MCP-native from day one.
Secrets live in an encrypted SQLite vault on your machine, never on a server. Values are encrypted with AES-256-GCM under a key hierarchy rooted in your master password (Argon2id). Decryption happens locally, and plaintext reaches a target process through exactly one path, a hardened Rust runner loaded over FFI. An MCP server exposes the vault to AI coding agents (Claude Code, Cursor, Codex, Zed, OpenCode, Claude Desktop) without secret values ever entering the model's context window.
vaulted init create a vault and project
vaulted import .env move your .env into the vault
vaulted run -- npm run dev run with secrets injected
vaulted tui browse and edit secrets in an interactive UI
vaulted mcp agent surface for Claude Code, Cursor, Codex, ...
curl -fsSL https://raw.githubusercontent.com/woosal1337/vaulted/main/scripts/install.sh | shThe script picks the tarball for your platform from the latest GitHub Release, verifies its SHA-256 checksum, and installs to ~/.local/bin. To install manually, download vaulted-<tag>-<platform>-<arch>.tar.gz from the release page and extract it onto your PATH. Each tarball contains the standalone vaulted binary and the Rust runner library in prebuilds/<platform>-<arch>/.
Prebuilt binaries: macOS Apple Silicon (arm64) and Linux (x64, arm64). Intel macOS (x64) builds from source. Windows is out of scope for 1.0.
Requires Bun and a Rust toolchain (cargo).
git clone https://github.com/woosal1337/vaulted
cd vaulted
bun install
bun run build:runner # cargo build --release for packages/runner
bun run --cwd apps/cli build # compiles apps/cli/dist/vaultedOr run straight from source with bun apps/cli/src/index.ts.
Initialize a vault in your project directory. This creates the encrypted SQLite vault at ~/.config/vaulted/vaulted.db, a project with development, staging, and production environments, and a vaulted.toml that pins the project and default environment for this directory:
cd my-app
vaulted init # prompts for a master password, saves it to the OS keychainMove your existing .env into the vault:
vaulted import .envWork with individual secrets:
vaulted set STRIPE_KEY # hidden prompt for the value
vaulted set DEBUG false
vaulted get STRIPE_KEY # raw value to stdout, pipeable
vaulted list # names, scopes, and types, never values
vaulted list --reveal # decrypted values, auditedRun your app with secrets injected. The command executes through the hardened Rust runner with a cleaned environment, so your .env file can be deleted:
vaulted run -- npm run dev
vaulted run -e production -- ./deploy.shExpose the vault to your coding agent:
claude mcp add vaulted -- vaulted mcp| Command | Description |
|---|---|
vaulted init [--name <project>] |
Create the vault, a project, default environments, and vaulted.toml |
vaulted unlock |
Verify the master password and save it for later commands |
vaulted lock |
Clear the stored master password (keychain entry and password file) |
vaulted set KEY [value] [-e env] [--scope s] [--folder f] |
Add or update a secret, hidden prompt or stdin when the value is omitted |
vaulted get KEY [-e env] [--folder f] |
Print a secret value to stdout, pipeable, nothing else on stdout |
vaulted list [-e env] [--folder f] [--reveal] |
List secret names, scopes, and value types, values only with --reveal |
vaulted rm KEY [-e env] [--folder f] |
Remove a secret (soft delete) |
vaulted import <file> [-e env] [--overwrite|--skip] |
Import secrets from a dotenv file |
vaulted export [-e env] [-o file] [--force] |
Reconstruct a dotenv file from an environment, audited |
vaulted run [-e env] [--folder f] -- <cmd> [args...] |
Run a command with decrypted secrets injected via the hardened runner |
vaulted projects list|create <name> |
Manage projects |
vaulted envs list|create <name> |
Manage environments for the current project |
vaulted rotate |
Rotate the project key and re-encrypt every secret |
vaulted tui |
Open an interactive terminal UI to browse and edit secrets (keyboard and mouse) |
vaulted mcp |
Start the MCP stdio server |
Every command defaults to the project and environment pinned by the vaulted.toml discovered by walking up from the current directory, like git.
vaulted mcp serves five tools over stdio. Four are read-only (status, list-projects, list-secrets, get-current-project) and return names and metadata, never values. The fifth, run-with-secrets, executes a command through the same hardened Rust runner as vaulted run and redacts the injected secret values from the captured output before returning it.
claude mcp add vaulted -- vaulted mcpConfiguration snippets for Cursor, Codex, Zed, OpenCode, and Claude Desktop, plus the full tool reference and security model, live in docs/mcp.md. Run vaulted unlock once before agent use, the server never prompts.
The master password derives an AES-256-GCM master key via Argon2id (64 MiB, 3 iterations, 4 lanes). That key encrypts an RSA-2048 private key, which unwraps per-project AES-256-GCM keys, which encrypt secret values. Only ciphertext values touch disk (key names are plaintext, needed for listing), the database and password file are 0600, and there is no password recovery by design. The Rust runner disables core dumps, clears the child environment down to a 10-variable allowlist plus the injected secrets, zeroizes secret buffers, and never writes to disk. Every reveal, export, run, and MCP access lands in a local audit log. The full model, including what Vaulted deliberately does not defend against, is in docs/security.md.
bun install
bun run lint # oxlint
bun run typecheck # tsc --noEmit
bun run test # bun test (all TypeScript packages + CLI e2e)
bun run test:rust # cargo test for packages/runner
bun run build # runner dylib + standalone CLI binaryPackage API contracts are pinned in CONTRACTS.md, design rationale in docs/architecture.md.
MIT, see LICENSE.
