Skip to content

Click/Type/Scroll tools reject valid loc coordinates: array serialized as JSON string, fails Pydantic validation #342

Description

@mesame20022007-code

Description

When calling Click (and other input tools that accept loc: list[int]) with explicit [x, y] coordinates, the call fails 100% of the time with a Pydantic validation error, even though the tool description explicitly documents loc as [x, y].

Error observed

1 validation error for call[click_tool]
loc
Input should be a valid list [type=list_type, input_value='[500, 500]', input_type=str]
For further information visit https://errors.pydantic.dev/2.12/v/list_type

Note input_value='[500, 500]' — the value arrives as the string "[500, 500]" rather than a native JSON array [500, 500]. loc: list[int] | None = None then fails strict validation.

Environment

  • windows-mcp version: 0.8.2
  • Installed as: Claude Desktop extension (ant.dir.cursortouch.windows-mcp), invoked via uv run windows-mcp
  • Client: Claude Code (CLI), MCP tool-calling
  • OS: Windows 11 Pro

Repro steps

  1. Call Snapshot or Screenshot to get desktop state.
  2. Call Click with loc=[x, y] (any coordinate pair).
  3. Observe the validation error above — happens consistently, regardless of which coordinates are passed.

Workaround found

Clicking by label (the integer element ID returned by Snapshot's UI tree) instead of raw loc coordinates works fine, since that code path (_resolve_label) never round-trips a client-supplied array through the same argument. This avoids the bug but forces an extra Snapshot call (which is itself expensive, 5-17s in our testing) purely to obtain an ID for what should be a direct coordinate click.

Expected behavior

Click(loc=[x, y]) should accept a native array/list argument without going through string serialization, matching the documented signature.

Suspected cause

Likely on the MCP client/tool-calling bridge side (JSON args getting stringified before reaching the server), rather than in windows_mcp itself — but flagging here since it makes loc-based calls to this server unusable from the affected client, and a defensive fix (e.g. accepting a JSON-string-encoded array as a fallback, similar to how use_vision: bool | str already tolerates string booleans elsewhere in this codebase) would make the tool more robust regardless of which client is at fault.

Suggested workaround for maintainers to consider

Since other boolean parameters in this codebase (e.g. use_vision: bool | str) already tolerate stringified input for robustness across MCP clients, it may be worth applying the same tolerance to loc: list[int] | str, parsing a JSON-encoded string if one is received instead of a native list.

Metadata

Metadata

Assignees

No one assigned

    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