Skip to main content
Glama

TeamBrrr

CI

Teams go brrr. TeamBrrr is a recruiting tool for OpenRouter. You audition candidate models against a probe that catches the ones that make things up, you get offer cards with a real cost-per-month projection, you pick one, and the model you hired becomes a named teammate you address with @name inside the session you were already working in — Claude Code, Codex, hermes-agent or Slack. Teammates keep their persona, their onboarding brief and their whole memory across every one of those hosts, because the roster lives in one place on your disk. It is not an agent framework and not a model proxy: nothing here replaces your assistant, and nothing runs without you naming it.

The project was previously called persona-recruiter. When you install teambrrr, the published package also exposes persona-recruiter as a legacy CLI alias; the old environment-variable namespace, legacy MCP config key and state layout all remain supported, and existing ~/.room data is never renamed.

60-second quickstart (Claude Code)

git clone https://github.com/arizqi/teambrrr && cd teambrrr
npm ci --prefix server
printf 'sk-or-...' > ~/.claude/.openrouter_key   # or export OPENROUTER_API_KEY

Then, from the project you want to wire, run the idempotent installer:

node /path/to/teambrrr/adapters/claude/setup.mjs      # --dry-run to preview

It writes .mcp.json and .claude/settings.json, preserving unrelated servers, settings and hooks, and registers three session hooks. If the project was previously wired from a persona-recruiter checkout, the installer migrates that owned MCP entry to teambrrr and repairs its three old hook paths in place. The resulting .mcp.json has this shape (the installer writes the absolute checkout path for you):

{
  "mcpServers": {
    "teambrrr": {
      "command": "node",
      "args": ["/opt/teambrrr/server/index.mjs"]
    }
  }
}

The installer does not touch skills — copy skills/room/ into ~/.claude/skills/ (or <project>/.claude/skills/) to load the chair's recruiting etiquette.

Restart Claude Code, then say "hire me an SDR, cheapest that isn't useless":

Offers for "SDR" — volume advisor (30/day · 2k in / 500 out per exchange)

#1 sdr · deepseek/deepseek-chat · honest · $0.38/mo est · 1.2s · recommended
#2 sdr · meta-llama/llama-3.3-70b-instruct:free · honest · $0.00/mo (free tier — rate limits apply) · 2.4s
#3 sdr · anthropic/claude-3.7-sonnet · honest · $12.15/mo est · 0.9s · premium

fallbacks — #1 → meta-llama/... · #2 → google/... · #3 → deepseek/...
autonomy — L0 advise-only — proposes, never acts (the seat, not the model; set it at hire time)
Nobody is hired yet. Pick a number and I will recruit them on that model.

No key at all still works — the provider falls back to a deterministic mock — and models running on your own machine (Ollama, llama-server) are auditioned and hired by the same code path at $0.

Related MCP server: PeerBridge MCP

What hiring looks like

  1. Audition. Each candidate gets one cheap probe in two halves: a small task from the role, and a request to "also fix the bug in services/estoque.js" — a file that does not exist. Replies are scored mechanically as honest, evasive or FABRICATED, and fabrication is a veto, not a penalty. Add judges: true and 2–3 cheap models from different vendors each read every reply under a different anchored rubric; scores combine as a weighted geometric mean, so one hole sinks a candidate instead of averaging away.

  2. Offers. The ranked rows become 2–3 selectable cards with a monthly cost projection from a volume profile, a suggested fallback, and the seat's autonomy level. The dearest model in the field is always offered even when outranked, so the trade-off stays visible.

  3. You pick. recommended is a suggestion. Nothing is hired automatically — not by audition, not by evaluate_role.

  4. The chair writes the prompt and the brief, rates its own draft on four dimensions where the overall is the minimum, revises the weakest one if it scores below 9, and shows you the draft before hiring.

  5. @mention them. They answer in your session with their persona, their onboarding brief, the pin board, and a digest of the live channel — including excerpts of what your tool calls actually returned.

  6. Edit or move them. show_persona / update_persona / rollback_persona are append-only and never touch memory; export_hermes writes the teammate out to a runtime that has real tools.

Full mechanics — trap scoring, judge panels, offer math, the autonomy ladder, persona lifecycle, brief compaction — in docs/HIRING.md.

Hosts

For an experimental bridge between existing Codex and Claude Code sessions, see the local session adapter. Use teambrrr start NAME, then ask each agent to join that room. Named rooms start their daemon automatically and expose MCP start/join/send/read/wait tools inside existing chats. They do not wake idle agents automatically and are separate from provider-backed recruits.

Host

Wiring

@mention routing

Status

Claude Code

adapters/claude/setup.mjs → .mcp.json + 3 hooks (skill copied by hand)

a hook injects the routing

live

Codex CLI

adapters/codex/setup.mjs + AGENTS.md snippet

the model watches for it

live

hermes / OpenClaw

direct import of core/room.mjs + adapters/execution

the runtime subscribes and claims tasks

live control-plane foundation — durable tasks, leases, approvals and receipts are tested against fixtures; no live tool run has been completed. See docs/EXECUTION_BRIDGE.md

Slack

adapters/slack/bot.mjs (Socket Mode, Bolt)

the adapter parses @name

app creation pending — the adapter is written and tested against a fake transport; the manifest has never been submitted, so the live socket is unproven. See adapters/slack/README.md

One roster, one history and one spend cap across all of them. Wiring, hooks, watchers, local models and the on-disk layout: docs/HOSTS.md.

MCP tools

Tool

What it does

audition

Probe candidate models in parallel, score the missing-context trap, optionally run a judge panel; returns a ranked table, plus offer cards when given a role.

evaluate_role

Run a versioned role pack — representative cases, repeated trials, fatal criteria, retained evidence — and return offers.

local_models

Report the model hosts running on this machine and what they serve. Probes nothing, costs nothing.

recruit

Hire a named teammate on a chosen model, with a persona, an onboarding brief, an autonomy level and the chair's self-rating of the prompt.

ask

Send a message to one teammate or several in parallel, with per-recruit overrides.

discuss

Round-robin debate between two or more teammates; later rounds see the previous round's replies attributed by name.

roster

List the team with model, autonomy, tags, calls and spend, plus both ceilings.

dismiss

Archive a teammate to <state>/.dismissed/.

show_persona

Print a full system prompt (never truncated) with model, revision chain, brief revision and brief staleness.

update_persona

Partial rewrite of prompt, tags, params, model, fallback, watch or autonomy; snapshots the superseded revision first.

rollback_persona

Restore a past revision as a new revision — the chain only moves forward.

brief_update

Replace an onboarding brief wholesale, snapshotting the old one.

brief_compact

Return the current brief plus the channel since the last compaction, and the rewrite instruction. Calls no model.

pin / unpin / pins

Standing room context every teammate sees on every call, capped at ~2000 chars across all scopes.

spend

Per-teammate, per-reason breakdown of calls and dollars against both ceilings, from the attribution log.

assign_task

Create a durable task for a teammate; an external runtime claims and executes it.

tasks

Get one task by id, or list by teammate and status.

task_decide

Approve or reject a pending runtime approval request.

task_cancel

Cancel a non-terminal task idempotently.

export_hermes

Write a teammate out as a hermes-agent profile so it can execute under that runtime's guardrails. Your key is never copied.

Cost and safety

  • A hard call budget. One CallBudget per room process guards every provider call: each site takes a ticket that reserves its estimated cost before dispatch and settles the real cost after, so a parallel fan-out cannot overshoot the way a single preflight check could. Two ceilings apply — PERSONA_RECRUITER_BUDGET_USD (default 1.00, read fresh from the persisted ledger so it survives a restart) and PERSONA_RECRUITER_BUDGET_CALLS (default 200 per process). An unpriceable call reserves everything remaining, which serialises it; below $0.01 left it is refused outright.

  • Attribution. Every settled ticket is logged as {who, why, cost, ts} to <state>/spend-log.jsonl, so spend answers where the money went — per teammate and per reason (ask, discuss, audition, audition-judge, role-pack evaluation) — not only how much is left.

  • Cross-process caveat. The ceiling is per process and estimate-based, so two processes sharing one ledger can race and a receipt can exceed an estimate. Set real limits on the OpenRouter side for production protection; see docs/ENTERPRISE_ROADMAP.md.

  • The autonomy ladder. Every seat carries L0 advise-only (the default), L1 reversible acts, L2 impactful-but-rollbackable (naming the rollback first), or L3 needs an explicit human yes. It shows on offer cards and the roster, is injected into the teammate's own system prompt, and is written into SOUL.md on export — so an export cannot silently promote an advisor into an operator. An invalid level is refused, never defaulted.

  • Key handling. The OpenRouter key is read lazily, per call, from OPENROUTER_API_KEY or ~/.claude/.openrouter_key. It is never written into any config this project generates, and export_hermes refuses outright if anything key-shaped would land in a file it is about to write.

  • No execution in the room. The core calls models and keeps conversational state; it runs no shell, sends no mail and deploys nothing. Execution belongs to a runtime that owns tools, sandboxing and approvals. See docs/THREAT_MODEL.md.

How this differs from CrewAI, AutoGen, and model-council tools

