Skip to content

Commit 6a0afb4

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 bfa5e30 commit 6a0afb4

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
@@ -407,6 +407,11 @@ func fileResourceHandler(dir string) ResourceHandler {
407407
//
408408
// Run blocks until the client terminates the connection or the provided
409409
// context is cancelled. If the context is cancelled, Run closes the connection.
410+
//
411+
// If tools have been added to the server before this call, then the server will
412+
// advertise the capability for tools, including the ability to send list-changed notifications.
413+
// If no tools have been added, the server will not have the tool capability.
414+
// The same goes for other features like prompts and resources.
410415
func (s *Server) Run(ctx context.Context, t Transport) error {
411416
ss, err := s.Connect(ctx, t)
412417
if err != nil {
@@ -655,24 +660,31 @@ func (ss *ServerSession) initialize(ctx context.Context, params *InitializeParam
655660
version = latestProtocolVersion
656661
}
657662

663+
caps := &serverCapabilities{
664+
Completions: &completionCapabilities{},
665+
Logging: &loggingCapabilities{},
666+
}
667+
ss.server.mu.Lock()
668+
hasTools := ss.server.tools.len() > 0
669+
hasPrompts := ss.server.prompts.len() > 0
670+
hasResources := ss.server.resources.len() > 0
671+
ss.server.mu.Unlock()
672+
if hasTools {
673+
caps.Tools = &toolCapabilities{ListChanged: true}
674+
}
675+
if hasPrompts {
676+
caps.Prompts = &promptCapabilities{ListChanged: true}
677+
}
678+
if hasResources {
679+
caps.Resources = &resourceCapabilities{ListChanged: true}
680+
}
681+
658682
return &InitializeResult{
659683
// TODO(rfindley): alter behavior when falling back to an older version:
660684
// reject unsupported features.
661685
ProtocolVersion: version,
662-
Capabilities: &serverCapabilities{
663-
Completions: &completionCapabilities{},
664-
Prompts: &promptCapabilities{
665-
ListChanged: true,
666-
},
667-
Tools: &toolCapabilities{
668-
ListChanged: true,
669-
},
670-
Resources: &resourceCapabilities{
671-
ListChanged: true,
672-
},
673-
Logging: &loggingCapabilities{},
674-
},
675-
Instructions: ss.server.opts.Instructions,
686+
Capabilities: caps,
687+
Instructions: ss.server.opts.Instructions,
676688
ServerInfo: &implementation{
677689
Name: ss.server.name,
678690
Version: ss.server.version,

mcp/streamable_test.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,6 @@ func TestStreamableServerTransport(t *testing.T) {
159159
Capabilities: &serverCapabilities{
160160
Completions: &completionCapabilities{},
161161
Logging: &loggingCapabilities{},
162-
Prompts: &promptCapabilities{ListChanged: true},
163-
Resources: &resourceCapabilities{ListChanged: true},
164162
Tools: &toolCapabilities{ListChanged: true},
165163
},
166164
ProtocolVersion: latestProtocolVersion,

0 commit comments

Comments
 (0)