charmbracelet/crush · error

failed to enable docker MCP: status code %d

Error message

failed to enable docker MCP: status code %d

What it means

Returned by Client.EnableDockerMCP when the POST reached the server but the response status was not 200. The library treats only 200 as success for this fire-and-forget enable operation. A 404 means the route or workspace doesn't exist; 401/403 indicate auth problems; 500 indicates the server failed while enabling Docker MCP (e.g. Docker unavailable on the host).

Source

Thrown at internal/client/config.go:271

}

// MCPResourceContents holds the contents of an MCP resource.
type MCPResourceContents struct {
	URI      string `json:"uri"`
	MIMEType string `json:"mime_type,omitempty"`
	Text     string `json:"text,omitempty"`
	Blob     []byte `json:"blob,omitempty"`
}

// EnableDockerMCP enables the Docker MCP server on the workspace.
func (c *Client) EnableDockerMCP(ctx context.Context, id string) error {
	rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/mcp/docker/enable", id), nil, nil, nil)
	if err != nil {
		return fmt.Errorf("failed to enable docker MCP: %w", err)
	}
	defer rsp.Body.Close()
	if rsp.StatusCode != http.StatusOK {
		return fmt.Errorf("failed to enable docker MCP: status code %d", rsp.StatusCode)
	}
	return nil
}

// DisableDockerMCP disables the Docker MCP server on the workspace.
func (c *Client) DisableDockerMCP(ctx context.Context, id string) error {
	rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/mcp/docker/disable", id), nil, nil, nil)
	if err != nil {
		return fmt.Errorf("failed to disable docker MCP: %w", err)
	}
	defer rsp.Body.Close()
	if rsp.StatusCode != http.StatusOK {
		return fmt.Errorf("failed to disable docker MCP: status code %d", rsp.StatusCode)
	}
	return nil
}

// RefreshMCPTools refreshes tools for a named MCP server.

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Read the status code from the message: 404 -> verify workspace ID and server version support; 401/403 -> fix auth; 500 -> check server logs for Docker availability.
  2. Confirm the target server exposes POST /workspaces/{id}/mcp/docker/enable.
  3. Verify Docker is installed and running on the workspace host.
  4. Re-authenticate if credentials expired.
  5. Check the workspace is in a state that permits MCP changes (not suspended/deleting).

Example fix

// before
err := client.EnableDockerMCP(ctx, wsID) // status code 500
// after
err := client.EnableDockerMCP(ctx, wsID)
if err != nil && strings.Contains(err.Error(), "500") {
    log.Printf("server failed to enable docker MCP; ensure Docker is running on the host")
    return err
}
Defensive patterns

Strategy: validation

Validate before calling

// Verify prerequisites before enabling
ws, err := client.GetWorkspace(ctx, wsID)
if err != nil || ws == nil {
    return fmt.Errorf("workspace %s not found", wsID)
}
// also ensure the server supports the feature
if !serverSupportsFeature(minServerVersionForDockerMCP) {
    return ErrDockerMCPUnsupported
}

Type guard

func isNon200(err error) (code int, ok bool) {
    m := regexp.MustCompile(`status code (\d+)`).FindStringSubmatch(err.Error())
    if len(m) < 2 { return 0, false }
    code, err2 := strconv.Atoi(m[1])
    return code, err2 == nil
}

Try / catch

err := client.EnableDockerMCP(ctx, wsID)
if err != nil {
    if code, ok := isNon200(err); ok {
        switch {
        case code == 404: return ErrDockerMCPRouteUnavailable
        case code == 401 || code == 403: return ErrInsufficientPermissions
        default: return fmt.Errorf("enable failed, check server logs: %w", err)
        }
    }
    return err
}

Prevention

When it happens

Trigger: Calling EnableDockerMCP on a nonexistent workspace ID (404), without adequate permissions (403), against an older server lacking the /mcp/docker/enable route (404/405), or when the server-side Docker integration fails (500).

Common situations: Server version older than the Docker MCP feature; workspace already torn down; token lacking admin scope; host machine where Docker is not installed so the enable handler errors.

Related errors


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/e2b3f3edf56e43de. Report an issue: GitHub.