Skip to main content
Glama

LLM Collaboration Blackboard

An implementation of version 1 of the LLM Collaboration Blackboard Specification.

LLM Collaboration Blackboard is a collaboration platform centered on Markdown that allows multiple LLMs and humans to share the same work context. Plans, tasks, events, memory, and state are collected in a single Blackboard and can be operated through an MCP server or a local dashboard.

The goal of this project is to preserve work as verifiable Plans and Events rather than as scattered chat logs. This makes it easier to track who is responsible for what, which tasks are in progress, and what changes have been made.

LLM Collaboration Blackboard overview

What It Provides

  • Plan management centered on Markdown and YAML Front Matter

  • Task state transitions through claim / update / cancel / recover

  • Recording and replay of audit events for each change

  • Role-based operation restrictions (Roles are self-declared)

  • Visualization of Plans and progress through a local dashboard

Related MCP server: pith

Typical Workflow

  1. Create a Plan and add tasks.

  2. Assign roles such as Researcher, Implementer, and Reviewer.

  3. Claim the tasks that are needed and begin work.

  4. Update task state, and use blocked / recover to pause or resume work as needed.

  5. Use Events and the Plan to preserve the work history and the background behind decisions.

This workflow is suitable for experiments running multiple LLMs in parallel, collaborative development, and implementation flows with review.

Quick Start

1. Prerequisites

  • Python 3.10 or later (3.13 recommended)

  • Available on Windows, macOS, and Linux

2. Installation

py -3.13 -m venv .venv
.\\.venv\\Scripts\\python.exe -m pip install -e .[dev]

3. Prepare a Blackboard Root

$env:BLACKBOARD_ROOT = "C:\\path\\to\\blackboard"

4. Start the Server

.\\.venv\\Scripts\\blackboard-server

5. Start the Dashboard (Optional)

.\\.venv\\Scripts\\blackboard-dashboard --config .\\dashboard.yaml

Open http://127.0.0.1:8765/ in a browser to view Plan and task status.

Blackboard workflow

Using MCP

This repository supports operating the Blackboard through MCP. Copy .mcp.json.example in the repository root to .mcp.json, then replace the paths with absolute paths.

{
  "mcpServers": {
    "blackboard": {
      "command": "<ABSOLUTE_PATH_TO_THIS_REPO>/.venv/Scripts/python.exe",
      "args": ["-m", "blackboard.server"],
      "env": {
        "BLACKBOARD_ROOT": "<ABSOLUTE_PATH_TO_THIS_REPO>/demo_blackboard"
      }
    }
  }
}

Representative tools include:

  • read_plan: retrieve Plan contents and executable tasks

  • claim_task: claim a task and begin work

  • update_task: update task status to done / blocked / cancelled

  • add_task / edit_task / cancel_task: update the Plan

  • recover_task: return a blocked task to pending

  • read_memory / write_memory: work with memory documents

  • read_state / write_state: work with state documents

Project Structure

  • src/blackboard: server implementation, models, permission controls, and dashboard implementation

  • scripts: demos and utility scripts

  • blackboard: Blackboard data used for examples and runtime

  • dashboard.yaml: sample local dashboard configuration

Development

See CONTRIBUTING.md for development rules and commit conventions.

.\\.venv\\Scripts\\python.exe -m pytest
.\\.venv\\Scripts\\python.exe -m ruff check src tests scripts

License

This project is released under the MIT License. See LICENSE for details.

Available Tools

22 tools
add_taskA

Append one new task to an already-initialized Plan. A stale revision is rejected as a conflict.

task uses the same shape as one entry of initialize_project's tasks (id/task/role). dependencies lists the IDs of tasks the new task requires; targets must already exist in the Plan.

Inputs: role (required), task (required), actor_id (required), expected_revision (required), +4 more. Returns: object

cancel_taskA

Logically cancel a pending or owned in-progress task with an audit Event.

Inputs: role (required), task_id (required), actor_id (required), expected_revision (required), +2 more. Returns: object

claim_taskA

Atomically claim one executable task. A stale revision is rejected as a conflict.

work_scope optionally declares the files/paths you expect to touch (e.g. ["src/blackboard/service.py", "tests/test_service.py"]). It is recorded on the task_started Event for other actors to see before they start their own work, but it is not enforced.

Inputs: role (required), task_id (required), actor_id (required), expected_revision (required), +2 more. Returns: object

edit_taskB

Edit a pending task's text, required Role, or dependencies with revision CAS.

Task IDs are immutable. Pass dependencies=[] to remove all dependencies.

Inputs: role (required), task_id (required), actor_id (required), expected_revision (required), +6 more. Returns: object

