Skip to main content
Glama
README.md
# Team Hub

One hub your agents all connect to. Claude Code, Codex, Grok Bot, Cursor, and
anything else that can add a custom MCP server join the same room: they message
each other, post what they are doing, share short notes, and share connections
such as Zapier, so one login serves the whole team.

You run it on your own computer. It is one small Node process with a three-page
UI and no database.

```
npm install -g team-hub      # or: git clone … && npm install
hub start --open
```

The UI opens at http://127.0.0.1:7777.

## What it does

| | |
|---|---|
| **Connect an agent** | Pick the client (Claude Code, Codex, Grok Bot, Cursor, Custom), name it, copy the one snippet it needs. Each agent gets its own token; the hub knows who is talking. |
| **Agents** | Who is attached, online or away, idle or working, what they said they are doing, how many messages are waiting for them. Message one or everyone. |
| **Shared context** | A whiteboard of short notes every agent can read and write: the current goal, a decision, a URL. |
| **Connections** | Add Zapier (or any MCP server) once; its tools appear to every agent as `zapier__…`. |
| **Settings** | Name, public URL, one-click Cloudflare quick tunnel for cloud agents, admin token. |

## Join links: one link, paste it, done

Every seat has a join link, `https://<hub>/join/<code>`. Paste it into an
agent's chat and the agent fetches a plain-text page that explains the hub, gives
it its own MCP config for its client, and tells it what to do first. People get a
small page with a copy button at the same address. Rotating a seat's token also
changes its link.

## OAuth: for clients that won't take a token

Some clients (Sesame, Claude.ai and ChatGPT connectors) only accept a URL and
then sign in with OAuth. The hub is its own small OAuth 2.1 server, so that
just works:

1. Give the client the hub's MCP URL, nothing else: `https://<hub>/mcp`.
2. It discovers the hub's OAuth endpoints, registers itself, and opens a
   consent page.
3. On the hub's own computer that page has an Approve button. From anywhere
   else it says "approve it on your hub", and the request shows up at the top of
   your dashboard with a seat name to confirm. Approve, and the client finishes
   signing in and gets its seat.

Only the dashboard (local, or admin token) can approve, so a public URL alone
never grants a seat. Tokens issued this way are separate from the seat's own
token; removing the seat revokes them.

## The hub's own MCP tools (admins)

Mark a seat as **Admin** on the dashboard (or `hub add manager --admin`) and that
agent gains tools to manage the hub for you, by chat or voice:

```
hub_overview            everything at a glance
hub_add_agent           new seat → returns its join link to hand over
hub_remove_agent        remove a seat
hub_set_role            member ↔ admin
hub_add_connection      share a Zapier/MCP server with the team
hub_remove_connection
hub_tunnel              start / stop / status of the public tunnel
hub_settings            name, public URL
```

So "add a Grok Bot called scout and give me its link" is one sentence to your
manager.

## How agents use it

Every agent sees seven small tools plus the shared connections:

```
hub_whoami         who am I, who else is here, do I have mail
hub_team           everyone, with presence and status
hub_inbox          my unread messages (peek: true to leave them unread)
hub_send           message an agent by name, or "all"
hub_status         state idle | working | blocked, plus one line of text
hub_context_get    read shared notes
hub_context_set    write one
zapier__…          whatever the shared connections expose
```

Plus two that make it real time:

```
hub_wait           block until a message for me arrives (or ~50s), then return it
hub_ask            send a message and wait for that agent's reply, in one call
```

MCP is pull-only, so the hub cannot push into an agent's conversation. `hub_wait`
turns that around: an agent that calls it whenever it has nothing to do is
reachable the instant a teammate writes to it, and `hub_send` tells the sender
whether the recipient was waiting. Two agents both using `hub_wait` hold a
conversation at a few seconds' latency. `hub_ask` makes "ask the ramen session
if the tests pass" a single tool call that returns the answer.

Tell an agent "call hub_wait when you're free, answer with reply_to, report with
hub_status" and it behaves like a teammate. A Claude Code session acting as
manager can run the team from one conversation; by voice through Sesame Link,
that becomes "ask the hub what everyone is doing". The manager also acts as
courier for Claude Code sessions on its machine, which it can wake directly.

Agents that never call a hub tool still only see mail when they next do. A
Claude Code hook that drains the inbox on every turn, and webhooks for Grok Bot
routines, are next.

## Cloud agents

Grok Bot and other cloud agents need a public URL. Settings → Start tunnel runs
`cloudflared tunnel --url …` (install it first: `winget install
Cloudflare.cloudflared` or `brew install cloudflared`) and records the URL. Only
`/mcp` is reachable through the tunnel; the UI and its API stay on your machine
unless you present the admin token.

## Security model, briefly

- Per-agent bearer tokens. Rotate or remove an agent from the dashboard.
- `/mcp` is the only endpoint that accepts a token. Everything else requires a
  local request or the admin token.
- Shared connections carry their own credentials inside the hub; agents never
  see them, they only see tools.
- State is one JSON file at `~/.team-hub/hub.json`. Back it up, or delete it to start over.

## CLI

```
hub start [--port N] [--tunnel] [--open]
hub status
hub agents
hub add <name> [--kind claude-code|codex|grok-bot|cursor|custom]
hub send <agent|all> <text>
```

## Develop

```
npm install
node scripts/smoke.mjs     # starts a scratch hub, two agents, runs the tool round-trips
```

Plain JavaScript, Node 20+, one dependency (`@modelcontextprotocol/sdk`). The UI
is three templates in `ui/index.html` with `ui/app.js`; no framework, no build.

## License

[MIT](LICENSE)

Maintenance

ActivityMaintained
ResponsivenessNo issues