Skip to content

Conversation

xinwo
Copy link
Contributor

@xinwo xinwo commented Mar 4, 2025

#30
may also need to implement UnmarshalJSON method.

maybe restoring

InputSchema ToolInputSchema `json:"-"`

to

InputSchema ToolInputSchema `json:"inputSchema"`

also works.

related issue
#34

Summary by CodeRabbit

  • New Features

    • Enhanced JSON data handling for improved processing of diverse input formats, including support for both structured and raw schema data. This update delivers more robust parsing with better error management, ensuring a smoother and more reliable experience when working with JSON inputs.
    • The InputSchema field is now included in the JSON output under the key "inputSchema".
  • Tests

    • Added new test functions to improve coverage for unmarshaling tools with and without raw schemas.

Copy link
Contributor

coderabbitai bot commented Mar 4, 2025

Walkthrough

The changes modify the InputSchema field in the Tool struct within the mcp/tools.go file, updating its JSON tag from json:"-" to json:"inputSchema". This allows the InputSchema to be included in the JSON representation when the Tool struct is marshaled. Additionally, two new test functions are introduced in mcp/tools_test.go to enhance test coverage for unmarshaling functionality with and without raw schemas.

Changes

File Change Summary
mcp/tools.go Updated InputSchema field's JSON tag from json:"-" to json:"inputSchema" in the Tool struct.
mcp/tools_test.go Added new test functions: TestUnmarshalToolWithRawSchema and TestUnmarshalToolWithoutRawSchema to test the unmarshaling of tools with and without raw schemas.
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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

🔭 Outside diff range comments (1)
mcp/tools.go (1)

75-77: 💡 Verification agent

🧩 Analysis chain

Consider updating the JSON tags as mentioned in PR description

The PR description mentioned updating the InputSchema field tag from json:"-" to json:"inputSchema", but the field still has json:"-" in the code. This inconsistency should be addressed.

The current implementation uses custom marshal/unmarshal methods to handle these fields, so changing the tag might require adjusting these methods. Let's verify the PR objective:


🏁 Script executed:

#!/bin/bash
# Check the PR description to confirm intended changes to JSON tags
echo "Looking for references to JSON tag changes in the repository..."
git log -p --grep="input[Ss]chema" 

# Check for any related issues
echo "Looking for related issues..."
gh issue list --search "inputSchema json tag"

Length of output: 253


Action Required: Update JSON Tag on InputSchema Field

  • Update the tag for the InputSchema field from json:"-" to json:"inputSchema" as specified in the PR description.
  • Verify that the custom marshal/unmarshal methods (in mcp/tools.go) correctly process the updated tag to avoid any unintended side effects in JSON serialization.
🧹 Nitpick comments (2)
mcp/tools.go (2)

107-137: Missing validation for schema conflict

The existing MarshalJSON method checks for conflicts between InputSchema and RawInputSchema, but this new UnmarshalJSON method doesn't have similar validation.

Consider adding validation to ensure both aren't set simultaneously, similar to the check in MarshalJSON. This would ensure consistency in your codebase and prevent potential issues:

func (t *Tool) UnmarshalJSON(b []byte) error {
    // Temporary structure for decoding
    var raw struct {
        Name        string          `json:"name"`
        Description string          `json:"description"`
        InputSchema json.RawMessage `json:"inputSchema"`
    }

    // Unmarshal into the temporary structure
    if err := json.Unmarshal(b, &raw); err != nil {
        return err
    }

    // Assign name and description
    t.Name = raw.Name
    t.Description = raw.Description

+    // Clear both schema fields to avoid conflicts
+    t.InputSchema = ToolInputSchema{}
+    t.RawInputSchema = nil

    // Try to unmarshal InputSchema into structured format
    var schema ToolInputSchema
    if err := json.Unmarshal(raw.InputSchema, &schema); err == nil {
        // Successfully parsed structured schema
        t.InputSchema = schema
    } else {
        // Couldn't parse as structured schema, use as raw schema
        t.RawInputSchema = raw.InputSchema
    }

    return nil
}

107-137: Missing test coverage for JSON unmarshaling

Adding new functionality like this should be accompanied by unit tests to ensure correct behavior.

Consider adding tests that verify:

  1. Unmarshaling valid JSON with a structured schema
  2. Unmarshaling valid JSON with a raw schema
  3. Error handling for invalid JSON
  4. Marshaling and then unmarshaling produces equivalent objects (roundtrip test)
// Example test for UnmarshalJSON (to be placed in appropriate test file)
func TestToolUnmarshalJSON(t *testing.T) {
    // Test case 1: Valid JSON with structured schema
    jsonData := `{
        "name": "testTool",
        "description": "A test tool",
        "inputSchema": {
            "type": "object",
            "properties": {
                "param1": {"type": "string"}
            },
            "required": ["param1"]
        }
    }`
    
    var tool Tool
    err := json.Unmarshal([]byte(jsonData), &tool)
    if err != nil {
        t.Fatalf("Failed to unmarshal valid JSON: %v", err)
    }
    
    // Verify the tool was populated correctly
    if tool.Name != "testTool" || tool.Description != "A test tool" {
        t.Errorf("Unexpected tool data: %+v", tool)
    }
    
    // Verify the schema was parsed correctly
    if tool.InputSchema.Type != "object" || tool.RawInputSchema != nil {
        t.Errorf("Schema not parsed correctly: %+v", tool.InputSchema)
    }
    
    // Additional test cases would follow...
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 56273d2 and fbac167.

📒 Files selected for processing (1)
  • mcp/tools.go (1 hunks)

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.go (1)

133-136: Consider error handling vs. fallback for invalid schema
Currently, if the raw input cannot be unmarshaled into a valid ToolInputSchema, the code silently falls back to storing raw JSON. If the MCP server is expected never to return unsanctioned raw schemas, you might consider returning an error or logging a warning instead, to catch potential mismatches or schema violations early.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fbac167 and 2b5060f.

📒 Files selected for processing (1)
  • mcp/tools.go (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: xinwo
PR: mark3labs/mcp-go#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.
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:107-137
Timestamp: 2025-03-04T06:59:43.882Z
Learning: Tool responses from the MCP server should only contain structured InputSchema and should not contain RawInputSchema. This is why the UnmarshalJSON method for the Tool struct is implemented to handle only the structured InputSchema format and returns an error if it cannot parse the schema.
mcp/tools.go (2)
Learnt from: xinwo
PR: mark3labs/mcp-go#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.
Learnt from: xinwo
PR: mark3labs/mcp-go#35
File: mcp/tools.go:107-137
Timestamp: 2025-03-04T06:59:43.882Z
Learning: Tool responses from the MCP server should only contain structured InputSchema and should not contain RawInputSchema. This is why the UnmarshalJSON method for the Tool struct is implemented to handle only the structured InputSchema format and returns an error if it cannot parse the schema.
🔇 Additional comments (3)
mcp/tools.go (3)

107-109: Well-defined documentation block
The doc comment clearly states the purpose of the UnmarshalJSON method and aligns with the method's actual behavior.


110-120: Robust decoding structure
Defining a dedicated temporary struct for capturing raw input ensures a clean separation of concerns. It makes the code more understandable and reduces the likelihood of confusion or variable shadowing in the main struct.


126-132: Successful parse path works as expected
When the raw inputSchema can be parsed into a valid ToolInputSchema with a non-empty Type, it is correctly assigned to InputSchema, and RawInputSchema is nulled out. This approach follows the logic that a fully recognized schema should take precedence over raw data.

@ezynda3
Copy link
Contributor

ezynda3 commented Mar 4, 2025

@xinwo Can you add a simple test that confirms the correct structure is produced by the new Unmarshal function?

@xinwo
Copy link
Contributor Author

xinwo commented Mar 4, 2025

@xinwo Can you add a simple test that confirms the correct structure is produced by the new Unmarshal function?

@ezynda3
test added
and
restoring

InputSchema ToolInputSchema `json:"-"`

to

InputSchema ToolInputSchema `json:"inputSchema"`

works.

so I remove UnmarshalJSON method

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 (2)
mcp/tools_test.go (2)

107-110: Consider using more precise assertion methods.

While the Subset assertion works, it's not ideal for exact matching of properties as it only checks that a subset of expected keys/values exist.

-	assert.Subset(t, toolUnmarshalled.InputSchema.Properties["query"], map[string]interface{}{
-		"type":        "string",
-		"description": "Search query",
-	})
+	queryProps := toolUnmarshalled.InputSchema.Properties["query"]
+	assert.Equal(t, "string", queryProps["type"])
+	assert.Equal(t, "Search query", queryProps["description"])

77-144: Consider adding edge case tests for better coverage.

While the current tests cover the basic functionality, adding tests for edge cases would enhance robustness.

Consider adding tests for:

  1. Invalid JSON input
  2. Missing required fields
  3. Schema validation failures
  4. Very large schemas that might approach serialization limits

Example test case for invalid JSON:

func TestUnmarshalToolWithInvalidJSON(t *testing.T) {
    invalidJSON := []byte(`{"name": "broken-tool", "inputSchema": {invalid}`)
    
    var tool Tool
    err := json.Unmarshal(invalidJSON, &tool)
    
    assert.Error(t, err)
    // Optionally verify specific error type/message if your implementation 
    // returns custom errors
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2b5060f and 045451f.

📒 Files selected for processing (2)
  • mcp/tools.go (1 hunks)
  • mcp/tools_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • mcp/tools.go
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: xinwo
PR: mark3labs/mcp-go#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
PR: mark3labs/mcp-go#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
PR: mark3labs/mcp-go#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.
🔇 Additional comments (5)
mcp/tools_test.go (5)

77-118: Well-structured test for unmarshaling tool with raw schema.

This test effectively validates that the Tool struct can correctly unmarshal a JSON representation that was originally created from a raw schema. The test covers important validation points including the proper reconstruction of nested properties and their values.

A few observations:

  • The test provides good coverage for the new UnmarshalJSON functionality
  • The assertions are thorough, checking nested properties and their types
  • The use of Subset assertions is appropriate for validating complex nested structures

114-115: Be aware of potential floating-point precision issues in JSON parsing.

When unmarshaling JSON numbers, they are decoded as float64 by default in Go, which is why the test is using 1.0 and 50.0 instead of integers.

This is the correct approach for the test, but it's worth noting that this behavior is something to be aware of when dealing with JSON data in production code. The JSON unmarshaling process in Go deserializes all numbers as float64 by default when using the map[string]interface{} approach.


120-144: Good test case for tools without raw schemas.

This test appropriately verifies that a tool created with only structured schema (without raw schema) can be properly marshaled and unmarshaled, maintaining all its properties correctly.

The assertions effectively verify:

  • Basic properties (name, description)
  • Complex nested properties in the InputSchema
  • Proper handling of empty fields (Required, RawInputSchema)

142-143: Thorough validation of empty fields.

These assertions explicitly verify that both the Required array and RawInputSchema are empty after unmarshaling, which is important for confirming the symmetry between marshaling and unmarshaling operations.

This aligns with the learning that the Tool struct should handle both InputSchema and RawInputSchema consistently between MarshalJSON and UnmarshalJSON methods.


77-144: Verify that the new tests align with the PR objectives.

These tests effectively validate the UnmarshalJSON functionality for the Tool struct mentioned in the PR objectives. The tests ensure that both marshaling and unmarshaling of the Tool struct work correctly with the modified InputSchema field (now using json:"inputSchema" tag instead of json:"-").

The tests fulfill the request from user ezynda3 to add simple tests confirming that the new UnmarshalJSON function produces the correct structure.

@ezynda3
Copy link
Contributor

ezynda3 commented Mar 4, 2025

Awesome! Thanks!

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.

2 participants