anthropics / anthropics/claude-code

[BUG] Desktop app rejects MCP calls that omit optional parameters (expected, nonoptional, rerecived undefined)

Closed
#94,608 3 comments 1 reaction 0 assignees View on GitHub
area:desktop area:mcp bug has repro platform:macos
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.