Repository navigation
Description
Description
What happened?
MCP server entries under mcp in ~/.config/opencode/opencode.json can include an env object, but opencode debug config shows the resolved config with the env field missing entirely. As a result, the spawned MCP child processes never receive the environment variables, and any MCP server that depends on per-server env vars fails at runtime.
This reproduces with at least two different MCP servers, so it doesn't appear to be specific to one server implementation:
grok-search(needsGROK_API_URL,GROK_API_KEY, etc.)mysql(needsMYSQL_HOST,MYSQL_DATABASE, etc.)
This is not a credentials/provider issue:
- The same
grok-searchMCP config (same command, same env values) works correctly in Claude Code (claude mcp listshows it connected, and tool calls succeed). - The configured API endpoint responds successfully to both
/v1/modelsand/v1/chat/completionswhen called directly.
So the problem is isolated to how OpenCode resolves/passes mcp.<name>.env.
Expected behavior
mcp.<name>.env should remain present after config resolution, and should be passed to the spawned MCP child process's environment.
Actual behavior
env is silently dropped during config resolution, and the MCP processes report missing configuration at runtime (e.g. missing API URL, missing DB config), even though the raw config file has the values.
Raw config (~/.config/opencode/opencode.json, secrets redacted)
{
"mcp": {
"grok-search": {
"type": "local",
"command": [
"uvx",
"--from",
"git+https://github.com/GuDaStudio/GrokSearch@grok-with-tavily",
"grok-search"
],
"enabled": true,
"env": {
"GROK_API_URL": "https://example.com/v1",
"GROK_API_KEY": "sk-***",
"GROK_MODEL": "grok-4.5"
}
},
"mysql": {
"type": "local",
"command": ["uvx", "mysql_mcp_server"],
"enabled": true,
"env": {
"MYSQL_HOST": "localhost",
"MYSQL_PORT": "13306",
"MYSQL_USER": "root",
"MYSQL_PASSWORD": "***",
"MYSQL_DATABASE": "testdb"
}
}
}
}Resolved config (opencode debug config)
"mcp": {
"grok-search": {
"command": [
"uvx",
"--from",
"git+https://github.com/GuDaStudio/GrokSearch@grok-with-tavily",
"grok-search"
],
"enabled": true,
"type": "local"
},
"mysql": {
"command": ["uvx", "mysql_mcp_server"],
"enabled": true,
"type": "local"
}
}Note env is absent from both entries, despite being present in the raw file.
Plugins
/Users/agiuser/.config/opencode/superpowers/.opencode/plugins/superpowers.js
OpenCode version
1.17.16
Steps to reproduce
- Add an MCP server under
mcpin~/.config/opencode/opencode.jsonwith anenvobject (e.g. anylocaltype server needing an API key). - Restart OpenCode.
- Run
opencode debug configand inspect themcp.<name>entry. - Observe that
envis missing from the resolved output, even though it's present in the raw config file. - Call a tool from that MCP server that depends on the env vars.
- Observe the tool call fails with a "missing configuration" style error, even though the raw config has the correct values.
Screenshot and/or share link
cat ~/.config/opencode/opencode.json

opencode debug config
Operating System
macOS 26.5.2
Terminal
Ghostty 1.3.1
Activity
github-actions commentedon Jul 11, 2026
This issue might be a duplicate of existing issues. Please check:
envblock not propagated to child process #30892: Same root bug —mcp.<name>.envblock not propagated to the spawned child process (reported in v1.16.0, still open)envbut schema/runtime expectenvironment#35860: Related — the config schema usesenvironment(notenv) for local MCP servers, and the runtime mergesmcp.environmentinto the child process env;envis silently dropped as an unknown keyThe
env→environmentfield naming discrepancy described in #35860 may be the direct cause of what you're seeing: if the correct field name isenvironment, renaming it in your config may resolve the issue while the underlying bug is tracked.Gelly52 commentedon Jul 13, 2026
Confirmed — renaming
env→environmentin myopencode.jsonfixed it.Before:
→ silently dropped, opencode debug config showed no env at all.
After:
→ opencode debug config now shows the full environment block, and the MCP tool reports config_status: fully configured.
This is the same root cause as #30892 and #35860 — the built-in customize-opencode skill docs use env, but the actual schema/runtime expects environment, and the config loader silently drops unknown keys instead of erroring. Feel free to close this as a duplicate of #35860 (which already has a fix PR, #35867, for the docs). Thanks for the pointer!
hazlamahedich commentedon Jul 20, 2026
Confirming this still reproduces in 1.18.0 (upgraded from 1.17.16 where I first saw it).
opencode debug configdrops theenvblock on everymcp.<name>entry — even for servers that have noenvin the source file, so it's not just a redaction artifact. For servers that do require env vars, the spawned child genuinely never receives them, which I confirmed with a logging wrapper:→
PEXELS_API_KEY len: 0when opencode launches it (the value is present inopencode.json).open-designfails the same way becauseELECTRON_RUN_AS_NODE=1is dropped, so the Electron Helper tries to launch as a GUI app and the stdio MCP handshake dies with-32000 Connection closed.Two of the three affected servers (
pexels,open-design) reportMCP error -32000: Connection closed, not a missing-config error — so this may be part of why the issue is under-diagnosed: failures look like protocol/transport bugs rather than an env regression.Workaround that works reliably on 1.18.0: point the
commandat a small wrapper script thatexports the env vars itself beforeexec-ing the real server. Local MCP servers are then fully functional.jond34 commentedon Jul 29, 2026
Cross-linking: I filed #39431 for the underlying validation gap that makes this class of bug silent.
Verified on 1.18.9, the inconsistency is one level of nesting:
Error: Configuration is invalid ... ↳ Unrecognized key: <name>mcp.<name>→ silently discarded, no error, no warning, server reports healthySo
env(vsenvironment) is stripped with no diagnostic. @Gelly52 your read that "the config loader silently drops unknown keys instead of erroring" is exactly right, and @hazlamahedich the opaque-32000 Connection closedis the downstream symptom of that.Worth noting the docs half is now fixed — the bundled
customize-opencodeskill saysenvironmentin 1.18.9 (it saidenvin 1.18.5, per #39135). But the silent-drop behavior is unchanged, so configs written against the older skill keep failing silently after upgrade. Homebrew is also still shipping 1.18.5, so newbrewusers still get the skill that teaches the stripped key.In my case this silently loaded a different
dbt-mcptoolset than configured — everyDISABLE_*flag ignored, and write tools exposed despite being explicitly disabled, while the server reported healthy. Details in #39431.github-actions commentedon Sep 27, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.