Skip to content

MCP tool parameters of type "object" are serialized as strings instead of being passed as objects #28472

Closed as not planned

Description

@e-picas

Description

When calling MCP tools that have a top-level parameter named body of type object, opencode passes the value as a JSON string instead of a native object. The MCP tool's input validation then fails with:

MCP error -32602: Input validation error: Invalid arguments for tool send-mail: [
  {
    "code": "invalid_type",
    "expected": "object",
    "received": "string",
    "path": ["body"],
    "message": "Expected object, received string"
  }
]

This affects all write tools in @softeria/ms-365-mcp-server where the only required parameter is body: object (e.g. send-mail, create-draft-email, create-calendar-event, send-chat-message). Read-only tools with simple scalar parameters (e.g. list-mail-messages, verify-login) work correctly.

Plugins

@softeria/ms-365-mcp-server (latest, type: local / stdio)

OpenCode version

1.15.5

Steps to reproduce

  1. Add @softeria/ms-365-mcp-server as a local MCP in opencode.jsonc
  2. Login with ms365_login
  3. Ask the assistant to send an email: "send a test email to myself"
  4. The tool ms365_send-mail is called — fails with Expected object, received string on the body parameter

Any MCP tool with a single required parameter of type object named body will reproduce this.

Operating System

Ubuntu 22.04

Terminal

Warp

Activity

  1. github-actions commented on May 20, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

  2. Keesan12 commented on May 20, 2026

    @Keesan12

    If object parameters are arriving as strings, I would check whether there is a JSON stringify boundary happening before the MCP transport layer thinks it has a schema-typed payload.

    This is one of those bugs where a receipt helps quickly: original JSON Schema type, model-emitted arguments, post-normalization payload, and the final wire payload handed to the tool transport. Once one boundary serializes early, downstream code can still look "valid" while object tools behave like they got plain text.

  3. davilima6 commented on Jun 18, 2026

    @davilima6

    I’m seeing the same kind of failure with the Next.js DevTools MCP integration.

    Versions I tested with:

    • OpenCode: 1.17.8
    • Node: 24.16.0
    • Next.js: 16.2.9
    • Next MCP endpoint: the built-in /_next/mcp endpoint from next-server (v16.2.9)
    • OS: macOS

    The connection itself works. OpenCode can discover the Next MCP server on http://localhost:3000, and nextjs_index lists the tools correctly:

    • get_project_metadata
    • get_errors
    • get_page_metadata
    • get_logs
    • get_server_action_by_id
    • get_routes

    The failure happens when OpenCode tries to call one of those tools through nextjs_call.

    For example, calling the no-arg get_errors tool fails with:

    MCP error -32603: Invalid argument 'args': [
      {
        "code": "invalid_type",
        "expected": "object",
        "received": "string",
        "path": [],
        "message": "Expected object, received string"
      }
    ]
    

    I also tried get_routes with args set to JSON text like this:

    {"routerType":"pages"}

    That fails the same way: the server still receives a string where it expects an object.

    This same Next MCP setup works for me in Cursor, so the Next server and MCP endpoint seem fine. The difference looks like it is in how OpenCode forwards or normalizes the tool arguments. It lines up with Keesan12’s comment above: something appears to stringify the object-shaped argument before it reaches the MCP transport layer.

  4. davilima6 commented on Jun 18, 2026

    @davilima6

    I proposed a fix in #32812. The Next.js MCP server works as expected with that branch

  5. rekram1-node commented on Jun 22, 2026

    @rekram1-node
    Collaborator
    Image

    this would just be ur model not calling tools correctly rather than an opencode bug, maybe u can share a repro? but i cannot reproduce this

  6. davilima6 commented on Jun 22, 2026

    @davilima6

    @rekram1-node , thanks for looking into it! I'll try to prepare a separate, throw-away PR with a repro

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

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