AI & MCP

The JSON schema of an agent tool: fields, required and bounds

A tool schema is type object, properties and required: the model reads that shape, not the code. Here is how to keep it narrow and citable.

Key points

  • The schema is a contract the model reads before calling: three required fields, not ten.
  • Numeric bounds and typed arrays replace hand-written validation.
  • Descriptions are prompts: keep them short, with a quoted example and no hidden instructions.

The JSON schema of an agent tool is an object with type: object, a map of properties and a required list: the model reads that shape, not the server code. A free-text field without a description is a field the model fills at random.

The minimum shape

{
  "name": "get_component",
  "inputSchema": {
    "type": "object",
    "properties": {
      "library": { "type": "string" },
      "name": { "type": "string" }
    },
    "required": ["library", "name"]
  }
}

Two strings, both required, no optional field. The server rejects a call without library and suggests search_components, because the model usually does not know the exact id. The schema declares what it needs, the error message declares what to do next.

Required is a product decision

Out of 18 properties, EneUI marks 8 as required: query for the two searches, library and name to read a component, source and name for a block, intent for composition, path for a page. Every extra required field is a call the model can get wrong, so the rule is: required only what the tool cannot work without.

Constraints instead of logic

The limit parameter of search_components is an integer with minimum: 1 and maximum: 30; compose_page stops at 20. The sections field is an array whose items are strings. With those three constraints the server never handles negative numbers, text where a list belongs or out-of-range values: the schema stops them first.

The description is part of the schema

The nine descriptions we measured run from 61 to 230 characters. The one for search_components says what it returns and quotes examples, such as pricing table or modal with focus trap. A concrete example beats an adjective: the model copies the format of the example when it fills a free-text field.

No enum, and not out of laziness

ToolPropertiesRequiredArrays
search_components410
get_component220
search_blocks310
get_block220
get_design_system100
list_design_systems000
compose_page511
list_categories000
get_page110

An enum would help for pageType, which accepts landing, pricing, dashboard, auth, ecommerce and blog. Today it is a string with the list in the description, because the list changes when the catalogue changes and a stale enum would reject a new value. The choice has a cost: the model can invent a category that does not exist.

Input and output are two contracts

The 2025-06-18 revision also allows outputSchema, with the result structured in structuredContent. EneUI does not use it: it returns Markdown text with count, name, library, licence, URL and install command. The gain is that the model can cite it as it stands; the cost is that no client validates the shape of the result.

The limitation

JSON Schema validates shape, not meaning. It cannot say that a library must exist in the catalogue, that name should be looked up with search_components first, or that a URL must answer 200. Those rules stay in the description and the error message, which is text the model reads as untrusted content.

Where to continue

Name and output choices are in designing an MCP tool, transport and server wiring in an MCP server with the Node SDK, the protocol in what MCP is. The catalogue behind the examples is 111,985 components and 1,556 blocks; a record with a declared MIT licence upstream is Magic UI rainbow button.

Frequently asked questions

Which JSON Schema dialect should I use?

The Tools page of the 2025-06-18 revision does not fix a dialect. Stay on the subset every client shares: type, properties, required, items, minimum, maximum. Every extra keyword is compatibility you lose.

Should every field be required?

No, only those the tool cannot work without. EneUI marks 8 required properties out of 18: one more required field is a call the model can get wrong, and a validation error costs a whole step.

Enum or free string?

An enum when the list is stable and short, like the six pageType values. A string with the list in the description when values follow the catalogue, accepting that the model may invent one.

How long should a field description be?

One or two sentences with a quoted example: the EneUI tool descriptions measure 61 to 230 characters. Beyond that the text spends context on every request without changing the model's choice.

Do I need an outputSchema?

You need one when a client must validate or process the result. EneUI declares only the input and returns Markdown, because the consumer is a model citing the text. With outputSchema you must also return conforming structuredContent, otherwise the contract is broken.