Skip to content

Commit 1110edf

Browse files
committed
Add tests for session ID tagging
1 parent c704875 commit 1110edf

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

contrib/mark3labs/mcp-go/mcpgo.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ func NewToolHandlerMiddleware() server.ToolHandlerMiddleware {
5959
outputText = string(resultJSON)
6060
}
6161

62+
tagWithSessionID(ctx, toolSpan)
63+
6264
toolSpan.AnnotateTextIO(string(inputJSON), outputText)
6365

6466
if err != nil {
@@ -86,6 +88,7 @@ func (h *hooks) onBeforeInitialize(ctx context.Context, id any, request *mcp.Ini
8688
taskSpan.Annotate(llmobs.WithAnnotatedTags(map[string]string{"client_name": clientName, "client_version": clientName + "_" + clientVersion}))
8789

8890
h.spanCache.Store(id, taskSpan)
91+
tagWithSessionID(ctx, taskSpan)
8992
}
9093

9194
func (h *hooks) onAfterInitialize(ctx context.Context, id any, request *mcp.InitializeRequest, result *mcp.InitializeResult) {
@@ -114,6 +117,14 @@ func (h *hooks) onError(ctx context.Context, id any, method mcp.MCPMethod, messa
114117
span.Finish(llmobs.WithError(err))
115118
}
116119

120+
func tagWithSessionID(ctx context.Context, span llmobs.Span) {
121+
session := server.ClientSessionFromContext(ctx)
122+
if session != nil {
123+
sessionID := session.SessionID()
124+
span.Annotate(llmobs.WithAnnotatedTags(map[string]string{"mcp_session_id": sessionID}))
125+
}
126+
}
127+
117128
func finishSpanWithIO[Req any, Res any](h *hooks, id any, request Req, result Res) {
118129
value, ok := h.spanCache.LoadAndDelete(id)
119130
if !ok {

contrib/mark3labs/mcp-go/mcpgo_test.go

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ func TestIntegrationSessionInitialize(t *testing.T) {
5454
server.WithHooks(hooks))
5555

5656
ctx := context.Background()
57+
sessionID := "test-session-init"
58+
session := &mockSession{id: sessionID}
59+
session.Initialize()
60+
ctx = srv.WithContext(ctx, session)
61+
5762
initRequest := `{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test-client","version":"1.0.0"}}}`
5863

5964
response := srv.HandleMessage(ctx, []byte(initRequest))
@@ -79,6 +84,8 @@ func TestIntegrationSessionInitialize(t *testing.T) {
7984
assert.Contains(t, taskSpan.Tags, "client_name:test-client")
8085
assert.Contains(t, taskSpan.Tags, "client_version:test-client_1.0.0")
8186

87+
assert.Contains(t, taskSpan.Tags, "mcp_session_id:test-session-init")
88+
8289
assert.Contains(t, taskSpan.Meta, "input")
8390
assert.Contains(t, taskSpan.Meta, "output")
8491

@@ -102,7 +109,11 @@ func TestIntegrationToolCallSuccess(t *testing.T) {
102109
tt := testTracer(t)
103110
defer tt.Stop()
104111

112+
hooks := &server.Hooks{}
113+
AddServerHooks(hooks)
114+
105115
srv := server.NewMCPServer("test-server", "1.0.0",
116+
server.WithHooks(hooks),
106117
server.WithToolHandlerMiddleware(NewToolHandlerMiddleware()))
107118

108119
calcTool := mcp.NewTool("calculator",
@@ -134,9 +145,13 @@ func TestIntegrationToolCallSuccess(t *testing.T) {
134145
session.Initialize()
135146
ctx = srv.WithContext(ctx, session)
136147

148+
initRequest := `{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test-client","version":"1.0.0"}}}`
149+
response := srv.HandleMessage(ctx, []byte(initRequest))
150+
assert.NotNil(t, response)
151+
137152
toolCallRequest := `{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"calculator","arguments":{"operation":"add","x":5,"y":3}}}`
138153

139-
response := srv.HandleMessage(ctx, []byte(toolCallRequest))
154+
response = srv.HandleMessage(ctx, []byte(toolCallRequest))
140155
assert.NotNil(t, response)
141156

142157
responseBytes, err := json.Marshal(response)
@@ -148,10 +163,25 @@ func TestIntegrationToolCallSuccess(t *testing.T) {
148163
assert.Equal(t, "2.0", resp["jsonrpc"])
149164
assert.NotNil(t, resp["result"])
150165

151-
spans := tt.WaitForLLMObsSpans(t, 1)
152-
require.Len(t, spans, 1)
166+
spans := tt.WaitForLLMObsSpans(t, 2)
167+
require.Len(t, spans, 2)
168+
169+
var initSpan, toolSpan *testtracer.LLMObsSpan
170+
for i := range spans {
171+
if spans[i].Name == "mcp.initialize" {
172+
initSpan = &spans[i]
173+
} else if spans[i].Name == "calculator" {
174+
toolSpan = &spans[i]
175+
}
176+
}
177+
178+
require.NotNil(t, initSpan, "initialize span not found")
179+
require.NotNil(t, toolSpan, "tool span not found")
180+
181+
expectedTag := "mcp_session_id:test-session-123"
182+
assert.Contains(t, initSpan.Tags, expectedTag)
183+
assert.Contains(t, toolSpan.Tags, expectedTag)
153184

154-
toolSpan := spans[0]
155185
assert.Equal(t, "calculator", toolSpan.Name)
156186
assert.Equal(t, "tool", toolSpan.Meta["span.kind"])
157187

@@ -218,6 +248,8 @@ func TestIntegrationToolCallError(t *testing.T) {
218248
assert.Equal(t, "error_tool", toolSpan.Name)
219249
assert.Equal(t, "tool", toolSpan.Meta["span.kind"])
220250

251+
assert.Contains(t, toolSpan.Tags, "mcp_session_id:test-session-456")
252+
221253
assert.Contains(t, toolSpan.Meta, "error.message")
222254
assert.Contains(t, toolSpan.Meta["error.message"], "intentional test error")
223255
assert.Contains(t, toolSpan.Meta, "error.type")

0 commit comments

Comments
 (0)