multica-ai/multica · error

remove workspace mcp server: %w

Error message

remove workspace mcp server: %w

What it means

Wrapped failure of the HTTP DELETE to /api/workspaces/{id}/mcp-servers/{serverId} (path-escaped) performed by `multica workspace mcp remove`. Chained causes: 404 when the server ID or workspace does not exist, 401/403 for auth/permission problems, or transport errors.

Source

Thrown at server/cmd/multica/cmd_workspace.go:737

	wsID, err := resolveWorkspaceArg(cmd, args[1:])
	if err != nil {
		return err
	}
	if wsID == "" {
		return fmt.Errorf("workspace ID is required: pass an id/slug/prefix as argument or set MULTICA_WORKSPACE_ID")
	}

	client, err := newAPIClient(cmd)
	if err != nil {
		return err
	}

	ctx, cancel := cli.APIContext(context.Background())
	defer cancel()

	path := "/api/workspaces/" + wsID + "/mcp-servers/" + url.PathEscape(serverID)
	if err := client.DeleteJSON(ctx, path); err != nil {
		return fmt.Errorf("remove workspace mcp server: %w", err)
	}

	fmt.Fprintf(os.Stdout, "removed MCP server %s\n", serverID)
	return nil
}

// workspaceMcpServer is the CLI's half of the write-only boundary. Decoding
// into named fields — rather than a map[string]any that gets re-encoded —
// means a server that regressed to returning a stored entry, or a `url` /
// `headers` inside one, cannot reach stdout through ANY output format. Fields
// not declared here are dropped by encoding/json.
type workspaceMcpServer struct {
	ID        string `json:"id"`
	Name      string `json:"name"`
	Transport string `json:"transport"`
	// Only set on an agent's assignment list; nil in the workspace library.
	Enabled *bool `json:"enabled,omitempty"`
}

View on GitHub (pinned to 2c0912b6ec)

Solutions

  1. If the server is already gone, treat 404 as success in scripts (grep the wrapped message) or check existence with `mcp list` first
  2. Re-list to get current IDs and re-run with a valid one
  3. For 401/403, use a token with owner/admin rights on the workspace

Example fix

# before (script fails on second run)
multica workspace mcp remove 17 acme

# after (tolerate already-removed)
multica workspace mcp list acme | grep -q '^17 ' && multica workspace mcp remove 17 acme || echo "already removed"
Defensive patterns

Strategy: try-catch

Validate before calling

// check existence first to make removal idempotent
servers, err := listServers(ctx, wsID)
if err != nil {
    return err
}
found := false
for _, s := range servers {
    if s.ID == serverID {
        found = true
    }
}
if !found {
    return nil // already removed; nothing to do
}

Try / catch

err := client.DeleteJSON(ctx, path)
if err != nil {
    var httpErr *apiclient.HTTPError
    if errors.As(err, &httpErr) && httpErr.StatusCode == 404 {
        return nil // treat as already-removed for idempotent cleanup
    }
    return fmt.Errorf("remove workspace mcp server: %w", err)
}

Prevention

When it happens

Trigger: Removing a server that was already deleted (double-run of a cleanup script), using an ID from another workspace, or the token lacking write permission.

Common situations: Idempotency-unaware cleanup scripts that re-run removals; stale IDs after re-adding a server; read-only member attempting removal.

Related errors


AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15). Data as JSON: /api/errors/3d512cdda7fb130a. Report an issue: GitHub.