Skip to content
| Marketplace
Sign in
Visual Studio Code>Machine Learning>SplitIn Agent RouterNew to Visual Studio Code? Get it now.
SplitIn Agent Router

SplitIn Agent Router

SplitIn

| (0) | Free
Route Cursor agents to Claude Code, Codex, ChatGPT, Slack, and catalog peers — extensions first, CLI/API for platform tools.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Agent Router

vscode-agent-router

Cursor / VS Code dispatcher: any local model talks to Claude, Codex, Slack, and catalog peers over MCP, CLI, or API.

Visual Studio Marketplace Open VSX MIT license Open Internal Tools

Hub · Docs · Use cases · MCP · Careers

www.splitin.net/tech-stack/open-internal-tools/vscode-agent-router

vscode-agent-router by SplitInTech — Route developer tasks across agents inside VS Code

One Cursor agent. Official Claude, Codex, and Slack. No scraped UIs.

A Cursor (or VS Code) extension that routes work. The agent in this window — any model — calls small MCP tools. For Claude / Codex / ChatGPT, the router opens the official extension (vscode://splitin.agent-router/launch). It does not run claude -p, codex exec, or those vendors’ HTTP APIs. GitHub / Railway / Slack CLI stay as tools. Cursor Cloud API is available only when you pass runtime=cloud.

Built internally at SplitIn as the tech side of a product, then packaged so others can install the same dispatcher. A tool specialist owns this folder end to end. It can stay MIT and later also power a hosted SplitIn service. Every contributor would have % equity in that hosted service.

  • Compose, do not rebuild: Slack CLI, Claude Code / Codex / ChatGPT extensions, Cursor Cloud Agents API (opt-in), @modelcontextprotocol/sdk, tsup, vitest, @vscode/vsce.
  • Indie-cheap: no extra daemon, no extra cloud, no extra seat. Secrets in env / ~/.agent-router, never in git.
  • Out of the box: Marketplace / Open VSX install, F5, or a VSIX. Sidebar Peers + Jobs, Command Palette, editor/explorer handoff menus, URI handler.
  • Version by version: catalog JSON adds peers without a new adapter class.

This does not merge Composer, Claude’s sidebar, and Codex into one transcript. It is a dispatcher, the same way ideation-loop-system routes Slack threads instead of inventing a new bot per vendor.

Cursor agent (any model)
  → MCP tools (list_peers, route, call_cli, slack_api, list_jobs)
    → AgentRouter
      → Claude: vscode://splitin.agent-router/launch → Claude Code URI (prefills, does not auto-submit)
      → Codex / ChatGPT: same URI → chatgpt.addToThread (openai.chatgpt)
      → Cursor: Composer command if present; otherwise you already are the agent
      → Slack:  ~/.slack/bin/slack api | SLACK_BOT_TOKEN
      → GitHub / Railway / Vercel / Supabase / Stripe / Linear: allowlisted CLI or API
      → ideation-hq: POST /hooks/jobs (failed jobs stay on the Slack thread)

Table of contents

  • How this folder is built
  • Getting started
  • Use cases
  • Install
  • MCP tools
  • Peers
  • Slack
  • Cloud jobs
  • IDE handoff
  • Add a peer
  • Commands
  • Settings and secrets
  • Layout
  • Confirm it works
  • Careers

How this folder is built

open-internal-tools is a program repo: each folder is the tech of one product, MIT, install from that folder, one specialist owns it. Stack is chosen per job, not one language for the hub.

Folder Language / runtime How it is built
mac-unlock-notify zsh on macOS LaunchAgent + ioreg + curl + Slack webhook. No Node. Secrets in ~/.config.
slack-agent-hq TypeScript on Node 20+ Slack Bolt + Slack CLI + YAML integrations. Official @Cursor / @Claude / @Codex apps, not a custom bot per vendor.
in-app-otp TypeScript tsup + vitest. Core + adapters (React, Express, Django, Supabase).
react-mobile-interactions TypeScript + React Package-only primitives, vitest, tsup.
vscode-agent-router (this folder) TypeScript on Node 20+ Cursor/VS Code extension + MCP stdio. Catalog JSON + adapters. Same compose rule: official CLIs and APIs.

Shared defaults across those folders, followed here:

  1. Internal, then package — ship a VSIX / dist/ others can load.
  2. Right tool for the job — extension host for executeCommand / URI handoff; stdio MCP for any model; catalog/peers.json for generic CLIs.
  3. Pick existing OSS — do not scrape Claude or Codex UIs; do not persist API keys in settings.json.
  4. One folder, one PR surface — keep Agent Router work inside vscode-agent-router/.
  5. People and agents in sync — the product is that sync: Cursor agents call Claude/Codex/Slack instead of working in silos.

Getting started

git clone https://github.com/splitintech/open-internal-tools.git
cd open-internal-tools/vscode-agent-router
npm install
npm test
npm run build

Then F5 (Run Agent Router Extension) or install the VSIX (see Install). Work in sync with other contributors and agents. PRs stay in vscode-agent-router/.

Use cases

Ten ways developers integrate Agent Router:

  1. Consult Claude from Cursor — a Composer agent calls route peer=claude action=consult runtime=ide (default). Agent Router opens Claude Code with a prefilled prompt. It does not auto-submit and does not run claude -p.
  2. Fan-out a fix — same prompt, runtime=ide on claude, codex, and chatgpt; Jobs sidebar holds ids; poller can POST ideation HQ /hooks/jobs.
  3. Handoff a selection to Claude Code — editor context menu prefills vscode://anthropic.claude-code/open?prompt=… (does not auto-submit).
  4. Add the current file to Codex — explorer or editor title uses chatgpt.addFileToThread when openai.chatgpt is installed.
  5. Post a cloud result to Slack — slack_api method=chat.postMessage or Agent Router: Post to Slack, using the public Slack CLI (~/.slack/bin/slack).
  6. Search Slack docs from the agent — route peer=slack action=consult runs slack docs search.
  7. List GitHub PRs without a GitHub MCP — call_cli peer=github argv=["pr","list","--limit","5"] (gh allowlist).
  8. Add Docker as a peer — Add Peer from Template writes ~/.agent-router/peers.json; call_cli enforces allow.
  9. Probe the laptop — Probe Transports / sidebar dots for which of claude, codex, gh, railway, Slack CLI, and API keys are actually present.
  10. Status a Railway or Vercel service — catalog CLI rows, still one call_cli tool, no per-vendor MCP explosion.

Install

VS Code Marketplace — search SplitIn Agent Router, or:

code --install-extension splitin.agent-router

https://marketplace.visualstudio.com/items?itemName=splitin.agent-router

Cursor (Open VSX) — Extensions panel → search SplitIn Agent Router (splitin.agent-router), or:

cursor --install-extension splitin.agent-router

https://open-vsx.org/extension/splitin/agent-router

From this folder (VSIX / F5)

npm run package

In Cursor: Extensions: Install from VSIX… → agent-router-0.1.0.vsix. Reload. Or F5 Run Agent Router Extension (.vscode/launch.json).

Publish a release (needs VSCE_PAT + OVSX_PAT in the environment):

npm run publish:marketplaces

On activate the extension registers MCP via Cursor cursor.mcp.registerServer when that API exists, otherwise it spawns dist/mcp.js. After install, a Cursor agent of any model can call the tools without a project mcp.json.

Keep the stdio binary for Claude Code or Codex MCP configs (and for the hub’s “reply as a peer” path):

{
  "mcpServers": {
    "agent-router": {
      "command": "node",
      "args": ["dist/mcp.js"]
    }
  }
}

Claude Code and Codex extensions are not hard dependencies. If they are missing, handoff commands prompt you to install them.

MCP tools

Transport preference is MCP → CLI → API. If Railway/Supabase/Linear is already on Cursor MCP, the agent should call those tools directly. route with transport=mcp tells you the same instead of proxying MCP inside MCP.

Tool What it does
list_peers Catalog ids, kinds, runtimes, transports
probe_peers CLIs on PATH, API env vars, mcp.json, Slack CLI fingerprint
route Opens the VS Code/Cursor extension for claude / codex / chatgpt / local cursor. params.promptId loads a catalog prompt; params.memoryPacket appends shared MEMORY. Platform peers still CLI/API.
call_cli Allowlisted argv for a catalog CLI
call_api HTTP to that peer’s baseUrl using authEnv
slack_api slack api family.method key=value with HTTP fallback
list_jobs Cloud launches recorded by the router
job_status Get or refresh one job
route peer=claude action=consult runtime=ide prompt="Summarize src/auth.ts"
route peer=chatgpt action=handoff params.promptId=chatgpt.plan params.memoryPacket="…"
route peer=codex action=consult runtime=ide prompt="Fix tests"
route peer=cursor action=consult runtime=ide prompt="Continue in Composer"
route peer=cursor action=launch runtime=cloud prompt="Add a README"
route peer=slack action=launch params.channel=C0123 text="Cloud job finished"
slack_api method=chat.postMessage channel=C0123 text="done"
call_cli peer=github argv=["pr","list","--limit","5"]
list_jobs
job_status jobId=ar-… refresh=true

runtime=local / cloud on claude, codex, and chatgpt is rejected (claude -p / codex exec / vendor HTTP). Default is runtime=ide. Local Cursor opens Composer if this build exposes a handoff command; otherwise you already are the agent. Cursor Cloud remains runtime=cloud.

Peers

Shipped in catalog/peers.json. User overlay: ~/.agent-router/peers.json.

Peer MCP CLI API Cloud / IDE
cursor — — POST /v1/agents (opt-in runtime=cloud) default ide: Composer / you are the agent
claude — refused refused vscode://splitin.agent-router/launch → Claude Code URI (no auto-submit)
codex — refused refused same URI → chatgpt.addToThread
chatgpt — refused refused same URI → openai.chatgpt
ideation-hq — — POST /hooks/jobs link jobs into the Slack thread
slack optional slack api / docs / auth slack.com/api —
github optional gh api.github.com —
railway optional railway GraphQL —
vercel optional vercel api.vercel.com —
supabase optional supabase api.supabase.com —
stripe optional stripe api.stripe.com —
linear optional — GraphQL —

Slack

Same rule as mac-unlock-notify and slack-agent-hq: use Slack’s own surface, not a homemade bot.

  • Binary: ~/.slack/bin/slack (public CLI). Fingerprint d41d8cd98f00b204e9800998ecf8427e.
  • Install: curl -fsSL https://downloads.slack-edge.com/slack-cli/install.sh | bash
  • Fallback: SLACK_BOT_TOKEN → https://slack.com/api
  • Commands: Slack Auth Status, Post to Slack, selection → Handoff Selection to Slack
  • Settings: agentRouter.slackTeamId, agentRouter.slackChannel (channel id, not a token)
slack api chat.postMessage channel=C0123456789 text="Hello from Agent Router"

Cloud jobs

Launches (action=launch) write a JobStore row. The extension polls every agentRouter.pollIntervalMs (default 15s) and POSTs ideation HQ POST {hqUrl}/hooks/jobs with x-agent-router-secret (AGENT_ROUTER_JOBS_SECRET) so failed jobs stay on the Slack thread.

Cursor Cloud: GET https://api.cursor.com/v1/agents/{id} (CURSOR_API_KEY) when you explicitly pass runtime=cloud.

Set agentRouter.hqUrl / AGENT_ROUTER_HQ_URL and optional agentRouter.projectId. Set agentRouter.notifySlackOnJobComplete and a channel to post when a job hits succeeded/failed.

Unpushed local files are not on the cloud clone. Push (or pass a remote SHA) first.

IDE handoff

MCP route (including the node dist/mcp.js child) cannot call vscode.commands.executeCommand. It opens vscode://splitin.agent-router/launch?peer=&prompt=. The extension host then:

  • Claude: vscode://anthropic.claude-code/open?prompt= — prefills a new tab, does not auto-submit, does not return a result.
  • Codex / ChatGPT: chatgpt.addToThread after ensureExtension("openai.chatgpt").
  • Cursor local/ide: Composer command from probeCursorHandoff if present; otherwise “you are already the agent”.

Add a peer

Agent Router: Add Peer from Template, or edit ~/.agent-router/peers.json. Example:

{
  "version": 1,
  "transportPreference": ["mcp", "cli", "api"],
  "peers": [
    {
      "id": "docker",
      "title": "Docker",
      "kind": "platform",
      "runtimes": ["local"],
      "capabilities": ["api"],
      "transports": {
        "cli": { "bin": "docker", "allow": ["ps", "compose"] }
      }
    }
  ]
}

call_cli rejects argv that is not on allow. No new TypeScript adapter required.

Commands

Command What it does
Agent Router: Probe Transports Refresh Peers tree + Output JSON
Agent Router: List Peers Catalog dump
Agent Router: Handoff to Claude Code Prefill Claude tab
Agent Router: Handoff to Codex chatgpt.addToThread
Agent Router: Add File to Codex chatgpt.addFileToThread
Agent Router: Slack Auth Status slack auth list
Agent Router: Post to Slack chat.postMessage
Agent Router: Add Peer from Template Write ~/.agent-router/peers.json
Agent Router: Open Job Open job URL

Editor context (selection): Claude, Codex, Slack. Explorer file: Codex add-file.

Settings and secrets

Do not put tokens in settings.json or this repo.

Setting / env Purpose
CURSOR_API_KEY Cursor Cloud Agents (runtime=cloud only)
SLACK_BOT_TOKEN HTTP fallback if Slack CLI is missing
AGENT_ROUTER_HQ_URL / agentRouter.hqUrl Ideation HQ base URL for POST /hooks/jobs
AGENT_ROUTER_JOBS_SECRET Shared secret header x-agent-router-secret
AGENT_ROUTER_PROJECT_ID / agentRouter.projectId Default HQ project_id on job posts
AGENT_ROUTER_PROMPTS_DIR / agentRouter.promptsDir Prompt catalog (default: sibling ../ideation-loop-system/prompts or ~/.agent-router/prompts)
CURSOR_CLOUD_REPO_URL / agentRouter.cursorCloudRepoUrl Git remote for Cursor cloud
agentRouter.slackTeamId / slackChannel Slack --team and default channel
agentRouter.notifySlackOnJobComplete Slack on terminal job status
agentRouter.pollIntervalMs Job poll interval
agentRouter.timeoutMs CLI/API timeout
agentRouter.catalogPath Extra catalog file; user file still merges

Layout

catalog/peers.json     shipped peers (MCP / CLI / API / cloud / ide)
src/core/              vscode-free: router, registry, jobs, poll, probe
src/adapters/          cursor, claude, codex, slack, generic
src/transports/        spawn (no shell), Slack CLI resolve, HTTP
src/mcp/               createMcpServer + stdio bootstrap
src/ext/               VS Code: MCP host, trees, handoff, poller
src/extension.ts       activate
tests/                 vitest, no vscode

Core stays vscode-free so npm test and node dist/mcp.js never load the extension host.

Confirm it works

npm test
npm run build

Then in Cursor:

  • Probe Transports — sidebar Peers dots match CLIs on the machine
  • Handoff a selection to Claude and Codex (those extensions installed)
  • Slack Auth Status (or docs search if the CLI is present)
  • call_cli github with argv=["config"] → allowlist error
  • Cloud launch (if keys exist) shows a row under Jobs

Careers

Own this dispatcher end to end — or explore SplitIn tech careers — at https://www.splitin.net/careers-requests.

vscode-agent-router by SplitInTech — Route developer tasks across agents inside VS Code

License

MIT. See LICENSE. Program rules live with the hub: CONTRIBUTING.md.

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