From df4e398cfb31cdb63c90a321308a12d4557ba848 Mon Sep 17 00:00:00 2001 From: Yuen Date: Sat, 17 Jan 2026 21:23:05 +0800 Subject: [PATCH] fix: ToolInputSchema inherits MarshalJSON from ToolArgumentsSchema Fixes #694 Changed ToolInputSchema and ToolOutputSchema from type definitions to type aliases so they properly inherit the MarshalJSON method from ToolArgumentsSchema. This ensures the 'properties' field is always included in JSON output, even when empty. Co-Authored-By: Claude --- mcp/tools.go | 4 ++-- mcp/tools_test.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/mcp/tools.go b/mcp/tools.go index d0cebe829..a7fb6b1cd 100644 --- a/mcp/tools.go +++ b/mcp/tools.go @@ -642,8 +642,8 @@ type ToolArgumentsSchema struct { AdditionalProperties any `json:"additionalProperties,omitempty"` } -type ToolInputSchema ToolArgumentsSchema // For retro-compatibility -type ToolOutputSchema ToolArgumentsSchema +type ToolInputSchema = ToolArgumentsSchema // For retro-compatibility (true alias, inherits methods) +type ToolOutputSchema = ToolArgumentsSchema // MarshalJSON implements the json.Marshaler interface for ToolInputSchema. func (tis ToolArgumentsSchema) MarshalJSON() ([]byte, error) { diff --git a/mcp/tools_test.go b/mcp/tools_test.go index 6a722532f..7a4e7d0c3 100644 --- a/mcp/tools_test.go +++ b/mcp/tools_test.go @@ -1765,3 +1765,37 @@ func TestWithSchemaAdditionalProperties(t *testing.T) { assert.NoError(t, err) assert.Contains(t, string(data), `"additionalProperties":false`) } + +// TestToolInputSchema_MarshalJSON_EmptyProperties verifies that ToolInputSchema +// inherits the MarshalJSON method from ToolArgumentsSchema, ensuring that +// the 'properties' field is included in JSON output even when empty. +// This fixes issue #694. +func TestToolInputSchema_MarshalJSON_EmptyProperties(t *testing.T) { + schema := ToolInputSchema{ + Type: "object", + Properties: map[string]any{}, // empty but not nil + } + + b, err := json.Marshal(schema) + assert.NoError(t, err) + + result := string(b) + // Ensure 'properties' field is present in JSON output + assert.Contains(t, result, `"properties"`, "Expected properties field in JSON output") + // Verify the full expected output + assert.Contains(t, result, `"properties":{}`, "Expected empty properties object in JSON output") +} + +// TestToolOutputSchema_MarshalJSON_EmptyProperties verifies the same for ToolOutputSchema. +func TestToolOutputSchema_MarshalJSON_EmptyProperties(t *testing.T) { + schema := ToolOutputSchema{ + Type: "object", + Properties: map[string]any{}, // empty but not nil + } + + b, err := json.Marshal(schema) + assert.NoError(t, err) + + result := string(b) + assert.Contains(t, result, `"properties":{}`, "Expected empty properties object in JSON output") +}