MCP tool definition features in Apicurio Registry
You can store and manage MCP (Model Context Protocol) tool definitions as first-class artifacts in Apicurio Registry. You can use MCP tool features for central governance, version management, and discovery of MCP tools across your organization.
Overview
The Model Context Protocol (MCP) defines a standard for servers to expose tools that language models can invoke. With MCP tools, models can interact with external systems, such as querying databases, calling APIs, or running computations.
Apicurio Registry provides a Tool Registry that stores MCP tool definitions with the following capabilities:
Storing an MCP_TOOL definition in Apicurio Registry provides governance, versioning, and searchability for tool definitions. To make stored tools available to LLM clients such as Claude Desktop, you must also deploy the Apicurio Registry MCP server. For more information, see Additional resources.
|
- Version management
-
Track tool evolution with full version history.
- Validation
-
Ensure that tool definitions conform to the MCP specification.
- Compatibility checking
-
Detect breaking changes in tool input schemas.
- Discovery
-
Search for tools by name or input parameter.
- Well-known endpoints
-
Serve tool definitions at standard URLs.
| Well-known endpoints | Capabilities |
|---|---|
|
|
Configuration
You can configure MCP tool features by using the following configuration properties.
| Property | Default | Description |
|---|---|---|
|
|
Enables or disables MCP tool definition support (experimental) |
|
|
Set to |
To enable MCP tool support, set both properties:
apicurio.features.experimental.enabled=true
apicurio.mcp-tools.enabled=true
MCP tool definition schema
Tool definitions follow the MCP specification (2025-11-25).
| The MCP specification has two authoritative sources: the formal JSON schema and the specification docs. In some cases, these sources diverge. The following table notes where Apicurio Registry validation follows the spec docs guidance rather than the formal JSON schema. |
| Field | Type | Required | Description |
|---|---|---|---|
|
string |
Yes |
Unique identifier for the tool (1-128 characters, alphanumeric + underscore/hyphen/dot) |
|
string |
No |
Human-readable name for display purposes |
|
string |
No |
Human-readable description of tool functionality |
|
object |
Yes |
JSON Schema defining expected input parameters |
|
object |
No |
JSON Schema defining expected output structure. Described in the spec docs but not yet present in the formal MCP JSON schema. |
|
object |
No |
Optional metadata annotations (audience, priority) |
|
array |
No |
Optional icons for display in user interfaces. Described in the spec docs but not yet present in the formal MCP Tool JSON schema. Passed through without validation. |
|
object |
No |
Optional execution-related properties such as task support. Described in the spec docs but not yet present in the formal MCP Tool JSON schema. Passed through without validation. |
The inputSchema field is a JSON Schema object with the following properties:
| Field | Type | Required | Description |
|---|---|---|---|
|
string |
Yes |
Must be |
|
object |
No |
Parameter definitions (each value is a JSON Schema object) |
|
array |
No |
List of required parameter names |
Annotations provide metadata about the tool by using the MCP ToolAnnotations type:
| Field | Type | Description |
|---|---|---|
|
string |
Optional fallback display name. Per the spec docs, display precedence is: top-level |
|
array of strings |
Intended audience. The MCP spec defines a |
|
number (0-1) |
Priority hint; higher values indicate higher priority |
{
"name": "get_weather",
"title": "Weather Information Provider",
"description": "Get current weather information 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"
}
},
"required": ["temperature", "conditions"]
},
"annotations": {
"title": "Weather Lookup",
"audience": ["user", "assistant"],
"priority": 0.8
}
}
Well-known endpoints
You can search for and retrieve MCP tool definitions by using the following well-known endpoints.
The GET /.well-known/mcp-tools endpoint searches for registered MCP tool definitions with filtering support. It accepts the following query parameters:
| Parameter | Type | Description |
|---|---|---|
|
string |
Filter by tool name (partial match) |
|
string (repeatable) |
Filter by input parameter name |
|
integer |
Pagination offset (default: 0) |
|
integer |
Pagination limit (default: 20) |
curl "http://localhost:8080/.well-known/mcp-tools?parameter=location"
McpToolSearchResults{
"count": 1,
"tools": [
{
"groupId": "mcp-tools",
"artifactId": "weather-tool",
"name": "get_weather",
"title": "Weather Information Provider",
"description": "Get current weather information",
"owner": "admin",
"createdOn": 1700000000000,
"parameters": ["location"]
}
]
}
The GET /.well-known/mcp-tools/{groupId}/{artifactId} endpoint retrieves a specific registered MCP tool definition. It accepts the following path parameters:
groupId-
The group containing the tool definition
artifactId-
The artifact ID of the tool definition
You can optionally specify the following query parameter:
version(optional)-
Specific version (defaults to latest)
The response is the MCP tool definition JSON document.
The GET /.well-known/schemas/mcp-tool/v1 endpoint retrieves the JSON Schema for MCP tool definitions. You can use the schema for IDE autocompletion and validation.
curl "http://localhost:8080/.well-known/schemas/mcp-tool/v1"
Creating an MCP tool artifact
You can create an MCP tool artifact in Apicurio Registry by using the REST API.
-
Apicurio Registry is installed and running.
-
MCP tools support is enabled (
apicurio.mcp-tools.enabled=trueandapicurio.features.experimental.enabled=true).
-
Send a
POSTrequest to the Apicurio Registry REST API to create the MCP tool artifact:curl -X POST "http://localhost:8080/apis/registry/v3/groups/mcp-tools/artifacts" \ -H "Content-Type: application/json" \ -d '{ "artifactId": "weather-tool", "artifactType": "MCP_TOOL", "firstVersion": { "version": "1.0.0", "content": { "contentType": "application/json", "content": "{\"name\": \"get_weather\", \"title\": \"Weather Tool\", \"description\": \"Get weather data\", \"inputSchema\": {\"type\": \"object\", \"properties\": {\"location\": {\"type\": \"string\"}}, \"required\": [\"location\"]}}" } } }'
Validation rules
Apicurio Registry validates MCP tool definitions at three levels.
| Level | Description |
|---|---|
|
No validation |
|
Validates JSON syntax and that the document is a JSON object |
|
Complete validation including:
|
At the FULL level, Apicurio Registry validates inputSchema, and outputSchema when it is present, against the meta-schema of the JSON Schema dialect that each one declares in its $schema keyword. When a schema does not declare $schema, Apicurio Registry uses JSON Schema 2020-12, which is the default dialect in the MCP specification. Apicurio Registry supports JSON Schema draft-04, draft-06, draft-07, 2019-09, and 2020-12. A $schema value that is not a string, or that declares any other dialect, is reported as a rule violation, and the schema is not validated against a different dialect.
If you already use the FULL validity level for MCP tool definitions, Apicurio Registry now rejects a tool definition whose inputSchema or outputSchema is not a valid JSON Schema document, for example a property that declares "type": "strng". Rules are applied when content is submitted, so versions that are already stored are not revalidated.
|
Compatibility checking
When a COMPATIBILITY rule is configured, Apicurio Registry compares the inputSchema and optional outputSchema of successive MCP_TOOL versions with the same Apitomy Data Models checker used for JSON Schema artifacts.
The two schemas have opposite directions:
-
BACKWARD: the new tool accepts every input allowed by the old input schema, and every output allowed by the new output schema satisfies the old output schema. -
FORWARD: the old tool accepts every input allowed by the new input schema, and every output allowed by the old output schema satisfies the new output schema. -
FULL: both conditions hold. -
The
_TRANSITIVEmodes check every earlier version rather than only the latest.NONEdisables compatibility checking. With no previous version, there is no compatibility comparison; configure aVALIDITYrule for initial content validation.
| Change (old to new) | Input BACKWARD | Input FORWARD | Output BACKWARD | Output FORWARD |
|---|---|---|---|---|
Make a required property optional, keeping its schema |
Yes |
No |
No |
Yes |
Make an optional property required |
No |
Yes |
Yes |
No |
Add a typed optional property to a closed object ( |
Yes |
No |
No |
Yes |
Add a typed optional property to an open object (absent or |
No |
Yes |
Yes |
No |
Remove an optional property declaration from a closed object |
No |
Yes |
Yes |
No |
Remove an optional property constraint from an open object |
Yes |
No |
No |
Yes |
Widen |
Yes |
No |
No |
Yes |
Change between disjoint types ( |
No |
No |
No |
No |
Expand |
Yes |
No |
No |
Yes |
Lower |
Yes |
No |
No |
Yes |
Allow additional properties, widen their schema, or relax |
Yes |
No |
No |
Yes |
The table assumes a strict change in accepted values with other constraints unchanged. Reverse a widening change to reverse its results. A property declaration is a constraint, not a guarantee that the property exists: use required for that guarantee. A required output can become optional only with a forward-compatible change; adding a required output can be backward compatible if the old schema already allowed that property and its values.
Adding an outputSchema where none existed is backward compatible but not forward compatible. Removing it loses the declared output guarantee and is backward incompatible but forward compatible. Changing the tool’s name, title, description, or annotations does not affect this schema comparison; that does not establish that a renamed tool or changed implementation is safe for callers.
Supported schema subset and limits
The publication rule supports recursive properties, schema-valued or boolean additionalProperties, homogeneous items, boolean subschemas, type (including unions), required, enum, const, numeric bounds and multipleOf, string length bounds, array size and uniqueness, and object property counts. It recognizes drafts 4, 6, 7, 2019-09, and 2020-12; absent $schema uses draft 7. Keywords must be valid for the declared draft. In draft 4, const (which draft 4 does not define) and the boolean exclusiveMinimum and exclusiveMaximum modifiers are outside the supported subset. The checker compares most numbers as 64-bit floating-point values, so numbers must be exactly representable at that precision, such as 0.1 or integers up to 253. A value such as 9007199254740993.0, or an integer above 253 in a numeric bound or multipleOf, is outside the supported subset and returns HTTP 422 rather than comparing equal to a neighboring value. Integers of any size inside enum and const values are compared exactly.
Schema annotations (title, description, default, examples, $comment, deprecated, readOnly, and writeOnly) do not enforce compatibility constraints. Default values do not fill missing inputs.
References ($ref, $dynamicRef, $recursiveRef, identifiers and definition containers), composition (allOf, anyOf, oneOf, not), conditionals, dependencies, tuple schemas, prefixItems, contains, unevaluated*, pattern, patternProperties, format, and other unlisted keywords are outside this publication rule’s supported subset. They are not silently discarded. If either compared schema uses one, even unchanged, the comparison fails with HTTP 422. No reference is fetched or resolved. This deliberately narrower contract does not change the JSON artifact checker or cross-tool chaining endpoint.
A known incompatible change returns HTTP 400 with a rule-violation context prefixed by /inputSchema or /outputSchema. For example, narrowing an input string reports /inputSchema/properties/query/maxLength. Input BACKWARD contexts point into the new schema; output BACKWARD contexts point into the old schema because its accepted outputs are the comparison target. FORWARD reverses those locations; FULL can report both. Invalid or unsupported schemas return HTTP 422. Neither rejection creates the candidate version or changes previously accepted content.
The engine can conservatively reject changes that accept the same values, especially when several constraints interact. A passing schema check is not proof of behavioral equivalence, runtime conformance, successful invocation, or compatibility between two different tools.
Upgrade and sample guidance
Earlier MCP tool checking compared only top-level input types, property names, and requiredness; output changes and nested constraint changes were unchecked. Version 3.4 checks the supported subset above and changes those results. Making an input optional is now backward compatible. Adding a typed optional input to an open schema is no longer automatically accepted. Stored versions are not rewritten; unsupported schemas in existing versions can prevent subsequent publication under an enabled compatibility rule.
For a release-safety demonstration, publish a tool whose input query is a string with maxLength: 10, enable BACKWARD, and propose maxLength: 5. Expect HTTP 400 and unchanged old content. Propose maxLength: 20 and expect acceptance. For an output schema, the direction is reversed. Use a disposable registry and retain the rule configuration, exact versions, responses, and retrieved content as evidence for the agent-registry graduation work (#10294). This demonstrates publication-time schema enforcement only; it is not evidence of runtime admission, authenticated invocation, or full feature graduation.
Automatic label extraction
When you store MCP tool definitions, Apicurio Registry automatically extracts structured elements for search.
| Element pattern | Source |
|---|---|
|
Each parameter name from inputSchema.properties |
You can use the extracted labels for efficient parameter-based discovery by using the Apicurio Registry search.
