Skip to content
varsafe
Esc
navigateopen⌘Jpreview
On this page

MCP Server (AI Agents)

Give AI coding assistants scoped, audited access to your secrets — hosted OAuth 2.1 endpoint or local stdio server, scoped tools, per-team grants.

CLI v7.2.7

Connect AI coding assistants like Claude Code and Cursor to varsafe via the Model Context Protocol. Your AI agent can list projects, read secrets, set values, compare environments, and export configurations — all with fine-grained permissions and a full audit trail.

Ways to Connect

varsafe offers two MCP transports, and the hosted one accepts two kinds of credential. They are near-identical, but not interchangeable — two tools exist on only one transport, so check the tool reference before committing:

Option Transport Auth Best for
Hosted + OAuth HTTPS OAuth 2.1 Zero-config: browser-based consent, no tokens to manage
Hosted + API token HTTPS API token Headless machines, or a different account from the one your CLI uses
Local stdio stdin/out API token Local inspection, self-hosting, or MCP clients without URL support

The two overlap heavily but are not identical: varsafe_generate_secret exists only on the hosted transport, and shared tools take different parameter names (the hosted endpoint uses environmentSlug, the stdio server uses environment). The stdio server also accepts a teamId argument on every tool, required when your token spans multiple teams. The tool reference lists both signatures per tool.

The Hosted option is the default recommendation — most users should start there.

How It Works (Hosted)

  1. Discover — Your AI tool reads the MCP server URL and discovers OAuth endpoints automatically
  2. Consent — Your browser opens a consent screen where you choose teams, scopes, and optional restrictions
  3. Authorize — The agent receives an OAuth 2.1 access token (PKCE-secured, 1-hour expiry, auto-refreshed)
  4. Use — The agent calls varsafe tools with the token; every action is audited

Quick Setup

Add the varsafe MCP server to your AI tool’s configuration.

Claude Code

Run the claude mcp add command:

claude mcp add --scope user --transport http varsafe https://api.varsafe.dev/mcp

--scope user registers the server globally for every project (written to ~/.claude.json). Drop it to add the server to the current project’s .mcp.json instead, which you can commit to share with teammates.

Prefer to manage the config by hand? Drop this into a .mcp.json at the repo root:

{
  "mcpServers": {
    "varsafe": {
      "type": "http",
      "url": "https://api.varsafe.dev/mcp"
    }
  }
}

Cursor

Add to .cursor/mcp.json (project) or ~/.cursor/mcp.json (global):

{
  "mcpServers": {
    "varsafe": {
      "type": "url",
      "url": "https://api.varsafe.dev/mcp"
    }
  }
}

On the first tool call, your browser opens a consent screen. Pick your teams and scope preset, and you’re connected.


Connect With an API Token

The OAuth flow opens a browser and waits for the redirect to come back to the machine your MCP client is running on. That machine and the browser have to be the same one. If you start the flow on a headless server over SSH and open the link on your laptop, the callback lands on your laptop’s localhost, where nothing is listening, and authorization never completes.

An API token connects to the same hosted endpoint without a browser. It is also how you run your agent as a different account from your CLI — the token is independent of whatever identity varsafe login stored in your keychain.

1. Create a token with MCP scopes

In the dashboard, go to API Tokens, create a token, and grant it the MCP scopes the agent needs. A token without MCP scopes is refused by the MCP endpoint — existing tokens are unaffected and cannot drive an agent until you say so.

Scopes are bounded by the token’s access level and by your own role: a read-only token cannot hold secrets:write, and narrowing a token to read-only later removes that scope automatically.

2. Point your client at the hosted endpoint with the token attached

claude mcp add --scope user --transport http varsafe https://api.varsafe.dev/mcp \
  --header "Authorization: Bearer vs_at_..."

Or in configuration:

{
  "mcpServers": {
    "varsafe": {
      "type": "http",
      "url": "https://api.varsafe.dev/mcp",
      "headers": { "Authorization": "Bearer vs_at_..." }
    }
  }
}

Because the request already carries a credential, the endpoint never asks for authorization — your client shows the server as connected rather than prompting you to authenticate.

Actions taken through a token are audited as the token, not as the person who created it. The creator’s team membership still governs the token: if they leave the team or are deactivated, the token stops working.


Local Stdio Alternative

If you prefer to run the MCP server as a local subprocess — useful for self-hosted instances, inspection, or clients that don’t support "type": "url" — use the @varsafe/mcp-server npm package (it also installs a varsafe-mcp binary if you prefer a global install over npx).

1. Create an API token

