{
  "markdown": "# secret-safe-env\n\n[![npm version](https://img.shields.io/npm/v/secret-safe-env.svg)](https://www.npmjs.com/package/secret-safe-env)\n[![MCP Registry](https://img.shields.io/badge/MCP%20Registry-listed-blue)](https://registry.modelcontextprotocol.io/v0/servers?search=io.github.irrenwill/secret-safe-env)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](./LICENSE)\n[![Platform: Windows](https://img.shields.io/badge/platform-Windows%20only-0078D6.svg)](#platform-support)\n\nA [Model Context Protocol](https://modelcontextprotocol.io) server that lets an AI agent put a secret (API key, token, password, connection string) into a project's `.env` file **without the agent ever seeing the value**.\n\nThe agent calls a tool with **only the variable name**. A native, masked Windows dialog opens locally; **you** type the value; a local PowerShell helper writes it straight to `.env`. The agent receives only a status token (`OK` / `CANCEL` / `ERR:<CODE>`) — never the secret.\n\n> 繁體中文說明見 [README.zh-TW.md](./README.zh-TW.md).\n\n## Demo\n\n![secret-safe-env demo — the agent calls the tool with only the key name; a masked dialog opens locally for you to type the value, which is written straight to .env](docs/demo.gif)\n\n<sub>▶︎ <a href=\"https://github.com/irrenwill/secret-safe-env/releases/download/v0.1.2/demo.mp4\">Full-quality video (with audio)</a></sub>\n\n---\n\n## Why\n\nWhen you ask an agent to \"add my OpenAI key to `.env`\", the usual paths all leak the secret: pasting it into the chat puts it in the model's context and transcripts; letting the agent write the value means the agent handled it; `cat .env` to \"verify\" exposes it again. `secret-safe-env` removes the secret from every one of those channels — the value travels **user → masked dialog → PowerShell → `.env`** and never enters the agent/model context.\n\n```\nagent: set_env_secret({ key: \"OPENAI_API_KEY\" })\n          │  (name only — no value)\n          ▼\n   ┌──────────────────────────┐     you type the value here\n   │  native masked dialog     │ ◄── (never shown to the agent)\n   └──────────────────────────┘\n          │  $script:SecretValue (never a parameter, never stdout)\n          ▼\n   PowerShell writes .env via [System.IO.File]\n          │\n          ▼\nagent receives:  \"OK\"   ← status token only\n```\n\n### \"Can't I just edit `.env` myself?\"\n\nYes — and this doesn't replace that. It removes the repetitive *leave the chat → open the file → paste* step so the agent handles it inline, with you only typing the value once. It also guards a **different** surface than `.gitignore`: keeping `.env` out of git doesn't help if the value already leaked into the chat / transcript / logs the moment you handed it over. Scope is deliberately just *getting the value safely into `.env`* — production secret management (vaults, runtime injection) is out of scope.\n\n## Platform support\n\nThis tool is **Windows-only by design** — the trust anchor is a native WinForms masked dialog driven by Windows PowerShell.\n\n| Requirement | Supported | Notes |\n|---|---|---|\n| **Windows 10 / 11** | ✅ Required | The only supported OS. |\n| **Linux / macOS** | ❌ Not supported | The tools return `UNSUPPORTED_PLATFORM` and refuse; the agent is told the machine is unsupported. (The npm package still *installs* on any OS, it just won't run there.) |\n| **Windows PowerShell 5.1** | ✅ Required | Launched from the **pinned path** `%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`. |\n| **PowerShell 7+ (`pwsh`)** | ❌ Not used | Deliberately never PATH-resolved, so a `pwsh` on `PATH` can't change the execution/logging surface. |\n| **Node.js** | ✅ 18+ | Runs the MCP server (spawns PowerShell; never touches the value). |\n\n## Install\n\n### Claude Code\n\n```bash\nclaude mcp add secret-safe-env -- npx -y secret-safe-env\n```\n\nFor the most stable setup (no `npx` cache surprises), install the global bin and point at it:\n\n```bash\nnpm i -g secret-safe-env\nclaude mcp add secret-safe-env -- secret-safe-env\n```\n\n> Updating: `npm i -g secret-safe-env@latest`. With unpinned `npx`, clear the cache (`npx clear-npx-cache`) or pin a version (`npx -y secret-safe-env@<version>`) to avoid running a stale cached copy.\n\n### Other MCP clients (`.mcp.json`)\n\n```jsonc\n{\n  \"mcpServers\": {\n    \"secret-safe-env\": { \"command\": \"secret-safe-env\" }        // requires `npm i -g secret-safe-env`\n    // zero-install alternative (pin a version):\n    // \"secret-safe-env\": { \"command\": \"npx\", \"args\": [\"-y\", \"secret-safe-env@<version>\"] }\n  }\n}\n```\n\nReload the client so it picks up the server. If an `npx`-launched stdio server appears in the list but never connects on Windows, wrap the command as `cmd /c npx -y secret-safe-env`.\n\n## Tools\n\n### `set_env_secret({ key, env_path? }) → status text`\n\nOpens the masked dialog for `key`; the user types the value; the helper writes `key=value` to `.env`. Returns human/agent-readable text plus an error flag — **never** the value. `key` must be `UPPER_SNAKE_CASE` (`^[A-Z_][A-Z0-9_]*$`). Values are **single-line** (for multi-line PEM/JSON, ask the user to edit `.env` manually). `destructiveHint: true` (it upserts a key in place).\n\n### `env_key_exists({ key, env_path? }) → { exists: boolean }`\n\nReturns only whether `key` is present in `.env` — never the value. Use it to confirm a write **instead of reading/`cat`-ing `.env`**. `readOnlyHint: true`.\n\n> `env_path` is the absolute path to the project `.env`. **Always pass it explicitly** — a runner-launched MCP server's working directory is the runner sandbox, not your workspace. If omitted it defaults to `<CLAUDE_PROJECT_DIR or cwd>/.env`.\n\n## For AI agents\n\nUse `set_env_secret` **whenever a task needs a secret/API key/token/password/credential in a project `.env`** (e.g. \"add my OpenAI key\", \"set `DATABASE_URL`\", \"configure my `.env`\"). Rules:\n\n- ✅ Pass **only the variable name**; the user supplies the value in the local dialog.\n- ✅ Confirm a write with `env_key_exists` (returns `true`/`false`, never the value).\n- ❌ **Never** ask the user to paste the secret into the chat.\n- ❌ **Never** write the value or a placeholder yourself.\n- ❌ **Never** `cat`/read `.env` to verify — that re-exposes the secret.\n\nThese rules are also delivered to the agent via the server's `instructions` and each tool's `description`, so a cold agent with zero prior context can use it correctly.\n\n## Security scope\n\n**In scope** — from the moment you type the value until it lands in `.env`, no audited Windows/agent channel records it: PSReadLine history, 4688/Sysmon process command lines, 4103 Module Logging, 4104 Script Block Logging, PowerShell Transcription, AMSI, the MCP/agent context, OTEL traces, and `mcp-debug` logs. The value never crosses a PowerShell parameter boundary and is written only via `[System.IO.File]`, never a cmdlet. A static AST lint (`npm run lint:ps`) and Pester transcript tests enforce this.\n\n**Out of scope** (your responsibility, once the value is in `.env`) — cloud sync / OneDrive, VSS / backup snapshots, antivirus scanning, file ACLs, and the agent reading `.env` afterward.\n\nSee [docs/SPEC.md](./docs/SPEC.md) for the full threat model and guarantees.\n\n## Development\n\n```bash\nnpm install\nnpm run build       # tsc -> dist/\nnpm test            # Node unit tests (vitest)\nnpm run test:ps     # PowerShell upsert + no-leak tests (Pester 5)\nnpm run lint:ps     # static value-path AST lint\n```\n\nPowerShell tests need Pester 5: `Install-Module Pester -MinimumVersion 5.0 -Scope CurrentUser`.\n\nReleases are automated: push a `vX.Y.Z` tag and GitHub Actions publishes to npm (Trusted Publishing / OIDC) and the MCP Registry — no tokens. See [docs/DECISIONS.md](./docs/DECISIONS.md).\n\n## Documentation\n\n- [docs/SPEC.md](./docs/SPEC.md) — purpose, guarantees, threat model, scope & non-goals.\n- [docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md) — modules and data flow.\n- [docs/DECISIONS.md](./docs/DECISIONS.md) — design decisions and rationale.\n\n## Contributing\n\nContributions welcome — see [CONTRIBUTING.md](./CONTRIBUTING.md). The one rule: keep the no-leak guarantee intact and tested.\n\n## License\n\n[MIT](./LICENSE)\n\n## Disclaimer\n\n`secret-safe-env` is provided \"as is\", without warranty of any kind (see [LICENSE](./LICENSE)). It reduces secret exposure within the documented [security scope](#security-scope) on a best-effort basis; it does **not** guarantee absolute secrecy. You are responsible for confirming it fits your threat model, and for whatever happens to a value **after** it is written to `.env` — cloud sync, backups, antivirus, file permissions, and any tool (including the agent) that later reads `.env`. For production secrets, prefer a dedicated secrets manager.\n\nThis is an independent open-source project. It is **not** affiliated with, endorsed by, or sponsored by Anthropic, \"Claude\", or the Model Context Protocol project; those names belong to their respective owners and are used only to describe compatibility.\n",
  "bytes": 8910,
  "sha": "f133536e86c03bcd964f778bd7baef38528c8e8f0bb2df81be36fe103110053b",
  "repo_slug": "irrenwill/secret-safe-env",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_irrenwill_secret_safe_env_52053d7d/readme"
}