Skip to main content

Local Board

Local Board is a lightweight issue tracker installed inside a repository. It gives autonomous agents and humans a shared SQLite-backed board, an MCP interface, and a local web UI without requiring a hosted service.

Is Local Board a fit?

Local Board is most useful when multiple agents, or humans and agents, work concurrently on the same local repository and need atomic claims, explicit handoffs, workflow rules, and an audit trail. It can replace an ad-hoc TODO.md for that local coordination loop while keeping project configuration and agent instructions in Git.

It is probably unnecessary for a single short-lived agent task, and it is not a replacement for a hosted tracker used by a distributed team. Issues, comments, identities, and activity live in the ignored SQLite database: Git clones receive the board configuration and instructions, not the operational board. Agents in other worktrees must connect to the one server that owns the common Git repository's database. Agents on other machines need a deliberately operated shared host (with appropriate network security) or a separate board; Local Board does not synchronize databases between machines.

Product scope

The first release includes:

  • projects and milestones;
  • task, bug, feature, chore, and epic issues;
  • a separately configurable workflow for every issue type;
  • Markdown descriptions and comments;
  • priorities, ordering, assignees, and reviewers;
  • checklists, labels, attachment references, and issue dependencies;
  • branch/commit/PR/MR references and issue-key matching for local branches;
  • authenticated human and agent identities;
  • an immutable append-only activity audit log;
  • MCP over Streamable HTTP at /mcp;
  • a repository-local web board.

Local Board deliberately does not reproduce Linear's entire product or API. Linear's MCP design was used as a product reference: expose focused, discoverable issue-management tools rather than leaking the database schema. The implementation uses standard MCP initialize, tools/list, and tools/call methods. Live verification against Linear's official documentation could not be completed in the development environment because outbound access returned HTTP 401/403; consequently this project claims MCP protocol interoperability, not tool-for-tool Linear compatibility.

Architecture

Agents ── Streamable HTTP MCP ─┐
Browser ─────── HTTP API ──────┼── Local Board server ── SQLite (WAL mode)
                               └── Web UI

Each command opens a short SQLite transaction. WAL mode, a busy timeout, foreign keys, and uniqueness constraints provide the storage foundation for multiple local agent processes. Tokens are generated from cryptographic randomness and stored only as SHA-256 digests. The plaintext token is shown once.

The single Local Board server owns .local-board/state/board.db in the repository by default. The runtime directory is ignored by Git; future project configuration and agent instructions in .local-board/ remain trackable. --db and LOCAL_BOARD_DB override the database location. Agents never open SQLite directly: every worktree connects to the same server URL. Attachments are repository-local path references; Local Board does not copy arbitrary files into its database.

Install in a repository

Requires Python 3.11 or newer.

python -m pip install -e /path/to/local-board
cd /path/to/your/repository
local-board init
local-board config validate
local-board config plan
local-board actor alice --kind human
local-board actor coding-agent --kind agent
local-board status
local-board doctor --offline

An automated coordinator can request machine-readable bootstrap credentials with local-board actor coordinator --kind agent --json. After the server starts, an authenticated admin coordinator can provision a separate least-privilege identity for every subagent through the MCP create_actor tool and invalidate/reissue credentials with rotate_actor_token. Both commands return plaintext tokens once; capture them without logging and pass them through the orchestrator's secret/environment channel, never through issue comments or tracked files.

Save each displayed token securely. Start the UI and HTTP MCP endpoint:

local-board serve

init creates .local-board/project.toml, applies it to SQLite, and adds runtime-only paths to the target repository's .gitignore. Open http://127.0.0.1:8765 and enter an actor token. Projects may also be created imperatively through MCP or HTTP when needed:

curl -X POST http://127.0.0.1:8765/api/projects \
  -H "Authorization: Bearer $LOCAL_BOARD_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"key":"APP","name":"Application"}'

Connect an MCP agent

Start one server for the repository and configure every agent to use its HTTP MCP endpoint:

URL: http://127.0.0.1:8765/mcp
Authorization: Bearer <actor token>

Every agent should receive its own token so activity and authorship remain attributable. MCP clients send JSON-RPC to POST /mcp with Authorization: Bearer <token>, Content-Type: application/json, and Accept: application/json, text/event-stream. Local Board is sessionless and returns JSON responses; notifications receive HTTP 202.

Available tools cover project and issue discovery, creation and update, workflow transitions, milestones, comments, checklists, labels, dependencies, attachment references, Git links, and activity. Use MCP tools/list for the authoritative schemas.

local-board init also installs .local-board/AGENT.md, a repository-local skill at .agents/skills/local-board/, and a root AGENTS.md discovery bridge when that file does not exist. It never overwrites existing root instructions, including with --force; merge the provided bridge instructions manually when the repository already has an AGENTS.md. local-board doctor warns when that bridge is not discoverable. Separate onboarding is available in the human guide, the agent guide, and the operations guide.

Human web UI

The local UI renders columns from the selected project's configured workflows rather than a fixed status list. Humans can filter issue types, open complete issue context, claim or release work, assign assignees and reviewers, change priority, complete checklist items, comment, and perform only policy-aware transitions. Project and activity views provide repository-level oversight.

The UI uses stable issue routes such as /api/issues/APP-12. REST mutations honor optimistic revisions and return HTTP 409 for stale writes. The same Board domain methods back REST and MCP, so workflow, blocking dependency, assignment, and revision rules remain consistent across human and agent clients.

Agent MCP workflow

The MCP contract is self-discovering and uses stable references instead of requiring agents to know SQLite IDs:

  1. Call whoami, then list_projects and get_project_context to discover identities, workflows, labels, milestones, defaults, and agent policy.
  2. Search with list_issues; fetch the complete Markdown description, discussion, checklist, blockers, attachments, Git links, activity, and allowed transitions with get_issue_context using an identifier such as APP-12.
  3. Call claim_issue with the current revision, update checklist items and comments while working, and attach dependencies or Git references as needed.
  4. Call transition_issue with the latest revision; stale mutations return a machine-readable conflict error and should be retried only after reading fresh context.
  5. Call release_issue if abandoning work.

Tool input schemas include enums, defaults, constraints, and stable-reference descriptions. Tool errors expose conflict, not_found, or invalid_request codes in structuredContent.error instead of requiring agents to parse prose.

Project as code

.local-board/project.toml is the versioned desired state for project metadata, labels, defaults, and per-type workflows. Issues, comments, actors, tokens, activity, and Git links remain operational data in the ignored SQLite database.

schema_version = 1

[project]
key = "APP"
name = "Application"
description = ""

[defaults]
issue_type = "task"
priority = "medium"

[agent_policy]
require_assignee_before_start = true
require_reviewer_for = ["feature", "bug"]
branch_pattern = "{issue_key}-{slug}"

[[labels]]
key = "backend"
name = "Backend"
color = "#64748b"

[workflows.task]
initial = "backlog"
terminal = ["done", "cancelled"]
states = ["backlog", "todo", "in_progress", "in_review", "done", "cancelled"]
transitions = [
  ["backlog", "todo"],
  ["todo", "in_progress"],
  ["in_progress", "in_review"],
  ["in_review", "in_progress"],
  ["in_review", "done"],
]

Use local-board config validate for syntax and semantic validation, config plan to inspect drift, and config apply to reconcile it atomically. Apply is non-destructive: entities omitted from TOML are not deleted. Config-managed workflows and labels have stable keys and every effective apply is recorded with its digest and diff. Removing a workflow state that is used by an issue is rejected.

The configuration schema and SQLite schema are versioned independently. Commit project.toml to Git, but never commit .local-board/state, backups, attachments, or secrets.

Workflows

New projects get the following states for each issue type:

backlog → todo → in_progress → in_review → done
   └────────────── any active state ──────────→ cancelled

Manual projects may replace states and allowed directed transitions with set_workflow. Config-managed workflows must be changed in project.toml and reapplied; direct mutation is rejected. Invalid or skipped transitions are rejected transactionally.

Concurrent agents

Issues carry a monotonically increasing revision. Mutation and transition tools accept expected_revision; a stale writer receives a conflict instead of silently overwriting another agent's work. Issue identifiers and board positions use transactional counters rather than MAX(...) + 1, so concurrent threads and server requests cannot allocate the same value.

Agents should call claim_issue before starting work. Claiming atomically assigns the authenticated actor and creates a renewable lease (30 minutes by default); only one actor can claim a given revision. Use release_issue to clear a claim. Projects whose agent_policy.require_assignee_before_start is enabled reject transitions into in_progress until an issue is claimed or assigned.

SQLite still serializes writes internally. Local Board uses WAL mode and a busy timeout, while optimistic revisions protect domain data from lost updates. The concurrency suite exercises simultaneous threads and independent processes and finishes with SQLite integrity and foreign-key checks.

Git branch linking

Include an issue identifier such as APP-12 in the branch name and run:

LOCAL_BOARD_TOKEN=... local-board sync-branch

This records the current branch against every matching issue. PR/MR URLs can later be associated through the add_git_link MCP tool without granting Local Board access to GitHub or GitLab.

Security boundaries

The server binds to 127.0.0.1 by default. Every actor has an admin, member, or read-only viewer role; the first actor is the bootstrap admin and later actors default to member. Admins can change roles with set_actor_role, and the last admin cannot be demoted. Tokens are still local bearer credentials, so do not expose the server to an untrusted network. Activity is append-only and protected by SQLite triggers as well as the domain API.

Releases and recovery

Project releases follow planned → active → released or may be cancelled before release. Agents can use list_releases, create_release, and transition_release; transitions use optimistic revisions just like issues. A release can be associated with issues through its local release_id.

Create a consistent online SQLite snapshot with local-board backup [path]. Each backup receives a JSON manifest containing its format, schema version, byte size, and SHA-256 checksum. Restore validates the checksum, SQLite integrity, and required Local Board tables before atomically replacing state:

local-board backup
local-board restore .local-board/backups/board-20260818T120000Z.db --force

Restore automatically writes a pre-restore safety backup when current state exists. Stop local-board serve before restoring so no process retains a connection to the replaced database.

Development

The runtime has no third-party dependencies.

python -m unittest discover -s tests/unit -v
python -m unittest discover -s tests/integration -v
python -m unittest discover -s tests/e2e -v
python -m compileall -q local_board tests

Release files for local-board 0.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for local-board 0.0.2
File Size Uploaded
local_board-0.0.2.tar.gz 44.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for local-board 0.0.2
File Interpreter ABI Platform
local_board-0.0.2-py3-none-any.whl Python 3 none any Details

Total release size: 88.0 kB

Release files / local_board-0.0.2.tar.gz

Download URL local_board-0.0.2.tar.gz
Size 44.1 kB
Tags Source
SHA-256 checksum
How to use checksums
afd91ec299989cfb3f45b9a05db48c50b656ff086b5c1aa5e184bc85c58956c0
BLAKE2b-256 checksum
How to use checksums
fd44623db9bb0e7d008816928e1966210825a49867056d44becc48929d4db072
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 19, 2026.

Transparency log

Release files / local_board-0.0.2-py3-none-any.whl

Download URL local_board-0.0.2-py3-none-any.whl
Size 43.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e3b855921fd48659769c3c1a675f0e613897ee538ae05a2b30d2dbee9dae7477
BLAKE2b-256 checksum
How to use checksums
7a48d76d2234f731dd2fec8fc372687fa6a776fab280a165318c21aed79d5498
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 19, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.0.2 This release

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page