whiteboard-mcp-server
README.md
# whiteboard-mcp-server
Shared context for multiple Claude Code sessions working on the same project.
When multiple Claude Code sessions work on different parts of a project, context gets lost. The whiteboard gives them a direct channel to share contracts, decisions, alerts, and questions — no human relay needed.
## The problem
```
Dev A -> Claude A -> Human A -> Human B -> Claude B -> Dev B
```
This game of telephone breaks down on every handoff. The whiteboard eliminates the middle:
```
Claude A <---> Whiteboard <---> Claude B
```
## What it does
- **Rooms** with token-based access and configurable TTL (default 24h)
- **4 board sections**: contracts, decisions, alerts, questions
- **Q&A system**: directed questions between sessions with pending/answered tracking
- **Hub-and-spoke pattern**: one context session answers questions from multiple workers
- **Moderator mode**: optionally restrict room closing to the creator
- **Volatile by design**: rooms are deleted when closed — no data accumulates
## Quick start
### 1. Run
```bash
git clone https://github.com/thebackpackdevorg/whiteboard-mcp-server.git
cd whiteboard-mcp-server
docker compose up -d
```
The server starts on port **8080**.
### 2. Register in Claude Code
```bash
claude mcp add whiteboard http://localhost:8080/mcp -t http
```
Or add to `~/.claude/settings.json`:
```json
{
"mcpServers": {
"whiteboard": {
"type": "http",
"url": "http://localhost:8080/mcp"
}
}
}
```
### 3. Use it
**Session A** creates a room:
```
Claude A -> room_create(name="payments-risk", description="Sprint 42 integration")
Returns: Token: xK9mQ2pL...
```
**Session B** joins and sees the board:
```
Claude B -> room_join(room="payments-risk", token="xK9mQ2pL...", alias="claude-risk")
Returns: board summary + section descriptions + pending questions
```
Both sessions read and write to the shared board:
```
Claude A -> board_write(section="contracts", title="POST /payments schema", content="...")
Claude B -> board_read(room="payments-risk", token="xK9mQ2pL...")
```
## Hub-and-spoke pattern
For projects with multiple parallel sessions, use a **context session** as the central oracle and **worker sessions** that ask questions when they need context.
```
Context Session (loop) Worker Session A Worker Session B
├── loads full context ├── works focused ├── works focused
├── board_pending() each iter ├── board_ask() ├── board_ask()
├── board_answer() if any │ when needs ctx │ when needs ctx
└── room_close() when done └── board_pending() └── board_pending()
to see response to see response
```
### Context session prompt template
```
You are the context session for this project. Your role is:
1. Keep the full project context loaded.
2. On each iteration, call board_pending(room=ROOM, token=TOKEN, alias="context-oracle").
3. If there are pending questions, answer them with board_answer().
4. Continue with your main task.
5. When the session ends, call room_close().
Room: <room_name>
Token: <token>
Alias: context-oracle
```
### Worker session prompt template
```
You are a worker session. Work on your specific module.
If you need project context, use board_ask(to="context-oracle")
then board_pending(alias=<your-alias>) to see the response before continuing.
Room: <room_name>
Token: <token>
Alias: <your-alias>
```
## Tools reference
### Room management
| Tool | Key params | Description |
|------|------------|-------------|
| `board_guide` | *(none)* | Returns the full usage guide. Call first in every new session. |
| `room_create` | `name`, `description?`, `ttl_hours?`, `moderator_only_close?`, `creator_alias?` | Create a room. Returns token (shown only once). |
| `room_join` | `room`, `token`, `alias` | Join a room. Alias must be unique. Returns board summary + pending questions. |
| `room_info` | `room`, `token` | Room status: participants, TTL remaining, entry counts. |
| `room_extend` | `room`, `token`, `hours` | Extend the TTL before expiration. |
| `room_close` | `room`, `token`, `reason?`, `author?` | Close and delete the room. Respects moderator setting. |
### Board operations
| Tool | Key params | Description |
|------|------------|-------------|
| `board_write` | `room`, `token`, `section`, `title`, `content`, `author?` | Write an entry. Sections: `contracts`, `decisions`, `alerts`. |
| `board_read` | `room`, `token`, `section?` | Read entries. Without section returns everything. |
| `board_list` | `room`, `token` | Compact overview with section descriptions. |
### Q&A
| Tool | Key params | Description |
|------|------------|-------------|
| `board_ask` | `room`, `token`, `title`, `content`, `to`, `author?` | Post a question directed to an alias. Returns `question_id`. |
| `board_answer` | `room`, `token`, `question_id`, `answer`, `author?` | Answer a question by ID. |
| `board_pending` | `room`, `token`, `alias` | Check pending questions for your alias. Lightweight — safe for loops. |
## Board sections
| Section | Purpose |
|---------|---------|
| `contracts` | API interfaces, schemas, and contracts between modules |
| `decisions` | Architectural decisions with context and rationale |
| `alerts` | Breaking changes, blockers, and changes that affect others |
| `questions` | Directed questions between participants (via `board_ask`) |
## Configuration
### config.yaml
```yaml
whiteboard:
data_path: "/data"
default_ttl_hours: 24
server:
host: "0.0.0.0"
port: 8080
```
### Environment variables (override config.yaml)
| Variable | Default | Description |
|----------|---------|-------------|
| `DATA_PATH` | `/data` | Root directory for room storage |
| `DEFAULT_TTL_HOURS` | `24` | Default room expiration in hours |
| `SERVER_HOST` | `0.0.0.0` | Bind address |
| `SERVER_PORT` | `8080` | Internal port |
## Security
- **Token per room** — generated at creation, SHA-256 hashed for storage. Plaintext shown only once.
- **Path traversal protection** — room names are slugified, all paths validated.
- **Unique aliases** — duplicate aliases are rejected on join.
- **Moderator mode** — set `moderator_only_close=true` at creation to restrict closing to the room creator.
## Alias conventions
- Context session: `context-oracle`
- Workers: `claude-<module>` (e.g. `claude-payments`, `claude-risk`, `claude-frontend`)
## Development
```bash
# Install locally
pip install -e .
# Run directly
DATA_PATH=./data python -m whiteboard_mcp.server
```
## Stack
- **Python 3.12** + FastMCP
- **Streamable HTTP** transport
- **Docker** + `uv` for fast builds
- **YAML** metadata for rooms, **Markdown** for board entries
## License
MIT
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues