Skip to content

Add AdditionalProperties to ToolInputSchema#678

Merged
ezynda3 merged 1 commit intomark3labs:mainfrom
mohit-gupta-glean:mohit-add-additional-properties-to-input-schema
Jan 5, 2026
Merged

Add AdditionalProperties to ToolInputSchema#678
ezynda3 merged 1 commit intomark3labs:mainfrom
mohit-gupta-glean:mohit-add-additional-properties-to-input-schema

Conversation

@mohit-gupta-glean
Copy link
Contributor

@mohit-gupta-glean mohit-gupta-glean commented Dec 22, 2025

Summary

Add support for additionalProperties field in the ToolInputSchema (alias ToolArgumentsSchema) struct, allowing tools to specify whether additional properties are allowed in their input schema.

Changes

  • Add AdditionalProperties field to ToolArgumentsSchema struct
  • Update MarshalJSON to include additionalProperties in output when set
  • Add WithSchemaAdditionalProperties ToolOption function
  • Add tests for marshal/unmarshal and ToolOption

Example Usage

// Strict tool - no extra properties allowed
tool := mcp.NewTool("strict-tool",
    mcp.WithDescription("Only accepts defined properties"),
    mcp.WithString("name", mcp.Required()),
    mcp.WithSchemaAdditionalProperties(false),
)

Notes

  • Uses any type to support false, true, or schema object values per JSON Schema spec
  • Field is omitted from JSON when nil (default behavior allows additional properties per JSON Schema)
  • Named WithSchemaAdditionalProperties to distinguish from existing AdditionalProperties PropertyOption

Fixes #672

Summary by CodeRabbit

  • New Features

    • Tool argument schemas now support an additional properties field for extended configuration options.
    • New configuration option available for setting additional properties on tool input schemas during construction.
  • Tests

    • Comprehensive test coverage added for schema properties handling, including marshaling, unmarshaling, and integration scenarios.

✏️ Tip: You can customize this high-level summary in your review settings.

- Add AdditionalProperties field to ToolArgumentsSchema struct
- Update MarshalJSON to include additionalProperties in output
- Add WithSchemaAdditionalProperties ToolOption function
- Add comprehensive tests for marshal/unmarshal and ToolOption

Fixes mark3labs#672
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 22, 2025

Walkthrough

This PR adds additionalProperties support to ToolArgumentsSchema by introducing a new struct field, updating JSON marshaling/unmarshaling logic, and providing a new WithSchemaAdditionalProperties tool option, along with comprehensive test coverage.

Changes

Cohort / File(s) Change Summary
Production code changes
mcp/tools.go
Added AdditionalProperties field (type any) to ToolArgumentsSchema struct to support JSON Schema's additionalProperties. Updated MarshalJSON() to serialize the field when non-nil. Updated UnmarshalJSON() to deserialize the field from input JSON. Added WithSchemaAdditionalProperties(schema any) ToolOption function to allow tools to set this property during construction.
Test coverage
mcp/tools_test.go
Added comprehensive tests covering: unmarshalling additionalProperties (boolean and schema object values); marshalling with various values and omission when nil; WithSchemaAdditionalProperties option functionality; round-trip serialization/deserialization; integration with $defs/definitions; and compatibility with tool construction APIs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • JSON marshaling/unmarshaling logic: Verify that AdditionalProperties is correctly handled in MarshalJSON() and UnmarshalJSON() methods with proper nil-checking and omitempty behavior
  • Test coverage completeness: Ensure tests adequately cover edge cases such as boolean values (true/false), complex schema objects, and interactions with existing schema fields ($defs, Properties, Required)
  • API consistency: Confirm that WithSchemaAdditionalProperties() naming and behavior aligns with existing tool option patterns and distinguishes appropriately from the existing AdditionalProperties PropertyOption

Possibly related issues

Possibly related PRs

