anthropics / anthropics/claude-code
[BUG] Desktop app rejects MCP calls that omit optional parameters (expected, nonoptional, rerecived undefined)
- Dominant language
- Python
- Stars
- 145k
- Forks
- 23.1k
- PR merge metrics
- PR metrics pending
Description
### Preflight Checklist
- [x] I have searched [existing issues](https://github.com/anthropics/claude-code/issues?q=is%3Aissue%20state%3Aopen%20label%3Abug) and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
### What's Wrong?
Desktop app rejects MCP calls that omit optional parameters (expected nonoptional, received undefined)
Tool params declared "default": null in the server's JSON Schema are being treated as required by the desktop app's client-side validation. Supplying them to satisfy the validator then trips server-side mutually-exclusive-parameter checks, making those tools uncallable — no value ("", {}, null) represents "absent".
Repro: call ha_config_set_dashboard (ha-mcp) with only url_path and config. Client rejects with expected nonoptional for 8 params. Supply them → server returns "Cannot use both config and python_transform simultaneously."
Not reproducible in the Claude Code CLI — same MCP server, same machine, same ~/.claude.json. Desktop-client-only.
nonoptional suggests a Zod v4 schema-conversion regression where default: null is mapped to a required field
### What Should Happen?
It should work. It works on the same machine from claude code terminal. It has explained to me the above report and this is a frustrating bug that makes using claude code and desktop are not able to do the same changes
### Error Messages/Logs
```shell
```
### Steps to Reproduce
1. Connect an MCP server whose tools declare optional parameters — i.e. properties
present in the schema with `"default": null` and *not* listed under `required`.
Reproduced with `ha-mcp` (Home Assistant), but the shape is generic.
2. In the **Claude Code desktop app**, have Claude call such a tool while omitting
one or more of those optional parameters. Example — `ha_config_set_dashboard`
with only `url_path` and `config`:
ha_config_set_dashboard(url_path="presence-radar", config={...})
3. The call is rejected by client-side validation before it reaches the server.
Every optional parameter is reported as missing:
{"code": "invalid_type",
"expected": "nonoptional",
"path": ["python_transform"],
"message": "Invalid input: expected nonoptional, received undefined"}
…repeated for config_hash, title, icon, require_admin, show_in_sidebar,
return_screenshot and view_path — 8 optional params in total.
4. Retry, now supplying a value for every parameter the validator demanded.
The call reaches the server and is rejected there, because two *mutually
exclusive* optional parameters are now both present:
"Cannot use both config and python_transform simultaneously"
5. Try to express "absent" for the conflicting parameter. Every option fails:
python_transform="" -> server sees a string, not None -> same error
python_transform=null -> arrives as the string "null" -> same error
config={} -> passes typing, still not None -> same error
config="" -> "expected a JSON object"
There is no value that means "omitted", so the tool is uncallable.
6. Run the identical task in the **Claude Code CLI** — same machine, same
`~/.claude.json`, same MCP server:
cd && claude --resume
It succeeds immediately. Desktop-client only.
### Expected
Properties with `"default": null` that are absent from `required` are optional.
Omitting them should send them not at all, and the server should apply its default.
### Actual
The desktop client treats them as required. Supplying them to satisfy the
validator then trips server-side mutual-exclusion checks (`is not None`), making
the tool impossible to call.
### Also affected (same server)
- `ha_config_set_dashboard` — `config` / `python_transform`
- `ha_get_entity` — `entity_id` / `unique_id` ("Provide exactly one of entity_id or unique_id, not both.")
- `ha_config_get_dashboard` — `mode`, typed `Literal['search'] | None`; None cannot be expressed, so only `mode="search"` is reachable
Read-only tools without a mutually-exclusive pair still work, which is what makes
this look like an HA or permissions problem at first.
### Note
`"expected": "nonoptional"` is Zod v4 wording, suggesting the JSON Schema ‚Üí
Zod conversion maps `default: null` to a required field rather than an optional
one defaulting to null.
### Claude Model
None
### Is this a regression?
I don't know
### Last Working Version
_No response_
### Claude Code Version
2.1.273 (Claude Code)
### Platform
Anthropic API
### Operating System
macOS
### Terminal/Shell
Terminal.app (macOS)
### Additional Information
Claude Desktop version: Claude 2.110.0 (dfb2ba) 2026-09-15T05:50:55.000Z
Contributor guide
No contributing guide indexed for this repository
Research direction
Start at the Claude Code desktop app's MCP client validation and compare its JSON Schema handling with the Claude Code CLI using the documented ha-mcp reproduction. Check schemas where parameters have default: null but are absent from required, then verify that omitted parameters reach the server as omitted and that the listed mutually exclusive tools can be called.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- json, python
- Domain
- api, desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100