Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
bin
dist
docker-mcp
.idea/
/.direnv/
/.vscode/
Expand Down
10 changes: 10 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ linters:
- path: cmd/docker-mcp/internal/gateway/dynamic_mcps.go
linters:
- gofumpt
- path: vendor/
linters:
- gofmt
- gofumpt
- goimports
- path: examples/
linters:
- gofmt
- gofumpt
- goimports
formatters:
enable:
- gofmt
Expand Down
1 change: 1 addition & 0 deletions cmd/docker-mcp/commands/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ func gatewayCommand(docker docker.Client, dockerCli command.Cli) *cobra.Command
runCmd.Flags().BoolVar(&options.LogCalls, "log-calls", options.LogCalls, "Log calls to the tools")
runCmd.Flags().BoolVar(&options.BlockSecrets, "block-secrets", options.BlockSecrets, "Block secrets from being/received sent to/from tools")
runCmd.Flags().BoolVar(&options.BlockNetwork, "block-network", options.BlockNetwork, "Block tools from accessing forbidden network resources")
runCmd.Flags().BoolVar(&options.DisableNetwork, "disable-network", options.DisableNetwork, "Disable network access for all MCP servers (overrides individual server settings)")
runCmd.Flags().BoolVar(&options.VerifySignatures, "verify-signatures", options.VerifySignatures, "Verify signatures of the server images")
runCmd.Flags().BoolVar(&options.DryRun, "dry-run", options.DryRun, "Start the gateway but do not listen for connections (useful for testing the configuration)")
runCmd.Flags().BoolVar(&options.Verbose, "verbose", options.Verbose, "Verbose output")
Expand Down
14 changes: 10 additions & 4 deletions pkg/gateway/clientpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,14 @@ func (cp *clientPool) InvalidateOAuthClients(provider string) {
func (cp *clientPool) runToolContainer(ctx context.Context, tool catalog.Tool, params *mcp.CallToolParams) (*mcp.CallToolResult, error) {
args := cp.baseArgs(tool.Name)

// Attach the MCP servers to the same network as the gateway.
for _, network := range cp.networks {
args = append(args, "--network", network)
// Security options - respect global DisableNetwork flag
if cp.DisableNetwork {
args = append(args, "--network", "none")
} else {
// Attach the MCP servers to the same network as the gateway.
for _, network := range cp.networks {
args = append(args, "--network", network)
}
}

// Convert params.Arguments to map[string]any
Expand Down Expand Up @@ -296,7 +301,8 @@ func (cp *clientPool) argsAndEnv(serverConfig *catalog.ServerConfig, readOnly *b
var env []string

// Security options
if serverConfig.Spec.DisableNetwork {
// Global DisableNetwork flag overrides individual server settings
if cp.DisableNetwork || serverConfig.Spec.DisableNetwork {
args = append(args, "--network", "none")
} else {
// Attach the MCP servers to the same network as the gateway.
Expand Down
87 changes: 87 additions & 0 deletions pkg/gateway/clientpool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,3 +255,90 @@ func TestStdioClientInitialization(t *testing.T) {

t.Logf("Successfully initialized stdio client and retrieved %d tools", len(tools.Tools))
}

func TestGlobalDisableNetwork(t *testing.T) {
catalogYAML := `
command:
- --transport=stdio
`

// Test that global DisableNetwork=true adds --network none
args, env := argsAndEnvWithGlobalDisableNetwork(t, "test-server", catalogYAML, "", nil, nil, true)

assert.Contains(t, args, "--network")
assert.Contains(t, args, "none")
assert.Empty(t, env)
}

func TestGlobalDisableNetworkOverridesServerSetting(t *testing.T) {
// Server has disableNetwork: false, but global flag should override
catalogYAML := `
command:
- --transport=stdio
disableNetwork: false
`

// Test that global DisableNetwork=true overrides server setting
args, env := argsAndEnvWithGlobalDisableNetwork(t, "test-server", catalogYAML, "", nil, nil, true)

assert.Contains(t, args, "--network")
assert.Contains(t, args, "none")
assert.Empty(t, env)
}

func TestServerDisableNetworkWhenGlobalFalse(t *testing.T) {
// Server has disableNetwork: true, global is false - should still disable network
catalogYAML := `
command:
- --transport=stdio
disableNetwork: true
`

// Test that server DisableNetwork=true works when global is false
args, env := argsAndEnvWithGlobalDisableNetwork(t, "test-server", catalogYAML, "", nil, nil, false)

assert.Contains(t, args, "--network")
assert.Contains(t, args, "none")
assert.Empty(t, env)
}

func TestNoNetworkDisabledWhenBothFalse(t *testing.T) {
// Both server and global disable network are false - should enable networks
catalogYAML := `
command:
- --transport=stdio
disableNetwork: false
`

// Test that when both global and server DisableNetwork are false, networks are enabled
args, env := argsAndEnvWithGlobalDisableNetwork(t, "test-server", catalogYAML, "", nil, nil, false)

// Should not contain --network none
networkNoneFound := false
for i, arg := range args {
if arg == "--network" && i+1 < len(args) && args[i+1] == "none" {
networkNoneFound = true
break
}
}
assert.False(t, networkNoneFound, "Should not disable network when both global and server settings are false")
assert.Empty(t, env)
}

func argsAndEnvWithGlobalDisableNetwork(t *testing.T, name, catalogYAML, configYAML string, secrets map[string]string, readOnly *bool, globalDisableNetwork bool) ([]string, []string) {
t.Helper()

clientPool := &clientPool{
Options: Options{
Cpus: 1,
Memory: "2Gb",
DisableNetwork: globalDisableNetwork,
},
}
return clientPool.argsAndEnv(&catalog.ServerConfig{
Name: name,
Spec: parseSpec(t, catalogYAML),
Config: parseConfig(t, configYAML),
Secrets: secrets,
}, readOnly, proxies.TargetConfig{})
}
1 change: 1 addition & 0 deletions pkg/gateway/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type Options struct {
LogCalls bool
BlockSecrets bool
BlockNetwork bool
DisableNetwork bool
VerifySignatures bool
DryRun bool
Watch bool
Expand Down
Loading