[BUG] Cowork: object MCP tool arguments arrive as JSON strings ("is not of type object"); works in Claude Code CLI

Status Open
Maintainer reply None cached
Activity 1 comment · opened Jul 26, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet (no open issue tracks it; the closed prior reports are listed below and differ in surface)
  • [x] This is a single bug report
  • [x] I am using the latest version (Claude Cowork in the current Claude Desktop app)

What's Wrong?

In Claude Cowork, calling a remote HTTP MCP server's tool with a nested-object argument fails server-side validation with Input validation error: '<json>' is not of type 'object'. String-only arguments to the same server succeed. The object parameters in question are declared with JSON-Schema $ref pointing into a top-level $defs block, and the value arrives at the server serialized as a JSON string instead of a structured object

This is the same defect that has been reported and closed several times against the Claude Code CLI, always with the same root cause (object arguments serialized as JSON strings because $ref/$defs schemas are not resolved before serialization):

  • #10590 "HTTP MCP transport doesn't resolve $ref in parameter schemas, causing JSON string parameters to not be parsed as objects" is the exact-mechanism match. It uses the same inline-vs-$ref control this report does: Notion declares its object param inline (type: object) and works, PagerDuty uses "$ref": "#/$defs/IncidentQuery" and fails with '{"limit": 25}' is not of type 'object'. Closed as NOT_PLANNED by the inactivity bot, so it was never actually fixed
  • #3084 / #6249 / #7845 are the FastMCP + Pydantic lineage. Pydantic models compile to $ref/$defs JSON schema, so it is the same root cause. #3084 was closed as completed; #7845 was filed because the fix did not hold ("still serialized as JSON strings, despite previous bug ticket being closed as fixed")
  • #32662 (WordPress MCP, object param serialized as string) was closed as a duplicate

What is new here, and what makes this a distinct, still-live problem rather than a duplicate: the identical MCP server and tools work correctly from the Claude Code CLI. Tested from the CLI, object arguments are sent as structured objects and the calls succeed; only Cowork sends them as strings. So the $ref-resolution behavior that the CLI has is missing from Cowork's MCP client path. This reads as a Cowork-specific regression of a bug that was previously addressed on the CLI

Observed on three tools from a remote HTTP MCP server that exposes Google Maps Platform APIs (lookup_weather, compute_routes, search_places). The affected parameters are lookup_weather.location, compute_routes.origin / .destination, and search_places.locationBias, each declared via $ref into $defs

What Should Happen?

Cowork's MCP client should resolve $ref/$defs in a tool's inputSchema before deciding how to serialize arguments, and send nested-object arguments as structured JSON objects in the tools/call arguments map, matching Claude Code CLI behavior. A structured value like {"location": {"address": "Bern, Switzerland"}} should reach the server as an object, not as the string "{\"address\": \"Bern, Switzerland\"}"

Error Messages/Logs

lookup_weather, location as an object:
  argument sent (intended): { "location": { "address": "Bern, Switzerland" } }
  server error:  Input validation error: '{"address": "Bern, Switzerland"}' is not of type 'object'

lookup_weather, nested lat/lng object:
  server error:  Input validation error: '{"latLng": {"latitude": 47.05, "longitude": 8.31}}' is not of type 'object'

compute_routes, object origin/destination:
  server error:  Input validation error: '{"address": "..."}' is not of type 'object'

Note: the object value is quoted as a string literal in the error. The MCP server
received a JSON string where its schema requires an object, i.e. the object was
serialized to a string on the client side before the tools/call was sent.

Steps to Reproduce

Minimal, maintainer-runnable repro (same one from #3084; a Pydantic model deterministically produces a $ref/$defs schema):

  1. Create a FastMCP server with a Pydantic-model parameter:
from fastmcp import FastMCP
from pydantic import BaseModel

mcp = FastMCP("test-server")

class TestModel(BaseModel):
    name: str
    age: int

@mcp.tool
def test_pydantic_model(data: TestModel) -> str:
    return f"{data.name} {data.age}"
  1. Connect it to Cowork over HTTP and ask Cowork to call test_pydantic_model with data = {"name": "Alice", "age": 30}
  2. Observe Input validation error: '{"name": "Alice", "age": 30}' is not of type 'object'

Real-world case as observed:

  1. Connect Cowork to a remote HTTP MCP server that exposes Google Maps Platform tools whose object parameters use $ref/$defs (lookup_weather, compute_routes, search_places)
  2. Ask Cowork for the weather in a city, which drives lookup_weather with location as an object
  3. Observe the is not of type 'object' error above

Controls that isolate the client as the cause:

  1. A string-only parameter on the same server succeeds (search_places with only textQuery), so this is not an outage, auth, or connectivity problem
  2. The identical server and tools succeed from the Claude Code CLI, so the server schema is correct and the object path works in the CLI
  3. A direct tools/call with the object argument (as in #10590's curl and #32662's call_mcp_tool) succeeds, confirming the server accepts objects

For reference, the server publishes fully typed schemas; the object params are objects via $ref, not untyped. Trimmed lookup_weather:

{
  "$defs": {
    "LatLng":   { "type": "object", "properties": { "latitude": {"type":"number"}, "longitude": {"type":"number"} } },
    "Location": { "type": "object", "properties": {
        "address": {"type":"string"},
        "latLng":  {"$ref": "#/$defs/LatLng"},
        "placeId": {"type":"string"} } }
  },
  "type": "object",
  "properties": {
    "location": { "$ref": "#/$defs/Location" }
  },
  "required": ["location"]
}

Claude Model

Not sure / Multiple models

Is this a regression?

I don't know

Additional Information

I could not inspect Cowork's source, so the precise line where the object is stringified is inferred, but the mechanism is well established by the prior reports: #10590 diagnosed it as the HTTP MCP client failing to resolve $ref/$defs and therefore serializing the parameter as a string, and #3084 traced the same object-to-string serialization in the MCP client layer

Regression framing: I cannot confirm whether a previous Cowork build handled this, so the dropdown answer is "I don't know". At the codebase level, though, the Claude Code CLI currently resolves these $ref/$defs object params correctly while Cowork does not, so the fix exists in the CLI path and is absent from Cowork's

The is not of type 'object' error originates from the MCP server's own input validator (the same way it did for PagerDuty in #10590, WordPress in #32662, and FastMCP/Pydantic in #3084/#7845). It fires only because the argument arrives as a string; the server is behaving correctly

Environment: Claude Cowork in the Claude Desktop app on macOS. This is not the Claude Code CLI; the CLI was tested only as the contrasting environment that works

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