F3.3 F3

The camelCase Trap: MCP Tool Definitions vs Claude API

If you work with both MCP and the Claude Messages API, you will get bitten by a naming difference. It’s small, easy to miss, and breaks things silently. Understanding the MCP tool definition format — and how it differs from the Claude API format — saves you from debugging phantom schema errors.

Three fields, that’s it

An MCP tool definition has exactly three fields:

  • name — the tool’s identifier, used by the client when requesting a tool call
  • description — what the tool does, helping the AI model select the right tool (optional but strongly recommended)
  • inputSchema — a standard JSON Schema defining the tool’s input parameters

That’s the entire surface area. No handler field pointing to an endpoint. No outputSchema defining what comes back. No parameters shorthand. The server implements execution internally — the definition only describes the interface.

The naming trap: inputSchema vs input_schema

Here’s where people trip up. MCP uses camelCase: inputSchema. The Claude Messages API uses snake_case: input_schema. Same concept, different casing.

Why? MCP follows JSON-RPC conventions (camelCase). The Claude API follows its own API naming conventions (snake_case). Both use standard JSON Schema for the content of that field — the difference is purely in the field name.

This matters because copy-pasting a tool definition from one system to the other without adjusting the field name produces a silently broken definition. The schema content is identical and valid, but the key name is wrong for the target system.

What’s NOT in the definition

Three things people assume exist but don’t:

  1. No outputSchema — only input is defined. What the tool returns is determined by the server’s implementation, not constrained by the definition. Neither MCP nor the Claude API includes output schema in tool definitions.

  2. No handler — the definition describes what the tool accepts, not where or how it executes. Implementation details stay on the server side.

  3. No optional flag on properties — optionality is controlled by JSON Schema’s required array. Properties listed in required are mandatory; everything else is optional. There is no per-property optional: true annotation in JSON Schema.

Putting it together

A tool that creates GitHub issues with a required title and optional body and labels:

{
  "name": "create_issue",
  "description": "Creates a new GitHub issue in the specified repository",
  "inputSchema": {
    "type": "object",
    "properties": {
      "title": { "type": "string" },
      "body": { "type": "string" },
      "labels": { "type": "array", "items": { "type": "string" } }
    },
    "required": ["title"]
  }
}

Note: inputSchema (camelCase) because this is MCP. In the Claude API, the same schema content would live under input_schema (snake_case). Both support full JSON Schema, including nested objects — there are no nesting limitations in either system.


One-liner: MCP tool definitions have three fields (name, description, inputSchema in camelCase) — the snake_case input_schema form belongs to the Claude API, and mixing them up is the most common integration mistake.