AgentStack
MCP verified MIT Self-run

Phantom Secrets

mcp-ashlrai-phantom-secrets · by ashlrai

Stop AI coding agents from leaking your API keys. Local proxy + MCP that swaps real secrets for phm_ tokens — works with Claude Code, Cursor, Windsurf, and Codex.

No reviews yet
0 installs
17 views
0.0% view→install

Install

$ agentstack add mcp-ashlrai-phantom-secrets

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Phantom Secrets? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Phantom

Delegate everything to AI. Without sharing a single key.

Phantom hands every AI tool a worthless phm_ token. The local proxy injects the real key at the network layer. Full access. Zero exposure.

[](https://github.com/ashlrai/phantom-secrets/stargazers) [](https://github.com/ashlrai/phantom-secrets/actions/workflows/ci.yml) [](https://www.npmjs.com/package/phantom-secrets) [](LICENSE)

[Quick start](#quick-start) · [Why Phantom?](#why-phantom) · [MCP setup](#mcp-integration-claude-code-cursor-windsurf-codex) · Docs · phm.dev


> Watch the 45-second demo  ·  > 🛡 [Security model](SECURITY.md)  ·  > 📋 [Threat model](THREATMODEL.md)  ·  > 💬 Discussions

Why Phantom?

AI coding agents read your .env files. Once a real API key enters an LLM's context window, it leaks — via prompt injection, session logs, malicious MCP servers, or training data. GitGuardian reports AI-assisted commits leak secrets at 2× the baseline rate.

Every other secrets manager protects keys at rest and in transit. Phantom protects them in context:

  • 🔒 Real keys never enter the LLM.env contains only phm_ tokens; the proxy swaps them at the network edge.
  • 10-second setupnpx phantom-secrets init and you're protected. No accounts, no DNS, no MITM cert dance.
  • 🧰 Works with every AI tool — Claude Code, Cursor, Windsurf, Codex, GitHub Copilot. Anything that reads .env.
  • 🦀 Open source, local-first, MIT — your secrets live in your OS keychain. The optional cloud sync is end-to-end encrypted; the server only ever sees ciphertext.

Used by developers who don't want to choose between delegating to AI and not pasting their Stripe key into a chat window.

Quick Start

$ npx phantom-secrets init
# Auto-detects .env, .env.local, or .env in subdirectories
# Stores real secrets in OS keychain, rewrites .env with phantom tokens
# Auto-configures Claude Code MCP server if detected

$ phantom agent doctor
# One human-readable readiness check for AI-agent safety

$ phantom exec -- claude
# Authenticated proxy running on 127.0.0.1:54321
# AI sees phantom tokens; proxy injects real keys

Windows

The same commands work on Windows. npx phantom-secrets init installs via npm as on macOS/Linux.

After phantom start --daemon, the CLI detects your shell and prints the matching env-var syntax. For reference:

PowerShell:

$env:OPENAI_BASE_URL = "http://127.0.0.1:PORT/openai/_phantom/TOKEN/"
$env:PHANTOM_PROXY_PORT = "PORT"
$env:PHANTOM_PROXY_TOKEN = "TOKEN"

cmd.exe:

set OPENAI_BASE_URL=http://127.0.0.1:PORT/openai/_phantom/TOKEN/
set PHANTOM_PROXY_PORT=PORT
set PHANTOM_PROXY_TOKEN=TOKEN

Git Bash / WSL: use the export X=Y syntax from the main quick-start.

Notes:

  • PHANTOM_PROXY_TOKEN is the proxy session authenticator. By default, phantom exec and phantom start include it in local *_BASE_URL values as /_phantom/TOKEN/ so unmodified SDKs work. Header-aware clients can set PHANTOM_PROXY_HEADER_AUTH_ONLY=1 and send x-phantom-proxy-token: $PHANTOM_PROXY_TOKEN instead.
  • If phantom.exe fails to run with "Application Control policy has blocked this file," Windows Smart App Control is honoring the downloaded file's Mark-of-the-Web tag. One-time fix from PowerShell: Get-ChildItem "$env:USERPROFILE\.phantom-secrets\bin\*.exe" | Unblock-File.
  • The pre-commit hook installed by phantom init is a #!/bin/sh script. Native git from the command line invokes it via Git for Windows' bundled sh.exe, which is what the official Git for Windows installer ships. GUI clients (GitHub Desktop, some IDE integrations) may run with a stripped-down PATH that lacks sh.exe and silently skip the hook — for these, run commits from a terminal, or use phantom check --staged directly. CI is the durable safety net regardless.
  • Windows-on-ARM64 not yet packaged — x64 only. Tracker: #1.

How It Works

  .env file (safe to leak)          OS Keychain / Vault
  +--------------------------+      +---------------------+
  | OPENAI_API_KEY=phm_a7f3  | ---> | sk-real-secret-key  |
  | STRIPE_KEY=phm_c9d1...   |      | sk_live_real-key... |
  +--------------------------+      +---------------------+
           |                                 |
           v                                 v
  AI Agent (Claude, Cursor)         Phantom Proxy (127.0.0.1)
  +--------------------------+      +------------------------------+
  | Reads .env               |      | Intercepts HTTP requests     |
  | Sees only phm_ tokens    | ---> | Replaces phm_ with real keys |
  | Makes API calls to proxy |      | Forwards over TLS to real API|
  +--------------------------+      +------------------------------+
  1. phantom init reads .env, stores real secrets in the OS keychain, rewrites .env with phm_ tokens
  2. phantom exec -- claude starts a local reverse proxy, sets SDK-compatible service base URLs such as OPENAI_BASE_URL=http://127.0.0.1:PORT/openai/_phantom/TOKEN/, exposes PHANTOM_PROXY_TOKEN to the child process, and launches the command
  3. API calls hit the proxy, which authenticates the local session, removes the local auth token before forwarding, replaces phantom tokens with real secrets, and forwards over TLS
  4. When the session ends, the proxy shuts down and the proxy session token is invalid. Phantom tokens remain worthless placeholders outside an authenticated proxy session.

MCP Integration (Claude Code, Cursor, Windsurf, Codex)

Phantom ships an MCP server so AI coding tools can manage secrets directly -- without ever seeing real values.

  • Vaultphantom_list_secrets, phantom_status, phantom_init, phantom_add_secret_interactive, phantom_add_secret (deprecated; refuses plaintext), phantom_remove_secret, phantom_rotate, phantom_copy_secret
  • Detection + diagnosticsphantom_doctor, phantom_why, phantom_check, phantom_env
  • Local-to-cloudphantom_wrap, phantom_unwrap, phantom_sync, phantom_cloud_push, phantom_cloud_pull, phantom_cloud_status
  • Teamsphantom_team_list, phantom_team_create, phantom_team_members, phantom_team_invite, phantom_team_key_publish, phantom_team_vault_push, phantom_team_vault_pull

Mutating tools require an explicit confirm: true parameter so a prompt-injected agent can't silently mutate state. Real secret values are never accepted as MCP tool arguments; new secrets are entered out-of-band in a trusted terminal.

One command per AI client — Phantom writes the right config file in the right place:

phantom setup --client claude     # .claude/settings.local.json (project)
phantom setup --client cursor     # ~/.cursor/mcp.json
phantom setup --client windsurf   # ~/.codeium/windsurf/mcp_config.json
phantom setup --client codex      # ~/.codex/config.toml
phantom setup --client claude --print   # snippet to stdout for any other client

If phantom-mcp isn't on PATH, Phantom falls back to npx -y phantom-secrets-mcp so the config still works on a fresh machine. Restart the AI tool after running phantom setup so it picks up the new config.

Phantom works with any tool that supports the Model Context Protocol.

Cloud Sync + Dashboard

Sync vaults across machines with end-to-end encryption. The server never sees plaintext.

$ phantom login
# Opens GitHub OAuth (device code flow)

$ phantom cloud push
# Encrypted client-side, uploaded to phm.dev

$ phantom cloud pull   # on another machine
# Downloaded and decrypted locally

$ phantom open
# Opens https://phm.dev/dashboard — read-only view of your projects,
# vault sizes, last sync, plan tier, and team membership.

Cloud sync uses ChaCha20-Poly1305 with a client-side passphrase derived via Argon2id. The server stores only ciphertext.

Team vaults (Pro)

Multiple developers can share a single E2E-encrypted vault per project. Server only ever stores ciphertext + per-member ciphertext shares.

$ phantom team create "engineering"
# Creates a team; you become the owner.

$ phantom team invite  
# Invites by GitHub login.

$ phantom team key-publish 
# Registers your X25519 public key on the team.
# (Run once per team; the private key stays in the OS keychain.)

$ phantom team vault-push 
# Encrypts the current project's vault with a fresh symmetric key,
# wraps that key (X25519 + ChaCha20-Poly1305) for every member that
# has a registered public key, then uploads.

$ phantom team vault-pull    # on a teammate's machine
# Pulls, decrypts the per-member share with their private key,
# decrypts the vault, writes secrets locally.

Team memberships and member lists are visible in the read-only dashboard at phm.dev/dashboard/team.

Command Reference

| Command | Description | |---------|-------------| | phantom init | Import .env secrets into vault, rewrite with phantom tokens. --all protects every git repo with a .env under ` in one go (with --dry-run to preview, --jobs N / -j N to control parallelism) | | phantom exec -- | Start an authenticated proxy and run a command with secret injection | | phantom start / stop | Manage proxy lifecycle (standalone/daemon mode) | | phantom list | Show secret names stored in vault (never values; --json for machine-readable output) | | phantom add [VAL] | Add a secret. With no VAL, prompts silently on the terminal; or pipe via --stdin | | phantom remove | Remove a secret from the vault | | phantom reveal | Print a secret value (or --clipboard to copy) | | phantom status | Show proxy state, vault info, and mapped services | | phantom rotate | Regenerate all phantom tokens (old ones become invalid) | | phantom doctor | Check configuration and vault health (--fix to auto-repair). Reports install source, vault backend, audit-log status, Argon2 params, and MCP wiring per client | | phantom agent report | Emit a read-only AI-agent readiness report (--json for automation). Reports unsafe, protected, verified, team-ready, or compliance-ready | | phantom agent doctor | Human-readable agent readiness view backed by the same policy engine | | phantom agent setup | Preview or apply safe defaults for agent use (--dry-run first, --apply to write changes) | | phantom check | Scan for unprotected secrets (pre-commit hook, --staged, --runtime) | | phantom sync | Push secrets to Vercel / Railway (--dry-run --json previews safely; --only PATTERN filters by glob, repeatable) | | phantom pull | Pull secrets from Vercel / Railway into vault | | phantom setup | Wire Phantom into an AI client. --client claude (default), cursor, windsurf, or codex. Add --print to emit the config snippet to stdout | | phantom env | Generate .env.example for team onboarding | | phantom export | Export vault to encrypted backup file (--passphrase), or emit plaintext JSON to stdout (--json --allow-plaintext) | | phantom import | Import from encrypted backup ( --passphrase), or migrate from --from doppler\|infisical\|dotenvx\|1password\|env --file . Add --force to overwrite existing secrets | | phantom audit show | Print recent audit events (--last N, --op OP, --name NAME, --json). Requires PHANTOM_AUDIT=1 | | phantom audit tail | Follow the audit log live (--op, --name filters) | | phantom audit path | Print the absolute path to the audit log file | | phantom audit verify | Verify HMAC-SHA256 chain integrity; exits 1 if tampering detected | | phantom login | Authenticate with Phantom Cloud via GitHub OAuth | | phantom logout | Clear cloud credentials | | phantom cloud push | Push encrypted vault to Phantom Cloud | | phantom cloud pull | Pull and decrypt vault from Phantom Cloud | | phantom wrap | Wrap package.json scripts with phantom exec automatically | | phantom unwrap | Restore original package.json scripts | | phantom watch | Watch .env files and auto-detect new unprotected secrets | | phantom why | Explain why a key is or is not protected | | phantom copy | Copy a secret to another project's vault | | phantom team list/create/members/invite | Team vault management | | phantom team key-publish | Register your X25519 pubkey on a team (once per team) | | phantom team vault-push | Push current project to shared team vault (E2E encrypted per-member) | | phantom team vault-pull | Pull team vault into local vault | | phantom open [page] | Open phm.dev pages in browser (dashboard, billing, team, docs, github, …) | | phantom upgrade | Self-replace this binary with the latest GitHub release (--check-only to inspect first) | | phantom completion ` | Print a shell-completion script (bash, zsh, fish, powershell, elvish) |

Features

  • Encrypted vault -- OS keychain (macOS Keychain / Secure Enclave, Linux Secret Service, Windows Credential Manager) with encrypted file fallback for CI/Docker. Argon2id hardened to OWASP balanced (m=64 MiB, t=3, p=1)
  • Phantom tokens -- 256-bit CSPRNG phm_ placeholders in .env, rotatable on demand
  • Authenticated proxy sessions -- each proxy run generates a fresh PHANTOM_PROXY_TOKEN; CLI-generated SDK URLs include it for compatibility, and header-aware clients can opt into x-phantom-proxy-token with PHANTOM_PROXY_HEADER_AUTH_ONLY=1
  • Streaming token replacement -- For text/* and application/x-www-form-urlencoded request bodies, phantom tokens are replaced frame-by-frame without buffering the full payload; a 67-byte carry buffer handles tokens that straddle chunk boundaries. JSON bodies use a buffered path to preserve field-level F9 scoping.
  • Full SSE/streaming support -- Response streaming preserved end-to-end for OpenAI, Anthropic, and other streaming APIs
  • Smart detection -- Heuristic engine distinguishes secrets (*_KEY, *_TOKEN, sk-*, ghp_*) from config (NODE_ENV, PORT)
  • Platform sync -- Push/pull secrets to Vercel and Railway
  • Pre-commit hook -- Blocks commits containing unprotected secrets
  • MCP server -- 25 tools for Claude Code, Cursor, Windsurf, and Codex to manage secrets without seeing values
  • Cloud sync -- E2E encrypted zero-knowledge vault sync across machines
  • Export/import -- Encrypted backup and restore (--passphrase); plaintext JSON export to stdout (--json --allow-plaintext); import from Doppler, Infisical, dotenvx, 1Password, or plain .env via --from
  • Tamper-evident audit log -- PHANTOM_AUDIT=1 writes vault events as JSONL to ~/.phantom/audit.log. Each entry is chained with HMAC-SHA256; phantom audit verify detects tampering. phantom audit show/tail/path for log access.
  • Response scrubbing -- Prevents secrets from leaking in API responses back to the AI
  • Script wrapping -- phantom wrap patches package.json so every npm script runs through the proxy
  • Watch mode -- phantom watch monitors .env files for new unprotected secrets
  • Multi-project scanner -- phantom init --all protects every git repo with a .env under ` in one command (with --dry-run); --jobs N` controls parallelism
  • Multi-IDE setup -- phantom setup --client claude|cursor|windsurf|codex writes the right MCP config for each AI tool, or --print for a generic snippet
  • Agent readiness -- phantom agent doctor and phantom agent report --json answer whether a repo is safe for Claude Code, Codex, Cursor, Windsurf, and other agents
  • Enriched diagnostics -- phantom doctor reports install source, vault backend, audit-log status, Argon2 params, an

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.