mcp: add resource subscriptions (#138)

This CL adds the ability for clients to subscribe and receive updates
for resources as described in
https://modelcontextprotocol.io/specification/2025-06-18/server/resources#subscriptions

Fixes: #23
This commit is contained in:
Sam Thanawalla 2025-07-23 15:23:50 -04:00 • committed by GitHub
commit bcbb31f072
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -5,6 +5,7 @@
package mcp
import (
"context"
"log"
"slices"
"testing"
@ -232,6 +233,7 @@ func TestServerCapabilities(t *testing.T) {
testCases := []struct {
name string
configureServer func(s *Server)
serverOpts ServerOptions
wantCapabilities *serverCapabilities
}{
{
@ -275,6 +277,25 @@ func TestServerCapabilities(t *testing.T) {
Resources: &resourceCapabilities{ListChanged: true},
},
},
{
name: "With resource subscriptions",
configureServer: func(s *Server) {
s.AddResourceTemplate(&ResourceTemplate{URITemplate: "file:///rt"}, nil)
},
serverOpts: ServerOptions{
SubscribeHandler: func(ctx context.Context, sp *SubscribeParams) error {
return nil
},
UnsubscribeHandler: func(ctx context.Context, up *UnsubscribeParams) error {
return nil
},
},
wantCapabilities: &serverCapabilities{
Completions: &completionCapabilities{},
Logging: &loggingCapabilities{},
Resources: &resourceCapabilities{ListChanged: true, Subscribe: true},
},
},
{
name: "With tools",
configureServer: func(s *Server) {
@ -294,11 +315,19 @@ func TestServerCapabilities(t *testing.T) {
s.AddResourceTemplate(&ResourceTemplate{URITemplate: "file:///rt"}, nil)
s.AddTool(&Tool{Name: "t"}, nil)
},
serverOpts: ServerOptions{
SubscribeHandler: func(ctx context.Context, sp *SubscribeParams) error {
return nil
},
UnsubscribeHandler: func(ctx context.Context, up *UnsubscribeParams) error {
return nil
},
},
wantCapabilities: &serverCapabilities{
Completions: &completionCapabilities{},
Logging: &loggingCapabilities{},
Prompts: &promptCapabilities{ListChanged: true},
Resources: &resourceCapabilities{ListChanged: true},
Resources: &resourceCapabilities{ListChanged: true, Subscribe: true},
Tools: &toolCapabilities{ListChanged: true},
},
},
@ -306,7 +335,7 @@ func TestServerCapabilities(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
server := NewServer(testImpl, nil)
server := NewServer(testImpl, &tc.serverOpts)
tc.configureServer(server)
gotCapabilities := server.capabilities()
if diff := cmp.Diff(tc.wantCapabilities, gotCapabilities); diff != "" {