﻿---
title: "Give Tool input schemas an object root"
description: "Tool arguments are always a JSON object, so after component resolution the inputSchema root must describe an object. Before MCP 2025-11-25 the root declares the literal type object"
source: "https://mcpdesc.org/docs/rules/0.9.0-rc.3/mcp/tool-input-schema-object-root/"
---

Tool arguments are always a JSON object, so after component resolution the inputSchema root must describe an object. Before MCP 2025-11-25 the root declares the literal type object. From MCP 2025-11-25 a declared root type must include object; a root in $ref or allOf stays valid, and mcp.tool.schema.native-shape warns that the MCP Tool type expects a literal type object.

## Requirement

Tool inputSchema describes an object: a literal type “object” before MCP 2025-11-25, and from MCP 2025-11-25 a declared root type that includes “object”.

## Details

**Rule ID:** `mcp.tool.input-schema.object-root`  
**Owner:** mcp  
**Surface:** Tool · **Path:** `inputSchema`  
**Kind:** structural  
**Requirement level:** must  
**Status:** arbitrated · **Enforcement:** internal

## Protocol version applicability

| 2024-11-05 | 2025-03-26 | 2025-06-18 | 2025-11-25 | 2026-07-28 |
| ---------- | ---------- | ---------- | ---------- | ---------- |
| applies    | applies    | applies    | applies    | applies    |

## Required by

* **MCP Description 0.9.0, Section 9.2**  
  * 9\. Tools: [req-tool-input-schema-object-root](https://mcpdesc.org/docs/specification/0.9.0-rc.3/tools#req-tool-input-schema-object-root)

## Based on

* **Tier 1 — MCP schema.ts and normative specification text:** MCP 2024-11-05 to 2026-07-28 schema.ts, interface Tool, inputSchema type: “object”  
  * [validation/mcp-schemas/2024-11-05/schema.ts#L696-L703](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/dae694f61a31f7a3ec2af3aff709e11f70f61e48/schema/2024-11-05/schema.ts#L696-L703)
  * [validation/mcp-schemas/2025-03-26/schema.ts#L797-L804](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/dae694f61a31f7a3ec2af3aff709e11f70f61e48/schema/2025-03-26/schema.ts#L797-L804)
  * [validation/mcp-schemas/2025-06-18/schema.ts#L938-L945](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/dae694f61a31f7a3ec2af3aff709e11f70f61e48/schema/2025-06-18/schema.ts#L938-L945)
  * [validation/mcp-schemas/2025-11-25/schema.ts#L1257-L1265](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/dae694f61a31f7a3ec2af3aff709e11f70f61e48/schema/2025-11-25/schema.ts#L1257-L1265)
  * [validation/mcp-schemas/2026-07-28/schema.ts#L1981-L1997](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/dae694f61a31f7a3ec2af3aff709e11f70f61e48/schema/2026-07-28/schema.ts#L1981-L1997)
* **Tier 1 — MCP schema.ts and normative specification text:** MCP 2026-07-28 specification, Server Features, Tools, Data Types, Tool (inputSchema MUST be a valid JSON Schema object, not null)  
  * <https://github.com/modelcontextprotocol/modelcontextprotocol/blob/dae694f61a31f7a3ec2af3aff709e11f70f61e48/docs/specification/2026-07-28/server/tools.mdx#L293-L293>
* **Tier 1 — MCP schema.ts and normative specification text:** MCP 2025-11-25 and 2026-07-28 specification, Basic, JSON Schema usage (schemas are validated under their declared or default dialect)  
  * <https://github.com/modelcontextprotocol/modelcontextprotocol/blob/dae694f61a31f7a3ec2af3aff709e11f70f61e48/docs/specification/2025-11-25/basic/index.mdx#L140-L186>
  * <https://github.com/modelcontextprotocol/modelcontextprotocol/blob/dae694f61a31f7a3ec2af3aff709e11f70f61e48/docs/specification/2026-07-28/basic/index.mdx#L251-L297>
* **Tier 4 — Official MCP clarifications and final SEPs:** MCP SEP-2106 (Final), which keeps type “object” deliberately  
  * <https://github.com/modelcontextprotocol/modelcontextprotocol/blob/dae694f61a31f7a3ec2af3aff709e11f70f61e48/seps/2106-json-schema-2020-12.md>

## Gaps and arbitrations

Arbitration: `2025-11-25`, `2026-07-28`

**Conflict:** The specification validates embedded schemas under their declared or default dialect, while schema.ts requires the JSON Schema keyword and value type “object” at the root. A schema rooted in $ref or allOf can describe an object but does not match the TypeScript type.

**Authority:** MCP specification text on schema dialects, with the requirement that tool arguments are objects

**Behavior:** Reject a declared root type that excludes “object”; accept other roots that are valid under the dialect, which mcp.tool.schema.native-shape reports as warnings.

**Rationale:** One position for every conflict between MCP’s dialect text and the schema syntax of its TypeScript types (Proposal 0032): MCP Description enforces what MCP requires of the data and reports, but does not decide, the narrower TypeScript syntax. Replaces the Draft 3 decision to require a literal type “object” in every protocol version.

**Review trigger:** Resolution of MCP issue 3238 or a later MCP protocol version that changes the inputSchema type..

Upstream: <https://github.com/modelcontextprotocol/modelcontextprotocol/issues/3238>.

## Examples

### Valid example

Source: [expected-valid/custom-tool-schema-keywords.json](https://github.com/mcpdesc/mcpdesc-specification/blob/v0.9.0-rc.3/spec/draft/fixtures/expected-valid/custom-tool-schema-keywords.json) · Selected: `/tools/0/inputSchema`

```json
{
  "type": "object",
  "properties": {
    "account": {
      "type": "string",
      "x-acme-account-id": true,
      "database-field-id": 123
    },
    "region": {
      "type": "string",
      "x-mcp-header": "Region"
    }
  }
}
```

### Valid example

Source: [expected-warning/tool-schema-mcp-type-mismatch.json](https://github.com/mcpdesc/mcpdesc-specification/blob/v0.9.0-rc.3/spec/draft/fixtures/expected-warning/tool-schema-mcp-type-mismatch.json) · Selected: `/tools/2/inputSchema`

```json
{
  "$ref": "#/$defs/Arguments",
  "$defs": {
    "Arguments": {
      "type": "object",
      "properties": {
        "query": {
          "type": "string"
        }
      },
      "required": [
        "query"
      ]
    }
  }
}
```

### Invalid example

Source: [expected-invalid/non-object-input-schema.json](https://github.com/mcpdesc/mcpdesc-specification/blob/v0.9.0-rc.3/spec/draft/fixtures/expected-invalid/non-object-input-schema.json) · Selected: `/tools/0/inputSchema`

```json
{
  "type": "string"
}
```

### Invalid example

Source: [expected-invalid/non-object-input-schema.json](https://github.com/mcpdesc/mcpdesc-specification/blob/v0.9.0-rc.3/spec/draft/fixtures/expected-invalid/non-object-input-schema.json) · Selected: `/tools/2/inputSchema`

```json
{
  "$componentRef": "#/components/schemas/StringArguments"
}
```

### Invalid example

Source: [expected-invalid/non-literal-object-input-schema-before-2025-11-25.json](https://github.com/mcpdesc/mcpdesc-specification/blob/v0.9.0-rc.3/spec/draft/fixtures/expected-invalid/non-literal-object-input-schema-before-2025-11-25.json) · Selected: `/tools/0/inputSchema`

```json
{
  "$ref": "#/$defs/Arguments",
  "$defs": {
    "Arguments": {
      "type": "object"
    }
  }
}
```

## Rule Source Code

[tool.yaml](https://github.com/mcpdesc/mcpdesc-specification/blob/v0.9.0-rc.3/spec/draft/validation/rules/tool.yaml) at immutable tag [v0.9.0-rc.3](https://github.com/mcpdesc/mcpdesc-specification/blob/v0.9.0-rc.3/spec/draft).
