Skip to content

Commit c6d95ad

Browse files
Support additional catalogs
* add an --additional-catalog option * --catalog can also override default catalogs with multiple other catalogs * catalogs are merged in order catalogs first and additional-catalogs second
1 parent c25b743 commit c6d95ad

File tree

4 files changed

+28
-14
lines changed

4 files changed

+28
-14
lines changed

cmd/docker-mcp/commands/gateway.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ func gatewayCommand(docker docker.Client) *cobra.Command {
1818

1919
// Have different defaults for the on-host gateway and the in-container gateway.
2020
var options gateway.Config
21+
var additionalCatalogs []string
2122
if os.Getenv("DOCKER_MCP_IN_CONTAINER") == "1" {
2223
// In-container.
2324
options = gateway.Config{
24-
CatalogPath: catalog.DockerCatalogURL,
25+
CatalogPath: []string{catalog.DockerCatalogURL},
2526
SecretsPath: "docker-desktop:/run/secrets/mcp_secret:/.env",
2627
Options: gateway.Options{
2728
Cpus: 1,
@@ -36,7 +37,7 @@ func gatewayCommand(docker docker.Client) *cobra.Command {
3637
} else {
3738
// On-host.
3839
options = gateway.Config{
39-
CatalogPath: "docker-mcp.yaml",
40+
CatalogPath: []string{"docker-mcp.yaml"},
4041
RegistryPath: "registry.yaml",
4142
ConfigPath: "config.yaml",
4243
SecretsPath: "docker-desktop",
@@ -60,12 +61,15 @@ func gatewayCommand(docker docker.Client) *cobra.Command {
6061
options.Port = 8811
6162
}
6263

64+
// Append additional catalogs to the main catalog path
65+
options.CatalogPath = append(options.CatalogPath, additionalCatalogs...)
6366
return gateway.NewGateway(options, docker).Run(cmd.Context())
6467
},
6568
}
6669

6770
runCmd.Flags().StringSliceVar(&options.ServerNames, "servers", nil, "names of the servers to enable (if non empty, ignore --registry flag)")
68-
runCmd.Flags().StringVar(&options.CatalogPath, "catalog", options.CatalogPath, "path to the docker-mcp.yaml catalog (absolute or relative to ~/.docker/mcp/catalogs/)")
71+
runCmd.Flags().StringSliceVar(&options.CatalogPath, "catalog", options.CatalogPath, "paths to docker catalogs (absolute or relative to ~/.docker/mcp/catalogs/)")
72+
runCmd.Flags().StringSliceVar(&additionalCatalogs, "additional-catalog", nil, "additional catalog paths to append to the default catalogs")
6973
runCmd.Flags().StringVar(&options.RegistryPath, "registry", options.RegistryPath, "path to the registry.yaml (absolute or relative to ~/.docker/mcp/)")
7074
runCmd.Flags().StringVar(&options.ConfigPath, "config", options.ConfigPath, "path to the config.yaml (absolute or relative to ~/.docker/mcp/)")
7175
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)")

cmd/docker-mcp/internal/catalog/catalog.go

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"io"
7+
"log"
78
"net/http"
89
"os"
910
"path/filepath"
@@ -15,20 +16,29 @@ import (
1516
)
1617

1718
func Get(ctx context.Context) (Catalog, error) {
18-
return ReadFrom(ctx, "docker-mcp.yaml")
19+
return ReadFrom(ctx, []string{"docker-mcp.yaml"})
1920
}
2021

21-
func ReadFrom(ctx context.Context, fileOrURL string) (Catalog, error) {
22-
servers, err := readMCPServers(ctx, fileOrURL)
23-
if err != nil {
24-
return Catalog{}, err
25-
}
26-
if servers == nil {
27-
servers = map[string]Server{}
22+
func ReadFrom(ctx context.Context, fileOrURLs []string) (Catalog, error) {
23+
mergedServers := map[string]Server{}
24+
25+
for _, fileOrURL := range fileOrURLs {
26+
servers, err := readMCPServers(ctx, fileOrURL)
27+
if err != nil {
28+
return Catalog{}, err
29+
}
30+
31+
// Merge servers into the combined map, checking for overlaps
32+
for key, server := range servers {
33+
if _, exists := mergedServers[key]; exists {
34+
log.Printf("Warning: overlapping key '%s' found in catalog '%s', overwriting previous value", key, fileOrURL)
35+
}
36+
mergedServers[key] = server
37+
}
2838
}
2939

3040
return Catalog{
31-
Servers: servers,
41+
Servers: mergedServers,
3242
}, nil
3343
}
3444

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package gateway
33
type Config struct {
44
Options
55
ServerNames []string
6-
CatalogPath string
6+
CatalogPath []string
77
ConfigPath string
88
RegistryPath string
99
SecretsPath string

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ func (c *Configuration) Find(serverName string) (*catalog.ServerConfig, *map[str
8686
}
8787

8888
type FileBasedConfiguration struct {
89-
CatalogPath string
89+
CatalogPath []string
9090
ServerNames []string // Takes precedence over the RegistryPath
9191
RegistryPath string
9292
ConfigPath string

0 commit comments

Comments
 (0)