Skip to content

Commit 922de93

Browse files
authored
fix: staticcheck linting error and schema normalization (#565)
- Convert if/else chain to switch statement in handlers_test.go (QF1003) - Fix NormalizeInputSchema to add 'type: object' when missing (required by go-sdk AddTool validation) - Update types_test.go to expect normalized empty schemas
2 parents 8972506 + d8bfac1 commit 922de93

File tree

5 files changed

+35
-10
lines changed

5 files changed

+35
-10
lines changed

internal/mcp/types.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,27 @@ func NormalizeInputSchema(schema map[string]interface{}, toolName string) map[st
7171

7272
// Check if this is an object type schema
7373
typeVal, hasType := schema["type"]
74+
75+
// If schema has no type but has properties, it's implicitly an object type
76+
// The MCP SDK requires "type": "object" to be present, so add it
7477
if !hasType {
75-
return schema
78+
_, hasProperties := schema["properties"]
79+
if hasProperties {
80+
logger.LogWarn("backend", "Tool schema normalized: %s - added 'type': 'object' to schema with properties", toolName)
81+
// Create a copy of the schema to avoid modifying the original
82+
normalized := make(map[string]interface{})
83+
for k, v := range schema {
84+
normalized[k] = v
85+
}
86+
normalized["type"] = "object"
87+
return normalized
88+
}
89+
// Schema without type and without properties - assume it's an empty object schema
90+
logger.LogWarn("backend", "Tool schema normalized: %s - schema missing type, assuming empty object schema", toolName)
91+
return map[string]interface{}{
92+
"type": "object",
93+
"properties": map[string]interface{}{},
94+
}
7695
}
7796

7897
typeStr, isString := typeVal.(string)

internal/mcp/types_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@ func TestNormalizeInputSchema_NilSchema(t *testing.T) {
2222
func TestNormalizeInputSchema_EmptySchema(t *testing.T) {
2323
schema := map[string]interface{}{}
2424
result := NormalizeInputSchema(schema, "test-tool")
25-
assert.Equal(t, schema, result, "Empty schema should be unchanged")
25+
// Empty schema should be normalized to a valid object schema since SDK requires type: object
26+
expected := map[string]interface{}{
27+
"type": "object",
28+
"properties": map[string]interface{}{},
29+
}
30+
assert.Equal(t, expected, result, "Empty schema should be normalized to object schema")
2631
}
2732

2833
func TestNormalizeInputSchema_NonObjectType(t *testing.T) {

internal/server/handlers_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,10 @@ func TestHandleClose_MultipleRequests(t *testing.T) {
244244
goneCount := 0
245245

246246
for _, rec := range responses {
247-
if rec.Code == http.StatusOK {
247+
switch rec.Code {
248+
case http.StatusOK:
248249
okCount++
249-
} else if rec.Code == http.StatusGone {
250+
case http.StatusGone:
250251
goneCount++
251252
}
252253
}

internal/server/http_helpers.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ var logHelpers = logger.New("server:helpers")
1818
// and logs connection details. Returns empty string if validation fails.
1919
func extractAndValidateSession(r *http.Request) string {
2020
logHelpers.Printf("Extracting session from request: remote=%s, path=%s", r.RemoteAddr, r.URL.Path)
21-
21+
2222
authHeader := r.Header.Get("Authorization")
2323
sessionID := auth.ExtractSessionID(authHeader)
2424

@@ -38,7 +38,7 @@ func extractAndValidateSession(r *http.Request) string {
3838
// The backendID parameter is optional and can be empty for unified mode.
3939
func logHTTPRequestBody(r *http.Request, sessionID, backendID string) {
4040
logHelpers.Printf("Checking request body: method=%s, hasBody=%v, sessionID=%s", r.Method, r.Body != nil, sessionID)
41-
41+
4242
if r.Method != "POST" || r.Body == nil {
4343
logHelpers.Printf("Skipping body logging: not a POST request or no body present")
4444
return
@@ -70,7 +70,7 @@ func logHTTPRequestBody(r *http.Request, sessionID, backendID string) {
7070
// Returns the modified request with updated context.
7171
func injectSessionContext(r *http.Request, sessionID, backendID string) *http.Request {
7272
logHelpers.Printf("Injecting session context: sessionID=%s, backendID=%s", sessionID, backendID)
73-
73+
7474
ctx := context.WithValue(r.Context(), SessionIDContextKey, sessionID)
7575

7676
if backendID != "" {

internal/server/register_tools_from_backend_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ func TestRegisterToolsFromBackend_ToolNaming(t *testing.T) {
491491

492492
tool := us.tools["my-server___my_tool"]
493493
require.NotNil(tool, "Tool should be registered with prefixed name")
494-
494+
495495
// Verify naming convention
496496
assert.Equal("my-server___my_tool", tool.Name, "Tool name should be prefixed with server ID")
497497
assert.Equal("[my-server] Does something useful", tool.Description, "Description should include backend info")
@@ -584,11 +584,11 @@ func TestRegisterToolsFromBackend_SchemaNormalization(t *testing.T) {
584584

585585
tool := us.tools["schema-backend___schema_tool"]
586586
require.NotNil(tool)
587-
587+
588588
// Verify schema was normalized (should have "type": "object" added)
589589
schema := tool.InputSchema
590590
require.NotNil(schema)
591-
591+
592592
schemaType, ok := schema["type"]
593593
assert.True(ok, "Schema should have 'type' field after normalization")
594594
assert.Equal("object", schemaType, "Schema type should be 'object'")

0 commit comments

Comments
 (0)