Cursor Auto-Selected Model Stringifies MCP Tool Parameters

Describe the Bug

When using Cursor’s auto-selected model, nested object parameters for MCP tools are incorrectly serialized as strings instead of being passed as JSON objects. This causes validation errors in MCP tools that expect object parameters (e.g., Notion MCP’s update-page tool expects data as an object, but receives it as a stringified JSON string).

Impact: Critical - Prevents use of MCP tools with nested object parameters when relying on auto-selected models.

Actual Behavior

When the model is auto-selected, nested object parameters are serialized as strings before being sent to the MCP server, causing Zod validation errors.

Affected Tools

Any MCP tool that accepts nested object parameters, including but not limited to:

  • mcp_user-notion_notion-update-page - data parameter
  • mcp_user-notion_notion-create-pages - parent parameter
  • mcp_user-notion_notion-move-pages - new_parent parameter

Error Message

MCP error -32602: Invalid arguments for tool notion-update-page: [
  {
    "code": "invalid_type",
    "expected": "object",
    "received": "string",
    "path": ["data"],
    "message": "Expected object, received string"
  }
]

Workaround

Temporary Solution: Explicitly select a model (Sonnet or Opus) instead of using auto-selection when calling MCP tools with nested object parameters.

Note: This workaround is not ideal as it requires manual intervention and defeats the purpose of auto-selection.

Evidence

Successful Call (Explicitly Selected Model)

# Model: Sonnet (explicitly selected)
mcp_user-notion_notion-create-pages(
    parent={
        "type": "data_source_id",
        "data_source_id": "21c55d8e-446d-8084-9d76-000b20add166"
    },
    pages=[{
        "properties": {
            "Doc name": "Test Document",
            "Category": "[\"1k Arch Brief\"]",
            "Status": "Draft"
        }
    }]
)

Result: :white_check_mark: Success - Page created successfully

Failed Call (Auto-Selected Model)

# Model: Auto-selected
mcp_user-notion_notion-update-page(
    data={
        "page_id": "2c5554462918a75cb",
        "command": "update_properties",
        "properties": {"Status": "Shared"}
    }
)

Result: :cross_mark: Error - “Expected object, received string”

Root Cause Analysis

The issue appears to be in Cursor’s parameter serialization layer for auto-selected models. When a model is auto-selected:

  1. The tool call is processed through a different code path than explicit model selection
  2. Nested object parameters are incorrectly serialized as JSON strings
  3. The MCP server receives stringified parameters instead of proper JSON objects
  4. Zod validation fails because it expects an object but receives a string

When a model is explicitly selected, the same parameters are passed correctly as JSON objects, indicating the bug is specific to the auto-selection path.

Environment

  • Cursor IDE Version: 2.1.50 (Universal)
  • VSCode Version: 1.105.1
  • Commit: 56f0a83df8e9eb48585fcc4858a9440db4cc7770
  • Build Date: 2025-12-06T23:39:52.834Z
  • Electron: 37.7.0
  • Chromium: 138.0.7204.251
  • Node.js: 22.20.0
  • V8: 13.8.258.32-electron.0
  • OS: Darwin arm64 25.1.0 (macOS 25.1.0)
  • MCP Tools Affected: Notion MCP (commercial), potentially others
  • Model Selection: Auto-selected (fails), Sonnet/Opus explicitly selected (works)

Impact Assessment

Severity: High

  • Breaks core functionality (MCP tool calls) when using auto-selection
  • Forces users to manually select models, reducing productivity
  • Creates inconsistent behavior based on model selection method
  • Affects any workflow relying on MCP tools with nested object parameters

Requested Fix

Fix the parameter serialization logic in Cursor’s auto-selection path to match the behavior of explicit model selection. Nested object parameters should be passed as JSON objects, not stringified, regardless of model selection method.

Additional Context

Steps to Reproduce

  1. Open Cursor IDE with model selection set to “Auto”

  2. Attempt to call an MCP tool that requires a nested object parameter, for example:

    mcp_user-notion_notion-update-page(
        data={
            "page_id": "example-page-id",
            "command": "update_properties",
            "properties": {"Status": "Draft"}
        }
    )
    
  3. Observe the validation error indicating the parameter was received as a string instead of an object

  4. Explicitly select Sonnet or Opus model

  5. Repeat the same tool call with identical parameters

  6. Observe successful execution

Expected Behavior

When calling MCP tools with nested object parameters, Cursor should pass these parameters as JSON objects, not as stringified JSON strings. This works correctly when a model is explicitly selected (Sonnet or Opus).

Operating System

MacOS

Current Cursor Version (Menu → About Cursor → Copy)

Version: 2.1.50 (Universal)
VSCode Version: 1.105.1
Commit: 56f0a83df8e9eb48585fcc4858a9440db4cc7770
Date: 2025-12-06T23:39:52.834Z
Electron: 37.7.0
Chromium: 138.0.7204.251
Node.js: 22.20.0
V8: 13.8.258.32-electron.0
OS: Darwin arm64 25.1.0

For AI issues: which model did you use?

auto -vs- Sonnet 4.5 / Opus 4.5

For AI issues: add Request ID with privacy disabled

5bbef8d7-daf6-4a1f-9417-17490f7016a4

Additional Information

This bug was discovered while attempting to update Notion documents via MCP tools. The same parameter format that works with explicitly selected models consistently fails with auto-selected models, indicating a systematic issue in Cursor’s parameter handling.

The bug report for the Notion MCP server itself (regarding parameter serialization) was previously submitted and closed, as the issue was determined to be on Cursor’s side, not the MCP server.

Does this stop you from using Cursor

No - Cursor works, but with this issue

Hey, thanks for the report. This is clearly a bug in parameter handling during auto model selection.

I’ll pass this to the engineers - your problem description with repro steps and the request ID is excellent. As a temporary workaround, keep explicitly choosing the model (Sonnet/Opus) for MCP calls with nested objects.

Thanks, Dean!

I’ve recently had the same issue when using Composer, switching to Opus resolves the issue. I saw this same issue when trying to push updates back to Notion with the notion-update-page tool.

1 Like

Environment:

Version: 2.2.43
VSCode Version: 1.105.1
Commit: 32cfbe848b35d9eb320980195985450f244b3030
Date: 2025-12-19T06:06:44.644Z
Electron: 37.7.0
Chromium: 138.0.7204.251
Node.js: 22.20.0
V8: 13.8.258.32-electron.0
OS: Linux x64 6.8.0-88-generic

Here another example that prevents us from using an important MCP tool. In auto modus Cursor produces such JSON as parameters:

{
    "id": 55,
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
        "_meta": {
            "progressToken": 55
        },
        "arguments": {
            "params": "{}'state': new"
        },
        "name": "zammad_search_tickets"
    }
}

Or another example

{
    "id": 55,
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
        "_meta": {
            "progressToken": 55
        },
        "arguments": {
            "params": "{}'state': new"
        },
        "name": "zammad_search_tickets"
    }
}

When we use sonnet, it works perfectly:

{
    "id": 24,
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
        "_meta": {
            "progressToken": 24
        },
        "arguments": {
            "params": {
                "page": 1,
                "per_page": 50,
                "state": "new"
            }
        },
        "name": "zammad_search_tickets"
    }
}