AgentRouter is a GitHub App router for explicit SummonAgent commands across personal and organization repositories. It lets installed private apps listen across their accounts and queue work only when someone deliberately calls a configured lane.
It listens for GitHub comments and reviews, validates that the sender is allowed to dispatch work, and creates jobs from commands like:
@SummonAgent codex fix this@SummonAgent claude review this@SummonAgent huma handle this
The first version is intentionally conservative: it stores jobs locally, exposes a small runner API, and only dispatches when @SummonAgent is mentioned with a supported lane name. No ambient code review, no surprise bot activity, no repo-by-repo workflow file required.
pnpm install
pnpm verify
cp .env.example .envSet the required values in .env, then start the router:
pnpm devIn another terminal, run a worker lane:
pnpm runner --agent codexBy default the runner previews the next queued job without claiming it. Add --execute to claim the job and start the selected agent.
- Put the server on a public URL that GitHub can reach. For local development, use a tunnel and set
AGENT_ROUTER_PUBLIC_URLto the tunnel URL. - Start the server:
pnpm dev- Open the setup URL for your personal account:
pnpm setup:url YOUR_USER userFor organization setup, use:
pnpm setup:url YOUR_ORG org- GitHub will redirect back to
/setup/callback. AgentRouter exchanges the temporary manifest code and writes generated credentials to.state/github-app.envwith file mode0600. - Copy those values into your runtime
.env, restart the server, then install the app on the repos/accounts it should watch.
pnpm dev # start the webhook server
pnpm runner --agent codex # preview the next Codex job
pnpm runner --agent codex --execute --once
# claim one job and run Codex locally
pnpm setup:url YOUR_USER user # generate a GitHub App manifest URL
pnpm test # run tests
pnpm verify # typecheck and testFor the background service, keep private runtime values in ~/.agentrouter/.env. For one-off development, a repo-local .env also works. Set:
AGENT_ROUTER_WEBHOOK_SECRETAGENT_ROUTER_RUNNER_TOKENAGENT_ROUTER_SETUP_SECRETGITHUB_APP_IDGITHUB_PRIVATE_KEY_B64AGENT_ROUTER_PULLY_EVENT_URLpoints at Pully's local event listener. The default ishttp://127.0.0.1:17655/github-event.AGENT_ROUTER_HUMA_AGENToptionally selects the OpenClaw agent id for the Huma lane. It defaults tomain.AGENT_ROUTER_GITHUB_APPS_JSONoptionally configures multiple private GitHub Apps for one router.
GITHUB_PRIVATE_KEY_B64 should be the GitHub App private key PEM encoded as base64. For private apps across multiple accounts, set AGENT_ROUTER_GITHUB_APPS_JSON to an array of app credentials; each app stays private to its owning account while AgentRouter serves them together.
Use agent-router.config.json to restrict which repositories can dispatch jobs. Start from:
cp agent-router.config.example.json agent-router.config.jsonThe runner resolves jobs to fixed worktrees from workspaceRoot and repositories:
{
"workspaceRoot": "~/Projects",
"repositories": {
"OWNER/REPOSITORY": "Repository",
"ORG/REPOSITORY": "OrgRepository"
},
"laneBranches": {
"codex": "codex/workspace",
"claude": "claude/workspace",
"huma": "huma/workspace"
}
}For a @SummonAgent codex PR job on OWNER/REPOSITORY, that maps to ~/Projects/Repository/codex and requires the branch to already be codex/workspace.
- No agent runs unless a comment or review contains
@SummonAgentpluscodex,claude, orhuma. - Raw
@codex,@claude, and@humamentions are ignored. - Codex, Claude, and Huma are runner lanes behind SummonAgent. They are not separate GitHub Apps.
- Bot users are ignored.
- Senders must have
write,maintain, oradminrepository permission. - Repositories can be allowlisted in
agent-router.config.json. - The runner claims jobs over an authenticated local API.
- PR fix jobs only run on fixed lane branches:
@SummonAgent codex->codex/workspace@SummonAgent claude->claude/workspace@SummonAgent huma->huma/workspace
- Deployment-specific branch names can be set in
laneBranches. - AgentRouter blocks fork PRs and unexpected PR branches instead of creating new branches.
AgentRouter currently understands:
- issue comments
- issue bodies
- pull request review comments
- pull request review bodies
When a valid mention is accepted, AgentRouter stores a queued job. Runners claim jobs per lane and report completion back to the local API.
For pull requests, jobs include the PR head branch and base branch. The router only queues a PR job when the PR head branch matches the mentioned agent's fixed workspace branch in the same repository.
The Huma lane runs through OpenClaw with openclaw agent --agent ${AGENT_ROUTER_HUMA_AGENT:-main} --message ....
Pully can read open PRs from AgentRouter instead of searching GitHub directly:
curl -H "Authorization: Bearer $AGENT_ROUTER_RUNNER_TOKEN" \
http://127.0.0.1:8787/pully/pull-requestsThe feed discovers repositories from the installed GitHub Apps, so new repos appear automatically after the relevant app is installed on that account. If installation discovery fails, AgentRouter falls back to agent-router.config.json repositories and reports the discovery error in failures.
AgentRouter also pings Pully's local event listener when GitHub sends PR/comment/review webhooks. That replaces the old per-repo Pully workflow path for live menu bar updates.
After changes are merged into main and ~/.agentrouter/.env exists, install the login service from the main/ worktree:
scripts/install_launch_agent.shThe LaunchAgent runs from /Volumes/Thorium/Projects/AgentRouter/main, not an agent worktree.
pnpm install
pnpm verifyRuntime state is intentionally local and ignored by git:
.env.state/agent-router.config.json- SQLite files
MIT