opencode icon indicating copy to clipboard operation
opencode copied to clipboard

`{env:...}` variable substitution inconsistently fails for specific MCP server URLs

Open fpdy opened this issue 1 month ago • 1 comments

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

  1. Configure two remote MCP servers with the same {env:...} pattern in opencode.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
  }
}
  1. Export both environment variables in ~/.zshrc:
export EXA_API_KEY=<valid-key>
export TAVILY_API_KEY=<valid-key>
  1. Start OpenCode from a terminal where both env vars are confirmed to be set.
  2. 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

fpdy avatar Dec 09 '25 22:12 fpdy

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.

github-actions[bot] avatar Dec 09 '25 22:12 github-actions[bot]

@fpdy if you do:

opencode debug config

are the urls populating correctly?

rekram1-node avatar Dec 10 '25 06:12 rekram1-node