Skip to content

Commit 5fc3c83

Browse files
committed
add test
1 parent 86db7bb commit 5fc3c83

File tree

4 files changed

+133
-2
lines changed

4 files changed

+133
-2
lines changed

client/sse_test.go

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,44 @@ func TestSSEMCPClient(t *testing.T) {
149149
}, nil
150150
})
151151

152+
mcpServer.AddResource(mcp.Resource{
153+
URI: "resource://testresource",
154+
Name: "My Resource",
155+
}, func(ctx context.Context, requestContext server.RequestContext, request mcp.ReadResourceRequest) ([]mcp.ResourceContents, error) {
156+
totalProgressValue := float64(100)
157+
startFuncMessage := "start read resource"
158+
err := requestContext.SendProgressNotification(ctx, float64(0), &totalProgressValue, &startFuncMessage)
159+
if err != nil {
160+
return nil, err
161+
}
162+
163+
err = requestContext.SendLoggingNotification(ctx, mcp.LoggingLevelInfo, map[string]any{
164+
"filtered_log_message": "will be filtered by log level",
165+
})
166+
if err != nil {
167+
return nil, err
168+
}
169+
err = requestContext.SendLoggingNotification(ctx, mcp.LoggingLevelError, map[string]any{
170+
"log_message": "log message value",
171+
})
172+
if err != nil {
173+
return nil, err
174+
}
175+
176+
startFuncMessage = "end read resource"
177+
err = requestContext.SendProgressNotification(ctx, float64(100), &totalProgressValue, &startFuncMessage)
178+
if err != nil {
179+
return nil, err
180+
}
181+
return []mcp.ResourceContents{
182+
mcp.TextResourceContents{
183+
URI: "resource://testresource",
184+
MIMEType: "text/plain",
185+
Text: "test content",
186+
},
187+
}, nil
188+
})
189+
152190
// Initialize
153191
testServer := server.NewTestServer(mcpServer,
154192
server.WithSSEContextFunc(func(ctx context.Context, r *http.Request) context.Context {
@@ -638,4 +676,92 @@ func TestSSEMCPClient(t *testing.T) {
638676
assert.Equal(t, "progress_token", progressNotifications[1].Params.AdditionalFields["progressToken"])
639677
assert.EqualValues(t, 100, progressNotifications[1].Params.AdditionalFields["total"])
640678
})
679+
680+
t.Run("GetResource for testing log and progress notification", func(t *testing.T) {
681+
client, err := NewSSEMCPClient(testServer.URL + "/sse")
682+
if err != nil {
683+
t.Fatalf("Failed to create client: %v", err)
684+
}
685+
686+
var messageNotification *mcp.JSONRPCNotification
687+
progressNotifications := make([]*mcp.JSONRPCNotification, 0)
688+
notificationNum := 0
689+
client.OnNotification(func(notification mcp.JSONRPCNotification) {
690+
println(notification.Method)
691+
if notification.Method == string(mcp.MethodNotificationMessage) {
692+
messageNotification = &notification
693+
} else if notification.Method == string(mcp.MethodNotificationProgress) {
694+
progressNotifications = append(progressNotifications, &notification)
695+
}
696+
notificationNum += 1
697+
})
698+
defer client.Close()
699+
700+
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
701+
defer cancel()
702+
703+
if err := client.Start(ctx); err != nil {
704+
t.Fatalf("Failed to start client: %v", err)
705+
}
706+
707+
// Initialize
708+
initRequest := mcp.InitializeRequest{}
709+
initRequest.Params.ProtocolVersion = mcp.LATEST_PROTOCOL_VERSION
710+
initRequest.Params.ClientInfo = mcp.Implementation{
711+
Name: "test-client",
712+
Version: "1.0.0",
713+
}
714+
715+
_, err = client.Initialize(ctx, initRequest)
716+
if err != nil {
717+
t.Fatalf("Failed to initialize: %v", err)
718+
}
719+
720+
setLevelRequest := mcp.SetLevelRequest{}
721+
setLevelRequest.Params.Level = mcp.LoggingLevelWarning
722+
err = client.SetLevel(ctx, setLevelRequest)
723+
if err != nil {
724+
t.Errorf("SetLevel failed: %v", err)
725+
}
726+
727+
request := mcp.ReadResourceRequest{}
728+
request.Params.URI = "resource://testresource"
729+
request.Params.Meta = &mcp.Meta{
730+
ProgressToken: "progress_token",
731+
}
732+
733+
result, err := client.ReadResource(ctx, request)
734+
if err != nil {
735+
t.Fatalf("ReadResource failed: %v", err)
736+
}
737+
738+
assert.NotNil(t, result)
739+
assert.Len(t, result.Contents, 1)
740+
assert.Equal(t, result.Contents[0].(mcp.TextResourceContents).URI, "resource://testresource")
741+
assert.Equal(t, result.Contents[0].(mcp.TextResourceContents).MIMEType, "text/plain")
742+
assert.Equal(t, result.Contents[0].(mcp.TextResourceContents).Text, "test content")
743+
744+
time.Sleep(time.Millisecond * 200)
745+
746+
assert.Equal(t, notificationNum, 3)
747+
assert.NotNil(t, messageNotification)
748+
assert.Equal(t, messageNotification.Method, string(mcp.MethodNotificationMessage))
749+
assert.Equal(t, messageNotification.Params.AdditionalFields["level"], "error")
750+
assert.Equal(t, messageNotification.Params.AdditionalFields["data"], map[string]any{
751+
"log_message": "log message value",
752+
})
753+
754+
assert.Len(t, progressNotifications, 2)
755+
assert.Equal(t, string(mcp.MethodNotificationProgress), progressNotifications[0].Method)
756+
assert.Equal(t, "start read resource", progressNotifications[0].Params.AdditionalFields["message"])
757+
assert.EqualValues(t, 0, progressNotifications[0].Params.AdditionalFields["progress"])
758+
assert.Equal(t, "progress_token", progressNotifications[0].Params.AdditionalFields["progressToken"])
759+
assert.EqualValues(t, 100, progressNotifications[0].Params.AdditionalFields["total"])
760+
761+
assert.Equal(t, string(mcp.MethodNotificationProgress), progressNotifications[1].Method)
762+
assert.Equal(t, "end read resource", progressNotifications[1].Params.AdditionalFields["message"])
763+
assert.EqualValues(t, 100, progressNotifications[1].Params.AdditionalFields["progress"])
764+
assert.Equal(t, "progress_token", progressNotifications[1].Params.AdditionalFields["progressToken"])
765+
assert.EqualValues(t, 100, progressNotifications[1].Params.AdditionalFields["total"])
766+
})
641767
}

mcp/prompts.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ type GetPromptRequest struct {
2424
Name string `json:"name"`
2525
// Arguments to use for templating the prompt.
2626
Arguments map[string]string `json:"arguments,omitempty"`
27-
Meta *Meta `json:"_meta,omitempty"`
27+
// Meta is metadata attached to a request's parameters. This can include fields
28+
// formally defined by the protocol or other arbitrary data.
29+
Meta *Meta `json:"_meta,omitempty"`
2830
} `json:"params"`
2931
}
3032

mcp/types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,9 @@ type ReadResourceRequest struct {
531531
URI string `json:"uri"`
532532
// Arguments to pass to the resource handler
533533
Arguments map[string]any `json:"arguments,omitempty"`
534+
// Meta is metadata attached to a request's parameters. This can include fields
535+
// formally defined by the protocol or other arbitrary data.
536+
Meta *Meta `json:"_meta,omitempty"`
534537
} `json:"params"`
535538
}
536539

server/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,7 @@ func (s *MCPServer) handleReadResource(
728728
request mcp.ReadResourceRequest,
729729
) (*mcp.ReadResourceResult, *requestError) {
730730

731-
requestContext := NewRequestContext(s, request.Request.Params.Meta)
731+
requestContext := NewRequestContext(s, request.Params.Meta)
732732

733733
s.resourcesMu.RLock()
734734
// First try direct resource handlers

0 commit comments

Comments
 (0)