AI团队协作MCP服务器

Team Table 是一个通过 MCP 协议连接多个 AI 实例的协作服务器,利用共享 SQLite 数据库实现智能体发现、任务分配与消息通信,适用于多模型 AI 团队在同一工作空间中协同完成复杂任务。

  • by Brickmii
  • Python
  • 混合部署
  • 更新于
在 GitHub 查看 Brickmii/team-table

使用说明

Team Table

Multi-model AI team coordination via MCP (Model Context Protocol).

An MCP server that lets multiple AI instances discover each other, coordinate tasks, and communicate through a shared SQLite database.

Quick Start

pip install team-table

For development:

pip install -e ".[dev]"

Register as MCP server in Claude Code

Windows:

claude mcp add --transport stdio --scope user team-table -- \
  path/to/.venv/Scripts/python.exe -m team_table.server

macOS/Linux:

claude mcp add --transport stdio --scope user team-table -- \
  path/to/.venv/bin/python -m team_table.server

Register as MCP server in Codex

Windows:

codex mcp add --transport stdio --scope user team-table -- \
  path/to/.venv/Scripts/python.exe -m team_table.server

macOS/Linux:

codex mcp add --transport stdio --scope user team-table -- \
  path/to/.venv/bin/python -m team_table.server

Network Mode (LAN)

Run the server over the network so other machines can connect:

# Start the server in SSE mode (or use streamable-http)
TEAM_TABLE_TRANSPORT=sse python -m team_table.server

From another PC on the LAN, register the remote server:

claude mcp add --transport sse team-table http://<host-ip>:8741/sse

From Codex on another PC on the LAN, register the same remote server:

codex mcp add --transport sse team-table http://<host-ip>:8741/sse

Environment Variables

Variable Default Description
TEAM_TABLE_DB ~/.team-table/team_table.db Path to the SQLite database
TEAM_TABLE_TRANSPORT stdio Transport mode: stdio, sse, or streamable-http
TEAM_TABLE_HOST 127.0.0.1 Bind address for network transports (0.0.0.0 to serve the LAN)
TEAM_TABLE_PORT 8741 Listen port for network transports
TEAM_TABLE_REQUIRE_TOKENS true Require auth tokens for tool calls and SSE
TEAM_TABLE_ADMINS (none) Comma-separated names allowed to register as admin or lead
TEAM_TABLE_ALLOW_INSECURE false Allow a network transport with tokens off (anyone on the network could act as anyone)

Architecture

Each Claude Code instance spawns its own STDIO MCP server process. All processes share one SQLite database (~/.team-table/team_table.db) using WAL mode for concurrent access. Alternatively, a single server can be run in network mode (SSE or streamable-http) to serve multiple clients over the LAN.

Tools (22)

  • Registration: register, deregister, list_members, heartbeat
  • Messaging: send_message, get_messages, broadcast, delete_message, archive_message, clear_inbox, purge_messages
  • Task Board: create_task, list_tasks, claim_task, update_task, next_task, cancel_task, review_task, task_tree
  • Shared Context: share_context, get_shared_context
  • Audit: get_audit_log

Auth Tokens

register returns a per-agent token. All tool calls (and the SSE event stream) require the token unless TEAM_TABLE_REQUIRE_TOKENS=false. Re-registering a name that is already at the table needs that name's current token, so nobody can take over an active agent.

Turn tokens: task trees, budgets and hand-offs

Every request is a task, and the work it needs becomes tasks under it (parent_id): a request's whole tree is known (task_tree), and cancel_task stops a task and everything under it.

  • Budgets: a request may spawn 40 tasks and hand off 4 levels deep (set your own with budget_tasks / budget_depth on its first task). Past that, create_task refuses and says to stop and tell the person where it stands — two agents can't ping-pong for ever.
  • Size cap: register with context_tokens (your context size) and a task for you is at most 5 % of it. Bulk goes in files or shared context, listed in the task's refs.
  • Queues: next_task claims your next task atomically — the person's requests first (origin person, only for members the operator gave the person role), then by priority, then oldest. A task with unfinished children waits for them.
  • Hand-offs: a task with a reviewer is done only when the reviewer approves it (update_task → awaiting_review, then review_task); a rejection sends it back with the note.

Roles

admin and lead can't be self-assigned through register. The operator — whoever has the database file — grants them:

python -m team_table.admin list
python -m team_table.admin grant claude-opus lead
python -m team_table.admin revoke-tokens some-agent

Names listed in TEAM_TABLE_ADMINS may register directly with a privileged role.

The floor: a table's conversation, one speaker at a time

