Start

Safely manage the secrets your agent uses without .env files, shell history, or chat leaks. Stored in your macOS Keychain.

Migrate every key=value pair from a .env file straight into Keychain.

~/projects/myapp
mxkey migrate --delete .env.local myapp
Found 4 key(s): STRIPE_SECRET_KEY (33 chars) DATABASE_URL (46 chars) OPENAI_API_KEY (41 chars) RESEND_API_KEY (25 chars) Migrate all of these under project.myapp.* ? [y/N] y set project.myapp.stripe_secret_key (STRIPE_SECRET_KEY) set project.myapp.database_url (DATABASE_URL) set project.myapp.openai_api_key (OPENAI_API_KEY) set project.myapp.resend_api_key (RESEND_API_KEY) migrated 4 / 4 secrets. skipped: 0 project.myapp now contains 4 secret(s). wrote .env.mxkey. deleted .env.local.
Agent

Drop the SKILL.md into Claude Code, Cursor, or Codex and the agent learns every secret-handling behavior on this page.

~/projects/myapp
ln -sfn ~/GitHub/mxkey ~/.claude/skills/mxkey
# Skill loaded. Claude now triggers mxkey for any # .env, hardcoded key, or pasted secret it sees.

When the agent spots a .env in your project, it offers to migrate the contents into Keychain — without you asking.

Claude
I see .env.local with 4 keys (Stripe, OpenAI, Resend, Postgres). Want me to migrate them into Keychain under project.myapp.* and delete the file?
You
yes
Claude
Migrated 4 secrets. Wrote .env.mxkey. Deleted .env.local. Your dev command now uses mxkey run-here -- pnpm dev.

If you paste a secret into chat, the agent refuses to act on it and tells you to rotate first — never stores or echoes the value.

You
save this openai key for me: sk-proj-abc123def456ghi789...
Claude
That looks like a live API key. Because it's now in this conversation, rotate it at OpenAI first. Then run mxkey set api.openai OPENAI_API_KEYand type the new value at the hidden prompt — it won't enter the chat.

When the agent sees a hardcoded API key in source code, it warns before any commit and suggests the safe pattern.

Claude
I noticed src/api.ts has a hardcoded Stripe key on line 12. Don't commit this — store it with mxkey set api.stripe STRIPE_SECRET_KEY and read it via process.env.STRIPE_SECRET_KEY instead. Want me to rewrite the file?

The agent rewrites your dev commands so they load secrets from Keychain via mxkey run, not from .env files on disk.

~/projects/myapp
# Before: pnpm dev # reads from .env.local # After (agent suggested): mxkey run-here -- pnpm dev
> Server listening on :3000 # Same env vars, no .env file needed.
Save & run

Save a secret to Keychain at a hidden prompt — never echoed, never logged, never written to disk.

~/projects/myapp
mxkey set api.openai OPENAI_API_KEY
Value for mxkey.api.openai (input hidden): set mxkey.api.openai (OPENAI_API_KEY)

Run any command with named secrets injected as environment variables — values never appear in argv or shell history.

~/projects/myapp
mxkey run api.openai -- curl https://api.openai.com/v1/models
{"object":"list","data":[...]}

List every stored secret name, optionally filtered by group prefix — values stay in Keychain and are never printed.

~/projects/myapp
mxkey list project.myapp
NAME ENV_VAR ---------------------------------------- ------------------------------ project.myapp.database_url DATABASE_URL project.myapp.openai_api_key OPENAI_API_KEY project.myapp.resend_api_key RESEND_API_KEY project.myapp.stripe_secret_key STRIPE_SECRET_KEY
Project groups

Write a .env.mxkey manifest listing every secret a project needs — names only, no values, safe to commit.

~/projects/myapp
mxkey init project.myapp
wrote .env.mxkey with 4 name(s): project.myapp.stripe_secret_key project.myapp.database_url project.myapp.openai_api_key project.myapp.resend_api_key

Walk up to the nearest .env.mxkey and run a command with every listed secret loaded — works from any subfolder.

~/projects/myapp/services/api
mxkey run-here -- pnpm dev
> myapp@1.0.0 dev > next dev ▲ Next.js 16.2.4 - Local: http://localhost:3000 - Ready in 372ms
Safety

Save a secret with macOS authentication required on every read — Touch ID for prod DBs, billing keys, and anything where silent theft would hurt.

~/projects/myapp
mxkey set --require-auth db.prod-postgres DATABASE_URL
Value for mxkey.db.prod-postgres (input hidden): set mxkey.db.prod-postgres (DATABASE_URL) — requires authentication on every read

Store 2FA recovery codes one per line, then atomically print-and-delete the next available code on demand so a code can never be re-used.

~/projects/myapp
mxkey backup use github
abc1-2def-3ghi consumed backup.github.1; 7 code(s) remaining

Stop committing secrets.

macOS only. Single bash script. Bundled agent skill.

github →docs →