Skip to content

Commit 220066c

Browse files
committed
Update capabilities handling and test cases for tools, prompts, and resources
Signed-off-by: edmondfrank <[email protected]>
1 parent 9595774 commit 220066c

File tree

2 files changed

+64
-14
lines changed

2 files changed

+64
-14
lines changed

server/server.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,12 @@ func NewMCPServer(
210210
version: version,
211211
notificationHandlers: make(map[string]NotificationHandlerFunc),
212212
notifications: make(chan ServerNotification, 100),
213+
capabilities: serverCapabilities{
214+
tools: &toolCapabilities{listChanged: true},
215+
resources: &resourceCapabilities{subscribe: false, listChanged: true},
216+
prompts: &promptCapabilities{listChanged: true},
217+
logging: false,
218+
},
213219
}
214220

215221
for _, opt := range opts {
@@ -319,7 +325,7 @@ func (s *MCPServer) HandleMessage(
319325
}
320326
return s.handleListResourceTemplates(ctx, baseMessage.ID, request)
321327
case "resources/read":
322-
if s.capabilities.resources == nil {
328+
if !s.capabilities.resources.listChanged {
323329
return createErrorResponse(
324330
baseMessage.ID,
325331
mcp.METHOD_NOT_FOUND,
@@ -353,7 +359,7 @@ func (s *MCPServer) HandleMessage(
353359
}
354360
return s.handleListPrompts(ctx, baseMessage.ID, request)
355361
case "prompts/get":
356-
if s.capabilities.prompts == nil {
362+
if !s.capabilities.prompts.listChanged {
357363
return createErrorResponse(
358364
baseMessage.ID,
359365
mcp.METHOD_NOT_FOUND,
@@ -387,7 +393,7 @@ func (s *MCPServer) HandleMessage(
387393
}
388394
return s.handleListTools(ctx, baseMessage.ID, request)
389395
case "tools/call":
390-
if len(s.tools) == 0 {
396+
if !s.capabilities.tools.listChanged || len(s.tools) == 0 {
391397
return createErrorResponse(
392398
baseMessage.ID,
393399
mcp.METHOD_NOT_FOUND,
@@ -523,20 +529,20 @@ func (s *MCPServer) handleInitialize(
523529
Subscribe bool `json:"subscribe,omitempty"`
524530
ListChanged bool `json:"listChanged,omitempty"`
525531
}{
526-
Subscribe: false,
527-
ListChanged: true,
532+
Subscribe: s.capabilities.resources.subscribe,
533+
ListChanged: s.capabilities.resources.listChanged,
528534
}
529535

530536
capabilities.Prompts = &struct {
531537
ListChanged bool `json:"listChanged,omitempty"`
532538
}{
533-
ListChanged: true,
539+
ListChanged: s.capabilities.prompts.listChanged,
534540
}
535541

536542
capabilities.Tools = &struct {
537543
ListChanged bool `json:"listChanged,omitempty"`
538544
}{
539-
ListChanged: true,
545+
ListChanged: s.capabilities.tools.listChanged,
540546
}
541547

542548
if s.capabilities.logging {

server/server_test.go

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ func TestMCPServer_Capabilities(t *testing.T) {
5555
options: []ServerOption{
5656
WithResourceCapabilities(true, true),
5757
WithPromptCapabilities(true),
58+
WithToolCapabilities(true),
5859
WithLogging(),
5960
},
6061
validate: func(t *testing.T, response mcp.JSONRPCMessage) {
@@ -73,8 +74,8 @@ func TestMCPServer_Capabilities(t *testing.T) {
7374
assert.Equal(t, "1.0.0", initResult.ServerInfo.Version)
7475

7576
assert.NotNil(t, initResult.Capabilities.Resources)
76-
// Resources capabilities are now always false for subscribe and true for listChanged
77-
assert.False(t, initResult.Capabilities.Resources.Subscribe)
77+
78+
assert.True(t, initResult.Capabilities.Resources.Subscribe)
7879
assert.True(t, initResult.Capabilities.Resources.ListChanged)
7980

8081
assert.NotNil(t, initResult.Capabilities.Prompts)
@@ -83,6 +84,43 @@ func TestMCPServer_Capabilities(t *testing.T) {
8384
assert.NotNil(t, initResult.Capabilities.Tools)
8485
assert.True(t, initResult.Capabilities.Tools.ListChanged)
8586

87+
assert.NotNil(t, initResult.Capabilities.Logging)
88+
},
89+
},
90+
{
91+
name: "Specific capabilities",
92+
options: []ServerOption{
93+
WithResourceCapabilities(true, false),
94+
WithPromptCapabilities(true),
95+
WithToolCapabilities(false),
96+
WithLogging(),
97+
},
98+
validate: func(t *testing.T, response mcp.JSONRPCMessage) {
99+
resp, ok := response.(mcp.JSONRPCResponse)
100+
assert.True(t, ok)
101+
102+
initResult, ok := resp.Result.(mcp.InitializeResult)
103+
assert.True(t, ok)
104+
105+
assert.Equal(
106+
t,
107+
mcp.LATEST_PROTOCOL_VERSION,
108+
initResult.ProtocolVersion,
109+
)
110+
assert.Equal(t, "test-server", initResult.ServerInfo.Name)
111+
assert.Equal(t, "1.0.0", initResult.ServerInfo.Version)
112+
113+
assert.NotNil(t, initResult.Capabilities.Resources)
114+
115+
assert.True(t, initResult.Capabilities.Resources.Subscribe)
116+
assert.False(t, initResult.Capabilities.Resources.ListChanged)
117+
118+
assert.NotNil(t, initResult.Capabilities.Prompts)
119+
assert.True(t, initResult.Capabilities.Prompts.ListChanged)
120+
121+
assert.NotNil(t, initResult.Capabilities.Tools)
122+
assert.False(t, initResult.Capabilities.Tools.ListChanged)
123+
86124
assert.NotNil(t, initResult.Capabilities.Logging)
87125
},
88126
},
@@ -600,14 +638,10 @@ func TestMCPServer_HandleUndefinedHandlers(t *testing.T) {
600638
}
601639

602640
func TestMCPServer_HandleMethodsWithoutCapabilities(t *testing.T) {
603-
server := NewMCPServer(
604-
"test-server",
605-
"1.0.0",
606-
)
607-
608641
tests := []struct {
609642
name string
610643
message string
644+
options []ServerOption
611645
expectedErr int
612646
}{
613647
{
@@ -620,6 +654,9 @@ func TestMCPServer_HandleMethodsWithoutCapabilities(t *testing.T) {
620654
"name": "test-tool"
621655
}
622656
}`,
657+
options: []ServerOption{
658+
WithToolCapabilities(false),
659+
},
623660
expectedErr: mcp.METHOD_NOT_FOUND,
624661
},
625662
{
@@ -632,6 +669,9 @@ func TestMCPServer_HandleMethodsWithoutCapabilities(t *testing.T) {
632669
"name": "test-prompt"
633670
}
634671
}`,
672+
options: []ServerOption{
673+
WithPromptCapabilities(false),
674+
},
635675
expectedErr: mcp.METHOD_NOT_FOUND,
636676
},
637677
{
@@ -644,12 +684,16 @@ func TestMCPServer_HandleMethodsWithoutCapabilities(t *testing.T) {
644684
"uri": "test-resource"
645685
}
646686
}`,
687+
options: []ServerOption{
688+
WithResourceCapabilities(false, false),
689+
},
647690
expectedErr: mcp.METHOD_NOT_FOUND,
648691
},
649692
}
650693

651694
for _, tt := range tests {
652695
t.Run(tt.name, func(t *testing.T) {
696+
server := NewMCPServer("test-server", "1.0.0", tt.options...)
653697
response := server.HandleMessage(
654698
context.Background(),
655699
[]byte(tt.message),

0 commit comments

Comments
 (0)