Skip to content

The value of "additionalProperties" MUST be a valid JSON Schema. #445

Closed

Description

@lp2jx0309

Activity

  1. tzolov commented on Aug 7, 2025

    @tzolov
    Contributor

    @lp2jx0309, please elaborate.
    the JsonSchema has additionalProperties filed:

    @JsonProperty("additionalProperties") Boolean additionalProperties,

  2. topikachu commented on Sep 29, 2025

    @topikachu

    @tzolov

    additionalProperties in the current JsonSchema definition is too restrictive.

    According to the JSON Schema spec, additionalProperties can be either a boolean or a schema object (e.g. { "type": "boolean" }).

    Defining it only as Boolean makes it impossible to handle the schema form.
    Please check the official JSON Schema test example.

  3. david-christ commented on May 19, 2026

    @david-christ

    This is actively biting us via Notion's MCP server. Their tools/list response includes tools like:

    {
      "name": "API-post-page",
      "inputSchema": {
        "type": "object",
        "properties": { ... },
        "additionalProperties": { "type": "string" }
      }
    }

    Workaround until this is fixed in the SDK: register a Jackson mixin that replaces the record's default deserialization for additionalProperties. Coerce any JSON object to null (or true, depending on your semantics) and pass booleans through as-is:

    public abstract class JsonSchemaMixin {
        @JsonDeserialize(using = AdditionalPropertiesDeserializer.class)
        @JsonProperty("additionalProperties")
        public abstract Boolean additionalProperties();
    
        static class AdditionalPropertiesDeserializer extends StdDeserializer<Boolean> {
            AdditionalPropertiesDeserializer() { super(Boolean.class); }
    
            @Override
            public Boolean deserialize(JsonParser p, DeserializationContext ctx) throws IOException {
                if (p.currentToken() == JsonToken.START_OBJECT) {
                    p.skipChildren(); // consume the schema object, treat as unconstrained
                    return null;
                }
                return p.getBooleanValue();
            }
        }
    }

    Then register it on your ObjectMapper:

    objectMapper.addMixIn(McpSchema.JsonSchema.class, JsonSchemaMixin.class);

    This is a stopgap — ideally additionalProperties would be typed as Object (or a sealed BooleanOrSchema type) to faithfully represent the spec.

  4. DragonFSKY commented on May 21, 2026

    @DragonFSKY

    Thanks for the report and for the recent Notion MCP example.

    I took a look at the current main branch, and it seems that the main Tool.inputSchema path now uses Map<String, Object> rather than the deprecated JsonSchema record. With that shape, schema-valued additionalProperties, for example:

    {
      "additionalProperties": { "type": "string" }
    }

    should be preserved when deserializing and serializing a tool schema.

    The deprecated McpSchema.JsonSchema helper still has additionalProperties typed as Boolean, so that helper cannot represent the schema-object form. Since JsonSchema is now deprecated in favor of Map<String, Object>, I am not sure whether the intended fix should be to change the deprecated helper API, or simply add a regression test for the current Tool.inputSchema map path.

    If this is still reproducible on current main, or on a version that includes #749, I would be happy to help with a focused regression test or a narrow compatibility fix.

  5. tzolov commented on Aug 17, 2026

    @tzolov
    Contributor

    As pointed out by @DragonFSKY this should have been resolved by moving the input schema to Map<String, Object> in 2.0GA+.
    Closing as resolved.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions