Skip to main content
Glama

Lockstep Chain Protocol

Chain-based project tracking for Human+AI collaboration. An MCP server that gives your AI coding assistant persistent memory across sessions — chains link work together, tickets track what needs doing, and handoffs preserve context so nothing gets lost between conversations.

Who is this for?

Anyone using AI coding assistants (Claude, etc.) who's tired of re-explaining context every session. Lockstep is especially useful if you:

  • Work on multi-session projects where continuity matters

  • Want structured session types (discovery, planning, build, review) without rigid enforcement

  • Are neurodivergent and benefit from external scaffolding for executive function

  • Want your AI partner to track growth and capacity over time

Related MCP server: Adaptive Reasoning Server

Features

  • 37 tools + 5 commands for full project lifecycle management

  • Chain-based tracking — sessions link together as a chain of work

  • YAML-defined chain types — full-funnel, enhancement, refactor, bug-fix out of the box, or create your own

  • Progressive disclosure — early phases show fewer fields to reduce cognitive load; information surfaces as it becomes relevant

  • Ticket promotion — standalone tickets can be promoted into chains when they grow; related tickets discovered automatically

  • Session types — discovery, research, planning, architecture, build, review

  • Structured handoffs — decisions, files changed, open threads, and next-session recommendations transfer between conversations

  • Capacity tracking — growth stages (training-wheels → partnership → safety-net) with event logging

  • Advisory, not enforcing — the protocol flags and explains, never blocks

  • Fully local — all data stored as YAML files on your machine, no network access

  • Cross-platform — tested on macOS, Windows 11, and Linux (x64 and ARM)

  • Human-readable data — inspect, edit, or version-control your project data directly

Installation

From Anthropic Directory (Claude Desktop)

  1. Find "Lockstep Core" in the Anthropic Directory

  2. Click Install

  3. When prompted, choose a data directory (default: ~/.lockstep/data)

MCPB Bundle (Manual)

  1. Download lockstep-core.mcpb from the latest release

  2. Open it with Claude Desktop (double-click or drag in)

  3. When prompted, choose a data directory (default: ~/.lockstep/data)

Manual Setup

Requires uv and Python 3.11+. Works on macOS, Windows, and Linux.

git clone https://github.com/dandelionrosegroup/lockstep-core.git
cd lockstep-core

Add to your Claude Desktop config:

Platform

Config Location

macOS

~/Library/Application Support/Claude/claude_desktop_config.json

Windows

%APPDATA%\Claude\claude_desktop_config.json

Linux

~/.config/Claude/claude_desktop_config.json

macOS / Linux:

{
  "mcpServers": {
    "lockstep": {
      "command": "uv",
      "args": ["run", "--python", "3.11", "--with", "mcp>=1.0.0", "--with", "pydantic>=2.0.0", "--with", "PyYAML>=6.0", "src/server.py"],
      "cwd": "/path/to/lockstep-core",
      "env": {
        "LOCKSTEP_DATA_DIR": "/path/to/your/data",
        "PATH": "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin:~/.local/bin"
      }
    }
  }
}

Important: Claude Desktop is a GUI app and does not inherit your shell's PATH. The PATH entry above ensures uv (typically installed at ~/.local/bin/uv) is discoverable. If you installed uv via Homebrew, /opt/homebrew/bin covers that path.

Windows:

{
  "mcpServers": {
    "lockstep": {
      "command": "uv",
      "args": ["run", "--python", "3.11", "--with", "mcp>=1.0.0", "--with", "pydantic>=2.0.0", "--with", "PyYAML>=6.0", "src/server.py"],
      "cwd": "C:\\Users\\you\\Projects\\lockstep-core",
      "env": {
        "LOCKSTEP_DATA_DIR": "C:\\Users\\you\\.lockstep\\data"
      }
    }
  }
}

Note: On Windows, use double backslashes (\\) or forward slashes (/) in JSON paths.

Troubleshooting

"uv: command not found" or server fails to start: Claude Desktop doesn't inherit your terminal's PATH. Make sure uv is findable:

  • macOS/Linux: Add the PATH env var as shown in the config example above, or use the full path to uv (e.g., "command": "/Users/you/.local/bin/uv")

  • Windows: The uv installer usually adds itself to the system PATH. If not, use the full path (e.g., "command": "C:\\Users\\you\\.local\\bin\\uv.exe")

Server starts but immediately disconnects:

  • Verify Python 3.11+ is available: uv python list (uv will auto-download if needed thanks to the --python 3.11 flag)

  • Check Claude Desktop's MCP logs: ~/Library/Logs/Claude/mcp*.log (macOS) or %APPDATA%\Claude\logs\ (Windows)

Configuration

Lockstep needs one setting: a data directory where it stores chains, tickets, and capacity data.

  • Default: ~/.lockstep/data

  • Custom: Set LOCKSTEP_DATA_DIR environment variable or configure during MCPB install

  • Lockstep creates subdirectories automatically (chains/, tickets/, capacity/, declarations/, handoffs/, catches/, archive/)

Usage Examples

Start a new initiative

Create a ticket, chain, and first session in one command.

User prompt:

"Create a new initiative called 'Build user authentication' with the vision 'Users can sign up, log in, and manage their accounts.'"

Tool call: cmd_new_initiative

{
  "title": "Build user authentication",
  "vision": "Users can sign up, log in, and manage their accounts."
}

Response:

{
  "ticket_id": "TICKET-001",
  "chain_id": "build-user-authentication",
  "chain_type": "full-funnel",
  "first_session": "discovery",
  "link_number": 1,
  "message": "Initiative created. Discovery session is active. Record your session declaration."
}

Promote a ticket into a chain

When a standalone ticket grows in scope, promote it to get chain tracking with automatic discovery of related work.

User prompt:

"Promote TICKET-005 into a chain. The completion vision is 'OAuth fully integrated and tested.'"

Tool call: promote_ticket

{
  "ticket_id": "TICKET-005",
  "completion_vision": "OAuth fully integrated and tested"
}

Response:

{
  "promoted": true,
  "ticket_id": "TICKET-005",
  "chain_id": "add-oauth-support",
  "chain_type": "enhancement",
  "first_session": "planning",
  "nesting_candidates": [
    {
      "ticket_id": "TICKET-008",
      "title": "Review Auth Flows",
      "shared_tags": ["auth"]
    }
  ],
  "candidate_message": "Found 1 related ticket(s) that could be nested.",
  "message": "Ticket promoted to chain 'add-oauth-support'. Planning session is active."
}

Record a handoff

Capture session context so the next conversation can pick up seamlessly.

User prompt:

"Record a handoff — we decided on JWT tokens and bcrypt for passwords. Files changed: auth.py (created), models.py (modified). Next session should be Planning."

Tool call: record_handoff

{
  "chain_id": "build-user-authentication",
  "session_type": "discovery",
  "status": "complete",
  "decisions_made": ["JWT tokens for auth", "bcrypt for password hashing"],
  "files_changed": [
    {"path": "auth.py", "action": "created"},
    {"path": "models.py", "action": "modified"}
  ],
  "recommended_next_type": "planning",
  "quick_start": "Define API routes, data models, and auth middleware based on JWT+bcrypt decisions."
}

Tools Reference

Chain Lifecycle (15 tools)

Tool

Description

create_chain

Create a new chain from a ticket

read_chain

Read chain state (filtered by progressive disclosure)

get_chain_status

Lightweight status check

set_chain_status

Update chain status

set_chain_entity

Tag chain with entity ownership

update_chain_metadata

Update vision, entity, capacity role

add_chain_link

Add a new session link

complete_chain_link

Mark a link as complete

pause_chain

Pause chain (preserves state)

resume_chain

Resume a paused chain

complete_chain

Mark chain complete (auto-closes ticket for bug-fix/maintenance)

archive_chain

Move to archive with retention metadata

branch_chain

Fork when work splits

spawn_child_chain

Cross-type fork with spawn reason (e.g. infrastructure → content)

rename_chain

Rename chain and update all cross-references

Ticket Lifecycle (7 tools)

Tool

Description

create_ticket

Create ticket with auto-assigned ID

read_ticket

Read full ticket state

update_ticket

Update metadata and append notes (returns promotion nudge at 3+ notes)

close_ticket

Close ticket (advisory: flags if chain incomplete)

tag_ticket

Add or remove tags (returns promotion nudge if applicable)

link_ticket_chain

Associate ticket with chain (auto-detects child tickets)

promote_ticket

Promote standalone ticket into a chain with candidate scanning

Capacity Tracking (5 tools)

Tool

Description

read_capacity

Read capacity role data

update_capacity_stage

Transition between growth stages

record_capacity_event

Log a capacity-relevant event

get_capacity_events

Query capacity event history

check_stagnation

Check for stalled growth

Query Tools (6 tools)

Tool

Description

search_chains

Filter chains by entity, status, type, date

list_chains

List all active chains

search_tickets

Filter tickets by type, entity, priority

list_tickets

List all open tickets

get_dashboard

Overview with progressive disclosure per chain phase

