1package config
2
3import (
4 "context"
5 "fmt"
6 "os/exec"
7 "time"
8)
9
10// DockerMCPName is the name of the Docker MCP configuration.
11const DockerMCPName = "crush_docker"
12
13// IsDockerMCPAvailable checks if Docker MCP is available by running
14// 'docker mcp version'.
15func IsDockerMCPAvailable() bool {
16 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
17 defer cancel()
18
19 cmd := exec.CommandContext(ctx, "docker", "mcp", "version")
20 err := cmd.Run()
21 return err == nil
22}
23
24// IsDockerMCPEnabled checks if Docker MCP is already configured.
25func (c *Config) IsDockerMCPEnabled() bool {
26 if c.MCP == nil {
27 return false
28 }
29 _, exists := c.MCP[DockerMCPName]
30 return exists
31}
32
33// EnableDockerMCP adds Docker MCP configuration and persists it.
34func (c *Config) EnableDockerMCP() error {
35 if !IsDockerMCPAvailable() {
36 return fmt.Errorf("docker mcp is not available, please ensure docker is installed and 'docker mcp version' succeeds")
37 }
38
39 mcpConfig := MCPConfig{
40 Type: MCPStdio,
41 Command: "docker",
42 Args: []string{"mcp", "gateway", "run"},
43 Disabled: false,
44 }
45
46 // Add to in-memory config.
47 if c.MCP == nil {
48 c.MCP = make(map[string]MCPConfig)
49 }
50 c.MCP[DockerMCPName] = mcpConfig
51
52 // Persist to config file.
53 if err := c.SetConfigField("mcp."+DockerMCPName, mcpConfig); err != nil {
54 return fmt.Errorf("failed to persist docker mcp configuration: %w", err)
55 }
56
57 return nil
58}
59
60// DisableDockerMCP removes Docker MCP configuration and persists the change.
61func (c *Config) DisableDockerMCP() error {
62 if c.MCP == nil {
63 return nil
64 }
65
66 // Remove from in-memory config.
67 delete(c.MCP, DockerMCPName)
68
69 // Persist to config file by setting to null.
70 if err := c.SetConfigField("mcp", c.MCP); err != nil {
71 return fmt.Errorf("failed to persist docker mcp removal: %w", err)
72 }
73
74 return nil
75}