Skip to content

Credentials

Keep API keys and tokens out of capabilities.yaml. Use capa placeholders for install-time secrets, and capa auth when remotes need git OAuth.

Anywhere in the capabilities file (for example server env or headers), write ${VarName}:

servers:
- id: brave
type: mcp
def:
cmd: npx
args: ['-y', '@modelcontextprotocol/server-brave-search']
env:
BRAVE_API_KEY: ${BraveApiKey}

capa resolves ${VarName} at install time. These are not shell variables and are not expanded into provider hook environments as process env by default.

You can supply placeholder values in two ways:

MethodHow
Web UIRun capa install (managed). capa opens a local prompt for missing variables.
.env fileRun capa install -e (loads project .env) or capa install -e .prod.env
Terminal window
# .env: keys match the placeholder name without ${}
BraveApiKey=your-api-key
capa install -e
capa install -e .staging.env

Resolved values are stored per project in ~/.capa/capa.db, encrypted (see Storage and encryption). Subsequent installs reuse stored credentials unless you replace them via the UI or another -e file.

If a server is still missing a value, capa install does not fail on it: that server’s tools are reported as pending credentials (for example ⏳ 2 pending credentials (@brave)). Supply the value and install again.

In CI or a cloud sandbox, pass the global --headless flag so install prints the credential setup URL instead of trying to open a browser.

MCP server env and headers values can also point at a secret that capa fetches when it connects to the server, instead of storing it. Each value is either a string (literal or ${VarName}) or an object with exactly one of these keys:

SourceResolves to
fromEnv: NAMEThe environment variable NAME. Errors if it is unset or empty
fromCommand: <command>The command’s stdout, trimmed. Runs through the system shell with a 10-second timeout; a non-zero exit or empty output is an error
fromFile: <path>The file’s contents, minus one trailing newline. Relative paths resolve from the project root
servers:
- id: brave
type: mcp
def:
cmd: npx
args: ['-y', '@modelcontextprotocol/server-brave-search']
env:
BRAVE_API_KEY:
fromCommand: op read "op://Engineering/Brave/credential"
- id: remote-mcp
type: mcp
def:
url: https://mcp.example.com
headers:
Authorization:
fromEnv: MCP_BEARER_TOKEN

From the CLI, capa add --server accepts --env-from-env, --env-from-command, and --env-from-file (plus the matching --header-from-* flags), each as KEY=VALUE.

capa never stores values from these sources. In managed mode the capa server resolves them, so fromEnv reads the environment the server was started with; after changing the variable, run capa restart from a shell where it is set. With --passthrough, sources are resolved once and the resulting value is written into the provider’s native config file.

A source that fails to resolve during install marks the server as pending credentials, just like a missing placeholder.

Stored variables, MCP OAuth tokens, and git credentials are encrypted at rest in ~/.capa/capa.db with AES-256-GCM. Plaintext values left by older capa versions are encrypted automatically the next time the database is opened.

The master key lives in the OS keyring when one is available (macOS Keychain, Windows Credential Manager, Linux Secret Service). Otherwise capa falls back to a key file at ~/.capa/master.key with owner-only permissions, which is typical on headless Linux and CI. capa status prints the active tier as Secret storage: keychain, dpapi, libsecret, or file (fallback). Set CAPA_SECRET_STORE=file to force the file tier.

The web UI and local HTTP API never return secret values: variables only show whether they are set, and server env / headers values are redacted when a project is read back.

MCP OAuth tokens survive an unreachable server or a transient refresh failure. capa deletes them only when the authorization server explicitly reports the token as invalid, expired, or revoked; reconnect the server from the web UI when that happens.

Skills, plugins, rules, and agent snippets from private GitHub or GitLab repos need git authentication. Authenticate once with:

Terminal window
capa auth github.com --access-token <token> # personal access token (recommended)
capa auth github.com # browser OAuth
capa auth gitlab.com

capa stores those credentials encrypted in the capa database and uses them when cloning or updating remotes during install (and when warming the cache). Tokens are handed to git without appearing in clone URLs, process arguments, or the cache’s git config.

  1. Replace literal secrets in the capabilities file with ${VarName} placeholders or fromEnv / fromCommand / fromFile sources.
  2. Run capa auth <host> --access-token <token> (or capa auth <host>) if any remotes are private.
  3. Run capa install and complete the web UI prompts, or capa install -e with a local env file (add --headless in CI).
  4. Confirm tools that need those env vars work via your client or capa sh.