
This page is part of our MCP specification reference, a plain-English guide to the Model Context Protocol spec (version 2026-07-28), within The MCP Guide. Building a server? See MCP development.
An MCP tool's inputSchema is a JSON Schema that says which arguments the tool accepts. Its optional outputSchema says what shape the tool's structured result will have. Together they act as a contract between the AI model, the client and the server.
Status in the 2026-07-28 spec: core. inputSchema is required on every tool. outputSchema is optional.
This page explains both schemas for technical managers and developers. It is based on the 2026-07-28 Tools page and the JSON Schema usage rules in the base protocol, checked on 28 October 2026.
Key Takeaways
inputSchemais a required JSON Schema object whose root must betype: "object", because tool arguments are always objects.- Schemas default to JSON Schema 2020-12 when no
$schemafield is present. - The 2026-07-28 spec allows any JSON Schema 2020-12 keyword, including
oneOf,$refandif/then/else. - If a tool declares an
outputSchema, the server must return structured results that match it. - Implementations must not automatically fetch
$refURLs from the network, which closes a server-side request forgery risk. - A new
x-mcp-headerkeyword lets a server mirror a simple argument into an HTTP header for gateways and load balancers.
What the schemas are
JSON Schema is a standard way to describe the shape of JSON data. It says which fields exist, their types, and which are required. MCP uses it so a model knows how to fill in a tool's arguments, and so code on both sides can check them.
The schema reference puts it plainly: "Tool arguments are always JSON objects, so type: "object" is required at the root." Beyond that, any 2020-12 keyword may appear.
outputSchema is the other half. It describes the structuredContent a tool returns. Our page on structured tool output covers the result side in detail.
Why schemas exist
A model writes tool arguments from natural language. Without a schema, it would guess field names and formats. The schema, plus each property's description, tells the model exactly what to send.
Schemas also protect the server. The spec says servers MUST validate all tool inputs. A schema gives you a ready-made rule set to validate against before any business logic runs.
How it works
Here is the spec's example of a tool with both schemas:
{
"name": "get_weather_data",
"title": "Weather Data Retriever",
"description": "Get current weather data for a location",
"inputSchema": {
"type": "object",
"properties": {
"location": { "type": "string", "description": "City name or zip code" }
},
"required": ["location"]
},
"outputSchema": {
"type": "object",
"properties": {
"temperature": { "type": "number", "description": "Temperature in celsius" },
"conditions": { "type": "string", "description": "Weather conditions description" },
"humidity": { "type": "number", "description": "Humidity percentage" }
},
"required": ["temperature", "conditions", "humidity"]
}
}
Dialect rules
The base protocol sets these rules for every schema in MCP:
- With no
$schemafield, a schema is JSON Schema 2020-12. - A schema may name another dialect, such as draft-07, with
$schema. - Implementations must support at least 2020-12, and should document any others.
- Unsupported dialects must be handled gracefully with an error.
Tools with no arguments
The spec gives two valid options. The recommended one is { "type": "object", "additionalProperties": false }, which accepts only an empty object. The other, { "type": "object" }, accepts any object. A null schema is not valid.
Output schema rules
If a tool provides an outputSchema, servers MUST return structured results that conform to it. Clients SHOULD validate those results. In 2026-07-28 the output schema can describe any JSON value, including an array. The spec's list_users example uses "type": "array" at the root.
Mirroring arguments into headers
The 2026-07-28 spec added x-mcp-header. You place it inside a property's schema, and the client copies that argument into an Mcp-Param-{name} HTTP header on the Streamable HTTP transport. A load balancer or firewall can then route on it without reading the body.
The rules are strict. It works only on string, integer and boolean properties, never number. Values must be valid header tokens and unique within the schema. Clients on Streamable HTTP must drop any tool whose x-mcp-header breaks these rules. Clients on other transports, such as stdio, may ignore the keyword. The spec also warns servers not to mark passwords, API keys, tokens or personal data this way, because headers are visible to intermediaries.
Security rules for schemas
Two new rules in 2026-07-28 matter for anyone running a validator.
First, $ref resolution. JSON Schema lets $ref point to a URL. MCP says implementations MUST NOT automatically dereference $ref values that point to a network URI. An opt-in fetch mode is allowed, but it must be off by default and should block loopback and private addresses.
Second, resource bounds. Composition keywords like anyOf and oneOf can be expensive to check. The spec says implementations SHOULD apply limits such as maximum depth or a time budget, so a malicious schema cannot become a denial-of-service attack. Our MCP security center covers related threats.
What changed across spec versions
| Version | Schema change |
|---|---|
| 2024-11-05 | Tools have an inputSchema; no output schema (2024-11-05 Tools) |
| 2025-06-18 | outputSchema and structured tool output added |
| 2025-11-25 | JSON Schema 2020-12 becomes the default dialect (changelog) |
| 2026-07-28 | Any 2020-12 keyword allowed in both schemas; output schema no longer limited to objects; $ref and resource-bound rules; x-mcp-header (changelog) |
In the 2025-11-25 schema, outputSchema required type: "object" at the root. The 2026-07-28 change (SEP-2106) removed that limit and let structuredContent be any JSON value.
Common mistakes
- Missing property descriptions. The model reads them. A field called
dtwith no description invites bad input. - Skipping server-side validation. A client may validate too, but the server's MUST rule does not go away.
- Fetching remote
$reftargets by default. That breaks a MUST NOT rule and opens an SSRF path. - Assuming older clients accept new keywords. A client built for 2025-11-25 may expect an object-only output schema. Test against the clients you support.
- Putting secrets in
x-mcp-header. Header values can be logged by proxies and gateways.
If you are building your first tool, our Learn MCP lesson on tool design walks through good argument design.
Next step
Schemas tell a model how to call a tool. Annotations tell a client how risky the call is. Read MCP tool annotations next, or return to the MCP specification reference.
Frequently asked questions
Is inputSchema required for every MCP tool?
Yes. The spec says inputSchema must be a valid JSON Schema object and not null. For a tool with no arguments, use { "type": "object", "additionalProperties": false }.
Which JSON Schema version does MCP use?
JSON Schema 2020-12 is the default when no $schema field is present. A schema may declare another dialect, such as draft-07. Implementations must support 2020-12 at minimum.
Can a tool's output schema be an array?
Yes, as of the 2026-07-28 spec. The output schema can describe any JSON value, and the spec includes an example that returns an array of users. Earlier versions required an object at the root.
What happens if the server returns data that does not match the output schema?
The server has broken a MUST rule. Clients should validate structured results against the schema, so a well-built client can flag or reject the mismatch.
Can schemas reference other schemas with $ref?
Yes. Local references using $ref and $defs are allowed. Automatic fetching of $ref targets on the network is not, unless an implementation offers a disabled-by-default opt-in mode.











