Skip to content

Commit b561584

Browse files
author
DevRev
committed
Improve dynamic tools implementation
- Add required validateFunc parameter for tool validation - Add tool capabilities registration for dynamic tools - Add startup validation with panic for nil functions - Simplify runtime checks (no redundant nil checks) - Address bot feedback on parameter validation and capabilities
1 parent 60a105d commit b561584

File tree

1 file changed

+28
-12
lines changed

1 file changed

+28
-12
lines changed

server/server.go

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,10 @@ type ToolFilterFunc func(ctx context.Context, tools []mcp.Tool) []mcp.Tool
4848

4949
// dynamicTools holds configuration for dynamic tool generation
5050
type dynamicTools struct {
51-
enabled bool
52-
listFunc func(ctx context.Context, request mcp.ListToolsRequest) ([]mcp.Tool, error)
53-
handlerFunc func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error)
51+
enabled bool
52+
listFunc func(ctx context.Context, request mcp.ListToolsRequest) ([]mcp.Tool, error)
53+
handlerFunc func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error)
54+
validateFunc func(ctx context.Context, toolName string) bool
5455
}
5556

5657
// ServerTool combines a Tool with its ToolHandlerFunc.
@@ -300,12 +301,24 @@ func WithDynamicTools(
300301
enabled bool,
301302
listFunc func(ctx context.Context, request mcp.ListToolsRequest) ([]mcp.Tool, error),
302303
handlerFunc func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error),
304+
validateFunc func(ctx context.Context, toolName string) bool,
303305
) ServerOption {
304306
return func(s *MCPServer) {
307+
// If enabled, all functions must be non-nil
308+
if enabled && (listFunc == nil || handlerFunc == nil || validateFunc == nil) {
309+
panic("WithDynamicTools: when enabled=true, all functions (listFunc, handlerFunc, validateFunc) must be non-nil")
310+
}
311+
305312
s.dynamicTools = &dynamicTools{
306-
enabled: enabled,
307-
listFunc: listFunc,
308-
handlerFunc: handlerFunc,
313+
enabled: enabled,
314+
listFunc: listFunc,
315+
handlerFunc: handlerFunc,
316+
validateFunc: validateFunc,
317+
}
318+
319+
// Ensure capabilities.tool is not nil so that clients know tools exist
320+
if enabled {
321+
s.implicitlyRegisterToolCapabilities()
309322
}
310323
}
311324
}
@@ -967,7 +980,7 @@ func (s *MCPServer) handleListTools(
967980
}
968981

969982
// Add dynamic tools if enabled
970-
if s.dynamicTools != nil && s.dynamicTools.enabled && s.dynamicTools.listFunc != nil {
983+
if s.dynamicTools != nil && s.dynamicTools.enabled {
971984
dynamicTools, err := s.dynamicTools.listFunc(ctx, request)
972985
if err != nil {
973986
return nil, &requestError{
@@ -1067,12 +1080,15 @@ func (s *MCPServer) handleToolCall(
10671080
}
10681081

10691082
// If still not found, try dynamic tool handler
1070-
if !ok && s.dynamicTools != nil && s.dynamicTools.enabled && s.dynamicTools.handlerFunc != nil {
1071-
// Create a ServerTool with the dynamic handler
1072-
tool = ServerTool{
1073-
Handler: s.dynamicTools.handlerFunc,
1083+
if !ok && s.dynamicTools != nil && s.dynamicTools.enabled {
1084+
// Check if this tool is valid using the validation function
1085+
if s.dynamicTools.validateFunc(ctx, request.Params.Name) {
1086+
// Create a ServerTool with the dynamic handler
1087+
tool = ServerTool{
1088+
Handler: s.dynamicTools.handlerFunc,
1089+
}
1090+
ok = true
10741091
}
1075-
ok = true
10761092
}
10771093

10781094
if !ok {

0 commit comments

Comments
 (0)