Туториал
MCP и JSON Schema: структуры данных tool calling AI-агента 2026
В pipeline агента минимум три JSON: arguments модели, params.arguments MCP, HTTP-body сервера. Они должны исходить из одной Schema.
2026 AI agents rely on tool calling: the model picks a function and fills arguments; the runtime forwards them to an MCP server, REST API, or internal service. JSON Schema is the usual shape spec—OpenAI function.parameters, Anthropic input_schema, Gemini function declarations, MCP inputSchema all describe the same thing: keys, types, and required fields for the arguments object. MCP is transport and discovery; JSON Schema is the field contract; Structured Output governs the final answer. This article follows the data path from tools/list Schema to model arguments JSON, JSON-RPC tools/call, server validation, and downstream HTTP—and links our Stateless MCP, Structured Output, and JSON error guides.
What MCP and JSON Schema each govern
Model Context Protocol (MCP) defines how clients discover tools and exchange JSON-RPC. It does not invent a new type system—tool args use JSON Schema (2020-12 subset) in each Tool’s inputSchema. JSON Schema here is the tool contract: searchInvoices needs startDate, endDate; status must be draft/sent/paid/void.
JSON Schema also appears elsewhere: Structured Output constrains the model’s final answer; OpenAI Responses text.format.json_schema for extraction; OpenAPI for HTTP bodies. MCP inputSchema covers tool inputs only. Mixing the three yields “Structured Output passed but tools/call args still missing keys”—different hops.
MCP Tool objects include name, description, inputSchema (optional outputSchema). Servers expose them via tools/list; clients cache and inject into model context. Stateless MCP (2026-07-28) removes session state but does not validate arguments—inputSchema is declarative; execution must parse + Schema-validate. See our гид Stateless MCP.
Tool calling flow: model to MCP server
A typical remote MCP agent path in five steps:
- Client tools/list (or cache) fetches Tool defs with inputSchema.
- Map tools to model API format (OpenAI tools[], Anthropic tools[]); Schema field names may map inputSchema → parameters.
- Model returns tool_calls / tool_use; arguments are usually a JSON string.
- Client JSON.parse arguments, builds MCP tools/call with name + arguments object.
- MCP server validates again, runs logic, returns result.content (often text JSON).
Failures cluster at steps 3→4: numbers as strings, missing required, stale cached tools/list. Stateless _meta per request does not fix argument shape if step-2 Schema drifted from the server.
Example tools/call body (2026-07-28, HTTP headers omitted):
{
"jsonrpc": "2.0",
"id": 42,
"method": "tools/call",
"params": {
"name": "searchInvoices",
"arguments": {
"startDate": "2026-01-01",
"endDate": "2026-01-31",
"status": "paid"
},
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28"
}
}
}
inputSchema vs OpenAI parameters
MCP and OpenAI function calling are structurally similar; engineering details differ:
| Concept | MCP Tool | OpenAI function tool |
|---|---|---|
| Schema container | inputSchema | function.parameters |
| Strict mode | Spec recommends server validation; no unified model-side strict | tools[].strict: true (beta) on arguments |
| required semantics | Standard JSON Schema | Under strict, all properties must appear in required |
| Transport | JSON-RPC tools/call | Chat/Responses API tool_calls |
Same invoice search tool on MCP:
{
"name": "searchInvoices",
"description": "Search invoices by date range and status",
"inputSchema": {
"type": "object",
"properties": {
"startDate": { "type": "string", "format": "date" },
"endDate": { "type": "string", "format": "date" },
"status": {
"type": "string",
"enum": ["draft", "sent", "paid", "void"]
}
},
"required": ["startDate", "endDate"],
"additionalProperties": false
}
}
OpenAI strict tool (all properties must be in required for strict compile):
{
"type": "function",
"function": {
"name": "searchInvoices",
"description": "Search invoices by date range and status",
"strict": true,
"parameters": {
"type": "object",
"properties": {
"startDate": { "type": "string", "format": "date" },
"endDate": { "type": "string", "format": "date" },
"status": {
"type": "string",
"enum": ["draft", "sent", "paid", "void"]
}
},
"required": ["startDate", "endDate", "status"],
"additionalProperties": false
}
}
}
Anthropic uses input_schema; Gemini uses parameters on function declarations. Differences are field names and strict subsets—not business fields. Maintain one canonical Schema file and generate MCP, OpenAI, and OpenAPI shells in CI.
2026 stacks: OpenAI, Anthropic, Gemini, MCP
No portable Schema everywhere, but tool-calling JSON objects converge on JSON Schema subsets:
| Stack / protocol | Tool Schema field | arguments guarantee |
|---|---|---|
| MCP 2026-07-28 | Tool.inputSchema | Protocol does not validate; server must Schema-validate |
| OpenAI Responses / Chat | function.parameters + strict | Beta strict on argument shape; execution should re-validate |
| Anthropic Messages | tool.input_schema | tool_use input object; Schema + local validation |
| Gemini | function_declarations.parameters | functionCall args; responseSchema for final JSON |
Structured Output (final model JSON) and tool arguments are two hops. Our туториал Structured Output covers the former; гид ошибок JSON ИИ covers four error layers. Version answer Schema and tool Schema separately.
DeepSeek V4-Flash stays closer to json_object; stateless MCP scales horizontally but argument validation stays yours. Apple can expose one Swift function to App Intents, Foundation Models, and MCP—see Apple AI Agent и JSON.
One Schema, three surfaces
Keep a single source of truth, e.g. schemas/search-invoices.schema.json:
- Emit MCP Tool inputSchema (embed or $ref).
- Emit OpenAI/Anthropic tool defs; auto-fill required under strict.
- Emit OpenAPI requestBody for downstream HTTP.
On breaking changes, bump schema_version or tool name (searchInvoices_v2) and shorten tools/list cache TTL. Stateless MCP clients cache tool lists—stale Schema writes wrong shapes into arguments, as noted in our статья Stateless MCP FAQ.
Optional MCP outputSchema describes result JSON; many servers still return free text—if you control the server, structured results with Schema make agent retries more reliable.
Validation chain and JSONVue workflow
Every hop: parse → Schema → business rules.
- Model arguments string: JSON.parse; log raw + tool_call id on failure.
- Validate against inputSchema (or strict parameters) with Draft 2020-12; emit path/keyword.
- Business gate: date range, status vs permissions, foreign keys.
Align three JSON blobs side by side: model arguments, MCP params.arguments, server HTTP body. Mismatch usually means adapter mapping, not the model. In the browser: JSON formatter for parse; JSON Schema validator for arguments vs Schema file; JSON Diff for model args vs HTTP body. Share valid / missing-field / wrong-enum fixtures in CI and JSONVue.
Читать: Structured Output, Stateless MCP, ошибки JSON, DeepSeek V4-Flash.
FAQ
Does MCP validate inputSchema for the server?
No. inputSchema declares shape for clients and models. The MCP server must parse and Schema-validate arguments before calling business APIs. JSON-RPC errors beat silent 500s for agent retries.
Can inputSchema share a file with Structured Output Schema?
Same syntax, different semantics—tool inputs vs final answers. Split files even when fields overlap so tool changes do not break extraction.
Why must OpenAI strict list all properties in required?
The strict compiler requires every property in required; otherwise the model may omit fields you assumed defaulted. MCP has no compile rule, but OpenAI strict mapping must auto-fill required.
How long to cache tools/list?
Match change frequency. Use server ttlMs when stable; on breaking Schema, bump tool name/version, shorten TTL, force client refresh. Stateless MCP has no session-bound invalidation—use explicit versioning.
Summary and next steps
MCP uses JSON Schema for tool inputs (inputSchema) and JSON-RPC for tools/call; JSON Schema also serves Structured Output and OpenAPI. The 2026 tool-calling spine: one canonical Schema → multiple API shells → parse + Schema + business validation per hop.
Next: verify tools/list and OpenAI tools[] share one Schema; replay one tools/call round trip in JSONVue. For protocol details read Stateless MCP; for model output shape read Structured Output; for failure layers read the JSON errors guide.