MCP Session Coordinator
by jonburchel
README.md
# š MCP Session Coordinator
**Coordinate multiple AI coding sessions with file locking, intent broadcasting, and cross-session messaging.**
[](LICENSE)
[](https://nodejs.org/)
---
## The Problem
When running multiple AI coding sessions (like GitHub Copilot CLI) simultaneously on the same codebase, sessions have no awareness of each other. This leads to:
- **File edit conflicts** ā two sessions modify the same file at the same time
- **Duplicate git operations** ā multiple sessions attempt conflicting commits, rebases, or merges
- **Missed collaboration opportunities** ā one session discovers something valuable but has no way to tell the others
- **Wasted effort on overlapping work** ā sessions independently tackle the same task without knowing
## The Solution
A lightweight [Model Context Protocol](https://modelcontextprotocol.io/) (MCP) server that acts as a shared coordination layer, enabling sessions to:
- **Register themselves** and discover other active sessions working on the same project
- **Lock files** before editing to prevent conflicts
- **Broadcast intentions** before executing operations (edits, git commands, builds)
- **Exchange messages and ideas** across sessions in real time
- **Share discoveries, decisions, and conventions** as structured context
- **Detect conflicts proactively** before they cause problems
---
## Features
### 1. Session Management (5 tools)
| Tool | Description |
|------|-------------|
| `session_register` | Register a new session with name, project, branch, and working directory |
| `session_heartbeat` | Send periodic heartbeat to keep session active |
| `session_list` | List all active sessions, optionally filtered by project or branch |
| `session_get` | Get detailed information about a specific session |
| `session_deregister` | Gracefully deregister a session and release all its locks |
### 2. File Locking (4 tools)
| Tool | Description |
|------|-------------|
| `lock_acquire` | Acquire a lock on a file path (exclusive, shared, or intent) |
| `lock_release` | Release a previously acquired lock |
| `lock_list` | List all active locks, optionally filtered by session or file path |
| `lock_check` | Check whether a specific file is currently locked and by whom |
**Lock types:**
- **Exclusive** ā only one session can hold the lock; blocks all others
- **Shared** ā multiple sessions can read; blocks exclusive locks
- **Intent** ā advisory lock signaling planned future edits; does not block but warns
All locks support configurable TTL with automatic expiry.
### 3. Intent Broadcasting (4 tools)
| Tool | Description |
|------|-------------|
| `intent_announce` | Announce an intention to perform an operation |
| `intent_update` | Update the status of a previously announced intent |
| `intent_list` | List active intents, optionally filtered by type or session |
| `intent_clear` | Clear a completed or abandoned intent |
**Intent types:** `file_edit`, `git_commit`, `git_push`, `git_rebase`, `git_merge`, `build`, `test`, `refactor`, `dependency_change`
### 4. Cross-Session Messaging (3 tools)
| Tool | Description |
|------|-------------|
| `message_send` | Send a message to a specific session or broadcast to all |
| `message_list` | List messages for the current session, optionally filtered by channel |
| `message_mark_read` | Mark messages as read |
**Channels:** `general`, `coordination`, `ideas`, `alerts`, `git`
**Priority levels:** `low`, `normal`, `high`, `urgent`
Messages can be sent directly to a specific session or broadcast to all active sessions.
### 5. Conflict Detection (1 tool)
| Tool | Description |
|------|-------------|
| `conflict_check` | Comprehensive conflict check across locks, intents, and active sessions |
Analyzes potential conflicts before an operation by cross-referencing:
- Active file locks held by other sessions
- Announced intents from other sessions targeting the same files
- Other sessions working on the same branch
### 6. Shared Context (3 tools)
| Tool | Description |
|------|-------------|
| `context_share` | Share a piece of knowledge with all sessions |
| `context_query` | Query shared context by type, project, or keyword |
| `context_delete` | Remove outdated or incorrect shared context |
**Context types:** `decision`, `discovery`, `convention`, `blocker`, `note`
**Total: 20 tools** across 6 categories.
---
## Installation
```bash
# Clone the repository
git clone https://github.com/jonburchel/mcp-session-coordinator.git
cd mcp-session-coordinator
# Install dependencies
npm install
# Build
npm run build
```
## Configuration
Add the server to your MCP client configuration.
### GitHub Copilot CLI
In your `settings.json` or `mcp.json`:
```json
{
"mcpServers": {
"session-coordinator": {
"command": "node",
"args": ["F:/home/mcp-session-coordinator/dist/index.js"],
"env": {}
}
}
}
```
### Claude Desktop
In your Claude Desktop config (`claude_desktop_config.json`):
```json
{
"mcpServers": {
"session-coordinator": {
"command": "node",
"args": ["/path/to/mcp-session-coordinator/dist/index.js"]
}
}
}
```
### Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `MCP_COORDINATOR_DB_PATH` | Path to SQLite database file | `~/.mcp-session-coordinator/coordinator.db` |
| `MCP_CLEANUP_INTERVAL_SEC` | Stale session cleanup interval (seconds) | `60` |
| `MCP_SESSION_TIMEOUT_SEC` | Seconds before a session is considered stale | `300` |
---
## Usage Examples
### Basic Session Lifecycle
```
1. Register your session
ā session_register(name="feature-auth", project="my-app", branch="feature/auth")
ā { session_id: "abc-123", status: "registered" }
2. Before editing a file, acquire a lock
ā lock_acquire(session_id="abc-123", file_path="src/auth.ts")
ā { granted: true, lock_type: "exclusive" }
3. Announce your intent
ā intent_announce(session_id="abc-123", intent_type="file_edit", target="src/auth.ts")
ā { intent_id: "int-456", status: "announced" }
4. After editing, release the lock
ā lock_release(session_id="abc-123", file_path="src/auth.ts")
ā { released: true }
5. Before committing, check for conflicts
ā conflict_check(session_id="abc-123", intent_type="git_commit")
ā { conflicts: [], safe_to_proceed: true }
6. When finished, deregister
ā session_deregister(session_id="abc-123")
ā { status: "deregistered", locks_released: 0 }
```
### Two Sessions Coordinating
**Session A** is implementing authentication. **Session B** is building the user profile page. Both are working on the same project.
```
Session A registers:
ā session_register(name="auth-implementation", project="my-app", branch="feature/auth")
ā { session_id: "session-A" }
Session B registers:
ā session_register(name="profile-page", project="my-app", branch="feature/profile")
ā { session_id: "session-B" }
Session A locks the user model:
ā lock_acquire(session_id="session-A", file_path="src/models/user.ts", lock_type="exclusive")
ā { granted: true }
Session B tries to edit the same file:
ā lock_acquire(session_id="session-B", file_path="src/models/user.ts", lock_type="exclusive")
ā { granted: false, held_by: "session-A", holder_name: "auth-implementation" }
Session B sends a message to Session A:
ā message_send(
from_session="session-B",
to_session="session-A",
channel="coordination",
content="I need to add a 'bio' field to the User model. Can you include it in your changes?"
)
Session A sees the message and responds:
ā message_send(
from_session="session-A",
to_session="session-B",
channel="coordination",
content="Done! Added 'bio: string' to the User interface. Releasing lock now."
)
Session A releases the lock:
ā lock_release(session_id="session-A", file_path="src/models/user.ts")
Session B can now proceed:
ā lock_acquire(session_id="session-B", file_path="src/models/user.ts", lock_type="shared")
ā { granted: true }
```
### Sharing Context Across Sessions
One session discovers an important architectural detail and shares it:
```
Session A discovers something:
ā context_share(
session_id="session-A",
context_type="discovery",
project="my-app",
content="The auth module uses JWT tokens (not sessions). Tokens are stored in
httpOnly cookies, not localStorage. See src/auth/jwt.ts for the implementation."
)
Later, Session B queries for relevant context:
ā context_query(project="my-app", context_type="discovery")
ā [
{
content: "The auth module uses JWT tokens (not sessions)...",
shared_by: "auth-implementation",
context_type: "discovery"
}
]
Session B can also search by keyword:
ā context_query(project="my-app", keyword="auth")
ā [ ...matching context entries... ]
```
### Announcing Git Operations
Before performing git operations that could affect other sessions:
```
Session A is about to rebase:
ā intent_announce(
session_id="session-A",
intent_type="git_rebase",
target="feature/auth",
description="Rebasing feature/auth onto latest main"
)
Session B checks before pushing:
ā conflict_check(session_id="session-B", intent_type="git_push")
ā {
conflicts: [{
type: "git_operation",
description: "Session 'auth-implementation' is currently rebasing branch feature/auth",
severity: "high"
}],
safe_to_proceed: false
}
Session B waits. Session A finishes and clears the intent:
ā intent_clear(session_id="session-A", intent_id="int-789")
```
---
## Architecture
```
āāāāāāāāāāāāāāāā āāāāāāāāāāāāāāāā āāāāāāāāāāāāāāāā
ā AI Session ā ā AI Session ā ā AI Session ā
ā (Copilot) ā ā (Copilot) ā ā (Claude) ā
āāāāāāāā¬āāāāāāāā āāāāāāāā¬āāāāāāāā āāāāāāāā¬āāāāāāāā
ā ā ā
ā MCP Protocol (stdio) ā
ā ā ā
ā¼ ā¼ ā¼
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā MCP Session Coordinator ā
ā ā
ā āāāāāāāāāāāāā āāāāāāāāāāāā āāāāāāāāāāāāāāāāā ā
ā ā Session ā ā Lock ā ā Intent ā ā
ā ā Manager ā ā Manager ā ā Broadcaster ā ā
ā āāāāāāāāāāāāā āāāāāāāāāāāā āāāāāāāāāāāāāāāāā ā
ā āāāāāāāāāāāāā āāāāāāāāāāāā āāāāāāāāāāāāāāāāā ā
ā ā Message ā ā Conflict ā ā Context ā ā
ā ā Router ā ā Detector ā ā Store ā ā
ā āāāāāāāāāāāāā āāāāāāāāāāāā āāāāāāāāāāāāāāāāā ā
ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā SQLite (WAL mode) ā ā
ā ā ~/.mcp-session-coordinator/db ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
```
**Key design decisions:**
- **SQLite with WAL mode** for safe concurrent multi-process access from multiple MCP server instances
- **Automatic stale session cleanup** via configurable interval, removing sessions that miss heartbeats
- **Lock expiry with configurable TTL** so crashed sessions don't hold locks forever
- **Graceful shutdown handling** that releases all locks and deregisters the session on exit
- **No external dependencies** beyond Node.js and SQLite (via better-sqlite3)
---
## Roadmap
Future considerations for v2 and beyond:
- **Cloud sync** via GitHub or Google authentication for cross-machine coordination
- **Web dashboard** for monitoring active sessions, locks, and message traffic
- **Webhook notifications** for external integrations (Slack, Discord)
- **Cross-machine coordination** for distributed teams running sessions on different hosts
- **Session groups** for organizing related sessions into logical units
- **Lock queuing** with automatic grant when the current holder releases
---
## Contributing
Contributions are welcome! Here's how to get started:
1. Fork the repository
2. Create a feature branch: `git checkout -b feature/your-feature`
3. Make your changes and add tests
4. Ensure all tests pass: `npm test`
5. Submit a pull request
Please follow the existing code style and include tests for new functionality.
---
## License
This project is licensed under the MIT License. See [LICENSE](LICENSE) for details.
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessSyncing