MCP Server
The Envshed MCP server lets an AI agent work with your secrets without installing or configuring the CLI. You approve it once in the browser, and it can then look up what exists, see what is missing and ask a person for a secret.
No tool returns a secret value, and no tool accepts one. Whatever a tool returns enters the model's context, and whatever a tool receives is already in the transcript. So the server only deals in key names and statuses. A test fails if any tool gains a field that could hold a value.
It is available on every plan.
Connect Claude Code
claude mcp add --transport http envshed https://app.envshed.com/api/mcp
Then run /mcp inside Claude Code and follow the browser steps, or sign in from your shell with claude mcp login envshed. Claude Code stores the tokens and refreshes them, so you only do this once.
The browser shows you which application is asking and where it will return you. Your login and second factor apply as usual. Approve only if you started the connection: the application picks its own name, and Envshed cannot verify it.
Other MCP clients connect the same way, using the URL above.
Tools
| Tool | What it does |
|---|---|
list_organizations | Organizations this connection can reach |
list_projects | Projects in an organization |
list_environments | Environments in a project |
list_secret_keys | Key names in an environment, each set, placeholder, disabled or missing |
request_secret | Ask a person for a secret, and get the link where they enter it |
get_secret_request_status | Whether a request is pending, fulfilled, declined or expired |
list_secret_requests | Requests still waiting in an environment |
decline_secret_request | Decline a request. Needs write access |
list_agent_sessions | Live agent sessions. Signed-in people only |
revoke_agent_session | End an agent session. Signed-in people only |
Every tool applies the same permissions as the REST API: you never get more through MCP than your role already allows. A missing key is one defined for the project but absent from that environment. Each call is written to the audit log with the MCP client's name, or the token's id for a token, and counts toward your organization's API rate limit.
request_secret works like envshed request: a person opens the link and enters the value in the dashboard, so it never passes through the conversation.
Hosted Agents and Routines
A hosted agent or scheduled routine runs without a person. Choose the first of these that fits:
- MCP OAuth, where a person can approve once. If your platform lets a person sign in once and keeps the connection, use that. It works as above, with no token to store, and you can disconnect it at any time.
- OIDC workload identity, on GitHub Actions. No stored credential: the job proves which repository it runs in and gets a read-only session of at most an hour. See GitHub Actions with OIDC. This covers
envshed runin a job. The MCP server does not exchange ID tokens itself. - A machine token, everywhere else. Read-only, one environment, optional key limits. It stops after 90 days without use and rotates with no downtime. See machine tokens, and create one under Hosted agents in your organization.
Avoid calendar-expiry tokens for this. An annual token causes an outage when it runs out, and does not limit exposure when it leaks in its first month. A plain service token also works here, but it has no key limits and no idle expiry.
To use a token, pass it as a Bearer header. In Claude Code, put this in .mcp.json and set ENVSHED_TOKEN as a secret on the hosting platform, so the token stays out of the file:
{
"mcpServers": {
"envshed": {
"type": "http",
"url": "https://app.envshed.com/api/mcp",
"headers": {
"Authorization": "Bearer ${ENVSHED_TOKEN}"
}
}
}
}
The token keeps its limits. A token scoped to one environment only sees that environment, and a machine token or session limited to certain keys only sees those. Tokens cannot list or revoke agent sessions, and machine tokens and sessions cannot decline requests.
A personal CLI token from envshed login is refused here on purpose. It reaches everything you can reach and does not expire quickly, so use the browser flow or a scoped token.
Getting values at runtime
The MCP server does not hand out values. To run a program with its secrets:
- Create a machine token limited to what the job needs.
- Store it as a secret on the hosting platform, as
ENVSHED_TOKEN. - Run the program through the CLI:
envshed run -- npm start
The values go into the program's environment, not the conversation. An agent with a shell can still print that environment, so give the token only what the job needs.
An agent with no shell can use a tool you write. The tool fetches the value with the Node SDK, makes the call and returns only the result, so the model never sees the value:
import { EnvshedSecretsClient } from "@envshed/node";
const envshed = new EnvshedSecretsClient({
token: process.env.ENVSHED_TOKEN!,
org: "acme",
project: "billing",
env: "production",
});
export async function createInvoice(amount: number) {
const { secrets } = await envshed.secrets.list();
const response = await fetch("https://api.example.com/invoices", {
method: "POST",
headers: { Authorization: `Bearer ${secrets.BILLING_API_KEY}` },
body: JSON.stringify({ amount }),
});
return { ok: response.ok, status: response.status };
}
An agent with no shell and no code of your own, such as a third-party connector, cannot get values from Envshed today.
How Sign-In Works
The server follows the MCP authorization specification, revision 2026-07-28. Clients on 2025-era revisions are also served, without sessions.
| MCP endpoint | https://app.envshed.com/api/mcp (Streamable HTTP) |
| Protected resource metadata | /.well-known/oauth-protected-resource/api/mcp |
| Authorization server metadata | /.well-known/oauth-authorization-server |
| Client registration | /api/oauth/register, public clients only |
| Grant | Authorization code with PKCE (S256) |
| Access token | Lasts 1 hour, valid only on the MCP endpoint |
| Refresh token | Rotates on every use, lasts 30 days from its last use |
Redirect URIs must use HTTPS or a loopback address and must match what the client registered. On a loopback address only the port may differ, because desktop clients pick a free port each time.
Tokens are stored only as hashes. If a refresh token that was already used comes back, Envshed assumes it was stolen and ends that connection, so the client has to ask for your approval again. A client that lost the reply to a refresh sees the same thing.
Browser pages on other sites cannot call the MCP endpoint: a request with a foreign Origin header is refused, and there is no CORS.
Disconnecting a client
Open Settings > API Tokens. Under Connected MCP clients, choose Revoke. The client stops working on its next request.
What This Does Not Protect Against
This reduces accidental leaks. It is not a barrier against an agent with shell access.
- An agent with a shell can use other routes. It can run
envshed secret get, print its environment insideenvshed run, or read a.envfile with whatever access its login has. - A person can still paste a value into the chat. The server cannot see your conversation.
- A value can still get into a tool argument. Tools refuse a key name or
reasonthat matches a known token format, but a password with no recognizable shape looks like any other text. If an agent puts one there, it is saved and shown to whoever reads the request, and it is already in the transcript. - An approved client acts as you. It can see every key name you can see. Key names and the fact that a key exists are not secret here, and they do enter the model's context.
- The client name is not proof of identity. On a loopback address, any program on your computer could be the one asking.
- Whoever holds a token has its access. Keep it scoped and store it as a platform secret. Idle expiry limits a forgotten machine token. It does nothing for one that leaks and keeps being used.