// docs

MCP Server

Connect Claude, Cursor, or any MCP client directly to your Envpilot projects and variables.

MCP Server

MCP (Model Context Protocol) is an open standard that lets AI assistants like Claude call tools against your real data instead of guessing. Envpilot runs a remote MCP server so an assistant can look up your projects and pull variable values on your behalf, using the exact same auth, scoping, and audit trail as the REST API — nothing is duplicated or re-implemented.

Requires the Pro plan (mcp_server feature) and an API key.

Recommended key scopes: pick the resources for the MCP tools you intend to use — for the common project-discovery + variable-read workflow that means projects and variables. Most assistants open a session by calling envpilot_list_projects, so a key without projects typically fails on its first call with "That resource is not in this API key's scope" (a requests-only or accounts-only key is still valid for its own tools). The create-key form in Organization → Settings → API Keys shows this checklist live as you pick resources.

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

Connect a client#

Claude Code#

Export your key, then reference it — don't paste it inline:

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

The single quotes matter: they keep ${ENVPILOT_API_KEY} literal in the saved config, and Claude Code expands it from your environment at connect time — so the secret itself never lands in a file. That makes the shared scope safe: -s project writes a committable .mcp.json holding only the variable reference, -s user makes the server available across all your projects, and the default -s local keeps it to this project. (Never commit a config with the raw envpk_... key in it.)

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#

Codex reads the token from an environment variable rather than an inline header. Export your key, then register the server:

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

Or write it directly to ~/.codex/config.toml (use .codex/config.toml in a trusted project to scope it there):

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

The presence of url (rather than command) tells Codex to use the Streamable HTTP transport. Start a session and run /mcp to confirm the server is connected and its tools are listed.

Claude Desktop#

Open Settings → Connectors → Add custom connector, set the URL to https://www.envpilot.dev/api/mcp, and add a request header:

terminal
Authorization: Bearer <your-api-key>

Cursor#

Add a remote server entry to .cursor/mcp.json:

json
{
  "mcpServers": {
    "envpilot": {
      "url": "https://www.envpilot.dev/api/mcp",
      "headers": {
        "Authorization": "Bearer <your-api-key>"
      }
    }
  }
}

Rotating or updating a key#

A key's scopes are fixed at creation — to change what an existing MCP setup can do (say, adding the projects resource), create a new key with the right scopes and swap it into your client config. Where the swap happens depends on how you connected:

  • Claude Code / Codex CLI (env-var reference, as above): the saved config only holds ${ENVPILOT_API_KEY} — update the exported variable (in your shell profile) to the new key and restart the session. The config file itself needs no change.
  • Claude Code (key pasted inline): claude mcp remove envpilot, then re-run the claude mcp add command with the new key — claude mcp add refuses to overwrite an existing server name, so remove first. (Or edit the Authorization header in the config file directly: .mcp.json, or .claude.json for -s local servers.)
  • Claude Desktop: Settings → Connectors → edit the Envpilot connector's Authorization header.
  • Cursor: edit the Authorization header in .cursor/mcp.json.

Rotate safely: create the new key, swap it in, confirm a tool call works, then revoke the old key in Organization → Settings → API Keys. Revocation is instant — anything still using the old key stops working on its next call.

Tools#

The read tools share the same scope, rate limits, and plan gate as the REST API. Every value-returning call is audited. Resource is the API key resource each tool requires — see Understand scope.

ToolDescriptionResource
envpilot_list_projectsList every project in the key's scopeprojects
envpilot_get_variablesGet variables for a project + environment, with optional keys/prefix/metadata_only filtersvariables
envpilot_get_variableGet a single variable by exact keyvariables
envpilot_list_accountsList shared accounts (with credentials) for a project, optionally filtered by environmentaccounts
envpilot_searchSearch project names/slugs and variable keys (never values) across the key's projects, bounded to 20 projects / 100 matchesprojects (plus variables for key matches)

Two additional tools cover the only write path a machine credential has — filing a variable request for a human to approve. They are available only if the key's scope includes the requests resource:

ToolDescriptionResource
envpilot_request_variableFile a request for a variable, with a required justification. A human must approve it and supply the value.requests
envpilot_get_request_statusPoll a filed request — returns pending, approved, rejected (with the reviewer's reason), or canceled.requests

Requesting variables#

A machine credential can never write a secret value. The one thing it can do beyond reading is ask — and only if its key carries the requests resource. envpilot_request_variable takes the variable key and a required justification, and files a request into a human reviewer's dashboard queue. The agent never proposes a value; if the reviewer approves, the reviewer supplies it.

The loop for an agent is:

  1. Call envpilot_request_variable with the key and a justification explaining why it's needed.
  2. Poll envpilot_get_request_status until it returns approved or rejected.
  3. On approved, read the value with envpilot_get_variable. On rejected, the status carries the reviewer's reason — report it back rather than retrying blindly.

Request creation is deliberately strict: it is rate-limited to 5 per hour per key (burst 2), capped at 5 open pending requests per key, and a rejected request for a given variable can't be re-filed for 24 hours. Every created request emails a reviewer, so these limits stop an agent loop from becoming alert spam. See Rate limits for the full picture and Architecture for how "agent requests, human approves" fits the wider trust model.

Rate limits and scope#

MCP tool calls draw from the same rate-limit buckets as the REST API for that key — envpilot_get_variables and envpilot_list_accounts count against the 30/min value-pull bucket, everything else against the 120/min metadata bucket. A key's project/environment/resource scope applies identically: a tool call for a project outside the key's scope behaves as if it doesn't exist.

See API Reference for the underlying limits and error semantics, and API Security for the auth and audit model shared across the REST API, MCP server, and GitHub Action.

Troubleshooting#

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.

MessageMeaning / fix
Invalid or revoked API keyThe key is wrong, revoked, or expired — create a new key.
That resource is not in this API key's scopeThe key is missing the resource a tool needs — edit the key's scopes (see the Tools table). The 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 — add the environment, or use one already in scope.
Project not foundThe slug is wrong, or the project is outside the key's 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 enabled — enable it.
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 isn't Bearer envpk_....

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.