Suggested reviewers

  • pottekkat
  • rwjblue-glean
  • ezynda3

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding AdditionalProperties support to ToolInputSchema.
Description check ✅ Passed The description covers the key aspects including summary, changes, example usage, and notes. While it doesn't follow all template sections, it provides sufficient context.
Linked Issues check ✅ Passed The PR implementation fully addresses all objectives from issue #672: adds AdditionalProperties field to ToolArgumentsSchema, updates marshal/unmarshal logic, provides WithSchemaAdditionalProperties ToolOption, and includes comprehensive tests.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing issue #672 requirements. The modifications to tools.go and tools_test.go are focused on the AdditionalProperties feature with no extraneous changes.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
mcp/tools_test.go (1)

1756-1767: LGTM! ToolOption behaves correctly.

The test validates that WithSchemaAdditionalProperties properly sets the field on a tool's InputSchema and that it appears correctly in the JSON output.

Optional: Consider expanding test coverage

While the marshal/unmarshal tests already cover various additionalProperties values, you could optionally expand this test to verify the ToolOption works with true and schema objects as well:

 func TestWithSchemaAdditionalProperties(t *testing.T) {
-	tool := NewTool(
-		"strict-tool",
-		WithSchemaAdditionalProperties(false),
-	)
-
-	assert.Equal(t, false, tool.InputSchema.AdditionalProperties)
-
-	data, err := json.Marshal(tool)
-	assert.NoError(t, err)
-	assert.Contains(t, string(data), `"additionalProperties":false`)
+	tests := []struct {
+		name     string
+		value    any
+		expected string
+	}{
+		{"false", false, `"additionalProperties":false`},
+		{"true", true, `"additionalProperties":true`},
+		{"schema", map[string]any{"type": "string"}, `"additionalProperties":{"type":"string"}`},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tool := NewTool("test-tool", WithSchemaAdditionalProperties(tt.value))
+			assert.Equal(t, tt.value, tool.InputSchema.AdditionalProperties)
+			data, err := json.Marshal(tool)
+			assert.NoError(t, err)
+			assert.Contains(t, string(data), tt.expected)
+		})
+	}
 }
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a429ab3 and cf464f1.

📒 Files selected for processing (2)
  • mcp/tools.go
  • mcp/tools_test.go
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Order imports: standard library first, then third-party, then local packages (goimports enforces this)
Follow Go naming conventions: exported identifiers in PascalCase; unexported in camelCase; acronyms uppercase (HTTP, JSON, MCP)
Error handling: return sentinel errors, wrap with fmt.Errorf("context: %w", err), and check with errors.Is/As
Prefer explicit types and strongly-typed structs; avoid using any except where protocol flexibility is required (e.g., Arguments any)
All exported types and functions must have GoDoc comments starting with the identifier name; avoid inline comments unless necessary
Functions that are handlers or long-running must accept context.Context as the first parameter
Ensure thread safety for shared state using sync.Mutex and document thread-safety requirements in comments
For JSON: use json struct tags with omitempty for optional fields; use json.RawMessage for flexible/deferred parsing

Files:

  • mcp/tools_test.go
  • mcp/tools.go
