Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mcp/tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ type Tool struct {
// A human-readable description of the tool.
Description string `json:"description,omitempty"`
// A JSON Schema object defining the expected parameters for the tool.
InputSchema ToolInputSchema `json:"-"` // Hide this from JSON marshaling
InputSchema ToolInputSchema `json:"inputSchema"`
// Alternative to InputSchema - allows arbitrary JSON Schema to be provided
RawInputSchema json.RawMessage `json:"-"` // Hide this from JSON marshaling
}
Expand Down
69 changes: 69 additions & 0 deletions mcp/tools_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,72 @@ func TestToolWithRawSchema(t *testing.T) {
assert.True(t, ok)
assert.Contains(t, required, "query")
}

func TestUnmarshalToolWithRawSchema(t *testing.T) {
// Create a complex raw schema
rawSchema := json.RawMessage(`{
"type": "object",
"properties": {
"query": {"type": "string", "description": "Search query"},
"limit": {"type": "integer", "minimum": 1, "maximum": 50}
},
"required": ["query"]
}`)

// Create a tool with raw schema
tool := NewToolWithRawSchema("search-tool", "Search API", rawSchema)

// Marshal to JSON
data, err := json.Marshal(tool)
assert.NoError(t, err)

// Unmarshal to verify the structure
var toolUnmarshalled Tool
err = json.Unmarshal(data, &toolUnmarshalled)
assert.NoError(t, err)

// Verify tool properties
assert.Equal(t, tool.Name, toolUnmarshalled.Name)
assert.Equal(t, tool.Description, toolUnmarshalled.Description)

// Verify schema was properly included
assert.Equal(t, "object", toolUnmarshalled.InputSchema.Type)
assert.Contains(t, toolUnmarshalled.InputSchema.Properties, "query")
assert.Subset(t, toolUnmarshalled.InputSchema.Properties["query"], map[string]interface{}{
"type": "string",
"description": "Search query",
})
assert.Contains(t, toolUnmarshalled.InputSchema.Properties, "limit")
assert.Subset(t, toolUnmarshalled.InputSchema.Properties["limit"], map[string]interface{}{
"type": "integer",
"minimum": 1.0,
"maximum": 50.0,
})
assert.Subset(t, toolUnmarshalled.InputSchema.Required, []string{"query"})
}

func TestUnmarshalToolWithoutRawSchema(t *testing.T) {
// Create a tool with both schemas set
tool := NewTool("dual-schema-tool",
WithDescription("A tool with both schemas set"),
WithString("input", Description("Test input")),
)

data, err := json.Marshal(tool)
assert.Nil(t, err)

// Unmarshal to verify the structure
var toolUnmarshalled Tool
err = json.Unmarshal(data, &toolUnmarshalled)
assert.NoError(t, err)

// Verify tool properties
assert.Equal(t, tool.Name, toolUnmarshalled.Name)
assert.Equal(t, tool.Description, toolUnmarshalled.Description)
assert.Subset(t, toolUnmarshalled.InputSchema.Properties["input"], map[string]interface{}{
"type": "string",
"description": "Test input",
})
assert.Empty(t, toolUnmarshalled.InputSchema.Required)
assert.Empty(t, toolUnmarshalled.RawInputSchema)
}