Skip to content

fix: ToolInputSchema inherits MarshalJSON from ToolArgumentsSchema#696

Open
proyuen wants to merge 1 commit intomark3labs:mainfrom
proyuen:fix/tool-input-schema-marshal
Open

fix: ToolInputSchema inherits MarshalJSON from ToolArgumentsSchema#696
proyuen wants to merge 1 commit intomark3labs:mainfrom
proyuen:fix/tool-input-schema-marshal

Conversation

@proyuen
Copy link

@proyuen proyuen commented Jan 17, 2026

Summary

  • Changed ToolInputSchema and ToolOutputSchema from type definitions to type aliases
  • This ensures they properly inherit the MarshalJSON method from ToolArgumentsSchema
  • The properties field is now always included in JSON output, even when empty

Fixes #694

Problem

ToolInputSchema was defined as:

type ToolInputSchema ToolArgumentsSchema // type definition

This meant it didn't inherit MarshalJSON, causing properties to be omitted when empty.

Solution

Changed to a type alias:

type ToolInputSchema = ToolArgumentsSchema // type alias, inherits methods

Test plan

  • Added TestToolInputSchema_MarshalJSON_EmptyProperties test
  • Added TestToolOutputSchema_MarshalJSON_EmptyProperties test
  • All existing tests pass (go test ./...)

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • Refactor

    • Simplified internal type structure for improved code consistency and maintainability.
  • Tests

    • Added test coverage to verify proper JSON serialization behavior with empty data structures, enhancing system reliability.

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

Fixes mark3labs#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 <noreply@anthropic.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 17, 2026

Walkthrough

This PR converts ToolInputSchema and ToolOutputSchema from type definitions to type aliases of ToolArgumentsSchema. This enables them to inherit the MarshalJSON method, ensuring empty Properties maps are marshaled as {} rather than omitted. Two tests verify this behavior.

Changes

Cohort / File(s) Summary
Type alias conversion
mcp/tools.go
Changed ToolInputSchema and ToolOutputSchema from type definitions to type aliases (= ToolArgumentsSchema), enabling method inheritance and fixing JSON marshaling of empty Properties.
Empty properties marshaling tests
mcp/tools_test.go
Added TestToolInputSchema_MarshalJSON_EmptyProperties and TestToolOutputSchema_MarshalJSON_EmptyProperties to verify that empty Properties maps are marshaled as {"properties":{}} in JSON output.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: converting ToolInputSchema to inherit MarshalJSON from ToolArgumentsSchema through type aliasing.
Description check ✅ Passed The description is comprehensive and follows the template with clear sections covering the problem, solution, and test plan.
Linked Issues check ✅ Passed The PR successfully addresses issue #694 by converting ToolInputSchema and ToolOutputSchema to type aliases, enabling MarshalJSON inheritance and ensuring properties field inclusion.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing issue #694: type conversions in mcp/tools.go and corresponding tests in mcp/tools_test.go.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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: 1

🤖 Fix all issues with AI agents
In `@mcp/tools.go`:
- Around line 645-646: Add GoDoc comments for the exported type aliases: prepend
a comment starting with "ToolInputSchema" above the declaration "type
ToolInputSchema = ToolArgumentsSchema" and a comment starting with
"ToolOutputSchema" above "type ToolOutputSchema = ToolArgumentsSchema" that
briefly explains they are retro-compatible aliases of ToolArgumentsSchema and
inherit its methods; follow the project's style used for other aliases (e.g.,
OAuthConfig, Token) so the comments begin with the identifier name and
succinctly describe purpose/compatibility.
🧹 Nitpick comments (1)
mcp/tools_test.go (1)

1768-1801: Consider consolidating into a table-driven test to reduce duplication.

These two tests are structurally identical and can be merged into a single table-driven test for consistency and easier extension.

♻️ Proposed refactor
-// 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")
-}
+// TestToolSchema_MarshalJSON_EmptyProperties verifies both ToolInputSchema and
+// ToolOutputSchema marshal empty properties maps as {}.
+func TestToolSchema_MarshalJSON_EmptyProperties(t *testing.T) {
+	tests := []struct {
+		name   string
+		schema any
+	}{
+		{
+			name: "input_schema",
+			schema: ToolInputSchema{
+				Type:       "object",
+				Properties: map[string]any{},
+			},
+		},
+		{
+			name: "output_schema",
+			schema: ToolOutputSchema{
+				Type:       "object",
+				Properties: map[string]any{},
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			b, err := json.Marshal(tt.schema)
+			assert.NoError(t, err)
+			result := string(b)
+			assert.Contains(t, result, `"properties":{}`, "Expected empty properties object in JSON output")
+		})
+	}
+}

