diff --git a/mcp/tools.go b/mcp/tools.go index 493e8c778..fc4a64476 100644 --- a/mcp/tools.go +++ b/mcp/tools.go @@ -613,6 +613,11 @@ func (t Tool) MarshalJSON() ([]byte, error) { m["annotations"] = t.Annotations + // Marshal Meta if present + if t.Meta != nil { + m["_meta"] = t.Meta + } + return json.Marshal(m) } diff --git a/mcp/tools_test.go b/mcp/tools_test.go index 4bb07aa5d..d17236367 100644 --- a/mcp/tools_test.go +++ b/mcp/tools_test.go @@ -1396,3 +1396,54 @@ func TestNewItemsAPICompatibility(t *testing.T) { }) } } + +// TestToolMetaMarshaling tests that the Meta field is properly marshaled as _meta in JSON output +func TestToolMetaMarshaling(t *testing.T) { + meta := map[string]any{"version": "1.0.0", "author": "test"} + // Marshal the tool to JSON + data, err := json.Marshal(Tool{ + Name: "test-tool", + Description: "A test tool with meta data", + Meta: NewMetaFromMap(meta), + InputSchema: ToolInputSchema{ + Type: "object", + Properties: map[string]any{ + "input": map[string]any{ + "type": "string", + "description": "Test input", + }, + }, + }, + }) + assert.NoError(t, err) + + // Unmarshal to map for comparison + var result map[string]any + err = json.Unmarshal(data, &result) + assert.NoError(t, err) + + // Check if _meta field is present and correct + assert.Contains(t, result, "_meta", "Tool with Meta should include _meta field") + assert.Equal(t, meta, result["_meta"], "_meta field should match expected value") +} + +func TestToolMetaMarshalingOmitsWhenNil(t *testing.T) { + // Marshal a tool without Meta + data, err := json.Marshal(Tool{ + Name: "test-tool-no-meta", + Description: "A test tool without meta data", + InputSchema: ToolInputSchema{ + Type: "object", + Properties: map[string]any{}, + }, + }) + assert.NoError(t, err) + + // Unmarshal to map + var result map[string]any + err = json.Unmarshal(data, &result) + assert.NoError(t, err) + + // Check that _meta field is not present + assert.NotContains(t, result, "_meta", "Tool without Meta should not include _meta field") +}