Skip to content

Tool.InputSchema silently defaults to {"type":"object"} when absent from JSON, masking missing required field #1575

Closed

Description

@jwoo-msft

Describe the bug

Tool.InputSchema has a field initializer = McpJsonUtilities.DefaultMcpToolSchema that defaults to {"type":"object"}. When deserializing a JSON payload that omits inputSchema entirely, System.Text.Json leaves the field at its default rather than throwing. This silently accepts a spec-violating Tool definition.

Per the MCP spec (2025-03-26 through 2025-11-25), inputSchema is required on Tool ("required": ["inputSchema", "name"]). A missing inputSchema in JSON should cause deserialization to fail, not silently produce a valid-looking default.

To reproduce

string json = """{"name":"frob"}"""; // no inputSchema
Tool? tool = JsonSerializer.Deserialize<Tool>(json);
// Expected: throws (inputSchema is required per spec)
// Actual: succeeds, tool.InputSchema.ValueKind == Object, raw = {"type":"object"}

Expected behavior

Deserialization should fail when inputSchema is absent. Either add [JsonRequired] to the property, or validate in the setter that the value was explicitly provided.

Impact

Consumers using Tool for manifest deserialization cannot detect missing inputSchema after deserialization — the default masks the authoring error. This affects Windows MCP manifest validation (WMSS/ODR).

Version: ModelContextProtocol 0.4.0-preview.1

Activity

  1. DragonFSKY commented on May 24, 2026

    @DragonFSKY
    Contributor

    I can take this.

    I reproduced the current behavior locally: deserializing {"name":"frob"} into Tool succeeds and leaves InputSchema as the default {"type":"object"}, so the missing required inputSchema field is masked.

    I plan to add a regression test for the missing-inputSchema deserialization case and make the smallest change needed so JSON deserialization fails for that invalid payload while preserving the existing default schema behavior for code-created Tool instances.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions