Skip to content

Agents & profiles

An agent profile is a small config — name, command, arguments, environment — that tells VibeGuild how to launch a CLI agent. Profiles for Claude Code, Grok Build, Codex, Gemini CLI, Kimi Code, Qwen Code, opencode, and Goose are built into the app and kept current with every release — and any CLI can be added: if it runs in a terminal, it runs in a pane.

Managing profiles

Profiles live in Settings → Agent profiles. Editing a built-in creates your own copy (badged "Modified", with one-click reset to the shipped default); deleting one hides it until you restore it. Each profile also has a show-in-menus switch and a drag handle: the switch keeps rarely-used agents out of your pickers (Kimi Code, Qwen Code, and Goose ship switched off), and the drag order is the order every menu lists them in — including which profile answers each p n 1…9 sequence in command mode. Both are per-user settings, so hiding or reordering a built-in leaves it otherwise pristine.

Each profile can also wire up session resume, so a restarted pane picks its previous chat back up where the CLI supports it. A profile whose CLI isn't installed is badged in the picker and in Settings, and its pane offers a one-click Install that runs the vendor's official one-liner — shown in full first, executed visibly in that pane, never silently. When it finishes, the agent starts by itself.

Per-agent notes

  • Grok Build — sessions are fully wired (the app assigns the session id at launch and resumes it across restarts). For MCP, grok has no per-launch config injection, but every grok pane exports VIBEGUILD_MCP_URL and VIBEGUILD_MCP_TOKEN while the gateway is live, and grok expands environment variables inside its own MCP config — so one entry in your ~/.grok/config.toml connects every pane (and stays inert outside them). In the app, a grok pane's ⋯ menu → MCP setup… shows this snippet with a copy button:

    [mcp_servers.vibeguild]
    url = "${VIBEGUILD_MCP_URL}"
    bearer_token_env_var = "VIBEGUILD_MCP_TOKEN"

    Third-party MCP servers you enable in the app ride the same entry: their tools appear to grok namespaced (github_create_issue, attributed to their server), and the per-pane toggles behave like every other agent's — switching a server off cuts the pane off instantly, switching one on applies at the next pane restart.

  • Kimi Code — launches and notifies out of the box, and connects to VibeGuild's MCP tools through a one-time entry in ~/.kimi-code/mcp.json: kimi hands its stdio MCP servers the pane's environment, so the entry just names VibeGuild's bundled relay — no URL or token ever sits in the file, and outside VibeGuild panes the relay simply serves no tools. A kimi pane's ⋯ menu → MCP setup… shows the exact entry (with the real binary path filled in) and a copy button; MCP servers you enable ride along namespaced, exactly like grok's. Session capture still needs config that only lives in $KIMI_CODE_HOME, which the app won't displace (it would log you out) — resume-across-restarts lands with a later release.

  • opencode — resumes are wired, but session capture is pending the same follow-up work.

Writing your own profile

A profile is one JSON object. The required trio is id, name, and command; everything else is optional wiring:

{
  "id": "my-agent",
  "name": "My Agent",
  "command": "my-agent-cli",
  "args": ["--flag"],
  "env": { "MY_AGENT_OPTION": "1" },
  "session": {
    "resumeArgs": ["--resume", "${sessionId}"],
    "newArgs": ["--session-id", "${newSessionId}"],
    "idFields": ["session_id"]
  },
  "fileRef": "@${path} ",
  "defaultEnabled": false,
  "mcp": {
    "args": ["--mcp-config", "…${mcpUrl}…${mcpToken}…"],
    "serverArgs": ["--mcp-config", "…${serverId}…${serverUrl}…"],
    "env": { "MY_AGENT_CONFIG_JSON": "{\"servers\":{${mcpEntries}}}" },
    "gatewayEntry": "\"vibeguild\":{…}",
    "serverEntry": "\"${serverId}\":{…}",
    "setupNote": "Add this to the CLI's config once:",
    "setupSnippet": "[mcp_servers.vibeguild]\n…"
  },
  "files": [{ "name": "settings.json", "content": "…${mcpEntries}…" }],
  "install": {
    "macos": "curl -fsSL https://example.com/install.sh | bash",
    "windows": "irm https://example.com/install.ps1 | iex",
    "url": "https://example.com/docs",
    "notes": "Shown under the install command."
  }
}
  • Session continuity, two ways: if the CLI takes a session id at launch (Gemini's --session-id), put it in newArgs — the app mints an id on every fresh spawn and reuses it via resumeArgs on restart. If the CLI instead reports its id through a hook or notify mechanism (Claude Code, Codex), point that mechanism at "${helper}" session-hook in args; the helper reads the id from the JSON payload (field names overridable via idFields).
  • MCP wiring connects the agent to VibeGuild's gateway (and any third-party servers you enabled): mcp.args append CLI flags while the gateway is live, mcp.serverArgs repeat once per enabled server, and mcp.env sets environment values the same way. CLIs that only read MCP config from a file get files: the app writes each entry (expanded) under its own data directory and ${file:<name>} resolves to its path — your own config files are never touched. A CLI the app can't inject config into at all (grok) uses an arg-less mcp block: its presence still exports VIBEGUILD_MCP_URL/VIBEGUILD_MCP_TOKEN into the pane, and setupNote/setupSnippet declare the one-time entry the user adds to the CLI's own config — shown in the pane menu's "MCP setup…" dialog. Adding "aggregateServers": true then serves the pane's enabled third-party servers through that same connection, tools namespaced <serverId>_<toolName> (it replaces serverArgs — a profile never carries both). ${helper} inside setupSnippet becomes the app binary's real path when the dialog shows it, and a pane whose agent declares setup but never connects shows a dismissible reminder banner.
  • install powers the not-installed overlay: the per-platform one-line command (shown, copyable, and runnable in the pane — never auto-run), the vendor's docs url, and an optional notes caveat line.
  • ${mcpEntries} builds a server list inside JSON/TOML content: gatewayEntry plus one serverEntry per enabled server, comma-joined (entryJoin overrides), and empty when the gateway is down — so a template like {"mcpServers":{${mcpEntries}}} degrades to an empty map.
  • fileRef controls what dragging a file onto the pane types: @${path} by default; CLIs without @-references take a plain path or their own syntax.
  • defaultEnabled is the profile's shipped visibility default: false starts it hidden from menus (absent = shown). Your own switch in Settings → Agent profiles always wins — this only decides the state before you first touch the toggle.

Placeholders (${helper}, ${sessionId}, ${newSessionId}, ${mcpUrl}, ${mcpToken}, ${serverId}, ${serverUrl}, ${mcpEntries}, ${file:<name>}) expand at spawn; unknown ${…} tokens pass through untouched, so a newer schema never breaks an older app.

Agents see the app

Whatever CLI a profile launches, its pane is automatically connected to VibeGuild's built-in MCP server: agents know which pane they are, see their neighbors and their activity, read your editor selection, open panes, message each other, and share the project's memory. That surface has its own page — MCP servers — along with the third-party servers you install once and hand out per project or per pane.

Each agent's own permission system still gates every tool call. VibeGuild never bypasses it.

Plain terminals

A pane can also run your default shell instead of an agent. Terminals get lifecycle status only — no activity heuristics, no chimes — and agents never message them. See Workspaces & panes.