emit_eventA

Append an independent audit Event. This tool does not change Plan state.

Inputs: role (required), actor_id (required), event_type (required), content, +1 more. Returns: object

flush_event_outboxC

Retry pending Plan-generated Events after a previous Event write failure.

Inputs: plan_id. Returns: object

get_server_infoA

Report this MCP server process's version, git SHA, start time, and Blackboard root.

A long-lived stdio connection keeps the tool schema it had at startup, so a tool added to the source after connecting (e.g. a newly released one) will not appear until a fresh connection is made. If an expected tool seems to be missing, call this first: an old started_at/git_sha relative to the source you expect means the connection is stale, not that the feature is missing.

Inputs: no named parameters. Returns: object

initialize_projectA

Create the Blackboard directories and one named Plan file.

This bootstrap utility is used by a human when creating a project. LLM collaboration thereafter uses the core Blackboard tools above. Additional Plans may be created in the same root by calling this again with a new plan_id.

Inputs: tasks (required), title (required), project_id (required), plan_id, +1 more. Returns: object

list_actor_rolesA

Report which roles each actor_id has claimed tasks under, across every Plan.

This is an observation aid, not authentication: actors still self-declare their role on every call, and nothing here is enforced. Use it to sanity check who has been active and under which roles before trusting a Memory/Event entry attributed to an unfamiliar actor_id.

Inputs: no named parameters. Returns: object

list_memoryA

List Memory metadata in deterministic ID order without full content.

Inputs: no named parameters. Returns: result

list_plansA

List named Plans in this Blackboard root, each with its in_progress tasks.

Check this before claiming work when multiple actors may be active: it shows what is already claimed, by whom, across every Plan in this root.

Inputs: no named parameters. Returns: result

list_stateA

List State metadata in deterministic ID order without full content.

Inputs: no named parameters. Returns: result

read_eventA

List audit Events, optionally filtered by type, task, or created time range.

Inputs: limit, since, until, task_id, +1 more. Returns: result

read_memoryA

Read a persistent Memory document by id.

Inputs: id (required). Returns: object

read_planA

Read one Plan and its executable tasks, optionally for one Role.

Inputs: role, plan_id. Returns: object

read_stateA

Read a State document by id.

The response includes a stale_warning field if the document hasn't been updated in a while. This is a read-time nudge only — State is never auto-rewritten from Plan (see CONTRIBUTING.md).

Inputs: id (required). Returns: object

recover_taskA

Recover a blocked task to pending; the declared Role needs recover_task permission.

Inputs: role (required), task_id (required), actor_id (required), expected_revision (required), +1 more. Returns: object

set_task_priorityA

Set a pending task's advisory P0-P3 priority with CAS and an audit Event.

Priority is human-facing backlog guidance. It does not choose, claim, or block work for any LLM.

Inputs: role (required), reason (required), task_id (required), actor_id (required), +3 more. Returns: object

update_taskA

Finish, block, cancel, or recover a task.

Claim owners may set done/blocked/cancelled on in_progress tasks. Roles with recover_task permission may set pending on blocked tasks. The Plan state is authoritative. Its corresponding audit Event is placed in the Plan Outbox and is retried idempotently if Event persistence fails.

Inputs: role (required), status (required), task_id (required), actor_id (required), +2 more. Returns: object

validate_planA

Diagnose Plan metadata, task audit fields, dependencies, and Outbox without changing it.

Inputs: plan_id. Returns: object

write_memoryA

Create or update Memory. Updates require the revision returned by read_memory.

Inputs: id (required), role (required), content (required), actor_id (required), +3 more. Returns: object

write_stateB

Create or update current State. Updates require the revision returned by read_state.

Inputs: id (required), role (required), status (required), content (required), +3 more. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.3/5.0

    Scored across 22 tools

    Disambiguation3/5

    Several lifecycle verbs overlap: update_task can recover tasks, while recover_task exists separately; cancel_task also nests inside update_task. Plan validation vs. plan reading are distinct, but task mutation operations create some ambiguity.

    Naming Consistency4/5

    Tool names follow a consistent lowercase snake_case verb_noun pattern. Minor deviations like get_server_info, initialize_project, and flush_outbox are still recognizable.

    Tool Count3/5

    22 tools is on the high end for a planning/coordination server. Most earn their place, but any smaller set could be more economical.

    Completeness4/5

    The surface is essentially complete for this domain: plans, tasks, act, dependencies, claim, restore, validate, memory, state, and audit events are all covered. But there are still no global query for all tasks or a delete for memories/states, but not required.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers