Skip to content

Config: unknown keys inside mcp.<name> are silently discarded, while unknown keys at root are rejected #39431

Description

@jond34

Summary

Unknown keys at the root of opencode.json are rejected with a clear
ConfigInvalidError. Unknown keys nested inside an mcp.<name> object are
silently discarded — no error, no warning, no log line. The server starts and
reports healthy.

This inconsistency is the actual footgun behind the recurring env vs
environment reports (#36434, #30892, #35860, #39135, #26332, #35867). Those
are about the correct key name. This issue is about the missing validation
that makes any such mistake silent. Correcting the docs does not fix it — see
"Why this survived the docs fix" below.

Reproduction

opencode 1.18.9 (darwin-arm64), macOS 26.1.

A. Unknown key at root — correctly rejected

{ "$schema": "https://opencode.ai/config.json",
  "totally_bogus_root_key_xyz": { "a": 1 } }
Error: Configuration is invalid at /tmp/root.json
↳ Unrecognized key: totally_bogus_root_key_xyz

B. Unknown key nested in mcp.<name> — silently accepted

{ "$schema": "https://opencode.ai/config.json",
  "mcp": { "x": { "type": "local", "command": ["/bin/echo"], "enabled": false,
                  "totally_bogus_nested_key_xyz": { "a": 1 } } } }

Starts normally. No diagnostic of any kind.

Identical results via OPENCODE_CONFIG and via project-local ./opencode.json.

Expected

mcp.<name> should reject or warn on unrecognized keys, consistent with root.
The message at root (Unrecognized key: …) is already exactly right — it just
isn't applied to nested objects.

Why this survived the docs fix

The customize-opencode skill in 1.18.5 documents the key as env:

"playwright": { "type": "local", "command": ["npx","-y","@playwright/mcp"],
                "enabled": true, "env": {} }

In 1.18.9 it correctly says environment (thanks — #39135). But the
silent-drop behavior is unchanged, so every config written against the older
skill keeps failing silently after upgrade, with nothing to point at the cause.

Note Homebrew is still shipping 1.18.5 (homebrew-core formula), so new
brew users are currently being handed the version whose bundled skill teaches
the key that gets silently stripped.

Confirmed on 1.18.9 with a stub MCP server that dumps its own environment:
"env": { "T_VIA_ENV": "should_be_set" } → server receives <UNSET>, and no
warning is emitted. The child does inherit opencode's own environment, so the
symptom presents as "my env var isn't set" rather than "my config key is
wrong", which is what makes it hard to diagnose. (#36434 shows it surfacing as
an opaque -32000 Connection closed instead.)

Why it matters beyond a typo

Configuring dbt-mcp with env instead of environment silently loaded a
different toolset than specified:

  • every DISABLE_* flag ignored, so dbt Platform toolsets loaded instead of the
    intended dbt Core CLI toolset
  • write tools trigger_job_run, cancel_job_run, retry_job_run exposed
    despite being explicitly disabled
  • DISABLE_TOOLS=build,run,test,clone ignored
  • the intended CLI tools absent entirely, because the missing DBT_PROJECT_DIR
    made dbt-mcp auto-disable them

The server reported healthy throughout. A user can reasonably believe they have
a read-only server while write tools are live. For anyone pointing MCP servers
at production data, that's a meaningful failure mode.

Related

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions