MCP and environment

Configure external tools, sandbox environment variables, and secrets for a chat.

Environment variables

Use env to bake variables into a newly created sandbox:

{
  "env": {
    "API_HOST": "https://api.example.com",
    "FEATURE_FLAG": "enabled"
  }
}

Environment variables:

  • are accepted only when creating a chat;
  • are passed through the queued run and baked into sandbox creation;
  • are not persisted on the chat or turn;
  • remain available while that chat uses the sandbox.

Limits:

LimitValue
Variables64
Key length256 bytes
Value length32 KiB
Total keys and values128 KiB

Names must match:

[A-Za-z_][A-Za-z0-9_]*

Sending non-empty env while resuming a chat returns 422.

Secret environment variables

Use secret_env_vars for API keys the agent needs to call a specific service but should never hold. The agent only ever sees a placeholder; the sandbox's egress proxy swaps in the real value on requests to the hosts you list.

Each entry is an object with a name, a value, and a list of domains:

curl https://app.epho.io/api/v1/chat/async \
  -H "Authorization: Bearer $EPHO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "List the five most recent Stripe charges.",
    "harness": "claude",
    "model": "claude-sonnet-5",
    "provider_api_key": "'"$ANTHROPIC_API_KEY"'",
    "secret_env_vars": [
      {
        "name": "STRIPE_API_KEY",
        "value": "'"$STRIPE_API_KEY"'",
        "domains": ["api.stripe.com"]
      }
    ]
  }'

Inside the sandbox, the variable holds a per-run placeholder instead of the real key:

$ echo $STRIPE_API_KEY
usersecret-…

The agent uses it like a normal key. When a request to api.stripe.com goes through the proxy, the placeholder is replaced with the real value wherever it appears: in headers, the query string, or the body.

curl "https://api.stripe.com/v1/charges?limit=5" \
  -H "Authorization: Bearer $STRIPE_API_KEY"

If the placeholder ends up anywhere else (a log, a file, a request to another host), only the placeholder leaks; the real value is never exposed to the agent.

FieldRequiredDescription
nameYesThe environment variable the agent sees. Must match [A-Za-z_][A-Za-z0-9_]*, at most 256 bytes.
valueYesThe real secret. Injected by the proxy only; never exposed to the agent.
domainsYesAt least one hostname the real value may be sent to, such as api.stripe.com.

Secret environment variables:

  • are applied per turn, so send them on every request that needs them, including resumes with chat_id;
  • may change from turn to turn;
  • are not persisted on the chat or turn;
  • are redacted from the runner's logs.

Write domains as exact hostnames: no scheme, path, port, or wildcards. List every host the key is used with, for example both api.example.com and uploads.example.com. The API does not reject values like https://api.example.com, but they never match a request, so the key is silently not injected. Requests to listed hosts must use the standard HTTPS or HTTP ports.

The proxy can only swap the placeholder when it is sent as-is. A value that the client encodes or uses to compute something before sending (for example a Base64-encoded Basic auth header or a signed request) is not replaced, so prefer passing the key directly, such as in a Bearer header.

Limits:

LimitValue
Entries64
Name length256 bytes
Domains per entryAt least 1
Size of the JSON-encoded secret_env_vars array32 KiB

The API returns 422 when:

  • name, value, or domains is missing or not the right type;
  • a name is invalid, or an entry has no domains or an empty domain;
  • there are more than 64 entries, or the encoded array is over 32 KiB;
  • the chat runs on an agent runner version too old to support secret environment variables.

env or secret_env_vars?

envsecret_env_vars
What the agent seesThe real valueA placeholder
When it can be setFirst turn onlyEvery turn
Where the value can goAnywhereOnly the listed hosts
Use forConfiguration, URLs, flagsAPI keys and tokens

Stdio MCP servers

Define a local MCP process with command, optional args, and optional env:

{
  "mcp_servers": [
    {
      "name": "linear",
      "command": "npx",
      "args": ["-y", "@tacticlaunch/mcp-linear"],
      "env": {
        "LINEAR_API_TOKEN": "lin_..."
      }
    }
  ]
}

Remote MCP servers

Define a remote server with url, optional transport type, and optional headers:

{
  "mcp_servers": [
    {
      "name": "figma",
      "url": "https://mcp.figma.com/mcp",
      "type": "http",
      "headers": {
        "Authorization": "Bearer ..."
      }
    }
  ]
}

Remote type may be http or sse. Omitting it defaults to HTTP behavior in the runner.

MCP rules

  • Every server needs a unique name.
  • Each server must set exactly one of command or url.
  • bruin and agent-runner are reserved names.
  • Stdio arguments and environment values must be strings.
  • Remote header values must be strings.

MCP configuration is stored on the chat and inherited by every later turn. Unlike top-level env, MCP env and headers are therefore durable chat configuration. Do not resend mcp_servers with chat_id; the API returns 422.