docker_mcp.go

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