❯envpilot
featurespricing❯docsblogchangelogwishlistfaq
sign-inget-started
// documentation
Start Here
  • Quickstart
  • Core concepts
  • Architecture: the machine surfaces
Platform
  • Data model
  • Variables
  • Secret files
  • Shared Accounts
  • Secret Sharing Links
  • Diagrams in documentation
  • Sharing documentation
  • Roles & permissions
  • Requests & approvals
  • Protected environments
  • Rotation & expiry
  • Security
Plans & Limits
  • Plans & Limits
  • Rate limits
CLI
  • CLI overview
  • Authentication & accounts
  • Linking projects
  • Pull & push
  • Running commands with secrets
  • Single secrets
  • Requests
  • Secret files
  • Command reference
  • CLI in CI & troubleshooting
VS Code
  • VS Code overview
  • Linking & sync
  • Protection
  • Editor features
  • Commands
  • Settings
  • Troubleshooting
JetBrains
  • JetBrains overview
  • Linking & sync
  • Protection
  • Troubleshooting
GitHub Action
  • GitHub Action overview
  • Inputs & outputs
  • Secret files in CI
  • Recipes
  • Action security
Docker
  • Docker overview
  • Build time
  • Runtime
  • Docker Compose
  • Docker reference
API Reference
  • API overview
  • API Quickstart
  • Authentication
  • Errors
  • Organization
  • Projects
  • Variables
  • Shared accounts
  • Secret files
MCP Server
  • MCP overview
  • MCP setup
  • Connecting a client
  • Tools
  • Agent requests
  • API keys (legacy)
Web Dashboard
  • Dashboard overview
  • Working in a project
  • Organization administration
Integrations
  • Slack & Discord Notifications
Guides
  • How to Share Environment Variables Securely
  • Next.js Environment Variables Best Practices
  • Android keystore in CI
  • Giving an agent secrets safely

// resources

  • github
  • npm
  • vs code marketplace
  • jetbrains marketplace
Start HerePlatformPlans & LimitsCLIVS CodeJetBrainsGitHub ActionDockerAPI ReferenceMCP ServerWeb DashboardIntegrationsGuides
❯envpilot

Encrypted environment variables for teams that live in the terminal. No .env files, no secrets in Slack.

$npm install -g @envpilot/cli

// product

  • Features
  • Pricing
  • Changelog
  • Wishlist

// resources

  • Getting Started
  • CLI Reference
  • VS Code Extension
  • Security

// compare

  • vs Doppler
  • vs Infisical
  • vs .env files

// support

  • FAQ
  • Support
  • Contact
  • Docs
  • Status

// legal

  • Privacy Policy
  • Terms of Service

© 2026 Envpilot · Built at Syntax Lab Technology · Abdul Rafay

ENVPILOT

❯envpilot
featurespricing❯docsblogchangelogwishlistfaq
sign-inget-started
// documentation
Start Here
  • Quickstart
  • Core concepts
  • Architecture: the machine surfaces
Platform
  • Data model
  • Variables
  • Secret files
  • Shared Accounts
  • Secret Sharing Links
  • Diagrams in documentation
  • Sharing documentation
  • Roles & permissions
  • Requests & approvals
  • Protected environments
  • Rotation & expiry
  • Security
Plans & Limits
  • Plans & Limits
  • Rate limits
CLI
  • CLI overview
  • Authentication & accounts
  • Linking projects
  • Pull & push
  • Running commands with secrets
  • Single secrets
  • Requests
  • Secret files
  • Command reference
  • CLI in CI & troubleshooting
VS Code
  • VS Code overview
  • Linking & sync
  • Protection
  • Editor features
  • Commands
  • Settings
  • Troubleshooting
JetBrains
  • JetBrains overview
  • Linking & sync
  • Protection
  • Troubleshooting
GitHub Action
  • GitHub Action overview
  • Inputs & outputs
  • Secret files in CI
  • Recipes
  • Action security
Docker
  • Docker overview
  • Build time
  • Runtime
  • Docker Compose
  • Docker reference
API Reference
  • API overview
  • API Quickstart
  • Authentication
  • Errors
  • Organization
  • Projects
  • Variables
  • Shared accounts
  • Secret files
MCP Server
  • MCP overview
  • MCP setup
  • Connecting a client
  • Tools
  • Agent requests
  • API keys (legacy)
Web Dashboard
  • Dashboard overview
  • Working in a project
  • Organization administration
Integrations
  • Slack & Discord Notifications
Guides
  • How to Share Environment Variables Securely
  • Next.js Environment Variables Best Practices
  • Android keystore in CI
  • Giving an agent secrets safely

// resources

  • github
  • npm
  • vs code marketplace
  • jetbrains marketplace
Start HerePlatformPlans & LimitsCLIVS CodeJetBrainsGitHub ActionDockerAPI ReferenceMCP ServerWeb DashboardIntegrationsGuides
❯envpilot

Encrypted environment variables for teams that live in the terminal. No .env files, no secrets in Slack.

$npm install -g @envpilot/cli

// product

  • Features
  • Pricing
  • Changelog
  • Wishlist

// resources

  • Getting Started
  • CLI Reference
  • VS Code Extension
  • Security

// compare

  • vs Doppler
  • vs Infisical
  • vs .env files

// support

  • FAQ
  • Support
  • Contact
  • Docs
  • Status

// legal

  • Privacy Policy
  • Terms of Service

© 2026 Envpilot · Built at Syntax Lab Technology · Abdul Rafay

ENVPILOT

// documentation
Start Here
  • Quickstart
  • Core concepts
  • Architecture: the machine surfaces
Platform
  • Data model
  • Variables
  • Secret files
  • Shared Accounts
  • Secret Sharing Links
  • Diagrams in documentation
  • Sharing documentation
  • Roles & permissions
  • Requests & approvals
  • Protected environments
  • Rotation & expiry
  • Security
Plans & Limits
  • Plans & Limits
  • Rate limits
CLI
  • CLI overview
  • Authentication & accounts
  • Linking projects
  • Pull & push
  • Running commands with secrets
  • Single secrets
  • Requests
  • Secret files
  • Command reference
  • CLI in CI & troubleshooting
VS Code
  • VS Code overview
  • Linking & sync
  • Protection
  • Editor features
  • Commands
  • Settings
  • Troubleshooting
JetBrains
  • JetBrains overview
  • Linking & sync
  • Protection
  • Troubleshooting
GitHub Action
  • GitHub Action overview
  • Inputs & outputs
  • Secret files in CI
  • Recipes
  • Action security
Docker
  • Docker overview
  • Build time
  • Runtime
  • Docker Compose
  • Docker reference
API Reference
  • API overview
  • API Quickstart
  • Authentication
  • Errors
  • Organization
  • Projects
  • Variables
  • Shared accounts
  • Secret files
MCP Server
  • MCP overview
  • MCP setup
  • Connecting a client
  • Tools
  • Agent requests
  • API keys (legacy)
Web Dashboard
  • Dashboard overview
  • Working in a project
  • Organization administration
Integrations
  • Slack & Discord Notifications
Guides
  • How to Share Environment Variables Securely
  • Next.js Environment Variables Best Practices
  • Android keystore in CI
  • Giving an agent secrets safely

// resources

  • github
  • npm
  • vs code marketplace
  • jetbrains marketplace
Start HerePlatformPlans & LimitsCLIVS CodeJetBrainsGitHub ActionDockerAPI ReferenceMCP ServerWeb DashboardIntegrationsGuides
MCP overviewMCP setupConnecting a clientToolsAgent requestsAPI keys (legacy)
docs/MCP Server

API keys (legacy)

The old way to connect an MCP client, with a scoped envpk_ key. New setups sign in with OAuth instead.

open in claudeopen in chatgptopen in cursor

API keys (legacy)

No longer supported

The MCP server only accepts sign-in now: see MCP setup. API keys get a 401 from the MCP server. They keep working for the REST API, the GitHub Action and the Docker image. To move a client over, follow Moving from an API key.

This page is kept for reference.

The tools that needed a key (shared accounts, secret files and variable requests) were removed with key support.

Creating an MCP key#

The dashboard no longer offers the MCP server surface, so new MCP keys cannot be created. This section explains what an existing key's settings mean. A key was created in Organization → Settings → API Keys → New API Key like this:

  1. Give the key a recognizable name, such as codex-development.
  2. Select the MCP server surface. Deselect REST API and GitHub Action unless this same credential genuinely needs them.
  3. Select only the projects the client needs. All projects also includes projects created in the future and is owner-only.
  4. Select only the environments the client needs. A development-only agent should not receive production access.
  5. Select the resources required by its tools:
ResourceMCP tools enabled
projectsenvpilot_list_projects; project-name and project-slug matches from envpilot_search
variablesenvpilot_get_variables, envpilot_get_variable; variable-key matches from envpilot_search (which also needs projects to enumerate)
accountsenvpilot_list_accounts
filesenvpilot_list_files, envpilot_get_file
requestsenvpilot_request_variable, envpilot_get_request_status
docsenvpilot_search_docs, envpilot_get_doc, envpilot_create_doc, envpilot_update_doc_draft. Cannot be combined with files — see below

