Skip to main content
Glama

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

Related MCP server: agentforge

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/vscode-agent-router.git
cd 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.

License

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

Standalone repository

This product is maintained at vscode-agent-router. Clone this repository and run the documented setup from its root. The npm/package and API identities are preserved. See migration provenance and contributing. See release setup; publishing starts disabled pending external configuration.

Standalone prompt catalog

The extension and MCP builds include a pinned Ideation prompt catalog, so an adjacent checkout is not required. Explicit agentRouter.promptsDir or AGENT_ROUTER_PROMPTS_DIR configuration takes precedence; existing sibling and personal catalogs remain supported. The bundled snapshot is a generated consumer of Ideation Loop System, with per-file provenance in prompt-catalog.json. Update prompts/ and run npm run sync:prompts to regenerate src/core/bundledPrompts.ts when deliberately upgrading the catalog.

Run npm ci, npm run typecheck, npm test, and npm run package. The VSIX retains extension ID splitin.agent-router. Publishing to either marketplace remains a separate, credentialed release action.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables multiple coding agents (Claude Code, Codex, Cursor) to discover each other's sessions, search transcripts, ask questions, and handoff tasks through a shared MCP server.
    5
    4 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides 300+ MCP tools for orchestrating AI agents — including swarm coordination, self-learning memory, and task management — enabling MCP clients like Claude Code and Cursor to spawn, coordinate, and learn from specialist agents across sessions.
    21,333 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Exposes specialized agents as MCP tools so users can manage and triage Jira tasks, analyze repositories for health and conventions, generate commit/PR/DevOps patterns, assemble reports, produce slides and infographics, and run semantic search over a knowledge base. Everything is invokable directly from inside a coding session in Claude Code, Cursor, or Claude Desktop.
    1
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Exposes a governed suite of 38 OAuth-gated tools over one MCP endpoint, letting web-based AI chat clients read and edit files, run whitelisted shell commands, search, and use Git, SQLite, browser automation, DevTools, background tasks, ports, clipboard, notifications, and localhost services on the user's own machine. It also allows local IDEs and automation tools to connect directly over localhost for offline, low-latency access.
    MIT