Skip to content

Commit e40e7a7

Browse files
authored
fix(MCPServer): Session tool handler not used due to variable shadowing (#242)
1 parent 2f24f3f commit e40e7a7

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

server/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,7 @@ func (s *MCPServer) handleToolCall(
856856

857857
session := ClientSessionFromContext(ctx)
858858
if session != nil {
859-
if sessionWithTools, ok := session.(SessionWithTools); ok {
859+
if sessionWithTools, typeAssertOk := session.(SessionWithTools); typeAssertOk {
860860
if sessionTools := sessionWithTools.GetSessionTools(); sessionTools != nil {
861861
var sessionOk bool
862862
tool, sessionOk = sessionTools[request.Params.Name]

server/session_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package server
22

33
import (
44
"context"
5+
"encoding/json"
56
"errors"
67
"sync"
78
"testing"
@@ -295,6 +296,64 @@ func TestMCPServer_AddSessionTool(t *testing.T) {
295296
assert.Contains(t, session.GetSessionTools(), "session-tool-helper")
296297
}
297298

299+
func TestMCPServer_CallSessionTool(t *testing.T) {
300+
server := NewMCPServer("test-server", "1.0.0", WithToolCapabilities(true))
301+
302+
// Add global tool
303+
server.AddTool(mcp.NewTool("test_tool"), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
304+
return mcp.NewToolResultText("global result"), nil
305+
})
306+
307+
// Create a session
308+
sessionChan := make(chan mcp.JSONRPCNotification, 10)
309+
session := &sessionTestClientWithTools{
310+
sessionID: "session-1",
311+
notificationChannel: sessionChan,
312+
initialized: true,
313+
}
314+
315+
// Register the session
316+
err := server.RegisterSession(context.Background(), session)
317+
require.NoError(t, err)
318+
319+
// Add session-specific tool with the same name to override the global tool
320+
err = server.AddSessionTool(
321+
session.SessionID(),
322+
mcp.NewTool("test_tool"),
323+
func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
324+
return mcp.NewToolResultText("session result"), nil
325+
},
326+
)
327+
require.NoError(t, err)
328+
329+
// Call the tool using session context
330+
sessionCtx := server.WithContext(context.Background(), session)
331+
toolRequest := map[string]interface{}{
332+
"jsonrpc": "2.0",
333+
"id": 1,
334+
"method": "tools/call",
335+
"params": map[string]interface{}{
336+
"name": "test_tool",
337+
},
338+
}
339+
requestBytes, err := json.Marshal(toolRequest)
340+
if err != nil {
341+
t.Fatalf("Failed to marshal tool request: %v", err)
342+
}
343+
344+
response := server.HandleMessage(sessionCtx, requestBytes)
345+
resp, ok := response.(mcp.JSONRPCResponse)
346+
assert.True(t, ok)
347+
348+
callToolResult, ok := resp.Result.(mcp.CallToolResult)
349+
assert.True(t, ok)
350+
351+
// Since we specify a tool with the same name for current session, the expected text should be "session result"
352+
if text := callToolResult.Content[0].(mcp.TextContent).Text; text != "session result" {
353+
t.Errorf("Expected result 'session result', got %q", text)
354+
}
355+
}
356+
298357
func TestMCPServer_DeleteSessionTools(t *testing.T) {
299358
server := NewMCPServer("test-server", "1.0.0", WithToolCapabilities(true))
300359
ctx := context.Background()

0 commit comments

Comments
 (0)