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 (18)
- 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 - 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.
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.
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
- Polls the database every 30 seconds for unread messages
- Sends an acknowledgement reply to each incoming message
- 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")
- 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:
- Run and debug code/tests in PyCharm.
- Use browser-based OAuth sign-in from PyCharm for provider access.
- Keep
team-tableauth-token enforcement enabled (TEAM_TABLE_REQUIRE_TOKENS=true). - 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 (
sseorstreamable-http) when agents run across multiple machines.
License
GPL-3.0-or-later
Metadata
Release files for team-table 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| team_table-0.2.1.tar.gz | 46.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| team_table-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 83.8 kB
Release files / team_table-0.2.1.tar.gz
| Download URL | team_table-0.2.1.tar.gz |
|---|---|
| Size | 46.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
afad5038447eb906fcf81cc8be3f566e95f1ff488dc1ba8f8edd5a788b892788
|
|
BLAKE2b-256 checksum How to use checksums |
b0d463a6ec0b530176e6eed92432fe18486bd4202e5dfdf0082bf28d4e90722b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / team_table-0.2.1-py3-none-any.whl
| Download URL | team_table-0.2.1-py3-none-any.whl |
|---|---|
| Size | 37.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
98cf312b8c8086ccbf76894bdb7be5fef6af68452fe7fe52a42596e35cc52b7f
|
|
BLAKE2b-256 checksum How to use checksums |
84553d5f7d7383fd34bc88d5e4948c5ff0951d502f97467b5c680c418a520f11
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Security for team-table 0.2.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.