As per coding guidelines, tests should follow a table-driven structure where practical.

Comment on lines +645 to +646
type ToolInputSchema = ToolArgumentsSchema // For retro-compatibility (true alias, inherits methods)
type ToolOutputSchema = ToolArgumentsSchema
Copy link
Contributor

@coderabbitai coderabbitai bot Jan 17, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Check the current state of mcp/tools.go around lines 645-646
sed -n '640,650p' mcp/tools.go

Repository: mark3labs/mcp-go

Length of output: 583


🏁 Script executed:

# Search for context around ToolInputSchema and ToolOutputSchema
rg -B 3 -A 3 'type ToolInputSchema|type ToolOutputSchema' mcp/tools.go

Repository: mark3labs/mcp-go

Length of output: 424


🏁 Script executed:

# Check if there are GoDoc comments anywhere above these lines
sed -n '630,650p' mcp/tools.go

Repository: mark3labs/mcp-go

Length of output: 852


🏁 Script executed:

# Check how ToolInputSchema and ToolOutputSchema are used in the codebase
rg 'ToolInputSchema|ToolOutputSchema' mcp/tools.go -B 2 -A 2

Repository: mark3labs/mcp-go

Length of output: 1108


🏁 Script executed:

# Check if there are any other type alias examples in the codebase with GoDoc comments
rg 'type \w+ = \w+' --type go -B 2 -A 0

Repository: mark3labs/mcp-go

Length of output: 1111


Add GoDoc comments for the exported aliases.

ToolInputSchema and ToolOutputSchema are exported type aliases but lack GoDoc comments. Other type aliases in the codebase (e.g., OAuthConfig, Token in client/oauth.go) follow the pattern of having GoDoc comments starting with the identifier name. Align these aliases with the project's documentation standard.

✍️ Proposed fix
+// ToolInputSchema is an alias of ToolArgumentsSchema for backward compatibility.
+// It inherits ToolArgumentsSchema's JSON marshaling behavior.
 type ToolInputSchema = ToolArgumentsSchema // For retro-compatibility (true alias, inherits methods)
+
+// ToolOutputSchema is an alias of ToolArgumentsSchema for backward compatibility.
+// It inherits ToolArgumentsSchema's JSON marshaling behavior.
 type ToolOutputSchema = ToolArgumentsSchema
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
type ToolInputSchema = ToolArgumentsSchema // For retro-compatibility (true alias, inherits methods)
type ToolOutputSchema = ToolArgumentsSchema
// ToolInputSchema is an alias of ToolArgumentsSchema for backward compatibility.
// It inherits ToolArgumentsSchema's JSON marshaling behavior.
type ToolInputSchema = ToolArgumentsSchema // For retro-compatibility (true alias, inherits methods)
// ToolOutputSchema is an alias of ToolArgumentsSchema for backward compatibility.
// It inherits ToolArgumentsSchema's JSON marshaling behavior.
type ToolOutputSchema = ToolArgumentsSchema
🤖 Prompt for AI Agents
In `@mcp/tools.go` around lines 645 - 646, Add GoDoc comments for the exported
type aliases: prepend a comment starting with "ToolInputSchema" above the
declaration "type ToolInputSchema = ToolArgumentsSchema" and a comment starting
with "ToolOutputSchema" above "type ToolOutputSchema = ToolArgumentsSchema" that
briefly explains they are retro-compatible aliases of ToolArgumentsSchema and
inherit its methods; follow the project's style used for other aliases (e.g.,
OAuthConfig, Token) so the comments begin with the identifier name and
succinctly describe purpose/compatibility.

Copy link
Contributor

Choose a reason for hiding this comment

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

@proyuen can you add these please?

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Contributor

Choose a reason for hiding this comment

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

@proyuen ping

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.

ToolInputSchema doesn't inherit MarshalJSON from ToolArgumentsSchema

2 participants