2 — Plugin: The Colibri Server

After a mutation enters through the transport (Section 1), it lands inside a stateful server plugin. Colibri is an MCP plugin implemented in TypeScript. It:

  • Boots in a specific sequence to ensure the transport connects before the client times out.
  • Opens a single SQLite database file (data/colibri.db) that holds all state — tasks, audit trails, Merkle proofs, decision logs.
  • Runs in one of 4 runtime modes that determine which tools are available.
  • Shuts down gracefully when signaled, draining in-flight requests and flushing the database.

This section is an overview. For detailed specs, see the linked sub-pages.

The Server at a Glance

┌─────────────────────────────────────┐
│  Colibri MCP Server (Node.js)       │
│  TypeScript 5.3+ · ESM               │
├─────────────────────────────────────┤
│  Transport Layer                    │
│  @modelcontextprotocol/sdk/stdio    │
├─────────────────────────────────────┤
│  5-Stage α Middleware Chain         │
│  tool-lock → validate → audit →     │
│  dispatch → audit-exit              │
├─────────────────────────────────────┤
│  Domain Handlers (β ζ η ε α γ)      │
│  Task Pipeline · Audit · Proof ·    │
│  Skill Registry · System            │
├─────────────────────────────────────┤
│  SQLite Database (WAL mode)         │
│  data/colibri.db · single writer    │
└─────────────────────────────────────┘

Every tool call flows top-to-bottom through this stack. The database is the single source of truth.

Runtime Modes

The server operates in one of 4 modes, selected via the COLIBRI_MODE environment variable at startup. Different modes enable different tool subsets:

Mode Accepts Use case
FULL All 14 shipped tools Normal operation after boot completes
READONLY Read-only tools (task_list, task_get, skill_list, server_health, server_ping, thought_record_list) Maintenance, audit review, diagnostics
TEST All 14 shipped tools with deterministic random seed Integration tests, scenario walkthroughs
MINIMAL Only server_ping, server_health Emergency, diagnostics, or bootstrap failure recovery

Mode is frozen at startup. It cannot be changed in-flight. If you need a different mode, restart the server with a different COLIBRI_MODE setting.

Boot Sequence

The server boots in a specific 6-step sequence. Understanding this sequence is critical because it explains why transport connects first:

  1. Create Server — instantiate the MCP server object.
  2. Register Handlers — register the 19 tool handlers (β task, ζ audit, η proof, ε skill, α/γ system).
  3. Connect Transport — connect the stdio transport before opening the database. This ensures the client handshake completes immediately and the client does not time out.
  4. Resolve initReady — wait for MCP initialize handshake to complete.
  5. Load Database — open data/colibri.db with better-sqlite3 in WAL mode. Run migrations. All tool calls arriving before this step queue behind a Promise gate.
  6. Load Domains — parse .agents/skills/, register the skill_list tool, start the 30-second health check loop.

At this point the server enters FULL mode (or the mode specified by COLIBRI_MODE) and begins dispatching queued tool calls.

Why transport first? The client sends a tool initialization request immediately after opening the connection. If the database is not yet open, that request could arrive before the database is ready. By connecting transport before opening the database, we guarantee the handshake succeeds. Tool calls that arrive before the database is ready are queued and executed once the database is available. This prevents the client from timing out during boot.

For detailed boot steps and the Promise gate behavior, see Boot Sequence.

Database

All state lives in a single data/colibri.db file opened via better-sqlite3. The database:

  • Uses WAL (Write-Ahead Log) mode for durability and concurrent read access without blocking writers.
  • Is accessed by one process writer — the Colibri server. No horizontal scaling in Phase 0.
  • Has three load-bearing tables for Phase 0: thought_records (ζ decision trail), merkle_nodes (η proof tree), and audit_events (every tool call).
  • Does not yet exist — it is a Phase 0 target (P0.2.2). When the server boots, it creates the database file and runs migrations.

Every mutation eventually writes to this database. A task lives in tasks. A decision record lives in thought_records. A Merkle leaf lives in merkle_nodes. If it is not in the database, it did not happen.

For schema details and the relationship between domains, see Database: data/colibri.db.

Middleware Chain

Between the transport boundary and the domain handler sits the 5-stage α middleware chain:

  1. Tool lock — serialize execution. Only one handler runs at a time per process.
  2. Schema validate — parse the request against Zod. Reject before the handler sees it.
  3. Audit enter — write the call to the decision trail with a monotonic sequence number.
  4. Dispatch — route the tool name to its handler.
  5. Audit exit — record the outcome and result hash.

The chain is ordered. Reordering is a breaking change. No other middleware (ACL, rate limits, reputation checks) is inserted in Phase 0 — they arrive with their concepts in Phase 1+.

For chain details, implementation targets, and the contract each stage enforces, see middleware.md (spec).

Health Checks

Every 30 seconds, the server runs a health check:

  1. Sample SQLite PRAGMA integrity_check (not every second, to avoid disk churn).
  2. Check memory usage against configured threshold.
  3. Measure event loop latency.
  4. Verify watcher status (if any file watchers are running).
  5. Check task queue depth.

If a health check fails, the server transitions to SAFE_MODE or DIAGNOSE depending on the failure. In SAFE_MODE, only read-only tools are accepted. This prevents corrupted or overloaded state from being written.

Graceful Shutdown

When the server receives SIGTERM or SIGINT (e.g., kill <pid>), it initiates a 6-stage shutdown:

  1. Announce — log that shutdown is starting.
  2. Quiesce router — stop accepting new tool calls.
  3. Drain tasks — wait for in-flight calls to complete (30-second timeout).
  4. Finalize proof — complete any pending Merkle operations.
  5. Close database — flush and close the SQLite connection.
  6. Release lock — clean up process-level locks.

Finally, the server exits with code 0 (success). If something goes wrong during shutdown, the exit code may be 1 (generic error), 73 (config), or 75 (resource).

Also: global handlers for unhandledRejection and uncaughtException trigger graceful shutdown instead of a crash. This ensures the database is closed cleanly even if the server encounters an unexpected error.

For exit codes and the full 6-stage drain, see Boot Sequence.

This section (2 — Plugin) has four sub-pages:

Page Purpose
Boot Sequence The 6-step boot, why transport connects first, Promise gate, domains load order, exit codes
Database: data/colibri.db SQLite WAL mode, single-writer, earned tables, schema relationships
Middleware 5-stage α chain details, validation boundaries, audit contract
Runtime Modes FULL / READONLY / TEST / MINIMAL mode specs and switching (future)

See Also


Table of contents


Back to top

Colibri — documentation-first MCP runtime. Apache 2.0 + Commons Clause.

This site uses Just the Docs, a documentation theme for Jekyll.