`{env:...}` variable substitution inconsistently fails for specific MCP server URLs
Summary
Environment variable substitution using {env:VAR_NAME} syntax works for some remote MCP servers but fails for others, even when using identical configuration patterns.
Environment
- OS: macOS (darwin)
- OpenCode version: Latest (installed via npm)
- Shell: zsh
-
Config location:
~/.config/opencode/opencode.jsonc
Steps to Reproduce
- Configure two remote MCP servers with the same
{env:...}pattern inopencode.jsonc:
"mcp": {
"exa": {
"type": "remote",
"url": "https://mcp.exa.ai/mcp?exaApiKey={env:EXA_API_KEY}",
"enabled": true
},
"tavily": {
"type": "remote",
"url": "https://mcp.tavily.com/mcp?tavilyApiKey={env:TAVILY_API_KEY}",
"enabled": true
}
}
- Export both environment variables in ~/.zshrc:
export EXA_API_KEY=<valid-key>
export TAVILY_API_KEY=<valid-key>
- Start OpenCode from a terminal where both env vars are confirmed to be set.
- Invoke both MCP tools.
Expected Behavior
Both MCP servers should receive the API key and work correctly, since the configuration pattern is identical.
Actual Behavior
- Exa MCP: Works correctly. API key is substituted and requests succeed.
- Tavily MCP: Fails with {"error":"Search failed","detail":"API key is required"}.
Additional Testing
| Test | Result |
|---|---|
| Hardcoding API key directly in Tavily URL | ✅ Works |
| Using {env:TAVILY_API_KEY} in URL | ❌ Fails |
| Using {env:EXA_API_KEY} in URL (Exa) | ✅ Works |
| Renaming MCP server from "tavily" to "tavily-mcp" | ❌ Still fails |
| Using headers with Authorization: Bearer {env:TAVILY_API_KEY} | ❌ Fails |
The environment variable values are confirmed identical between .zshrc and the hardcoded test. |
Possible Cause
There may be an issue with how OpenCode caches or resolves {env:...} substitutions for specific MCP server names or URLs. The inconsistency between Exa (working) and Tavily (not working) with identical patterns suggests a bug in the variable substitution logic.
Workaround
Just hardcoding the API key directly in the URL works, but this is not ideal for security reasons.
OpenCode version
1.0.137
Steps to reproduce
No response
Screenshot and/or share link
No response
Operating System
No response
Terminal
No response
This issue might be a duplicate of existing issues. Please check:
- #231: add ability to load secrets from external command or environment variables in the config file
- #318: feature: Ability to pass credentials without storing in environment file
Both of these issues relate to environment variable substitution in MCP server configurations, though they focus more on the feature request side. Your issue describes a specific bug where {env:...} works for some servers but not others.
Additionally, you may want to check #5278 (z.ai MCPs stopped working at 1.0.137) to see if there are any related environment variable loading issues introduced in recent versions.
Feel free to ignore if these don't match your specific case.
@fpdy if you do:
opencode debug config
are the urls populating correctly?