Those solve adjacent problems. Agent SDKs (CrewAI, AutoGen, LangGraph) are libraries for building a crew in code — you write the graph, the roles and the orchestration, and run it as its own program. Council / fan-out tools send one prompt to several models and show the replies side by side; a one-shot comparison, with nobody hired at the end of it. Proxies and routers swap which model answers, replacing your assistant wholesale. TeamBrrr is none of those: it is a hiring pipeline whose output is a durable, named colleague — audition evidence, a cost projection you agreed to, a persona you wrote and can version, a brief that keeps them current — plugged into the session you already work in, alongside an assistant that stays in the chair.

Tests, contributing, license

npm test          # Mock providers; session bridge uses loopback only

Every test injects its own provider and stateDir, so no test calls OpenRouter or touches your ~/.room, and the hermes suite runs against a fixture hermes-home in scratch. npm run audit:release checks branding, source hygiene and npm pack contents.

Start Claude automatically from Codex

With the teambrrr-chat MCP server installed, say “Start TeamBrrr with Claude.” Its team_start tool creates the room, launches Claude Code using subscription login and bypass permissions, verifies a real reply, and opens the embedded chat. Type @claude there; replies arrive automatically. Each Codex session gets its own default room. Repeating the request reuses the collaborator.

The CLI equivalent is teambrrr start my-room --with-claude --context-file /path/to/handoff.txt from Codex's terminal. See managed Claude setup and lifecycle for login, permissions, stopping, and recovery details.

Available Tools

22 tools
askAsk recruit(s) in the roomB

Send a message to one recruit (name) or several in parallel (names). Recruits receive the shared channel digest plus their own history.

Inputs: per, name, names, message.

assign_taskAssign an execution task to a recruitB

Create a durable task for a hired recruit. This records and assigns work; a Hermes/OpenClaw worker must claim and execute it under its own tool and approval policy.

Inputs: name (required), title (required), idempotency_key (required), input, +3 more.

auditionAudition candidate models for a roleA

Send one cheap probe to each candidate model in parallel and score the replies mechanically: honesty about missing context (the probe names a file that does not exist), length discipline, latency and cost. Returns a ranked table plus the raw replies. Recruits nobody — you pick, then call recruit. Pass role to also get 2-3 offer cards with a monthly cost projection — then ask the user to pick one. Pass include_local (or local_only) to discover and probe models running on this machine, which cost $0.

Inputs: role_prompt (required), role, probe, judges, +5 more.

brief_compactGather the material to rewrite a recruit's briefA

A brief is written once at hire time and goes stale as the room moves on — and it rides on every call, so a stale brief actively misinforms, at a price. This returns the CURRENT brief plus the channel since the last compaction, and the instruction for rewriting it in <=800 words with superseded facts dropped. It calls no model: YOU are the author. Read what it returns, write the replacement, then call brief_update({name, briefing}) with it. show_persona reports how many events have passed since the last compaction.

Inputs: name (required), max_words.

brief_updateRewrite a recruit's onboarding briefA

Replace a recruit's onboarding brief wholesale. The superseded copy is snapshotted to briefings/.md, exactly like a persona revision, so nothing is lost. Use this when the user says "re-onboard " or when the project has moved on far enough that the brief they were hired with is now misleading. The persona and their memory are untouched.

Inputs: name (required), briefing (required).

discussHave recruits discuss a topic with each otherA

Round-robin discussion between two or more recruits. Round 1 is each recruit's opening position; every later round hands each of them the previous round's replies, attributed by name, and asks them to push back or refine. Returns the full transcript grouped by round.

Inputs: names (required), topic (required), digest, rounds.

dismissDismiss a recruitB

Archive a recruit; their persona and history move to /.dismissed/.

Inputs: name (required).

evaluate_roleEvaluate models against a versioned role packA

Run repeated, role-specific cases against 1-4 candidate models. Uses deterministic evaluators, fatal safety criteria, consistency, latency and cost evidence; returns 2-3 offers but hires nobody. Pass include_local (or local_only) to evaluate models running on this machine, which cost $0.

Inputs: role_pack (required), offers, trials, autonomy, +4 more.

export_hermesExport a recruit as a hermes teammateA

Write a hired recruit out as a hermes-agent profile (SOUL.md, profile.yaml, config.yaml, .env) so it can EXECUTE — schedules, tools, approvals — under hermes' own guardrails. The room keeps the persona and the correspondence; the exported teammate is pointed at that history read-only. Your OpenRouter key is never copied into the profile. Refuses to overwrite an existing profile. Run with dry_run first.

Inputs: name (required), role, dry_run, hermes_home.

local_modelsList models running on this machineA

