Skip to content

Commit 9d20d89

Browse files
committed
Update capabilities
1 parent 63c687a commit 9d20d89

File tree

2 files changed

+35
-91
lines changed

2 files changed

+35
-91
lines changed

server/server.go

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ type MCPServer struct {
6767
capabilities serverCapabilities
6868
notifications chan ServerNotification
6969
currentClient NotificationContext
70+
initialized bool
7071
}
7172

7273
// serverKey is the context key for storing the server instance
@@ -422,6 +423,13 @@ func (s *MCPServer) AddPrompt(prompt mcp.Prompt, handler PromptHandlerFunc) {
422423
func (s *MCPServer) AddTool(tool mcp.Tool, handler ToolHandlerFunc) {
423424
s.tools[tool.Name] = tool
424425
s.toolHandlers[tool.Name] = handler
426+
427+
// Send notification if server is already initialized
428+
if s.initialized {
429+
if err := s.SendNotificationToClient("notifications/tools/list_changed", nil); err != nil {
430+
// We can't return the error, but in a future version we could log it
431+
}
432+
}
425433
}
426434

427435
// AddNotificationHandler registers a new handler for incoming notifications
@@ -439,31 +447,24 @@ func (s *MCPServer) handleInitialize(
439447
) mcp.JSONRPCMessage {
440448
capabilities := mcp.ServerCapabilities{}
441449

442-
if s.capabilities.resources != nil {
443-
capabilities.Resources = &struct {
444-
Subscribe bool `json:"subscribe,omitempty"`
445-
ListChanged bool `json:"listChanged,omitempty"`
446-
}{
447-
Subscribe: s.capabilities.resources.subscribe,
448-
ListChanged: s.capabilities.resources.listChanged,
449-
}
450+
capabilities.Resources = &struct {
451+
Subscribe bool `json:"subscribe,omitempty"`
452+
ListChanged bool `json:"listChanged,omitempty"`
453+
}{
454+
Subscribe: false,
455+
ListChanged: true,
450456
}
451457

452-
if s.capabilities.prompts != nil {
453-
capabilities.Prompts = &struct {
454-
ListChanged bool `json:"listChanged,omitempty"`
455-
}{
456-
ListChanged: s.capabilities.prompts.listChanged,
457-
}
458+
capabilities.Prompts = &struct {
459+
ListChanged bool `json:"listChanged,omitempty"`
460+
}{
461+
ListChanged: true,
458462
}
459463

460-
// Only include Tools capability if there are registered tools
461-
if len(s.tools) > 0 {
462-
capabilities.Tools = &struct {
463-
ListChanged bool `json:"listChanged,omitempty"`
464-
}{
465-
ListChanged: true, // Always true when tools are present
466-
}
464+
capabilities.Tools = &struct {
465+
ListChanged bool `json:"listChanged,omitempty"`
466+
}{
467+
ListChanged: true,
467468
}
468469

469470
if s.capabilities.logging {
@@ -479,6 +480,7 @@ func (s *MCPServer) handleInitialize(
479480
Capabilities: capabilities,
480481
}
481482

483+
s.initialized = true
482484
return createResponse(id, result)
483485
}
484486

server/server_test.go

Lines changed: 12 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,13 @@ func TestMCPServer_Capabilities(t *testing.T) {
3939
)
4040
assert.Equal(t, "test-server", initResult.ServerInfo.Name)
4141
assert.Equal(t, "1.0.0", initResult.ServerInfo.Version)
42-
assert.Nil(t, initResult.Capabilities.Resources)
43-
assert.Nil(t, initResult.Capabilities.Prompts)
44-
assert.Nil(t, initResult.Capabilities.Tools)
42+
assert.NotNil(t, initResult.Capabilities.Resources)
43+
assert.False(t, initResult.Capabilities.Resources.Subscribe)
44+
assert.True(t, initResult.Capabilities.Resources.ListChanged)
45+
assert.NotNil(t, initResult.Capabilities.Prompts)
46+
assert.True(t, initResult.Capabilities.Prompts.ListChanged)
47+
assert.NotNil(t, initResult.Capabilities.Tools)
48+
assert.True(t, initResult.Capabilities.Tools.ListChanged)
4549
assert.Nil(t, initResult.Capabilities.Logging)
4650
},
4751
},
@@ -53,60 +57,6 @@ func TestMCPServer_Capabilities(t *testing.T) {
5357
WithLogging(),
5458
},
5559
validate: func(t *testing.T, response mcp.JSONRPCMessage) {
56-
server := NewMCPServer("test-server", "1.0.0",
57-
WithResourceCapabilities(true, true),
58-
WithPromptCapabilities(true),
59-
WithLogging(),
60-
)
61-
62-
// Add a test tool to enable tool capabilities
63-
server.AddTool(mcp.Tool{
64-
Name: "test-tool",
65-
Description: "Test tool",
66-
InputSchema: mcp.ToolInputSchema{
67-
Type: "object",
68-
Properties: map[string]interface{}{},
69-
},
70-
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
71-
return &mcp.CallToolResult{}, nil
72-
})
73-
74-
// Create and handle the initialize message
75-
server = NewMCPServer(
76-
"test-server",
77-
"1.0.0",
78-
WithResourceCapabilities(true, true),
79-
WithPromptCapabilities(true),
80-
WithLogging(),
81-
)
82-
83-
// Add a test tool to enable tool capabilities
84-
server.AddTool(mcp.Tool{
85-
Name: "test-tool",
86-
Description: "Test tool",
87-
InputSchema: mcp.ToolInputSchema{
88-
Type: "object",
89-
Properties: map[string]interface{}{},
90-
},
91-
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
92-
return &mcp.CallToolResult{}, nil
93-
})
94-
95-
// Create and handle the initialize message
96-
message := mcp.JSONRPCRequest{
97-
JSONRPC: "2.0",
98-
ID: 1,
99-
Request: mcp.Request{
100-
Method: "initialize",
101-
},
102-
}
103-
messageBytes, err := json.Marshal(message)
104-
assert.NoError(t, err)
105-
106-
response = server.HandleMessage(
107-
context.Background(),
108-
messageBytes,
109-
)
11060
resp, ok := response.(mcp.JSONRPCResponse)
11161
assert.True(t, ok)
11262

@@ -122,23 +72,15 @@ func TestMCPServer_Capabilities(t *testing.T) {
12272
assert.Equal(t, "1.0.0", initResult.ServerInfo.Version)
12373

12474
assert.NotNil(t, initResult.Capabilities.Resources)
125-
if initResult.Capabilities.Resources != nil {
126-
assert.True(t, initResult.Capabilities.Resources.Subscribe)
127-
assert.True(
128-
t,
129-
initResult.Capabilities.Resources.ListChanged,
130-
)
131-
}
75+
// Resources capabilities are now always false for subscribe and true for listChanged
76+
assert.False(t, initResult.Capabilities.Resources.Subscribe)
77+
assert.True(t, initResult.Capabilities.Resources.ListChanged)
13278

13379
assert.NotNil(t, initResult.Capabilities.Prompts)
134-
if initResult.Capabilities.Prompts != nil {
135-
assert.True(t, initResult.Capabilities.Prompts.ListChanged)
136-
}
80+
assert.True(t, initResult.Capabilities.Prompts.ListChanged)
13781

13882
assert.NotNil(t, initResult.Capabilities.Tools)
139-
if initResult.Capabilities.Tools != nil {
140-
assert.True(t, initResult.Capabilities.Tools.ListChanged)
141-
}
83+
assert.True(t, initResult.Capabilities.Tools.ListChanged)
14284

14385
assert.NotNil(t, initResult.Capabilities.Logging)
14486
},

0 commit comments

Comments
 (0)