mctx
Centralized issue tracker CLI built on append-only JSONL event logs.
Installation
Requires Go ≥ 1.21.
go install github.com/tmsjngx0/mctx@latest
Verify:
mctx --version
Upgrading
mctx upgrade
mctx upgrade uses go install @latest by default. For local source installs,
set source_dir in ~/.mctx/config.yaml — then upgrade does git pull + go install from that path.
# ~/.mctx/config.yaml
workstation: myhost
store_dir: ~/.mctx/store
source_dir: ~/source/mindcontext-mgmt/mctx # optional
Quick start
# Set a short ID prefix for this project (run once per project)
mctx project set-prefix mcm
# Create issues
mctx issue create -t "Fix login bug"
mctx issue create --type epic --name auth -t "Auth overhaul"
mctx issue create --parent mcm-auth -t "OAuth2 integration"
# → mcm-auth.1
# Work on issues
mctx issue list
mctx issue start mcm-1
mctx issue close mcm-1 -r "fixed"
# Rename an issue (cascades to all children)
mctx issue rename mcm-auth mcm-oauth
# mcm-auth, mcm-auth.1, mcm-auth.1.1 → mcm-oauth, mcm-oauth.1, mcm-oauth.1.1
Issue IDs
mctx uses a short, readable ID scheme:
| Pattern |
Example |
Description |
<prefix>-<N> |
mcm-42 |
Sequential issue |
<prefix>-<slug> |
mcm-auth |
Named epic (--name) |
<prefix>-<slug>.<N> |
mcm-auth.1 |
Child of named epic |
<prefix>-<slug>.<N>.<M> |
mcm-auth.1.1 |
Grandchild |
Set a short project prefix once with mctx project set-prefix <alias>. Without it,
the full repo name is used as prefix (e.g. mindcontext-mgmt-42).
Commands
mctx issue create -t <title> [-b <body>] [-l <label>] [--type task|epic|spike]
[-p <priority>] [--parent <id>] [--name <slug>]
mctx issue list [--status open|in_progress|closed] [--type ...] [-l <label>]
mctx issue show <id>
mctx issue start <id>
mctx issue close <id> [-r <reason>]
mctx issue reopen <id>
mctx issue update <id> [-t <title>] [-b <body>]
mctx issue comment <id> -m <text>
mctx issue rename <old-id> <new-id>
mctx issue dep add <id> <depends-on> [--type blocks|relates]
mctx issue dep rm <id> <depends-on>
mctx issue children <id>
mctx issue ready [-l <label>]
mctx issue search <query>
mctx project set-prefix <alias>
mctx migrate import <beads-dir|jsonl> [--dry-run] [--open-only] [--open-branches]
mctx catchup # show session context (latest handoff + open issues)
mctx handoff # save session handoff comment on active issue
mctx git <args> # git passthrough on the store directory (for cross-workstation sync)
mctx upgrade # self-upgrade
Label filtering
Labels support prefix matching with ::
mctx issue list -l sp:1 # exact match
mctx issue list -l sp: # prefix match (sp:1, sp:2, sp:5 …)
mctx issue list -l bug -l sp:2 # AND — must match all
Storage
Events are stored as append-only JSONL files at:
~/.mctx/store/<owner>-<repo>/<issue-id>@<hostname>.jsonl
Each file contains one JSON event per line (create, status, update, comment,
label_add, dep_add, …). Per-host filenames make multi-workstation pulls conflict-free.
Cross-workstation sync
# one-time setup
mctx git init
mctx git remote add origin <url>
mctx git add -A && mctx git commit -m "init"
mctx git push -u origin main
# daily
mctx git pull
mctx git add -A && mctx git commit -m "sync $(date -I)"
mctx git push
Beads migration
Import issues from an existing .beads/ directory:
mctx migrate import --dry-run .beads/ # preview
mctx migrate import --open-branches .beads/ # import open branches only
mctx migrate import .beads/ # import all
Configuration
~/.mctx/config.yaml:
| Field |
Default |
Description |
workstation |
hostname |
Used for per-host file namespacing |
store_dir |
~/.mctx/store |
Root directory for issue event files |
source_dir |
— |
Local mctx source path (enables mctx upgrade from source) |
Versioning
Version is injected from git tags at build time. Release flow:
# update CHANGELOG.md, then:
make release-check
git tag vX.Y.Z && git push origin main --tags
make install
License
MIT