Skip to content

feat: add $schema field to ToolSchema per SEP-1613#696

Merged
devcrocod merged 2 commits intomainfrom
devcrocod/json-schema-property
Apr 14, 2026
Merged

feat: add $schema field to ToolSchema per SEP-1613#696
devcrocod merged 2 commits intomainfrom
devcrocod/json-schema-property

Conversation

@devcrocod
Copy link
Copy Markdown
Contributor

Add optional $schema field to ToolSchema, establishing JSON Schema 2020-12 as the default dialect per SEP-1613.

closes #422

How Has This Been Tested?

unit tests

Breaking Changes

none

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an optional $schema field to ToolSchema so tool input/output schemas can explicitly declare a JSON Schema dialect (defaulting to 2020-12 per SEP-1613 when omitted).

Changes:

  • Extend ToolSchema with schema: String? serialized as $schema.
  • Add unit tests covering serialization/deserialization of $schema.
  • Update public API dump to reflect the new ToolSchema shape.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
kotlin-sdk-core/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/types/ToolsTest.kt Adds round-trip tests ensuring $schema is serialized/deserialized on tool schemas.
kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/tools.kt Introduces ToolSchema.schema with @SerialName("$schema") and updates KDoc.
kotlin-sdk-core/api/kotlin-sdk-core.api Updates the API surface snapshot for the new ToolSchema constructor/components/getter.
Comments suppressed due to low confidence (1)

kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/tools.kt:100

  • ToolSchema’s public data class shape has changed by adding a new constructor parameter/property. This is a binary-incompatible API change for consumers (constructor/copy/componentN signatures change) and also a source-breaking change for any callers using positional arguments. Consider mitigating by adding a deprecated secondary constructor matching the previous parameter order, or moving the new parameter to the end (and/or avoiding a data class change if ABI stability is required).
@Serializable
public data class ToolSchema(
    @SerialName("\$schema")
    val schema: String? = null,
    val properties: JsonObject? = null,
    val required: List<String>? = null,
    @SerialName("\$defs")
    val defs: JsonObject? = null,
) {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 5135 to +5145
public final class io/modelcontextprotocol/kotlin/sdk/types/ToolSchema {
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema$Companion;
public fun <init> ()V
public fun <init> (Lkotlinx/serialization/json/JsonObject;Ljava/util/List;Lkotlinx/serialization/json/JsonObject;)V
public synthetic fun <init> (Lkotlinx/serialization/json/JsonObject;Ljava/util/List;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Lkotlinx/serialization/json/JsonObject;
public final fun component2 ()Ljava/util/List;
public final fun component3 ()Lkotlinx/serialization/json/JsonObject;
public final fun copy (Lkotlinx/serialization/json/JsonObject;Ljava/util/List;Lkotlinx/serialization/json/JsonObject;)Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;
public static synthetic fun copy$default (Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Lkotlinx/serialization/json/JsonObject;Ljava/util/List;Lkotlinx/serialization/json/JsonObject;ILjava/lang/Object;)Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;
public fun <init> (Ljava/lang/String;Lkotlinx/serialization/json/JsonObject;Ljava/util/List;Lkotlinx/serialization/json/JsonObject;)V
public synthetic fun <init> (Ljava/lang/String;Lkotlinx/serialization/json/JsonObject;Ljava/util/List;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Lkotlinx/serialization/json/JsonObject;
public final fun component3 ()Ljava/util/List;
public final fun component4 ()Lkotlinx/serialization/json/JsonObject;
public final fun copy (Ljava/lang/String;Lkotlinx/serialization/json/JsonObject;Ljava/util/List;Lkotlinx/serialization/json/JsonObject;)Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;
public static synthetic fun copy$default (Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lkotlinx/serialization/json/JsonObject;Ljava/util/List;Lkotlinx/serialization/json/JsonObject;ILjava/lang/Object;)Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The updated API dump indicates a binary-breaking public API change to ToolSchema (new ctor signature, new componentN/copy/getSchema). This conflicts with the PR metadata stating “Breaking Changes: none”. Either adjust the PR’s breaking-change note/versioning guidance, or add compatibility shims (e.g., old constructor overload) to preserve ABI/source compatibility if that’s a requirement.

Copilot uses AI. Check for mistakes.
Comment on lines +42 to +49
* Defaults to the JSON Schema 2020-12 dialect when no explicit `$schema` is provided.
* @property description A human-readable description of the tool and when to use it.
* Clients can use this to improve the LLM's understanding of available tools.
* It can be thought of like a "hint" to the model.
* @property outputSchema An optional JSON Schema object defining the structure of the tool's output
* returned in the [structuredContent][CallToolResult.structuredContent] field of a [CallToolResult].
* Must be an object type schema if provided.
* Defaults to the JSON Schema 2020-12 dialect when no explicit `$schema` is provided.
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The KDoc says the schema “defaults to JSON Schema 2020-12” when $schema is absent, but the SDK does not enforce/validate a dialect here—it only (de)serializes data. To avoid implying runtime behavior that isn’t implemented, consider rephrasing to explicitly attribute the default to the MCP/SEP-1613 protocol semantics (i.e., consumers should assume 2020-12 when $schema is missing).

Suggested change
* Defaults to the JSON Schema 2020-12 dialect when no explicit `$schema` is provided.
* @property description A human-readable description of the tool and when to use it.
* Clients can use this to improve the LLM's understanding of available tools.
* It can be thought of like a "hint" to the model.
* @property outputSchema An optional JSON Schema object defining the structure of the tool's output
* returned in the [structuredContent][CallToolResult.structuredContent] field of a [CallToolResult].
* Must be an object type schema if provided.
* Defaults to the JSON Schema 2020-12 dialect when no explicit `$schema` is provided.
* Per MCP/SEP-1613 protocol semantics, consumers should assume the JSON Schema 2020-12
* dialect when no explicit `$schema` is provided.
* @property description A human-readable description of the tool and when to use it.
* Clients can use this to improve the LLM's understanding of available tools.
* It can be thought of like a "hint" to the model.
* @property outputSchema An optional JSON Schema object defining the structure of the tool's output
* returned in the [structuredContent][CallToolResult.structuredContent] field of a [CallToolResult].
* Must be an object type schema if provided.
* Per MCP/SEP-1613 protocol semantics, consumers should assume the JSON Schema 2020-12
* dialect when no explicit `$schema` is provided.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@e5l e5l left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@devcrocod devcrocod merged commit 61fab2f into main Apr 14, 2026
20 checks passed
@devcrocod devcrocod deleted the devcrocod/json-schema-property branch April 14, 2026 11:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement SEP-1613: JSON Schema 2020-12 as Default Dialect

3 participants