check_chain_health

Find stale or blocked chains

Session Support (4 tools)

Tool

Description

record_session_declaration

Write session declaration (goal, deliverable, criteria)

record_handoff

Write session-end handoff with context for next session

record_gate_skip

Log when session type sequence is skipped

record_catch_event

Log scope drift or momentum shift

Commands (5 shortcuts)

Command

Description

cmd_new_ticket

Create a ticket (generic)

cmd_new_initiative

Ticket + full-funnel chain + discovery session

cmd_enhancement

Ticket + enhancement chain + planning session

cmd_refactor

Ticket + refactor chain + architecture session

cmd_bug_fix

Bug-fix ticket, optionally with chain

Creating Custom Chain Types

Chain types are defined as YAML files in templates/. Drop a new file to create a new chain type — no code changes required.

Template Format

# templates/your-type.yaml
chain_type: your-type
display_name: Your Type
phases: [planning, build, review]
autonomous_eligible: false
required_fields:
  - completion_vision
optional_fields:
  - capacity_role
  - parent_chain
progressive_disclosure:
  planning:
    show: [completion_vision, entity, tags]
    prompt: "What are we building and why?"
  build:
    show: [all]
    prompt: null
  review:
    show: [all]
    prompt: "Does this meet the completion vision?"

Fields

Field

Required

Description

chain_type

Yes

Unique identifier (kebab-case)

display_name

Yes

Human-readable name

phases

Yes

Ordered list of session types this chain walks through

autonomous_eligible

No

Can AI proceed without human review? (default: false)

required_fields

No

Fields required at chain creation

optional_fields

No

Fields that may be set later

progressive_disclosure

No

Per-phase field visibility and prompts

Progressive Disclosure

Each phase can define:

  • show: List of chain fields visible during this phase. Use [all] to show everything.

  • prompt: Optional guidance text surfaced to the AI partner during this phase.

Available fields for show: completion_vision, entity, tags, capacity_role, parent_chain, child_chains, child_tickets, spawn_reason, expected_sequence, gate_skips, all.

Core structural fields (chain_id, title, status, links, etc.) are always visible regardless of disclosure rules.

Built-in Chain Types

Type

Phases

Autonomous

full-funnel

discovery → research → planning → architecture → build → review

No

enhancement

planning → architecture → build → review

No

refactor

architecture → build → review

No

bug-fix

build → review

Yes

Migrating from v0.1.0

If you have existing v0.1.0 data, run the migration script:

python scripts/migrate_v1_to_v2.py ~/.lockstep/data

This creates a backup, renames template to chain_type, and bumps the schema version. The server also auto-migrates any v1 files it encounters on read, so migration is optional but recommended for clean data.

Design Principles

  1. Advisory, not enforcing. The protocol flags and explains — it never blocks. If you want to skip from Discovery straight to Build, it records the skip and moves on.

  2. Make the unconscious conscious. Session handoffs, catch events, and capacity tracking illuminate patterns over time without forcing behavior change.

  3. Scaffold growth, respect autonomy. Growth stages (training-wheels → partnership → safety-net) make the path of least resistance the productive path, but they're never the only path.

  4. Protocol serves partnership. If the structure fights the work, the structure bends.

Data Storage

All data is stored as YAML files in your configured data directory:

~/.lockstep/data/
├── chains/          # CHAIN-[kebab-title].yaml
├── tickets/         # TICKET-[number].yaml
├── capacity/        # [role-name].yaml
├── declarations/    # Session declaration records
├── handoffs/        # Session handoff records
├── catches/         # Catch event records
└── archive/         # Completed chains and tickets
    ├── chains/
    └── tickets/

YAML files are human-readable and version-controllable. No database required.

Privacy Policy

Lockstep is a fully local MCP server. It collects no data, makes no network requests, and includes no telemetry. Your project data stays on your machine.

Full policy: PRIVACY.md

Support

Contributing

Lockstep is GPL v3 licensed. Contributions welcome. Tested on macOS, Windows 11, and Linux.

# Set up development environment
git clone https://github.com/dandelionrosegroup/lockstep-core.git
cd lockstep-core

# Run tests (uv handles dependencies automatically)
uv run --python 3.11 --with mcp --with pydantic --with PyYAML python tests/test_integration.py
uv run --python 3.11 --with mcp --with pydantic --with PyYAML python tests/test_phase2_promotion.py
uv run --python 3.11 --with mcp --with pydantic --with PyYAML python tests/test_phase3_disclosure.py