In the dashboard, go to API Tokens, select the team, and click Create API Token. Copy the token — it’s only shown once.

2. Add the local stdio config

Claude Code — run:

claude mcp add --scope user --env VARSAFE_API_TOKEN=vs_at_... varsafe -- npx -y @varsafe/mcp-server

Or commit a project-scope .mcp.json at the repo root:

{
  "mcpServers": {
    "varsafe": {
      "command": "npx",
      "args": ["-y", "@varsafe/mcp-server"],
      "env": {
        "VARSAFE_API_TOKEN": "vs_at_..."
      }
    }
  }
}

Cursor — add to .cursor/mcp.json:

{
  "mcpServers": {
    "varsafe": {
      "command": "npx",
      "args": ["-y", "@varsafe/mcp-server"],
      "env": {
        "VARSAFE_API_TOKEN": "vs_at_..."
      }
    }
  }
}

3. Environment variables

Variable Required Default Description
VARSAFE_API_TOKEN Yes varsafe API token (vs_at_...). VARSAFE_TOKEN is accepted as an alias.
VARSAFE_API_URL No https://api.varsafe.dev Override the API base URL (self-hosted instances, staging, etc.).
VARSAFE_MCP_DEBUG No unset When set to any truthy value, logs every API call to stderr.

Trade-offs

  • Hosted is faster to set up (no token), auto-refreshes, and gets new tools without any update. Preferred for most users.
  • Local stdio keeps the token under your control, works offline against self-hosted instances, and is inspectable — every file is readable in the @varsafe/mcp-server package on npm or GitHub.
  • Both share the same audit trail server-side, so you can switch freely.

When your AI tool connects for the first time, your browser opens a consent screen where you control exactly what the agent can access.

Scope Presets

Choose how much access to grant:

Preset What the agent can do
Read Only List projects, environments, and secret keys (no values)
Secrets Full Everything in Read Only + read secret values, write secrets, export
Full Access Everything in Secrets Full + audit log access

Granular Restrictions

You can further limit what the agent accesses:

  • Team selection — Choose which teams to grant access to
  • Project restrictions — Limit to specific projects within a team
  • Environment restrictions — Limit to specific environments (e.g., only development, never production)

When no project or environment restriction is set, the agent can access all projects and environments in the granted teams — subject to your own role permissions.

Client Verification

The consent screen shows whether the connecting client is a verified application:

  • Verified (green shield) — Pre-registered clients like Claude Code (Anthropic) and Cursor
  • Third-party — Dynamically registered MCP clients; review carefully before approving

Available Tools

varsafe exposes 11 MCP tools across two transports:

Transport Endpoint Tools
Remote https://api.varsafe.dev/mcp 11
Subprocess npx @varsafe/mcp-server 10

The two transports are not interchangeable. 1 tool(s) exist on only one transport: varsafe_generate_secret (remote only). Check the Available on line before relying on a tool.

Parameter names differ between transports for varsafe_list_secrets, varsafe_diff_secrets, varsafe_get_secret_value, varsafe_get_secret_values, varsafe_export_secrets, varsafe_set_secret, varsafe_unset_secret. Each entry below lists both. The remote transport also accepts a teamId on every tool, which is required when the access token spans multiple teams.

varsafe_whoami

View current identity, granted teams, and scopes

Available on: remote + subprocess · Scopes: identity:read · Category: read

Remote parameters

Parameter Type Required Description
teamId string no Team ID to operate on. Required when the access token spans multiple teams; optional when only one team was consented (defaults to that team).

Subprocess parameters

Takes no parameters.

varsafe_list_projects

List all projects in a team

Available on: remote + subprocess · Scopes: projects:read · Category: read

Remote parameters

Parameter Type Required Description
teamId string no Team ID to operate on. Required when the access token spans multiple teams; optional when only one team was consented (defaults to that team).

Subprocess parameters

Takes no parameters.

varsafe_list_environments

List environments in a project

Available on: remote + subprocess · Scopes: projects:read · Category: read

Remote parameters

Parameter Type Required Description
projectId string yes Project ID
teamId string no Team ID to operate on. Required when the access token spans multiple teams; optional when only one team was consented (defaults to that team).

Subprocess parameters

Parameter Type Required Description
projectId string yes Project UUID — obtain via varsafe_list_projects.

varsafe_list_secrets

List secrets in an environment (metadata only, no values)

Available on: remote + subprocess · Scopes: secrets:read · Category: read

Remote parameters

Parameter Type Required Description
projectId string yes Project ID
environmentSlug string yes Environment slug (e.g. “production”)
teamId string no Team ID to operate on. Required when the access token spans multiple teams; optional when only one team was consented (defaults to that team).

Subprocess parameters

Parameter Type Required Description
projectId string yes Project UUID.
environment string yes Environment slug, e.g. “development”, “staging”, “production”.

varsafe_diff_secrets

Compare secret keys between two environments

Available on: remote + subprocess · Scopes: secrets:read · Category: read

Remote parameters

Parameter Type Required Description
projectId string yes Project ID
sourceEnvSlug string yes Source environment slug
targetEnvSlug string yes Target environment slug
teamId string no Team ID to operate on. Required when the access token spans multiple teams; optional when only one team was consented (defaults to that team).

Subprocess parameters

Parameter Type Required Description
projectId string yes Project UUID.
sourceEnv string yes Source environment slug to compare from.
targetEnv string yes Target environment slug to compare against.

varsafe_get_secret_value

Read the decrypted value of ONE secret, by key. Prefer this over varsafe_get_secret_values, which returns every value in the environment.

Available on: remote + subprocess · Scopes: secrets:read_values · Category: export

Remote parameters

Parameter Type Required Description
projectId string yes Project ID
environmentSlug string yes Environment slug (e.g. “production”)
key string yes Key of the single secret to read, in UPPER_SNAKE_CASE
teamId string no Team ID to operate on. Required when the access token spans multiple teams; optional when only one team was consented (defaults to that team).

Subprocess parameters

Parameter Type Required Description
projectId string yes Project UUID.
environment string yes Environment slug, e.g. “production”.
key string yes Key of the single secret to read, in UPPER_SNAKE_CASE.

varsafe_get_secret_values

List secrets with their decrypted values in an environment

Available on: remote + subprocess · Scopes: secrets:read_values · Category: export

Remote parameters

Parameter Type Required Description
projectId string yes Project ID
environmentSlug string yes Environment slug (e.g. “production”)
teamId string no Team ID to operate on. Required when the access token spans multiple teams; optional when only one team was consented (defaults to that team).

Subprocess parameters

Parameter Type Required Description
projectId string yes Project UUID.
environment string yes Environment slug, e.g. “production”.

varsafe_export_secrets

Export all secrets as key-value pairs for injection (e.g. into shell environment)

Available on: remote + subprocess · Scopes: secrets:run · Category: export

Remote parameters

Parameter Type Required Description
projectId string yes Project ID
environmentSlug string yes Environment slug (e.g. “production”)
includePattern string no Optional glob pattern to filter keys (e.g. “DB_*”); * is the only wildcard
teamId string no Team ID to operate on. Required when the access token spans multiple teams; optional when only one team was consented (defaults to that team).

Subprocess parameters

Parameter Type Required Description
projectId string yes Project UUID.
environment string yes Environment slug, e.g. “production”.

varsafe_set_secret

Create or update a secret in an environment

Available on: remote + subprocess · Scopes: secrets:write · Category: write

Remote parameters

Parameter Type Required Description
projectId string yes Project ID
environmentSlug string yes Environment slug (e.g. “production”)
key string yes Secret key name (e.g. “DATABASE_URL”)
value string yes Secret value
teamId string no Team ID to operate on. Required when the access token spans multiple teams; optional when only one team was consented (defaults to that team).

Subprocess parameters

Parameter Type Required Description
projectId string yes Project UUID.
environment string yes Environment slug, e.g. “production”.
key string yes Secret key name in UPPER_SNAKE_CASE.
value string yes The secret value to store.

varsafe_unset_secret

Delete a secret from an environment

Available on: remote + subprocess · Scopes: secrets:write · Category: write

Remote parameters

Parameter Type Required Description
projectId string yes Project ID
environmentSlug string yes Environment slug (e.g. “production”)
key string yes Secret key name to delete
disposition flatten | cascade no Required only if other secrets are composed from this one: “flatten” copies this secret’s current value into each of them, “cascade” deletes them too
teamId string no Team ID to operate on. Required when the access token spans multiple teams; optional when only one team was consented (defaults to that team).

Subprocess parameters

Parameter Type Required Description
projectId string yes Project UUID.
environment string yes Environment slug, e.g. “production”.
key string yes Secret key name to delete.
disposition flatten | cascade no Required only when other secrets are composed from this one. “flatten” copies this secret’s current value into each of them so they keep working; “cascade” deletes them too.

varsafe_generate_secret

Server-generates a secret value with the chosen shape and stores it (create or update). Plaintext never appears in the conversation transcript — generated and stored in one call. Use for HMAC keys, signing keys, webhook secrets, UUIDs, random passwords. Returns metadata + a sha256 fingerprint of the value for rotation verification.

Available on: remote only · Scopes: secrets:write · Category: write

Parameter Type Required Description
projectId string yes Project ID
environmentSlug string yes Environment slug (e.g. “production”)
key string yes Secret key name (e.g. “SECRET_OPERATION_HMAC_KEY”)
format random_bytes | uuid | alphanumeric | hex_token no Output shape: random_bytes (default, base64-encoded entropy), uuid (RFC 4122 v4), alphanumeric ([A-Za-z0-9]^length), hex_token (hex-encoded entropy). — default "random_bytes"
bytes number no Random byte count for random_bytes / hex_token. Default 32 (256-bit).
encoding base64 | hex | base64url no Encoding for random_bytes (base64 default).
length number no Character length for alphanumeric. Default 32.
prefix string no Optional literal prefix prepended to the generated value (e.g. “vk_”, “whsec_”).
teamId string no Team ID to operate on. Required when the access token spans multiple teams; optional when only one team was consented (defaults to that team).

Scopes Reference

Scope Description
identity:read View user identity and granted teams
projects:read List projects and environments
secrets:read List secret keys and metadata (no values)
secrets:read_values Read decrypted secret values
secrets:write Create, update, and delete secrets
secrets:run Export secrets for injection
audit:read View audit logs

Managing Connections

Viewing Active Connections

Go to MCP in the dashboard sidebar to see all active agent connections. Each connection shows:

  • Client name and verification status
  • Team access
  • Granted scopes
  • Connection date and last-used date

Revoking Access

Click Revoke on any connection to immediately disconnect the agent. The agent will need to re-authorize through the consent screen to reconnect.

Auto-Expiration

Connections that haven’t been used for 90 days are automatically expired. Re-authorize by using the agent again — the consent flow will re-trigger.


Security Model

OAuth 2.1 with PKCE

MCP uses the OAuth 2.1 authorization code flow with Proof Key for Code Exchange (PKCE S256). This means:

  • No client secrets are stored on your machine
  • Authorization codes are single-use (5-minute expiry)
  • Access tokens are short-lived (1 hour) and auto-refreshed
  • Refresh tokens are rotated on every use (old tokens are invalidated)

Audit Trail

Every MCP tool call is logged in the audit trail, just like CLI and dashboard actions. You can see:

  • Which agent performed the action
  • Which team, project, and environment were accessed
  • The specific operation (list, read values, write, export)
  • Timestamp and IP address

Rate Limits

MCP tools are rate-limited per connection:

Category Limit Burst
Read operations 120/min 30
Write operations 60/min 15
Export operations 20/min 5

When rate-limited, the agent receives a 429 response with a Retry-After header.

Permission Boundaries

MCP grants are bounded by your own permissions:

  • If you’re a Developer, the agent can’t write to protected environments — even with secrets:write scope
  • If you restrict the grant to specific projects, the agent can’t access other projects
  • Your role’s access level is the ceiling; MCP scopes can only narrow it further

Example Workflows

Ask your agent to check for missing secrets

“Compare the secrets between staging and production for the api-backend project. Are there any keys missing in production?”

The agent uses varsafe_list_projects to find the project, then varsafe_diff_secrets to compare environments.

Set a secret from your editor

“Set the OPENAI_API_KEY to sk-proj-abc123 in the development environment of my api project.”

The agent uses varsafe_set_secret to create or update the secret.

Export secrets for a local script

“Export all secrets matching DB_* from the staging environment.”

The agent uses varsafe_export_secrets with the includePattern parameter to filter by glob.


Troubleshooting

No MCP connections’ after setup

The consent flow only triggers on the first tool call, not when the config is added. Ask your AI agent to do something with varsafe (e.g., “list my varsafe projects”) to trigger the authorization.

Make sure you’re logged into the varsafe dashboard in the same browser that will handle the OAuth redirect. The MCP server redirects to your dashboard for consent.

Agent says ‘access denied’ for a project

Check your grant restrictions. If you limited the grant to specific projects or environments during consent, the agent can’t access anything outside those restrictions. Revoke the connection and re-authorize with broader access.

Agent stopped working after a while

Connections auto-expire after 90 days of inactivity. The agent will re-trigger the consent flow automatically — just use it again.

Rate limit exceeded

MCP tools are rate-limited. Wait for the Retry-After period and try again. If you’re hitting limits regularly, batch your requests or space them out.