For the common project-discovery and variable-read workflow, select projects and variables. Most assistants begin with envpilot_list_projects; without projects, that opening call is denied. An accounts-only or requests-only key is still valid, but only for the corresponding tools.

Think twice before granting `files`

files lets an agent fetch a signing keystore or a private key in full. A leaked string can be rotated in minutes; a leaked signing key is a different kind of day. Grant it only to a key whose agent genuinely runs builds, and never alongside All projects.

  1. Choose an expiry, create the key, and copy the envpk_... value immediately.

docs and files are mutually exclusive: a key may carry one or the other, never both. Documentation is prose an agent reads into its context and files returns decrypted key material, so a single credential holding both is an exfiltration chain. An agent that needs each gets two keys.

Project, environment, resource, and surface scopes are immutable. You cannot widen or edit them after creation; create a replacement key when the required access changes. The plaintext is also displayed once: Envpilot stores only its SHA-256 hash and cannot recover a lost key.

Endpoint#

❯terminal
https://www.envpilot.dev/api/mcp

Transport is Streamable HTTP (the current MCP spec transport for remote servers). Auth is a plain bearer token — the same envpk_... API key you'd use for the REST API:

❯terminal
Authorization: Bearer envpk_your_key_here

Set ENVPILOT_API_KEY#

Keep the plaintext out of MCP config files and repositories. Put it in the environment of the process that starts the client, then make the client reference the variable by name.

macOS#

For the current Terminal session (zsh), enter the key at the hidden prompt so it does not appear in shell history:

❯terminal
read -rs "ENVPILOT_API_KEY?Envpilot API key: "; echo
export ENVPILOT_API_KEY

This value disappears when the shell exits. For future terminal sessions, have a password manager inject it or edit a user-only shell startup file (do not build the line with a shell command that would record the key in history):

❯terminal
# ~/.zshrc
export ENVPILOT_API_KEY='envpk_your_key_here'

A literal export in a startup file is persistent but is plaintext on disk; never put it in a repository, and restrict the file to your user:

❯terminal
chmod 600 ~/.zshrc

Apps opened from Finder, the Dock, or Spotlight do not inherit variables from ~/.zshrc. To make the current login session pass the already-exported value to newly launched GUI apps:

❯terminal
launchctl setenv ENVPILOT_API_KEY "$ENVPILOT_API_KEY"

Fully quit and reopen Codex, Cursor, or the IDE afterward. launchctl setenv lasts only for the current login session; after logout or restart, set it again (preferably from a login automation that reads a keychain or password manager—do not embed the raw key in a LaunchAgent plist). Do not run launchctl getenv ENVPILOT_API_KEY without redirecting it, because that prints the secret.

Linux#

For the current bash session:

❯terminal
read -rsp "Envpilot API key: " ENVPILOT_API_KEY; echo
export ENVPILOT_API_KEY

For future terminal sessions, have a secret manager inject it or edit the appropriate user-only login file (do not build the line with a shell command that would record the key in history):

❯terminal
# ~/.profile
export ENVPILOT_API_KEY='envpk_your_key_here'

A literal export is stored as plaintext, so keep the file private:

❯terminal
chmod 600 ~/.profile

A desktop launcher inherits the graphical login session, not an interactive shell's .bashrc. The simplest safe option is to launch the app from a terminal that already has the variable. On systemd-based desktops, you can also import the current value into the user and D-Bus activation environments:

❯terminal
systemctl --user import-environment ENVPILOT_API_KEY
dbus-update-activation-environment --systemd ENVPILOT_API_KEY

Then fully quit and reopen the app. For persistence, configure the variable through your desktop login environment or secret manager and sign out and back in; do not put the raw key in a .desktop launcher.

Windows PowerShell#

Set the key for the current PowerShell process without echoing the input:

❯powershell
$secret = Read-Host "Envpilot API key" -AsSecureString
$pointer = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($secret)
try {
  $env:ENVPILOT_API_KEY = [Runtime.InteropServices.Marshal]::PtrToStringBSTR($pointer)
} finally {
  [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($pointer)
}
Remove-Variable secret, pointer

Child processes launched from that PowerShell window inherit it. To persist the current value for your Windows user:

❯powershell
[Environment]::SetEnvironmentVariable(
  "ENVPILOT_API_KEY",
  $env:ENVPILOT_API_KEY,
  "User"
)

The User-scope value is stored in your Windows profile and is available only to new processes. Fully quit and reopen terminals, Codex, Cursor, and IDE windows; already-running processes keep their old environment.

WSL#

Windows and WSL have separate process environments. A Windows User-scope variable does not automatically configure clients running inside WSL, and a variable exported in WSL does not configure Windows GUI apps. Set ENVPILOT_API_KEY separately inside the WSL distribution using the Linux instructions, then start the WSL-hosted client from a new WSL shell.

Check presence without printing the key#

Use a boolean check—never echo, printenv, Get-ChildItem Env:, or an unredirected launchctl getenv for a secret:

❯terminal
if [ -n "${ENVPILOT_API_KEY:-}" ]; then
  echo "ENVPILOT_API_KEY is set"
else
  echo "ENVPILOT_API_KEY is not set"
fi
❯powershell
if ([string]::IsNullOrEmpty($env:ENVPILOT_API_KEY)) {
  "ENVPILOT_API_KEY is not set"
} else {
  "ENVPILOT_API_KEY is set"
}

A repository .env or .env.local file does not automatically configure an MCP client. Those files are conventions loaded only by frameworks or commands that explicitly read them. Codex, Claude Code, Cursor, and desktop launchers inspect their own process environment; they do not source arbitrary repository dotenv files. Keeping the MCP credential outside the repository also prevents an agent from reading the very key that controls its access.

Rotating or updating a key#

A key's projects, environments, resources, and surfaces are fixed at creation. To recover a lost key, rotate a credential, or grant different access (for example, adding the projects resource or MCP surface), create a new key with the complete intended scope.

  1. Store the new value in the same environment-variable source. If you set both a persistent value and a current-session value, update both—an already-running shell or GUI process keeps the old value.
  2. For macOS GUI clients, update launchctl; for Linux desktop clients, update the login/user environment; for Windows, update the User-scope value. WSL remains separate.
  3. Fully quit and restart the client. The saved Claude Code, Codex, and Cursor configurations still reference the same variable name and need no secret edit.
  4. Confirm /mcp or the client's MCP panel lists the Envpilot tools, then make a permitted tool call.
  5. Revoke the old key in Organization → Settings → API Keys.

Revocation is instant—anything still using the old key stops on its next call. If you previously pasted a key directly into Claude Code, remove and re-add the server (claude mcp remove envpilot) or edit the saved entry; claude mcp add does not overwrite an existing server name.

Connecting a client with a key#

Set ENVPILOT_API_KEY in the client's environment first, using the instructions above.

Claude Code#

Reference the environment variable in an expanded Authorization header:

❯terminal
claude mcp add --transport http --scope user \
  envpilot https://www.envpilot.dev/api/mcp \
  --header 'Authorization: Bearer ${ENVPILOT_API_KEY}'

The single quotes matter in POSIX shells: they keep ${ENVPILOT_API_KEY} literal in the saved configuration, and Claude Code expands it from its environment at connection time. The secret never lands in the file.

Choose the Claude Code configuration scope deliberately:

  • --scope local (the default) keeps the server private to you in the current project.
  • --scope project writes .mcp.json for the team. The environment-variable reference is safe to commit, but each user must set their own key and approve/trust the project server before tools load.
  • --scope user keeps the server private to your user and makes it available across projects.

claude mcp list confirms the server is registered — a revoked or wrong key still shows as listed. To verify the connection is actually live and its tools loaded, run /mcp inside a session. Manage it later with claude mcp get envpilot / claude mcp remove envpilot.

Codex CLI, desktop, and IDE extension#

Codex's local CLI, desktop app, and IDE extension share the same MCP configuration layers. Register the server from the CLI:

❯terminal
codex mcp add envpilot --url https://www.envpilot.dev/api/mcp \
  --bearer-token-env-var ENVPILOT_API_KEY

Or add it to the user-level ~/.codex/config.toml:

❯toml
[mcp_servers.envpilot]
url = "https://www.envpilot.dev/api/mcp"
bearer_token_env_var = "ENVPILOT_API_KEY"

The url selects Streamable HTTP, while bearer_token_env_var makes Codex build the bearer header from the named variable. Do not replace it with the plaintext key.

You may put the same block in .codex/config.toml to scope it to a repository, but Codex loads project configuration only after you trust that project. After changing the variable or configuration, start a new CLI session, select Restart for the server in Codex desktop, or restart the IDE extension. Run /mcp to confirm the server is connected and the Envpilot tools—not merely the saved server entry—are present.

Cursor#

Add a remote server to the global ~/.cursor/mcp.json, or to .cursor/mcp.json for a trusted project:

❯json
{
  "mcpServers": {
    "envpilot": {
      "url": "https://www.envpilot.dev/api/mcp",
      "headers": {
        "Authorization": "Bearer ${env:ENVPILOT_API_KEY}"
      }
    }
  }
}

Cursor resolves ${env:ENVPILOT_API_KEY} from the environment it inherited at startup. Fully quit and reopen Cursor after setting or rotating the variable, then confirm the tools under MCP settings. Do not commit a raw envpk_... value.

Other Streamable HTTP clients#

Configure the endpoint as Streamable HTTP and send this header on every request:

❯text
Authorization: Bearer <the ENVPILOT_API_KEY value>

Prefer a client-native secret store or environment-variable reference. Placeholder syntax is client-specific: do not assume a generic client expands ${ENVPILOT_API_KEY} or ${env:ENVPILOT_API_KEY}.

Troubleshooting a key connection#

New MCP keys cannot be created. Where a fix below says to create a replacement key, switch the client to sign-in instead.

A failed MCP tool call returns an error message in its result — no separate error code, since tool clients only see the text. The table lists each message (tool-specific variants may append detail, e.g. the request tools' — filing requests needs the "requests" resource). One exception: a missing or malformed Authorization header is rejected at the transport level with HTTP 401 before any tool runs.

First separate client setup failures from Envpilot tool errors:

SymptomMeaning / fix
Server is registered but has no toolsRegistration only proves the config was saved. Open /mcp or the client's MCP panel and inspect initialization. The most common cause is that the client process did not inherit ENVPILOT_API_KEY; set it in the parent environment and fully restart the client.
Works in a terminal, not a GUI appThe terminal has a current-session variable, but the desktop launcher started from a different environment. Use launchctl on macOS, the graphical login/user environment on Linux, or Windows User scope, then launch a new process.
Works on Windows but not in WSLWindows and WSL environments are separate. Set the key inside the WSL distribution and restart the WSL-hosted client.
Header contains ${...} literallyThe client did not expand the placeholder. Claude Code uses ${ENVPILOT_API_KEY}; Cursor uses ${env:ENVPILOT_API_KEY}; Codex uses bearer_token_env_var = "ENVPILOT_API_KEY". Confirm the client supports that syntax and inherited the variable, then restart it.
HTTP 401 before tools loadEnsure the header is exactly Authorization: Bearer envpk_...: one Bearer prefix, one space, no surrounding quotes in the value, no duplicated prefix, and no literal placeholder. Use a safe presence check instead of printing the key.

Once tools load, these are the server's error semantics:

MessageMeaning / fix
Invalid or revoked API keyThe key is wrong, revoked, or expired—create a replacement key.
That resource is not in this API key's scopeThe key is missing the resource a tool needs. Scopes are immutable: use the Tools table to create a replacement with the required resource. Request tools append — filing requests needs the "requests" resource.
That environment is not in this API key's scopeThe key is limited to other environments. Use one already in scope, or create a replacement key that includes the required environment.
Project not foundThe slug is wrong, or the project is outside the key's immutable scope—the two are indistinguishable by design; see Understand scope.
This API key is not enabled for this surfaceThe key was created without the MCP server surface. Surfaces are immutable: create a replacement with MCP server selected.
The public API is available on the Pro plan — this organization's plan no longer includes itThe organization's plan no longer includes MCP access.
Rate limit exceeded — retry after NmsHit a rate-limit bucket: 120/min metadata or 30/min value pulls (both shared with REST), or 5/hour (burst 2) for envpilot_request_variable—back off for the given delay.
Missing or invalid API key. (HTTP 401)Transport-level rejection before any tool runs—the Authorization header is missing or malformed. It must resolve to Bearer envpk_..., not a literal placeholder.

Older server builds returned an opaque [Request ID] Server Error for all of the above instead of the real message — if you see that instead of one of these strings, the connected server predates this fix.

Limits#

  • Scope cannot be widened. Adding a project, environment or resource means a new key and a client restart.
  • The key is shown once. Store it in an environment variable, never in a config file you commit.
  • Pro plan (mcp_server), re-checked on every tool call.
  • Placeholder syntax is client-specific: ${VAR}, ${env:VAR} and bearer_token_env_var are not interchangeable.
  • A client only inherits the environment it was launched with; changing the key means fully restarting it.
← mcp serverAgent requests
web dashboard →Dashboard overview

// on this page

  • Creating an MCP key
  • Endpoint
  • macOS
  • Linux
  • Windows PowerShell
  • WSL
  • Check presence without printing the key
  • Rotating or updating a key
  • Connecting a client with a key
  • Claude Code
  • Codex CLI, desktop, and IDE extension
  • Cursor
  • Other Streamable HTTP clients
  • Troubleshooting a key connection
  • Limits