# Or run all tests with pytest (requires pytest + pytest-asyncio)
uv run --python 3.11 --with mcp --with pydantic --with PyYAML --with pytest --with pytest-asyncio \
  python -m pytest tests/ -v

Check open issues for good places to start.

License

GNU General Public License v3.0 — Copyright (C) 2025-2026 Jack Daniel Williams / Dandelion Rose Group, LLC

Built as part of Dandelion Rose Group's mission to prove that neurodivergent minds are uniquely wired for AI partnership.

Available Tools

42 tools
archive_chainC
DestructiveIdempotent

Move completed chain to archive with retention metadata.

Inputs: params (required). Returns: result

branch_chainB
Destructive

Fork chain when work splits. Parent doesn't complete until all branches do.

Inputs: params (required). Returns: result

check_chain_healthB
Read-onlyIdempotent

Detect stagnant/forgotten chains. Always active regardless of capacity_tracking.

Inputs: params (required). Returns: result

check_stagnationB
Read-onlyIdempotent

Evaluate if any role has hit its stagnation threshold.

Stagnation = active engagement but no growth. Dormancy = no engagement at all. Both surfaced as observations, not errors (Design Principle 2).

Inputs: params (required). Returns: result

close_ticketB
DestructiveIdempotent

Close ticket. Advisory: flags if associated chain is incomplete.

Inputs: params (required). Returns: result

cmd_bug_fixB
Destructive

Create bug-fix ticket. Optionally creates chain.

    Pre-typed: Build -> Review (optional). Asks before creating chain
    via create_chain parameter. If false, ticket exists for tracking
    but no chain is created.
    

Inputs: title (required), description (required), entity, create_chain. Returns: result

cmd_enhancementB
Destructive

Create enhancement: ticket + chain + planning declaration.

    Pre-typed: Planning -> Architecture -> Build -> Review.
    Starts in Planning.
    

Inputs: title (required), vision (required), entity. Returns: result

cmd_new_initiativeB
Destructive

Create initiative: ticket + full-funnel chain + discovery declaration.

    Pre-typed: full funnel (Discovery -> Research -> Planning ->
    Architecture -> Build -> Review). Starts in Discovery.
    

Inputs: title (required), vision (required), entity. Returns: result

cmd_new_ticketB
Destructive

Create a new ticket. Generic — human specifies everything.

If the ticket type triggers Lockstep threshold (not maintenance), returns a prompt suggesting chain creation. The Partner handles the conversational follow-up.

Inputs: type (required), title (required), tags, entity, +2 more. Returns: result

cmd_refactorB
Destructive

Create refactor: ticket + chain + architecture declaration.

    Pre-typed: Architecture -> Build -> Review.
    Starts in Architecture. scope = "what's being refactored and why?"
    

Inputs: scope (required), title (required), entity. Returns: result

complete_chainA
DestructiveIdempotent

Mark entire chain complete. Lifecycle hooks per Decision 1.

    Bug-fix/maintenance chains: auto-close associated ticket.
    Other chain types: advisory suggesting ticket closure.
    

Inputs: params (required). Returns: result

create_chainA
Destructive

Create a new chain from a ticket. Generates chain_id from kebab-case title.

Inputs: params (required). Returns: result

create_ticketB
Destructive

Create a new ticket with auto-assigned sequential ID.

Inputs: params (required). Returns: result

get_capacity_eventsC
Read-onlyIdempotent

Query capacity event history with optional filters.

Inputs: params (required). Returns: result

get_chain_statusC
Read-onlyIdempotent

Lightweight status check: current link, phase, health.

Inputs: params (required). Returns: result

get_dashboardA
Read-onlyIdempotent

Aggregate view: active chains, open tickets, capacity summary, alerts.

    First tool called every session — gives Partner the full operational
    picture in one call.
    

Inputs: params (required). Returns: result

list_chainsA
Read-onlyIdempotent

List all active chains (lightweight summary view).

Inputs: params (required). Returns: result

list_ticketsB
Read-onlyIdempotent

List all open tickets.

Inputs: params (required). Returns: result

pause_chainB
DestructiveIdempotent

Pause chain — preserves state, signals 'not abandoned'. Idempotent.

Inputs: params (required). Returns: result

promote_ticketB
Destructive

Promote a standalone ticket into a chain (Decision 1).

Creates a chain from the ticket, scans for related tickets (same entity + overlapping tags), and returns candidates for nesting. Optionally nests specified tickets immediately.

Inputs: params (required). Returns: result

read_capacityB
Read-onlyIdempotent

Read growth stage for a specific role or all roles.

Inputs: params (required). Returns: result

read_chainA
Read-onlyIdempotent