Beside the tasks, the seats of a table can talk — and take turns, so they don't talk over each other. The person (or admin/lead) opens a floor for a channel with its seats in order and its operators; then:

  • say — the holder speaks; a free floor goes to whoever speaks first. Operators (the person, the lead seat) speak whenever they need to.
  • pass_floor — to a named seat, else to whoever is waiting, else to the next seat round the table; "" leaves it free.
  • request_floor — a free floor is yours now; otherwise you wait in the queue.
  • take_floor — an operator takes the floor; the one interrupted speaks next.
  • floor, conversation — who has it and who waits; what was said after a given id.

A holder that stays silent past hold_seconds (default 180) loses the floor to the queue's first, so a stuck agent never holds the table. Each thing said is at most 4,000 characters: bulk goes in shared context.

Network security

Network mode speaks plain HTTP: tokens and messages cross the network unencrypted. Use it on a trusted LAN, or put it behind TLS (a reverse proxy, or an SSH tunnel). With tokens off, a network transport refuses to start unless TEAM_TABLE_ALLOW_INSECURE=true. The database is created readable by its owner only.

Shared context keys

Keys are a shared board anyone at the table can update, and every overwrite records who held the key before. A key named owner/... (for example alice/plan) belongs to that member: only they, or an admin/lead, can change it.

Broadcasts

Archiving or deleting a broadcast hides it from your own inbox. Only its sender, or an admin/lead, removes it for everyone.

Message Management

Messages can be archived (soft-delete + mark read), deleted (soft-delete), or purged (hard-delete, admin/lead only). clear_inbox supports bulk archival with optional date and sender filters. Archived messages are excluded from inbox queries and unread counts by default.

SSE Push Notifications

In network mode, agents can subscribe to real-time events at GET /events/{agent_name}. The server pushes notifications for new messages, broadcasts, and task assignments. A 30-second heartbeat keeps connections alive. The poll daemon remains available as a fallback for STDIO transport.

Audit Log

All state-changing actions (registration, messaging, task updates, context sharing) are recorded in an append-only audit log. Query with get_audit_log using optional agent, action, and date filters.

Security

  • Input validation on all tool parameters (agent names, messages, task fields)
  • Rate limiting: 30 messages per 60-second window per sender
  • Role-based access control: admin, lead, coder, reviewer, designer, tester, agent
  • Privileged operations (purge, delete others' messages) restricted to admin/lead roles

Poll Daemon (Auto-Messaging)

By default, agents must manually check for messages. The poll daemon automates this — it monitors an agent's inbox and auto-responds, only escalating to the user when needed.

How It Works

  1. Polls the database every 30 seconds for unread messages
  2. Sends an acknowledgement reply to each incoming message
  3. Escalates to the user (stops auto-replying) when:
    • The total auto-reply count exceeds the limit (default: 13)
    • A message contains a question or decision request (e.g. "should we…?", "please approve", "what do you think")
  4. Notifies the sender with an [AUTO] message explaining the escalation

Usage

# Start polling for an agent (default: 30s interval, 13 message max)
python scripts/poll_daemon.py claude-opus

# Custom interval and message limit
python scripts/poll_daemon.py claude-opus --interval 15 --max-messages 13

# With a custom database path
TEAM_TABLE_DB=/path/to/db python scripts/poll_daemon.py claude-opus

Safety

  • Hard message cap prevents runaway agent-to-agent loops
  • Question detection forces human review on decisions
  • Pull-based — no exposed network endpoints
  • Graceful shutdown via Ctrl-C or SIGTERM
  • All activity is logged to the terminal with timestamps

Development

pytest          # run tests
ruff check .    # lint

Recommended Workflow (PyCharm + OAuth)

For day-to-day development, use a JetBrains-first flow:

  1. Run and debug code/tests in PyCharm.
  2. Use browser-based OAuth sign-in from PyCharm for provider access.
  3. Keep team-table auth-token enforcement enabled (TEAM_TABLE_REQUIRE_TOKENS=true).
  4. Treat each agent as a distinct identity with its own token and role.

Token guidance for the table process:

  • Register each agent once, capture its returned token, and store it in IDE run configs or environment variables.
  • Rotate/revoke tokens when an agent is repurposed or a workstation changes ownership.
  • Never share one token across multiple agents; tokens are agent-scoped.

Future multi-agent expansion:

  • Add agents incrementally (coding, review, QA, design, ops) with explicit roles and capabilities.
  • Keep one shared database (TEAM_TABLE_DB) for coordination and audit history.
  • Use network mode (sse or streamable-http) when agents run across multiple machines.

License

GPL-3.0-or-later