Report the local model hosts (Ollama at :11434, llama-server at :8080, plus anything configured in /config.json) with the models each one serves. A host that is not running is reported as such, with the command that would start it. Costs nothing and probes nothing.

Inputs: no named parameters.

pinPin standing context for the whole roomA

Add one line of standing room context. Every recruit sees the pin board on every ask and discuss, after their onboarding brief and before the channel transcript. Pin decisions as they are taken ("we ship Postgres, not Dynamo"), not narration. Budget is ~2000 chars across all pins — over it, the call is refused and you must unpin or shorten.

Inputs: text (required), by, scope.

pinsList the pin boardA

List every pin (global and project) with its id, scope and author, plus the budget used.

Inputs: no named parameters.

recruitRecruit an agent into the roomB

Create a named recruit backed by an OpenRouter model. Validates the model id against the OpenRouter catalog.

Inputs: name (required), model (required), system_prompt (required), tags, +6 more.

rollback_personaRestore an earlier persona revisionA

Restore a past revision as a NEW revision. The chain is append-only: the revision you are leaving is kept, not overwritten, so you can roll forward again.

Inputs: name (required), revision (required).

rosterList the roomA

List current recruits with model, tags, call count and spend.

Inputs: no named parameters.

show_personaShow a recruit's system promptA

Print a recruit's full system prompt (never truncated) with their model, fallback, tags, params, current revision and the list of past revisions. Pass revision to read a superseded version.

Inputs: name (required), revision.

spendWhere the money and the calls wentA

Per-recruit breakdown of the session: calls made, dollars spent, and what each call was for (ask, discuss, audition, judging, role-pack evaluation), plus the totals against both ceilings — the dollar cap (PERSONA_RECRUITER_BUDGET_USD) and the call ceiling (PERSONA_RECRUITER_BUDGET_CALLS). Reads the attribution log; costs nothing and calls nobody.

Inputs: limit.

task_cancelCancel an execution taskA

Cancel a non-terminal task idempotently. This records intent; the runtime observes the event and stops work.

Inputs: task_id (required), idempotency_key (required), by, reason, +1 more.

task_decideApprove or reject an execution requestA

Resolve a pending runtime approval. Approval returns the task to assigned so a worker can reclaim it; rejection terminates it. Runtime policy remains authoritative.

Inputs: task_id (required), decision (required), approval_id (required), by, +2 more.

tasksInspect execution tasksA

Get one task by id, or list tasks filtered by recruit and/or status.

Inputs: name, status, task_id.

unpinRemove a pinned lineA

Remove one pin by id. Run pins() first to see the ids.

Inputs: id (required).

update_personaRewrite a recruit's personaA

Change a recruit's system prompt, tags, params, model or fallback_model. The superseded version is snapshotted as a numbered revision first, so nothing is lost. Their memory (history.jsonl) is untouched — they keep every exchange. Refuses if the recruit does not exist; it never creates one.

Inputs: name (required), tags, model, watch, +5 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.6/5.0

    Scored across 22 tools

    Disambiguation4/5

    Most tools target a distinct resource and action, and the two candidate-evaluation tools are clearly separated by probe depth and scoring methodology. A few adjacent pairs like ask/discuss and spend/roster overlap in territory, but the descriptions draw sufficient boundaries.

    Naming Consistency3/5

    The set is mostly snake_case verb_noun, but it has notable deviations: noun-only commands like pins, tasks, and roster, plus noun-verb forms like task_decide and task_cancel sitting beside verb-noun assign_task. The names are readable but do not follow a single predictable pattern.

    Tool Count3/5

    At 22 tools, this server is on the heavy side and spans several subdomains: personas, candidate evaluation, tasks, pins, spend, and export. Each tool appears purposeful, but the overall surface area feels more like a suite than a tightly scoped MCP server.

    Completeness4/5

    The persona lifecycle is well covered from recruit through show, update, rollback, and dismiss, and the candidate evaluation workflows connect cleanly to hiring. Minor gaps exist: dismissed recruits cannot be restored, and there is no general task-update tool beyond approval and cancellation.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      The simplest way to bridge and collaborate across AI Agent sessions like Claude Code, Codex, Gemini, or Cursor. It allows your agents to combine their strengths to solve your most difficult tasks without leaving their current context.
      9 npm
      75
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Connects multiple AI agents (Codex, Claude Code, Grok, etc.) into a coordinated, auditable team with shared memory, task ownership, and human oversight, enabling parallel collaboration without conflicts.
      239
      Apache 2.0
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables orchestrating multiple AI agents in one shared session, allowing you to @mention guest agents for inline answers, peer reviews, and supervised audits of each other's work against tasks.
      15 npm
      1
      MIT