Skip to content
Open
Show file tree
Hide file tree
Changes from all 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, 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, 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, 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, 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, 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: "test-server",
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