Skip to content

Commit 5a2bc75

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 e27a36e commit 5a2bc75

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
@@ -405,6 +405,11 @@ func fileResourceHandler(dir string) ResourceHandler {
405405
// Run runs the server over the given transport, which must be persistent.
406406
//
407407
// Run blocks until the client terminates the connection.
408+
//
409+
// If tools have been added to the server before this call, then the server will
410+
// advertise the capability for tools, including the ability to send list-changed notifications.
411+
// If no tools have been added, the server will not have the tool capability.
412+
// The same goes for other features like prompts and resources.
408413
func (s *Server) Run(ctx context.Context, t Transport) error {
409414
ss, err := s.Connect(ctx, t)
410415
if err != nil {
@@ -640,24 +645,31 @@ func (ss *ServerSession) initialize(ctx context.Context, params *InitializeParam
640645
version = v
641646
}
642647

648+
caps := &serverCapabilities{
649+
Completions: &completionCapabilities{},
650+
Logging: &loggingCapabilities{},
651+
}
652+
ss.server.mu.Lock()
653+
hasTools := ss.server.tools.len() > 0
654+
hasPrompts := ss.server.prompts.len() > 0
655+
hasResources := ss.server.resources.len() > 0
656+
ss.server.mu.Unlock()
657+
if hasTools {
658+
caps.Tools = &toolCapabilities{ListChanged: true}
659+
}
660+
if hasPrompts {
661+
caps.Prompts = &promptCapabilities{ListChanged: true}
662+
}
663+
if hasResources {
664+
caps.Resources = &resourceCapabilities{ListChanged: true}
665+
}
666+
643667
return &InitializeResult{
644668
// TODO(rfindley): alter behavior when falling back to an older version:
645669
// reject unsupported features.
646670
ProtocolVersion: version,
647-
Capabilities: &serverCapabilities{
648-
Completions: &completionCapabilities{},
649-
Prompts: &promptCapabilities{
650-
ListChanged: true,
651-
},
652-
Tools: &toolCapabilities{
653-
ListChanged: true,
654-
},
655-
Resources: &resourceCapabilities{
656-
ListChanged: true,
657-
},
658-
Logging: &loggingCapabilities{},
659-
},
660-
Instructions: ss.server.opts.Instructions,
671+
Capabilities: caps,
672+
Instructions: ss.server.opts.Instructions,
661673
ServerInfo: &implementation{
662674
Name: ss.server.name,
663675
Version: ss.server.version,

mcp/streamable_test.go

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

0 commit comments

Comments
 (0)