Skip to main content
Secrets management in mcp-agent cloud has two phases:
  1. Deployment secrets – values known at deploy time (provider API keys, service accounts, webhooks). Stored encrypted, mounted into the runtime automatically.
  2. User secrets – values each consumer must supply (personal access tokens, OAuth refresh tokens). Collected per user via mcp-agent cloud configure and scoped to that user’s configuration.
Understanding the difference lets you ship reusable agents without exposing credentials.

Secret files at a glance

FileWhenContainsChecked into git?
mcp_agent.secrets.yamlBefore deployRaw values you author locallyNo (add to .gitignore)
mcp_agent.deployed.secrets.yamlGenerated by mcp-agent deployHandles for deployment secrets, !user_secret placeholdersYes – safe to commit
mcp_agent.configured.secrets.yamlGenerated by mcp-agent cloud configureUser-supplied secrets bound to secret handlesOptional – safe to share with that user only

Step 1 – author your secrets file

Create mcp_agent.secrets.yaml next to mcp_agent.config.yaml:
openai:
  api_key: "sk-..."                 # deployment secret

notion:
  api_key: "!user_secret NOTION_KEY"  # user secret (collected later)

crm:
  base_url: "https://api.example.com"  # not a secret, but you can store config values too
You can tag secrets as user secrets in two ways:
notion:
  api_key: "!user_secret NOTION_KEY"     # inline tagged value
or
notion:
  api_key:
    !user_secret NOTION_KEY
Everything else is treated as a deployment secret by default.

Step 2 – transform during deployment

When you run mcp-agent deploy, the CLI:
  1. Loads mcp_agent.secrets.yaml.
  2. Asks how to treat each value (unless already tagged or using --non-interactive).
  3. Creates secrets via the cloud API and stores the resulting handles.
  4. Writes mcp_agent.deployed.secrets.yaml and bundles it with your deployment.
Example output:
? Store OPENAI_API_KEY as a deployment secret?  [Y/n] y
? Tag NOTION_KEY as user secret?  [Y/n] y
✓ Created 1 deployment secret, 1 user secret placeholder
✓ Wrote mcp_agent.deployed.secrets.yaml (commit safe)
Generated file:
mcp_agent.deployed.secrets.yaml
openai:
  api_key: !secret mcpac_sc_5c0e2d7b-5b1b-41af-b5c7-91e0a7c5c6f5

notion:
  api_key: !user_secret NOTION_KEY
Each !secret handle references an encrypted value stored in the control plane. Handles are opaque and cannot be used outside the deployment.

Step 3 – collect end-user secrets (optional)

If you exposed any !user_secret entries, share the deployment URL with your users and have them run:
mcp-agent cloud configure \
  --id https://<app_id>.deployments.mcp-agent.com
<app_id> is the hostname printed in your deployment output (for example, app_abc123xyz). The CLI:
  1. Checks what user secrets are required (--params shows them without storing).
  2. Prompts for each secret (or reads them from --secrets-file).
  3. Writes mcp_agent.configured.secrets.yaml (unless --dry-run).
  4. Uploads encrypted user secret handles tied to the caller’s API key.
Example output:
? Provide value for NOTION_KEY: ************************
✓ Stored 1 user secret
✓ Wrote mcp_agent.configured.secrets.yaml
Subsequent runs reuse stored values; use --dry-run to validate without persisting changes.

Sharing with automated clients

  • Provide mcp_agent.configured.secrets.yaml alongside the deployment URL for headless environments (CI, scheduled jobs).
  • Re-run mcp-agent cloud configure --params in pipelines to assert the contract matches expectations.
  • If you must rotate secrets automatically, script the configure command with --secrets-file.

Accessing secrets in code

Secrets are injected into your app via the config layer. Use app.config or the global settings helper:
from mcp_agent.config import get_settings

settings = get_settings()
openai_key = settings.openai.api_key           # decrypted value
notion_key = settings.notion.api_key           # user secret (per user)
You can also access them through environment variables if you prefer:
import os
api_key = os.environ["OPENAI__API_KEY"]
Deployment secrets are available to all users of the app. User secrets are scoped to the specific user/configuration that ran mcp-agent cloud configure and are only injected when that user’s API key is used to connect.

Non-interactive + CI/CD

  • Reuse existing handles: mcp-agent deploy --non-interactive reuses secrets stored in mcp_agent.deployed.secrets.yaml and fails if new values are required.
  • Custom API URL/keys: set MCP_API_KEY (or use --api-key) and MCP_API_BASE_URL for staging environments.
  • Partial updates: if you add a new entry to mcp_agent.secrets.yaml, the CLI prompts only for the new value.

Advanced tips

For local testing or one-off overrides, set MCP_APP_SETTINGS_PRELOAD to a YAML string that merges into the app settings before initialization. Useful when you do not want to create a secrets file on disk.
Handles are per deployment. If you want to share the same credential across multiple apps, store the raw value in a secure password manager and paste it during each deploy. Secret rotation APIs are on the roadmap.
Today rotation is manual (mcp-agent deploy with a new value). We log all secret creation/update events for future audit surfaces. Automatic rotation hooks are planned post-beta.
By default secrets are scoped to your user account. Team-wide sharing is coming with the upcoming workspace model—expect CLI flags to target a workspace instead of a personal scope.

Troubleshooting

  • “Must have API key to process secrets” – run mcp-agent login (or set MCP_API_KEY) before deploying.
  • Secrets not injected at runtime – double-check mcp_agent.deployed.secrets.yaml is present in your project and that you are reading via get_settings(). Also ensure the file is not ignored by .mcpacignore.
  • Configure prompts unexpectedly – you likely tagged a value as !user_secret. If it should be global, re-run mcp-agent deploy and choose “store as deployment secret”.
  • Need to revoke a user’s secrets – run mcp-agent cloud app revoke-config --id <configuration_id> (coming soon). For now, delete the configuration via the API or ask the user to run configure again.
I