**/*_test.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*_test.go: Testing: use testify/assert and testify/require
Write table-driven tests using a tests := []struct{ name, ... } pattern
Go test files must end with _test.go

Files:

  • mcp/tools_test.go
🧠 Learnings (5)
📓 Common learnings
Learnt from: xinwo
Repo: mark3labs/mcp-go PR: 35
File: mcp/tools.go:0-0
Timestamp: 2025-03-04T07:00:57.111Z
Learning: The Tool struct in the mark3labs/mcp-go project should handle both InputSchema and RawInputSchema consistently between MarshalJSON and UnmarshalJSON methods, even though the tools response from MCP server typically doesn't contain rawInputSchema.
Learnt from: xinwo
Repo: mark3labs/mcp-go PR: 35
File: mcp/tools.go:0-0
Timestamp: 2025-03-04T07:00:57.111Z
Learning: The Tool struct in mark3labs/mcp-go handles both InputSchema and RawInputSchema formats. When unmarshaling JSON, it first tries to parse into a structured ToolInputSchema format, and if that fails, it falls back to using the raw schema format, providing symmetry with the MarshalJSON method.
Learnt from: xinwo
Repo: mark3labs/mcp-go PR: 35
File: mcp/tools.go:107-137
Timestamp: 2025-03-04T06:59:43.882Z
Learning: Tool responses from the MCP server shouldn't contain RawInputSchema, which is why the UnmarshalJSON method for the Tool struct is implemented to handle only the structured InputSchema format.
📚 Learning: 2025-03-04T07:00:57.111Z
Learnt from: xinwo
Repo: mark3labs/mcp-go PR: 35
File: mcp/tools.go:0-0
Timestamp: 2025-03-04T07:00:57.111Z
Learning: The Tool struct in the mark3labs/mcp-go project should handle both InputSchema and RawInputSchema consistently between MarshalJSON and UnmarshalJSON methods, even though the tools response from MCP server typically doesn't contain rawInputSchema.

Applied to files:

  • mcp/tools_test.go
  • mcp/tools.go
📚 Learning: 2025-03-04T07:00:57.111Z
Learnt from: xinwo
Repo: mark3labs/mcp-go PR: 35
File: mcp/tools.go:0-0
Timestamp: 2025-03-04T07:00:57.111Z
Learning: The Tool struct in mark3labs/mcp-go handles both InputSchema and RawInputSchema formats. When unmarshaling JSON, it first tries to parse into a structured ToolInputSchema format, and if that fails, it falls back to using the raw schema format, providing symmetry with the MarshalJSON method.

Applied to files:

  • mcp/tools_test.go
  • mcp/tools.go
📚 Learning: 2025-03-04T06:59:43.882Z
Learnt from: xinwo
Repo: mark3labs/mcp-go PR: 35
File: mcp/tools.go:107-137
Timestamp: 2025-03-04T06:59:43.882Z
Learning: Tool responses from the MCP server shouldn't contain RawInputSchema, which is why the UnmarshalJSON method for the Tool struct is implemented to handle only the structured InputSchema format.

Applied to files:

  • mcp/tools_test.go
  • mcp/tools.go
📚 Learning: 2025-10-13T09:35:20.180Z
Learnt from: CR
Repo: mark3labs/mcp-go PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-13T09:35:20.180Z
Learning: Applies to **/*_test.go : Write table-driven tests using a tests := []struct{ name, ... } pattern

Applied to files:

  • mcp/tools_test.go
🔇 Additional comments (7)
mcp/tools_test.go (4)

1697-1713: LGTM! Proper test for boolean additionalProperties.

The test correctly verifies that additionalProperties: false is unmarshaled as a boolean value and stored in the schema.


1715-1732: LGTM! Correctly tests schema-object additionalProperties.

The test validates that additionalProperties can be a schema object (per JSON Schema spec), and properly asserts the parsed structure.


1734-1743: LGTM! Validates marshal behavior for additionalProperties.

The test correctly verifies that setting AdditionalProperties: false results in the expected JSON output.


1745-1754: LGTM! Confirms backward compatibility with omitempty.

This test is important for ensuring that tools without AdditionalProperties set won't have the field in their JSON output, maintaining backward compatibility.

mcp/tools.go (3)

638-642: LGTM! Proper struct field definition.

The AdditionalProperties any field is correctly defined with:

  • Appropriate type (any) to support boolean and schema-object values per JSON Schema spec
  • omitempty tag for backward compatibility
  • Follows Go naming conventions

The field integrates cleanly with the existing UnmarshalJSON method via the Alias pattern (lines 673-696).


666-668: LGTM! Correct marshaling logic.

The conditional inclusion of additionalProperties in the JSON output is consistent with the omitempty tag and follows the same pattern as other optional fields in this method.


927-934: LGTM! Well-designed ToolOption function.

The WithSchemaAdditionalProperties function:

  • Follows Go naming conventions and coding guidelines
  • Has a clear GoDoc comment explaining usage
  • Correctly sets the field on the tool's InputSchema
  • Naming avoids conflict with the existing AdditionalProperties PropertyOption

The implementation properly supports the feature objectives for controlling additional properties on tool input schemas.

@ezynda3 ezynda3 merged commit 0523523 into mark3labs:main Jan 5, 2026
4 checks passed
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.

Add AdditionalProperties field to ToolInputSchema

2 participants