docker_mcp.go

 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}