Skip to content

Commit 0b3b671

Browse files
committed
Consume tools.yaml in gateway
1 parent b93afa5 commit 0b3b671

File tree

7 files changed

+56
-4
lines changed

7 files changed

+56
-4
lines changed

cmd/docker-mcp/commands/gateway.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ func gatewayCommand(docker docker.Client) *cobra.Command {
4040
CatalogPath: "docker-mcp.yaml",
4141
RegistryPath: "registry.yaml",
4242
ConfigPath: "config.yaml",
43+
ToolsPath: "tools.yaml",
4344
SecretsPath: "docker-desktop",
4445
Options: gateway.Options{
4546
Cpus: 1,
@@ -65,6 +66,7 @@ func gatewayCommand(docker docker.Client) *cobra.Command {
6566
runCmd.Flags().StringVar(&options.CatalogPath, "catalog", options.CatalogPath, "path to the docker-mcp.yaml catalog (absolute or relative to ~/.docker/mcp/catalogs/)")
6667
runCmd.Flags().StringVar(&options.RegistryPath, "registry", options.RegistryPath, "path to the registry.yaml (absolute or relative to ~/.docker/mcp/)")
6768
runCmd.Flags().StringVar(&options.ConfigPath, "config", options.ConfigPath, "path to the config.yaml (absolute or relative to ~/.docker/mcp/)")
69+
runCmd.Flags().StringVar(&options.ToolsPath, "tools-config", options.ToolsPath, "path to the tools.yaml (absolute or relative to ~/.docker/mcp/)")
6870
runCmd.Flags().StringVar(&options.SecretsPath, "secrets", options.SecretsPath, "colon separated paths to search for secrets. Can be `docker-desktop` or a path to a .env file (default to using Docker Deskop's secrets API)")
6971
runCmd.Flags().StringSliceVar(&options.ToolNames, "tools", options.ToolNames, "List of tools to enable")
7072
runCmd.Flags().StringArrayVar(&options.Interceptors, "interceptor", options.Interceptors, "List of interceptors to use (format: when:type:path, e.g. 'before:exec:/bin/path')")

cmd/docker-mcp/internal/gateway/capabilitites.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"strings"
88
"sync"
99

10+
"slices"
11+
1012
"github.com/mark3labs/mcp-go/mcp"
1113
"github.com/mark3labs/mcp-go/server"
1214
"golang.org/x/sync/errgroup"
@@ -56,7 +58,7 @@ func (g *Gateway) listCapabilities(ctx context.Context, configuration Configurat
5658
logf(" > Can't list tools %s: %s", serverConfig.Name, err)
5759
} else {
5860
for _, tool := range tools.Tools {
59-
if !isToolEnabled(serverConfig.Name, serverConfig.Spec.Image, tool.Name, g.ToolNames) {
61+
if !isToolEnabled(configuration, serverConfig.Name, serverConfig.Spec.Image, tool.Name, g.ToolNames) {
6062
continue
6163
}
6264
capabilities.Tools = append(capabilities.Tools, server.ServerTool{
@@ -125,7 +127,7 @@ func (g *Gateway) listCapabilities(ctx context.Context, configuration Configurat
125127
var capabilities Capabilities
126128

127129
for _, tool := range *toolGroup {
128-
if !isToolEnabled(serverName, "", tool.Name, g.ToolNames) {
130+
if !isToolEnabled(configuration, serverName, "", tool.Name, g.ToolNames) {
129131
continue
130132
}
131133

@@ -193,9 +195,14 @@ func (c *Capabilities) PromptNames() []string {
193195
return names
194196
}
195197

196-
func isToolEnabled(serverName, serverImage, toolName string, enabledTools []string) bool {
198+
func isToolEnabled(configuration Configuration, serverName, serverImage, toolName string, enabledTools []string) bool {
197199
if len(enabledTools) == 0 {
198-
return true
200+
tools, exists := configuration.tools.ServerTools[serverName]
201+
if !exists {
202+
return true
203+
}
204+
205+
return slices.Contains(tools, toolName)
199206
}
200207

201208
for _, enabled := range enabledTools {

cmd/docker-mcp/internal/gateway/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ type Config struct {
66
CatalogPath string
77
ConfigPath string
88
RegistryPath string
9+
ToolsPath string
910
SecretsPath string
1011
}
1112

cmd/docker-mcp/internal/gateway/configuration.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type Configuration struct {
2525
serverNames []string
2626
servers map[string]catalog.Server
2727
config map[string]map[string]any
28+
tools config.ToolsConfig
2829
secrets map[string]string
2930
}
3031

@@ -97,6 +98,7 @@ type FileBasedConfiguration struct {
9798
ServerNames []string // Takes precedence over the RegistryPath
9899
RegistryPath string
99100
ConfigPath string
101+
ToolsPath string
100102
SecretsPath string // Optional, if not set, use Docker Desktop's secrets API
101103
Watch bool
102104

@@ -125,6 +127,11 @@ func (c *FileBasedConfiguration) Read(ctx context.Context) (Configuration, chan
125127
return Configuration{}, nil, nil, err
126128
}
127129

130+
toolsPath, err := config.FilePath(c.ToolsPath)
131+
if err != nil {
132+
return Configuration{}, nil, nil, err
133+
}
134+
128135
watcher, err := fsnotify.NewWatcher()
129136
if err != nil {
130137
return Configuration{}, nil, nil, err
@@ -175,6 +182,13 @@ func (c *FileBasedConfiguration) Read(ctx context.Context) (Configuration, chan
175182
return Configuration{}, nil, nil, err
176183
}
177184
}
185+
if toolsPath != "" {
186+
log("- Watching tools at", toolsPath)
187+
if err := watcher.Add(toolsPath); err != nil {
188+
_ = watcher.Close()
189+
return Configuration{}, nil, nil, err
190+
}
191+
}
178192

179193
return configuration, updates, watcher.Close, nil
180194
}
@@ -207,6 +221,11 @@ func (c *FileBasedConfiguration) readOnce(ctx context.Context) (Configuration, e
207221
return Configuration{}, fmt.Errorf("reading config: %w", err)
208222
}
209223

224+
serverToolsConfig, err := c.readToolsConfig(ctx)
225+
if err != nil {
226+
return Configuration{}, fmt.Errorf("reading tools: %w", err)
227+
}
228+
210229
var secrets map[string]string
211230
if c.SecretsPath == "docker-desktop" {
212231
secrets, err = c.readDockerDesktopSecrets(ctx, servers, serverNames)
@@ -236,6 +255,7 @@ func (c *FileBasedConfiguration) readOnce(ctx context.Context) (Configuration, e
236255
serverNames: serverNames,
237256
servers: servers,
238257
config: serversConfig,
258+
tools: serverToolsConfig,
239259
secrets: secrets,
240260
}, nil
241261
}
@@ -283,6 +303,25 @@ func (c *FileBasedConfiguration) readConfig(ctx context.Context) (map[string]map
283303
return cfg, nil
284304
}
285305

306+
func (c *FileBasedConfiguration) readToolsConfig(ctx context.Context) (config.ToolsConfig, error) {
307+
if c.ToolsPath == "" {
308+
return config.ToolsConfig{}, nil
309+
}
310+
311+
log(" - Reading tools from", c.ToolsPath)
312+
yaml, err := config.ReadConfigFile(ctx, c.docker, c.ToolsPath)
313+
if err != nil {
314+
return config.ToolsConfig{}, fmt.Errorf("reading tools.yaml: %w", err)
315+
}
316+
317+
cfg, err := config.ParseToolsConfig(yaml)
318+
if err != nil {
319+
return config.ToolsConfig{}, fmt.Errorf("parsing tools.yaml: %w", err)
320+
}
321+
322+
return cfg, nil
323+
}
324+
286325
func (c *FileBasedConfiguration) readDockerDesktopSecrets(ctx context.Context, servers map[string]catalog.Server, serverNames []string) (map[string]string, error) {
287326
var secretNames []string
288327
for _, serverName := range serverNames {

cmd/docker-mcp/internal/gateway/run.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ func NewGateway(config Config, docker docker.Client) *Gateway {
3535
RegistryPath: config.RegistryPath,
3636
ConfigPath: config.ConfigPath,
3737
SecretsPath: config.SecretsPath,
38+
ToolsPath: config.ToolsPath,
3839
Watch: config.Watch,
3940
docker: docker,
4041
},

examples/container/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ docker run -d \
1717
--catalog=/mcp/catalogs/docker-mcp.yaml \
1818
--config=/mcp/config.yaml \
1919
--registry=/mcp/registry.yaml \
20+
--tools-config=/mcp/tools.yaml \
2021
--secrets=docker-desktop \
2122
--watch=true \
2223
--transport=sse \

examples/mcp_toolkit/compose.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ services:
1010
- --catalog=/mcp/catalogs/docker-mcp.yaml
1111
- --config=/mcp/config.yaml
1212
- --registry=/mcp/registry.yaml
13+
- --tools-config=/mcp/tools.yaml
1314
- --secrets=docker-desktop
1415
- --watch=true
1516
- --transport=sse

0 commit comments

Comments
 (0)