secret-safe-env
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@secret-safe-envSet the OPENAI_API_KEY in .env"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
secret-safe-env
A Model Context Protocol 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.
The 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.
繁體中文說明見 README.zh-TW.md.
Demo

▶︎ Full-quality video (with audio)
Related MCP server: sops-mcp
Why
When 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.
agent: set_env_secret({ key: "OPENAI_API_KEY" })
│ (name only — no value)
▼
┌──────────────────────────┐ you type the value here
│ native masked dialog │ ◄── (never shown to the agent)
└──────────────────────────┘
│ $script:SecretValue (never a parameter, never stdout)
▼
PowerShell writes .env via [System.IO.File]
│
▼
agent receives: "OK" ← status token only"Can't I just edit .env myself?"
Yes — 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.
Platform support
This tool is Windows-only by design — the trust anchor is a native WinForms masked dialog driven by Windows PowerShell.
Requirement | Supported | Notes |
Windows 10 / 11 | ✅ Required | The only supported OS. |
Linux / macOS | ❌ Not supported | The tools return |
Windows PowerShell 5.1 | ✅ Required | Launched from the pinned path |
PowerShell 7+ ( | ❌ Not used | Deliberately never PATH-resolved, so a |
Node.js | ✅ 18+ | Runs the MCP server (spawns PowerShell; never touches the value). |
Install
Claude Code
claude mcp add secret-safe-env -- npx -y secret-safe-envFor the most stable setup (no npx cache surprises), install the global bin and point at it:
npm i -g secret-safe-env
claude mcp add secret-safe-env -- secret-safe-envUpdating:
npm i -g secret-safe-env@latest. With unpinnednpx, clear the cache (npx clear-npx-cache) or pin a version (npx -y secret-safe-env@<version>) to avoid running a stale cached copy.
Other MCP clients (.mcp.json)
{
"mcpServers": {
"secret-safe-env": { "command": "secret-safe-env" } // requires `npm i -g secret-safe-env`
// zero-install alternative (pin a version):
// "secret-safe-env": { "command": "npx", "args": ["-y", "secret-safe-env@<version>"] }
}
}Reload 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.
Tools
set_env_secret({ key, env_path? }) → status text
Opens 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).
env_key_exists({ key, env_path? }) → { exists: boolean }
Returns only whether key is present in .env — never the value. Use it to confirm a write instead of reading/cat-ing .env. readOnlyHint: true.
env_pathis 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.
For AI agents
Use 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:
✅ Pass only the variable name; the user supplies the value in the local dialog.
✅ Confirm a write with
env_key_exists(returnstrue/false, never the value).❌ Never ask the user to paste the secret into the chat.
❌ Never write the value or a placeholder yourself.
❌ Never
cat/read.envto verify — that re-exposes the secret.
These 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.
Security scope
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.
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.
See docs/SPEC.md for the full threat model and guarantees.
Development
npm install
npm run build # tsc -> dist/
npm test # Node unit tests (vitest)
npm run test:ps # PowerShell upsert + no-leak tests (Pester 5)
npm run lint:ps # static value-path AST lintPowerShell tests need Pester 5: Install-Module Pester -MinimumVersion 5.0 -Scope CurrentUser.
Releases 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.
Documentation
docs/SPEC.md — purpose, guarantees, threat model, scope & non-goals.
docs/ARCHITECTURE.md — modules and data flow.
docs/DECISIONS.md — design decisions and rationale.
Contributing
Contributions welcome — see CONTRIBUTING.md. The one rule: keep the no-leak guarantee intact and tested.
License
Disclaimer
secret-safe-env is provided "as is", without warranty of any kind (see LICENSE). It reduces secret exposure within the documented 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.
This 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.
Available Tools
2 toolsenv_key_existsCheck if a key exists in .envARead-only
Check whether an environment variable NAME already exists in a project .env file. Returns ONLY true/false - never the value. Use this to verify set_env_secret worked, INSTEAD of reading/cat-ing .env (which would expose the secret).
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | The env var NAME to check, e.g. OPENAI_API_KEY. | |
| env_path | No | Absolute path to the project .env (same as set_env_secret). Defaults to <CLAUDE_PROJECT_DIR or cwd>/.env. |
Output Schema
| Name | Required | Description |
|---|---|---|
| exists | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true and destructiveHint=false, confirming this is a safe read operation. The description adds that it returns only true/false and never the value, which is important behavioral detail beyond the annotations. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise: two sentences that front-load the core purpose and include key behavioral and usage notes. Every sentence earns its place, with zero wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 2 parameters fully described in the schema, a known output schema, comprehensive annotations, and a sibling tool mentioned, the description provides all necessary context. The agent has clear guidance on when and how to use the tool effectively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already defines the parameters. The description adds value by explaining the default for env_path and relating it to set_env_secret. This context helps the agent use the parameters correctly without repeating schema details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool checks if an environment variable NAME exists in a .env file and returns only true/false. It distinguishes itself from reading the file directly and mentions the sibling tool set_env_secret, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool—to verify set_env_secret worked—and what to avoid (reading/cat-ing .env). It provides a clear alternative (don't expose secrets), which helps the agent choose correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_env_secretSet an .env secret (value never seen by the agent)ADestructive
Use this WHENEVER a task needs a secret/API key/token/password/connection string/credential written to a project .env file - e.g. "add my OpenAI key", "set DATABASE_URL", "configure my .env", "save this API token". You pass ONLY the variable NAME; the user types the value into a local masked dialog and it is written straight to .env - you never see or handle the value. DO NOT ask the user to paste the secret into the chat; DO NOT write the value or a placeholder yourself; DO NOT cat/read .env to verify (use env_key_exists). The value must be single-line (not for multi-line PEM keys / JSON blobs - for those, tell the user to edit .env manually).
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | The env var NAME in UPPER_SNAKE_CASE, e.g. OPENAI_API_KEY, DATABASE_URL, STRIPE_SECRET_KEY. | |
| env_path | No | Absolute path to the project .env. Pass the project-root .env path explicitly; if omitted it defaults to <CLAUDE_PROJECT_DIR or cwd>/.env, which may NOT be your workspace when launched via a runner. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explains that the agent never sees the value (user types into a masked dialog), the value is written straight to .env, and it must be single-line. This adds significant context beyond the annotations (readOnlyHint=false, destructiveHint=true). No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is about six sentences, covering all necessary guidance without excessive verbosity. It is front-loaded with the core purpose and immediately transitions to usage rules. Minor redundancy could be trimmed, but overall well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description addresses the key behavioral aspects (value invisibility, single-line constraint) and provides alternatives for multi-line secrets. It does not explicitly state what happens if the key already exists (overwrite) or if the .env file does not exist, but these are minor gaps given the overall clarity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema describes both parameters with clear descriptions and examples. The description reinforces that the agent passes only the key name and the user provides the value, and for env_path it explains the default behavior and warns about incorrect defaults when launched via a runner.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool writes secrets/API keys/tokens to a .env file, with concrete examples like 'add my OpenAI key', 'set DATABASE_URL'. It distinguishes from the sibling env_key_exists by focusing on setting values.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells when to use the tool (whenever a secret needs to be written) and lists forbidden actions: 'DO NOT ask the user to paste the secret into the chat', 'DO NOT write the value or a placeholder yourself', 'DO NOT cat/read .env to verify (use env_key_exists)'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
2 tool updates
v0.1.2- First observed
env_key_exists - First observed
set_env_secret
TDQS
Scored across 2 tools
The two tools have clearly distinct purposes: setting a secret and checking for existence. There is no overlap or ambiguity.
Both tools follow a consistent verb_noun snake_case pattern (set_env_secret, env_key_exists), making them predictable.
With 2 tools, the server is minimal but appropriate for its focused scope of managing .env secrets. However, the count feels slightly low for a full-featured solution.
The server covers setting and checking existence of secrets but lacks a tool to delete or remove secrets, which is a notable gap for lifecycle management.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.
A secret store for AI agents: the agent never sees the plaintext.
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
Personal assistant MCP server with search, execute, packages, jobs, secrets, and integrations.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceMCP server that lets AI agents call APIs without ever seeing the credentials, using a local encrypted vault and per-secret allowlist policies for HTTP requests and subprocess environment variables.1AGPL 3.0
- AlicenseAqualityBmaintenanceMCP server for creating and managing SOPS-encrypted secret files using age encryption, enabling AI agents to generate and manage secrets without ever seeing plaintext values.9Apache 2.0
- AlicenseNot gradedqualityCmaintenanceMCP server enabling AI agents to use secrets (API keys, tokens) via encrypted vault, executing HTTP/shell/SSH actions server-side while never exposing secret values to the AI.MIT
- AlicenseNot gradedqualityBmaintenanceA self-hostable secrets manager with an MCP server that enables AI agents to securely store, version, and retrieve API keys and tokens, ensuring they are never lost.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/irrenwill/secret-safe-env'
If you have feedback or need assistance with the MCP directory API, please join our Discord server