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.
Placeholders
Section titled “Placeholders”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.
Provide values at install
Section titled “Provide values at install”You can supply placeholder values in two ways:
| Method | How |
|---|---|
| Web UI | Run capa install (managed). capa opens a local prompt for missing variables. |
.env file | Run capa install -e (loads project .env) or capa install -e .prod.env |
# .env: keys match the placeholder name without ${}BraveApiKey=your-api-key
capa install -ecapa install -e .staging.envResolved 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.
On-demand secret sources
Section titled “On-demand secret sources”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:
| Source | Resolves to |
|---|---|
fromEnv: NAME | The 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_TOKENFrom 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.
Storage and encryption
Section titled “Storage and encryption”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.
Private git
Section titled “Private git”Skills, plugins, rules, and agent snippets from private GitHub or GitLab repos need git authentication. Authenticate once with:
capa auth github.com --access-token <token> # personal access token (recommended)capa auth github.com # browser OAuthcapa auth gitlab.comcapa 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.
Checklist
Section titled “Checklist”- Replace literal secrets in the capabilities file with
${VarName}placeholders orfromEnv/fromCommand/fromFilesources. - Run
capa auth <host> --access-token <token>(orcapa auth <host>) if any remotes are private. - Run
capa installand complete the web UI prompts, orcapa install -ewith a local env file (add--headlessin CI). - Confirm tools that need those env vars work via your client or
capa sh.
Related
Section titled “Related”- Web UI
- CLI: install · CLI: auth
- Servers (common place for
${VarName}indef.env/ headers)