Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>MarcodeNew to Visual Studio Code? Get it now.
Marcode

Marcode

HiiiiD

|
24 installs
| (0) | Free
Use your code agents at ease
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Marcode

Run several coding-agent sessions at once, in resizable split panes, in VS Code's secondary sidebar. Tool-permission requests show up as cards in the transcript and are answered from the UI. Transcripts survive a window reload.

It is an orchestrator, not another agent: it drives other vendors' coding-agent backends (Claude, Codex, OpenCode) side by side, in one panel, rather than shipping its own agent loop.

Features

  • Cross-session messaging: a session can list the sessions open in a split pane (marcode__list_sessions) and send one a message (marcode__send_message) — across providers, so a Claude session can hand work to a Codex or OpenCode session, or check in on it, without you relaying anything by hand. Ask for it by naming the pane/session, not just "the other agent" — that phrasing can get confused with your harness's own agent-to-agent messaging, if it has one:
    • "Message the codex-2 pane and ask if it's finished the migration."
    • "Ask the other session in this panel whether it's still running tests."
    • "Tell the OpenCode session to pull latest before it starts."
  • A roster of concurrent agent sessions, each its own conversation with its own status, model, effort level and permission mode.
  • Split panes over the visible subset of that roster, with a persisted layout.
  • Tool-permission requests surfaced as cards in the transcript, answered from the UI.
  • Durable transcripts, paged on demand, that survive a window reload.
  • Three agent backends behind one interface: the Claude Agent SDK, the Codex CLI, and the OpenCode CLI over the Agent Client Protocol (ACP) — configurable via marcode.enabledProviders.
  • Extra named instances of a backend (marcode.providerInstances) — a second Claude account, a Codex instance pointed at a different CODEX_HOME, an OpenCode instance against a different config — each with its own binary path and secrets sourced from OS env vars, never stored in settings.
  • A fleet diff review tab (Marcode: Review fleet changes) showing every session's changes against a base ref, attributed to the session whose tool calls made them.
  • A fleet view (Marcode: Open fleet view) for drilling into one session's running or finished subagents in a focused list, linked from a subagent card in the sidebar.
  • Cross-provider memory: closed sessions are indexed as structured digests, and any session can recall them (marcode__recall / marcode__recall_fetch) without reloading full transcripts into context. A fresh session's first message is also primed with up to three related past sessions. Recall is scoped to the workspace folder holding the session's cwd.
  • Self-control: a session can spawn a new Marcode session for itself — provider, model, permission mode, cwd and an initial prompt — via a local marcode__spawn_session MCP tool (blocked from spawning in unrestricted bypass mode).
  • One-click reauth from the panel when a Claude or Codex login expires — no need to leave the extension to run the CLI's sign-in flow.
  • Context-usage and plan-usage indicators per session and per panel.
  • An optional prompt-cache warm/cold timer badge in the composer (Claude sessions only), off by default — see Prompt-cache timer under Requirements.
  • A CLAUDE.md/AGENTS.md drift nudge: flags directories where the two have drifted (one has real content, the other is missing) and offers a one-click migrate to make AGENTS.md the source of truth with CLAUDE.md as a @AGENTS.md stub. Scanned paths beyond the built-in node_modules/.git/dist/out/.claude/worktrees/.worktrees excludes are configurable via marcode.agentsMdNudge.excludePaths.

Install

Published on the VS Code Marketplace as Marcode (publisher HiiiiD) — search "Marcode" in the Extensions view, or:

code --install-extension HiiiiD.mar-code

CI builds and publishes a separate .vsix per platform/arch (Windows, macOS, Linux glibc and musl, each x64 and arm64) on every tagged release, so the Marketplace install carries only your platform's native binary — see the Platform note below. Per-platform .vsix files are also attached to each GitHub release if you'd rather install one directly with code --install-extension <file>.vsix.

To remove it: code --uninstall-extension HiiiiD.mar-code.

The rest of this section is for working on the extension itself: a throwaway Extension Development Host for iterating on the code, or building your own local .vsix.

Both start from a build. dist/webview.css is produced by the Tailwind plugin inside esbuild.js, so any build script covers it — there is no separate CSS step.

yarn install

Extension Development Host

Press F5 (Run Extension in .vscode/launch.json). It builds via the default task and opens .vscode/dev.code-workspace — a separate window identity over this same folder, so VS Code doesn't refuse the launch with an already-open-folder conflict.

To iterate, run yarn watch in one terminal (esbuild, tsc --noEmit and Tailwind in parallel) and launch with F5. After a rebuild, reload the dev-host window with Ctrl+R. Because the extension host owns all state and the webview is rehydrated from it, a reload is a real test of persistence rather than a reset.

If the debugger itself is the problem or --disable-extensions is needed, launch via a VS Code task instead of F5 — add one to .vscode/tasks.json running code --extensionDevelopmentPath=. .vscode/dev.code-workspace [--disable-extensions].

Building your own .vsix locally

yarn run package              # check-types + lint + production bundle
npx @vscode/vsce package      # -> mar-code-<version>.vsix, native deps for your host platform only
code --install-extension mar-code-<version>.vsix

Reload the window afterwards.

.vscodeignore excludes node_modules/** but re-includes @anthropic-ai/claude-agent-sdk and whichever platform-specific native package yarn install fetched for the machine you're packaging on — see the Platform note below. A plain local vsce package (no --target) therefore only ever produces a .vsix for your own platform; the per-platform CI matrix (--target win32-x64, --target darwin-arm64, etc.) is what produces the others.

Transcripts live under the extension's storage path, which is per profile and per workspace. The dev host and an installed .vsix therefore keep separate histories.

Setup: move the panel to the secondary sidebar

VS Code extensions cannot place a view in the secondary sidebar directly, so this is a one-time manual step:

  1. Open the secondary sidebar — View → Appearance → Secondary Side Bar, or Ctrl+Alt+B.
  2. Drag the Marcode icon from the activity bar into the secondary sidebar.
  3. Widen it by dragging its inner edge — split panes need the room.

VS Code stores this per profile and workspace, so it only has to be done once. The extension also ships a walkthrough with the same steps — open it from the Command Palette with Get Started: Open Walkthrough... and pick "Set up the Marcode panel".

Requirements

Each backend needs its own CLI installed and authenticated before starting a session — this extension does not manage or prompt for authentication itself, except where noted:

  • Claude — the claude CLI must be on PATH and authenticated, same as running it standalone in a terminal: either claude login (browser OAuth, stored in the CLI's own config dir), or an ANTHROPIC_API_KEY set as an OS environment variable before VS Code starts (setx ANTHROPIC_API_KEY "sk-ant-..." on Windows, then relaunch VS Code so it inherits the new value). Marcode doesn't read or store this key itself — the default Claude backend spawns claude with the same environment VS Code was launched with, unchanged. If login expired, use the panel's own Log in action (see Features) or the Command Palette's Marcode: Sign in to Claude. marcode.providerInstances is only for extra accounts beyond this default one — see below.
  • Codex — the codex CLI must be on PATH (or set via marcode.codex.path). Sign in from the Command Palette with Marcode: Sign in to Codex.
  • OpenCode — the opencode CLI must be on PATH (or set via marcode.opencode.path).

Which providers this window registers is controlled by marcode.enabledProviders (default ["claude", "codex", "opencode"]); a provider left out is not probed and never appears in the panel. Changing the setting requires a window reload.

Prompt-cache timer

Claude's prompt cache is billed at different rates depending on whether a turn lands as a cache read (~0.1x) or a cache write (~1.25x, or more for a 1-hour write) — replying within the cache's TTL keeps turns cheap, replying after it expires re-writes the whole context at the expensive rate. marcode.showCacheTimer (default false) adds a small clock badge next to the context ring in the composer, showing how long the cache should stay warm and switching color once it's likely expired.

It's off by default because the number is a client-side estimate, not a confirmed one: Marcode reads which TTL a turn's cache write actually used (ephemeral_1h_input_tokens/ephemeral_5m_input_tokens on the assistant message's own usage — the Claude Agent SDK's summarized turn-end usage drops this split, so it has to come from the raw per-message usage instead) and starts the countdown from when this window received that message, not from a timestamp the server confirms later. Good enough to judge "should I reply now to keep this warm", not precise enough to present as fact to everyone by default. Enable it per window in settings.json:

"marcode.showCacheTimer": true

Reload the window after changing it. Claude sessions only — no other backend exposes an equivalent signal today.

Windows: use OpenCode for OpenAI models

On Windows, prefer connecting your OpenAI account to OpenCode and selecting its openai/... models in Marcode instead of running those tasks through the Codex provider. Codex's Windows sandbox restricts child-process creation in every mode except bypass; Git Bash/MSYS, WSL's bash.exe, and tools that spawn git or other commands from within a running process can therefore fail even when the initial command was allowed. This is a Codex CLI limitation, not a setting Marcode can relax.

  1. Run opencode in a terminal and use /connect to add the OpenAI provider. Follow its authentication flow, then use /models to confirm the OpenAI models are available. See the OpenCode provider documentation for its current authentication and configuration options.
  2. Restart VS Code if OpenCode was installed or configured after VS Code started, then reload the window so Marcode probes the updated OpenCode catalog.
  3. Create a Marcode session with provider OpenCode and choose the discovered openai/... model.

OpenCode owns the credentials and provider configuration; Marcode only starts its ACP server. To isolate an OpenCode account or configuration, use an OpenCode provider instance with OPENCODE_CONFIG or OPENCODE_CONFIG_DIR as described below.

Mirror Codex plan usage for OpenCode

OpenCode's ACP interface does not expose plan-usage windows. If its openai/... model uses the same OpenAI account as Codex, Marcode can query Codex after each matching OpenCode turn and show the result as an OpenCode row. Enable both providers, authenticate Codex to that same account, then add this to VS Code settings.json:

"marcode.usageMirrors": [
  {
    "sourceProviderId": "opencode",
    "modelPattern": "^openai/",
    "targetProviderId": "codex",
    "usageProviderId": "opencode-openai",
    "displayName": "OpenCode (OpenAI)"
  }
]

Reload the window after changing the setting. The mirror refreshes when an OpenCode turn using a matching model finishes; it does not make Codex run the turn or transfer credentials to OpenCode. Use a different usageProviderId for every mirror, and only use this when both backends represent the same plan/account.

Custom system prompts

marcode.systemPrompts overrides the system prompt per provider or provider instance, keyed by id (claude, codex, or an id from marcode.providerInstances):

"marcode.systemPrompts": {
  "claude": "You are a terse pair programmer. Never explain what you didn't change.",
  "claude-work": { "preset": "claude_code", "append": "Always run yarn lint before committing." },
  "codex": "Prefer editing existing files over creating new ones."
}

A plain string replaces the provider's own default prompt outright. Claude also accepts {"preset": "claude_code"} (optionally with append) to keep Claude Code's own default prompt instead of writing one from scratch — Codex has no equivalent preset, only the plain-string form. Reload the window after changing the setting.

OpenCode is not a valid key here: neither its ACP session/new call nor its system-prompt assembly exposes a per-session override, so there is nothing for Marcode to set. Use OpenCode's own opencode.json/agent files for that backend instead.

Session memory

Closed sessions (only closed ones) are digested and indexed in a local SQLite FTS store. The history tab shows the digest as each session's summary, and reopening a session removes it from the index.

  • marcode.memory.enabled (default true): turn off if another memory plugin already does this. No store, priming or recall tools; the history tab keeps a plain extractive summary.
  • marcode.memory.summarizer: { "mode": "off" } (default) builds digests from the transcript with no model call. { "mode": "llm", "provider": "claude", "model": "...", "effort": "low", "concurrency": 3 } runs a hidden, tool-less agent on session close, falling back to the extractive digest on failure. Summarizer runs leave no trace in the vendor CLI's history. concurrency (1–8, default 3) is how many sessions a rebuild summarizes at once; lower it if your provider rate-limits. prompt (optional, up to 2000 chars) is guidance for the summarizer, such as "Write in Italian"; it replaces only the default opening line, so the JSON reply format and the no-tools rule always apply.
  • Marcode: Rebuild memory index re-digests every closed session; the history tab also offers per-session re-summarize.

Reload the window after changing either setting.

Provider behavior and quirks

  • OpenCode's default mode is its build mode. Its own opencode.json decides which tool calls prompt. Marcode's plan mode selects OpenCode plan mode and disallows edits; bypass answers OpenCode permission requests with allow, while don't ask rejects them. There is no OpenCode auto mode in Marcode because ACP provides no classifier for it.
  • Codex loads your PowerShell profile for every shell command on Windows. A profile that assumes an interactive console, commonly through PSReadLine setup, can add errors to the agent's command output even when the command succeeds. Marcode warns when it recognizes this and offers a profile guard to copy.
  • Model catalogs are live probes. Install or reconfigure a CLI before opening/reloading the VS Code window; use the panel retry action to probe again when a provider is unavailable.
  • OpenCode does not currently supply plan-usage windows or question cards through ACP. Usage mirroring above covers the former for shared OpenAI accounts; questions remain unavailable for that backend.

Provider instances: setting secrets

marcode.providerInstances holds no secrets itself. Each entry's envMap maps a subprocess env var name to one of two shapes:

  • { "type": "env", "value": "<OS var name>" } — read the real value from that OS environment variable at launch. The value never sits in settings.json. Required for any credential (ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, OPENAI_API_KEY, OPENCODE_CONFIG_CONTENT — the setting's schema restricts these keys to "env" only).
  • { "type": "plain", "value": "<literal value>" } — written into settings.json as-is. Only for non-secret keys — a plain directory path or base URL, for example.
  1. Set the OS env var first, then start (or restart) VS Code from that same environment — a shell already open before you set it won't see the change:

    setx ANTHROPIC_API_KEY_WORK "sk-ant-..."
    

    setx writes it for future sessions; a shell you already have open needs $env:ANTHROPIC_API_KEY_WORK = "sk-ant-..." for the current session, or a fresh terminal after setx.

  2. Reference that OS var's name — not its value — in settings:

    "marcode.providerInstances": [
      {
        "id": "claude-work",
        "kind": "claude",
        "displayName": "Claude (work)",
        "envMap": {
          "ANTHROPIC_API_KEY": { "type": "env", "value": "ANTHROPIC_API_KEY_WORK" }
        }
      }
    ]
    
  3. Reload the window. If the instance doesn't probe successfully, check that the OS var is visible to the process VS Code was launched from (echo $env:ANTHROPIC_API_KEY_WORK in the same shell/session used to launch it).

Allowed envMap keys depend on kind — see the setting's schema in package.json for the full per-backend list (e.g. ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, CLAUDE_CONFIG_DIR for claude; OPENAI_API_KEY, CODEX_HOME for codex; OPENCODE_CONFIG, OPENCODE_CONFIG_DIR, OPENCODE_CONFIG_CONTENT for opencode).

envMap values don't have to be secrets — CLAUDE_CONFIG_DIR just points at a directory, useful for keeping a second account's claude login state (credentials, settings) fully separate from your default one. Being non-secret, it can use plain directly — no OS var, no setx, no restart:

"marcode.providerInstances": [
  {
    "id": "claude-personal",
    "kind": "claude",
    "displayName": "Claude (personal)",
    "envMap": {
      "CLAUDE_CONFIG_DIR": { "type": "plain", "value": "C:\\Users\\you\\.claude-personal" }
    }
  }
]

with C:\Users\you\.claude-personal an empty folder — run claude login once with CLAUDE_CONFIG_DIR set to that path in the shell to populate it, before starting a session on that instance from Marcode.

What v1 does not do

  • No plan-usage windows or question-card support for the OpenCode backend — ACP carries no plan-usage data, and question cards are out of scope for v1.
  • No transcript retention policy — transcripts accumulate under extension storage with no automatic pruning.
  • No virtualized scrolling in the transcript view.

Platform note

The Claude Agent SDK ships its native binaries as separate per-platform optional dependencies, so a .vsix only ever carries one platform's copy. The Marketplace release covers 8 targets — Windows, macOS and Linux (glibc and musl), each x64 and arm64 — built by CI's per-platform matrix (.github/workflows/publish.yml), so code --install-extension HiiiiD.mar-code or an Extensions-view install picks up the right one automatically. A .vsix you build yourself locally (vsce package with no --target) only ever contains your own machine's native package, per .vscodeignore.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft