Skip to content

Commit 6fde21f

Browse files
committed
mcp: advertise capability if and only if added
If tools are added to a Server when Run is called, it will send toolCapabilities to the client. Otherwise it won't. Ditto for prompts and resources.
1 parent ba7a064 commit 6fde21f

File tree

3 files changed

+29
-16
lines changed

3 files changed

+29
-16
lines changed

mcp/features.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ func (s *featureSet[T]) get(uid string) (T, bool) {
6666
return t, ok
6767
}
6868

69+
// len returns the number of features in the set.
70+
func (s *featureSet[T]) len() int { return len(s.features) }
71+
6972
// all returns an iterator over of all the features in the set
7073
// sorted by unique ID.
7174
func (s *featureSet[T]) all() iter.Seq[T] {

mcp/server.go

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,11 @@ func fileResourceHandler(dir string) ResourceHandler {
435435
// Run runs the server over the given transport, which must be persistent.
436436
//
437437
// Run blocks until the client terminates the connection.
438+
//
439+
// If tools have been added to the server before this call, then the server will
440+
// advertise the capability for tools, including the ability to send list-changed notifications.
441+
// If no tools have been added, the server will not have the tool capability.
442+
// The same goes for other features like prompts and resources.
438443
func (s *Server) Run(ctx context.Context, t Transport) error {
439444
ss, err := s.Connect(ctx, t)
440445
if err != nil {
@@ -670,24 +675,31 @@ func (ss *ServerSession) initialize(ctx context.Context, params *InitializeParam
670675
version = v
671676
}
672677

678+
caps := &serverCapabilities{
679+
Completions: &completionCapabilities{},
680+
Logging: &loggingCapabilities{},
681+
}
682+
ss.server.mu.Lock()
683+
hasTools := ss.server.tools.len() > 0
684+
hasPrompts := ss.server.prompts.len() > 0
685+
hasResources := ss.server.resources.len() > 0
686+
ss.server.mu.Unlock()
687+
if hasTools {
688+
caps.Tools = &toolCapabilities{ListChanged: true}
689+
}
690+
if hasPrompts {
691+
caps.Prompts = &promptCapabilities{ListChanged: true}
692+
}
693+
if hasResources {
694+
caps.Resources = &resourceCapabilities{ListChanged: true}
695+
}
696+
673697
return &InitializeResult{
674698
// TODO(rfindley): alter behavior when falling back to an older version:
675699
// reject unsupported features.
676700
ProtocolVersion: version,
677-
Capabilities: &serverCapabilities{
678-
Completions: &completionCapabilities{},
679-
Prompts: &promptCapabilities{
680-
ListChanged: true,
681-
},
682-
Tools: &toolCapabilities{
683-
ListChanged: true,
684-
},
685-
Resources: &resourceCapabilities{
686-
ListChanged: true,
687-
},
688-
Logging: &loggingCapabilities{},
689-
},
690-
Instructions: ss.server.opts.Instructions,
701+
Capabilities: caps,
702+
Instructions: ss.server.opts.Instructions,
691703
ServerInfo: &implementation{
692704
Name: ss.server.name,
693705
Version: ss.server.version,

mcp/streamable_test.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,6 @@ func TestStreamableServerTransport(t *testing.T) {
151151
Capabilities: &serverCapabilities{
152152
Completions: &completionCapabilities{},
153153
Logging: &loggingCapabilities{},
154-
Prompts: &promptCapabilities{ListChanged: true},
155-
Resources: &resourceCapabilities{ListChanged: true},
156154
Tools: &toolCapabilities{ListChanged: true},
157155
},
158156
ProtocolVersion: "2025-03-26",

0 commit comments

Comments
 (0)