Read chain state filtered through progressive disclosure.

Early-phase chains show fewer fields to reduce cognitive load. Full data always accessible via direct YAML read.

Inputs: params (required). Returns: result

read_ticketB
Read-onlyIdempotent

Read full ticket state.

Inputs: params (required). Returns: result

record_capacity_eventC
Destructive

Log a capacity-relevant event with typed attribution (Partner's field notes).

Inputs: params (required). Returns: result

record_catch_eventC
Destructive

Log Catch firing with qualitative capture.

    Catch events firing = system working, not failure. The metric is
    whether catches lead to better decisions, not whether they stop.
    human_reasoning is optional but gold when present.
    

Inputs: params (required). Returns: result

record_gate_skipC
Destructive

Log session-type leapfrog in chain metadata (Design Principle 1).

Partner flags, explains cost, asks — never refuses. The skip is recorded to enable pattern detection over time.

Inputs: params (required). Returns: result

record_handoffB
DestructiveIdempotent

Write session-end handoff to chain link and data directory.

Captures decisions, files changed, open threads, emotional context, and next-session recommendation.

Inputs: params (required). Returns: result

record_session_declarationC
DestructiveIdempotent

Write Session Declaration to current chain link.

    6 components: type, goal, deliverable, completion criteria,
    out of scope, partner confirm.
    

Inputs: params (required). Returns: result

rename_chainA
Destructive

Rename a chain: updates chain_id, renames YAML file, and fixes all cross-references.

    Updates: chain file, ticket references, declaration files, handoff files,
    catch files, and parent/child chain references.
    

Inputs: params (required). Returns: result

resume_chainA
DestructiveIdempotent

Resume a paused chain. Only valid from paused state.

Inputs: params (required). Returns: result

search_chainsC
Read-onlyIdempotent

Search chains by entity, status, session type, date range.

Inputs: params (required). Returns: result

search_ticketsC
Read-onlyIdempotent

Search tickets by type, entity, priority, status.

Inputs: params (required). Returns: result

set_chain_entityC
DestructiveIdempotent

Tag chain with entity ownership (which subsidiary).

Inputs: params (required). Returns: result

set_chain_statusC
DestructiveIdempotent

Update chain status with state transition validation.

Inputs: params (required). Returns: result

spawn_child_chainA
Destructive

Fork a chain when work needs a different type (Decision 5).

    Type changes create child chains; parent retains its type and
    history. spawn_reason is required — it's what makes cross-domain
    ideation patterns researchable.
    

Inputs: params (required). Returns: result

tag_ticketB
DestructiveIdempotent

Add or remove tags on a ticket.

Inputs: params (required). Returns: result

update_capacity_stageC
DestructiveIdempotent

Record a stage transition (training-wheels -> partnership -> safety-net).

Inputs: params (required). Returns: result

update_chain_metadataC
DestructiveIdempotent

General metadata updates: vision, entity, capacity_role, notes.

Inputs: params (required). Returns: result

update_ticketC
DestructiveIdempotent

Update ticket metadata and/or append a note.

Inputs: params (required). Returns: result

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    C2.9/5.0

    Scored across 42 tools

    Disambiguation3/5

    Several tools have overlapping retrieval or lifecycle roles: list_tickets/search_tickets, create_ticket/cmd_new_ticket, read_chain/get_chain_status/check_chain_health, and branch_chain/spawn_child_chain can be confused. Descriptions differentiate most cases, but an agent must read carefully to choose correctly.

    Naming Consistency4/5

    All names use snake_case with a mostly consistent verb_noun pattern. Retrieval verbs are mixed (read_/get_/list_) and the cmd_* family uses a distinct prefix convention, but the set remains readable and predictable.

    Tool Count2/5

    42 tools is well above the typical 3-15 sweet spot and exceeds the 25+ heavy threshold. Many lifecycle and command variants could be consolidated without losing core capability.

    Completeness4/5

    The surface covers chain/ticket CRUD, linking, promotion, capacity tracking, dashboards, session declarations/handoffs, and command shortcuts. Gaps include no explicit delete/reopen operations and limited direct editing of existing chain links, but core workflows are covered.

    Maintenance

    ActivityMaintained
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      D
      maintenance
      An MCP server that gives AI assistants persistent memory across sessions. It stores project context, decisions, and progress in structured markdown files as well as a knowledge graph and sequential thinking for better memory storage.
      36
      25 npm
      1
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      A local MCP memory server that gives AI assistants durable project memory across coding sessions, storing context, changes, and decisions.
      1 npm
      1
      MIT