MCP config API key: use an environment variable, not the file
Cursor, Claude Code, Windsurf and Codex can read an MCP API key from an environment variable. Here is each client's syntax and what an unset variable does.

Yes: keep the API key in an environment variable and let the MCP config point at it, so the key never lands in a file you commit. Cursor, Claude Code and Windsurf each expand a variable inside the config's headers; Codex names the variable instead. The syntax differs, and so does what happens when the variable is unset.
Client behavior below comes from each vendor's own page, read 2026-09-29. For Sume, an API-key session sends Authorization: Bearer <key> or x-api-key to https://mcp.sume.com/mcp, per MCP OAuth and API keys.
What is each client's syntax?
Cursor, Claude Code and Windsurf expand variables in headers, and Codex has fields that read a header value from a variable, so the Sume key goes in Authorization as Bearer plus the variable. Gemini CLI's page documents expansion for the env block only, so it is listed for comparison.
| Client | Syntax | Documented where | If the variable is unset |
|---|---|---|---|
| Cursor | ${env:NAME} | command, args, env, url, headers | Not stated on the page |
| Claude Code | ${VAR} or ${VAR:-default} | command, args, env, url, headers in .mcp.json | Loads with the ${VAR} text unexpanded and warns in claude mcp list |
| Windsurf | ${env:VAR_NAME}, or ${file:/path} for a file's contents | command, args, env, serverUrl, url, headers | Resolves to an empty string |
| Codex | bearer_token_env_var names the variable; env_http_headers maps header names to variable names | A [mcp_servers.<name>] table in config.toml | Not stated on the page |
| Gemini CLI | $VAR or ${VAR} | Documented for the env block of a server entry | Resolves to an empty string |
What does a Sume entry look like?
In Claude Code's .mcp.json, the transport type is required for a URL entry, and the header reads the variable:
- Cursor uses the same shape with no
typeand"Bearer ${env:SUME_API_KEY}". - Windsurf uses
serverUrlfor the address and${env:SUME_API_KEY}. - Codex takes
bearer_token_env_var = "SUME_API_KEY"under the server's table; see Codex bearer_token_env_var with Sume.
{
"mcpServers": {
"sume": {
"type": "http",
"url": "https://mcp.sume.com/mcp",
"headers": {
"Authorization": "Bearer ${SUME_API_KEY}"
}
}
}
}What happens if the variable is not set?
This is where the clients differ. Windsurf's page says an unset ${env:...} resolves to an empty string, so a header written as Bearer ${env:SUME_API_KEY} would carry no key at all, and the server would have nothing to authenticate. Claude Code keeps the literal ${VAR} text and warns, so the failure is visible in claude mcp list. Its page also says that in a remote server's url and headers, credential names such as ANTHROPIC_API_KEY always read as empty; a name of your own such as SUME_API_KEY expands as written.
Either way the fix is to export the variable in the shell or profile that launches the client. Cursor's page adds that remote servers do not support envFile, so for a remote server set the variable in your shell profile or system environment.
Is an API key the right credential here?
For interactive clients, Sume's quickstart prefers the OAuth connector flow and says not to paste API keys into chat. The API key remains the path for automation that does not speak OAuth. An API-key session sees the whole hosted tool set, including paid tools, so treat the variable like any secret and rotate the key if it appears in logs or chat history. See MCP server API key vs OAuth for the trade-off, and the quickstart for the OAuth setup.
Sources
Related posts
More in Integrations
- MCP OAuth rejects a callback with no iss: what to do
Gemini CLI and Codex validate the RFC 9207 iss parameter on the OAuth callback. Which clients reject a missing iss, and what a server without iss can rely on.
- Meta Ads CLI dynamic creative: limits for videos and text
Meta's Ads CLI dynamic creative takes up to 10 videos, 10 images and 5 each of titles, bodies, descriptions and CTAs. How to size a batch of AI variants.
- Meta Ads CLI video ad: upload an AI-generated MP4
Meta's Ads CLI makes a video ad from a local file with meta ads creative create --video. Download the Sume clip first, then upload; ads start paused.
- Meta ads MCP server in Claude Code: the add command
Meta's docs add its ads MCP server to Claude Code with one claude mcp add line. The same session can also add Sume's hosted MCP to make the video.
Written by Sume