Skip to content

feat(cockpit): desktop agents and Codex via cockpit mcp (part B of #243) - #253

Closed
Mystic0112 wants to merge 3 commits into
jacobaraujo7:mainfrom
Mystic0112:feat/desktop-agents-mcp-pr
Closed

Mystic0112 wants to merge 3 commits into
jacobaraujo7:mainfrom
Mystic0112:feat/desktop-agents-mcp-pr

Conversation

@Mystic0112

Copy link
Copy Markdown
Contributor

Part B of #243. It depends on #245 (part A), so the first two commits here are #245's. Review only the last commit, f4137166, or this diff after #245 merges. It brings the new surface the reviewer wanted reviewed separately.

What's in it

  • cockpit mcp --agent <claude-desktop|cursor|antigravity-ide|codex-desktop>: a stdio MCP server with send, peers, wait_messages (long-poll, max 55s, below Claude Desktop's request timeout) and list_agents.
  • Desktop apps as external graph nodes. Cockpit can't type into a GUI app, so messages to these nodes are queued and pulled with wait_messages. A presence ping shows the node as online or offline. They can be maestro, have colors and take part in links.
  • Editing third-party MCP configs. The New agent dialog has a "Desktop apps" row. Before writing, it shows the exact file and the entry and asks for consent. It writes a 0600 backup, then adds only mcpServers.cockpit (JSON) or [mcp_servers.cockpit] (TOML), leaving the rest byte-identical.
  • Codex in terminal tabs talks through the same MCP server. Codex's sandbox strips COCKPIT_* and blocks the socket (Operation not permitted), and MCP servers run outside that sandbox. The tab is identified by:
    • process ancestry;
    • an env hint;
    • or, since Codex 0.162 spawns MCP servers from a shared daemon, an explicit from plus from_token.

Review feedback addressed

  1. from impersonation. Every Codex intro carries a random 128-bit per-tab from_token. Each new intro rotates it, and closing the tab drops it. The app rejects from without a matching token, using a constant-time compare. The documented residual risk: a local process that can read that tab's terminal (e.g. cockpit read-tab) could learn the token. That's out of scope for a single-user app.

  2. Socket fallback permissions. Before, the socket followed the process umask. With umask 0002, ~/.cockpit was 0775 and the socket srwxrwxr-x, so group members could connect and other users could not. Now ~/.cockpit is set to 0700 before bind and the socket to 0600 before listen, for both flavors, with a POSIX test. The no-env fallback (~/.cockpit/status[-debug].sock) is the same socket COCKPIT_STATUS_SOCK already points at. On Windows, the documented status.json lives in the user profile (owner/SYSTEM/admins).

  3. Remove/undo path. Both places write a backup first and never restore an old backup over newer user edits:

    • Removing a desktop node from the canvas offers to also remove the integration.
    • Settings → Automations → "Desktop app integrations (MCP)" lists each app, shows whether the entry is present, and has Add and Remove buttons.

    Removal deletes only the cockpit entry (JSON entry, or the TOML table plus sub-tables). Codex is a special case: terminal Codex also needs the entry, so removing it turns off the new codexMcpIntegration setting and the hook installer stops re-adding it at boot. The confirmation text explains this.

Testing

  • flutter analyze reports no issues. cargo test: 55 + 39 passed.
  • Full suite: only the failures that also fail on a clean main.
  • New tests cover: token cases (missing, wrong, prefix, rotation, closed tab, startup identity), socket permission bits after bind, JSON/TOML removal and uninstall (backup 0600, user edits kept, invalid config refused), and the Codex opt-out in the installer.
  • Live on Linux: Claude Desktop as maestro, plus Codex 0.162 (through the daemon, via MCP send) and Antigravity (cockpit msg), exchanged messages in both directions.

🤖 Generated with Claude Code

Mystic0112 and others added 3 commits October 16, 2026 21:04
… files (jacobaraujo7#243)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#243)

Part B of jacobaraujo7#243 (split from jacobaraujo7#245 at the maintainer's request; builds on the
agents-graph PR).

- `cockpit mcp --agent <app>`: stdio MCP server (send, peers, wait_messages
  max 55s, list_agents). Desktop apps (Claude Desktop, Cursor, Antigravity
  IDE, Codex/ChatGPT) join the graph as external nodes with a queued inbox.
- New agent dialog: Desktop apps row; adds only the `cockpit` MCP entry to
  the app's config after explicit consent, with a 0600 backup.
- Removal/undo: node menu and Settings > Automations remove only the
  `cockpit` entry (JSON/TOML), backup first; Codex opt-out setting so the
  hook installer stops re-adding it.
- Codex in terminal tabs talks through the same MCP server (its sandbox
  blocks the shell CLI). Identity by process ancestry, env hint, or an
  explicit `from` + per-tab `from_token` (Codex 0.162 uses a shared daemon).
- Status socket hardening: ~/.cockpit 0700 and the socket 0600 before
  listen; the no-env fallback is the same socket COCKPIT_STATUS_SOCK names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jacobaraujo7

Copy link
Copy Markdown
Owner

Closing per the scope decision in #245. The Pi hook, the harness field and the Files attribution are welcome as separate small PRs; the MCP hub for desktop apps is out of scope.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants