{"slug": "tkmd-a-local-cli-task-manager-and-mcp-server-with-ai-agent-review-gates", "title": "Tkmd – A local CLI task manager and MCP server with AI agent review gates`", "summary": "A local task manager called tkmd, a single Rust binary distributed as a CLI (tk/tkmd) and a stdio MCP server, adds review gates that block AI coding agents such as Claude Code, Codex, Gemini and OpenCode from marking tasks done until they pass automated shell verification (eval) and a human signs off via pending-close. tkmd stores each task as a Markdown card with YAML frontmatter in tasks/tk-XXX-*.md and uses Critical Path Method and Design Structure Matrix algorithms to compute early start, early finish and schedule buffers and to surface circular deadlocks, with zero network requests and zero telemetry. The tool supports an Obsidian Kanban mode syncing to bases/tasks.base and a standalone CLI mode, and computes Little's Law, MTTC and TPM90 in Rust from a local .jsonl event log that can optionally be queried with DuckDB.", "body_md": "**Deterministic Program Engine for Developers and AI Agents**\n\n*Local Markdown cards • Mathematical CPM & DSM • Universal Stdio MCP*\n\n`tkmd` (CLI: `tk` / `tkmd`) is a deterministic program engine and multi-agent governance harness.\n\nIt stores every task as a plain Markdown card (`.md`) with YAML frontmatter in `tasks/tk-XXX-*.md`. It uses mathematical graph algorithms (Critical Path Method and Design Structure Matrices) to schedule work, calculate schedule buffers, and surface circular deadlocks.\n\nWhen you pair with AI coding agents (Claude Code, Codex, Gemini, OpenCode), `tkmd` prevents agents from falsely claiming work is finished. Agents must pass automated shell verification gates (`eval`) and submit work for human sign-off (` pending-close`) before a task can transition to `done`.\n\n- **100% Local & Offline** : No cloud accounts, no subscriptions, and zero background daemons. Single Rust binary with POSIX advisory file locking.\n- **AI Agent Guardrails** : Subagents cannot skip straight to`done` . They must pass automated shell tests and submit work to`pending-close` . Humans sign off directly or instruct an agent as proxy.\n- **Mathematical Scheduling** : Calculates early start, early finish, schedule buffers, and the Critical Path (`tk dep --cpm` ) deterministically.\n- **Blocker & Loop Detection** : View dependency trees (`tk tree` ) and circular deadlocks (`tk dep --dsm` ) in terminal colors.\n- **One-Command Session Resume** : Reopen the exact AI terminal session attached to any task (`tk u <id>` ).\n- **Flexible Storage** : Manage repository-level tasks (`tk init -L` ) or central Obsidian Kanban boards (`bases/tasks.base` ).\nIt supports two first-class local setups:\n\n1. **Obsidian + CLI Mode (Recommended)** — Syncs 1:1 with an Obsidian`.base` Kanban board (`bases/tasks.base` ), updates`.obsidian/types.json` , and logs completed tasks under`## Task List` in your Daily Note.\n2. **Standalone CLI Mode** — Pure plain-text Markdown cards in a local directory (`~/.local/share/tkmd/tasks` or`~/tasks` ), opening directly in`$EDITOR` (`hx` ,`nvim` ,`micro` ,`vim` ) with zero Obsidian dependency.\n\n- **Zero Network** :`tkmd` makes zero network/HTTP requests and has zero telemetry beacons. No accounts, no cloud sync, no tracking.\n- **Plain-Text Data Ownership** : Every task is an open`.md` file; every event is an open`.jsonl` record on your local disk.\n- **Self-Contained Telemetry** :`tk st` computes Little's Law, MTTC, and TPM90 directly in Rust. DuckDB is**not required** to run`tkmd` , but because the event log is standard`.jsonl` , users can optionally run instant SQL queries with DuckDB (`duckdb -c \"SELECT * FROM 'tasks/.events.jsonl'\"` ).\n\n`tkmd` acts as a deterministic scheduling and governance harness for teams of AI subagents. It solves the three hardest problems in multi-agent execution: **deadlocks**, **uncoordinated parallel writes**, and **premature completion claims**.\n\n```\nflowchart TD\n    subgraph Phase1[\"1. Autonomous Planning & Decomp\"]\n        Lead[\"Lead Architect / Human\"] -->|\"Decomposes spec\"| T1[\"Task 1: Core API\\n(Status: ready)\"]\n        Lead -->|\"Declares dependency\"| T2[\"Task 2: Frontend\\n(Status: blocked by Task 1)\"]\n        T1 -.->|\"Mathematical CPM\\n(tk dep --cpm)\"| Critical[\"Critical Path: Task 1 → Task 2\\nZero Buffer\"]\n    end\n\n    subgraph Phase2[\"2. Guarded Subagent Execution\"]\n        T1 -->|\"Claimed (tk c 1)\"| Agent1[\"Backend Subagent\\n(Attaches session ID)\"]\n        Agent1 -->|\"Shell eval passes ✅\"| Gate[\"Review Gate: pending-close\\n(tk r 1)\"]\n        Gate -->|\"Human Sign-Off (tk d 1)\"| Done[\"Task 1: done\"]\n    end\n\n    subgraph Phase3[\"3. Automatic Blocker Cascade\"]\n        Done ==>|\"Auto-unblocks\"| T2Ready[\"Task 2: promoted to ready\"]\n        T2Ready -->|\"Claimed (tk c 2)\"| Agent2[\"Frontend Subagent\\n(Attaches session ID)\"]\n    end\n\n    style Critical fill:#1e293b,stroke:#ef4444,stroke-width:2px,color:#f87171\n    style Done fill:#1e293b,stroke:#10b981,stroke-width:2px,color:#4ade80\n    style Gate fill:#1e293b,stroke:#f59e0b,stroke-width:2px,color:#fbbf24\n```\n\n1. **Topological Planning (No Circular Loops)** :\nA lead architect agent decomposes an epic into tasks. Running`tk dep --dsm` runs cycle detection across the dependency matrix, catching circular deadlocks before coding starts.\n2. **Mathematical CPM Allocation** :`tk dep --cpm` computes early start (ES), late finish (LF), and schedule buffers. The orchestrator prioritizes subagents on zero-buffer Critical Path tasks.\n3. **Collision-Free Concurrent Execution** :\nMultiple subagents running concurrently across separate terminal panes or CLI processes claim independent tasks (`tk c <id>` ). POSIX advisory file locking prevents write collisions without a database server.\n4. **Automated Verification Gates (`eval`)** :\nSubagents running autonomously cannot skip`pending-close` . A subagent must run automated verification (`tk eval <id>` ) and submit work for review (`tk r <id>` ). Only human sign-off (entered directly or instructed as a proxy) marks a task`done` .\n5. **Cascade Unblocking & Session Resumption** :\nWhen human sign-off marks a blocker`done` (`tk d <id>` ),`tkmd` automatically promotes downstream blocked tasks to`ready` . If any subagent stalls,`tk u <id>` immediately resumes its conversation session.\n\n```\ncurl -fsSL https://raw.githubusercontent.com/ktreharrison/tkmd/main/install.sh | sh\n# Install directly from crates.io (or git):\ncargo install tkmd\n\n# Or build locally from cloned repository:\ncargo install --path .\n```\n\n`Cargo.toml` declares two binary targets: `tkmd` and `tk`. Running `cargo install tkmd` installs both binaries to `~/.cargo/bin/`:\n\n```\ntkmd --help\n# Or use the ergonomic 2-letter alias:\ntk --help\n```\n\nThe short command `tk` is also claimed by:\n\n1. **`wedow/ticket`** : A Git-backed markdown issue tracker that installs a binary named`tk` .\n2. **Grafana Tanka (`grafana/tanka`)** : The Kubernetes Jsonnet configuration tool whose official Homebrew package installs`/opt/homebrew/bin/tk` .\n\nTo eliminate silent namespace collisions and PATH clobbering, the crate and primary binary is named **`tkmd`**, with **` tk`** provided as a first-class co-installed binary. Every command, flag, and MCP capability functions identically under both `tkmd` and `tk`. If your workstation already has Grafana Tanka or `wedow/ticket` installed, you can invoke `tkmd` directly or set a customized shell alias (`alias tkm=\"tkmd\"`).\n\n`tkmd` generates native completion scripts for Zsh, Bash, Fish, PowerShell, and Elvish. In Zsh, a single script enables tab-completion for both `tkmd` and `tk`:\n\n```\n# Zsh (add to ~/.zshrc for instant completion):\neval \"$(tkmd completions zsh)\"\n\n# Or persist to your Zsh completion directory:\ntkmd completions zsh > ~/.zfunc/_tkmd\n\n# Bash:\nsource <(tkmd completions bash)\n\n# Fish:\ntkmd completions fish > ~/.config/fish/completions/tkmd.fish\n```\n\nYou can run the interactive setup wizard at any time:\n\n```\ntk init\n```\n\nOr initialize non-interactively with flags:\n\n```\ntk init --obsidian --path ~/Vault --base bases/tasks.base --daily journals/daily\n```\n\nWhat this configures automatically:\n\n- Creates `<vault>/tasks/` (e.g.`~/Vault/tasks/` ) for atomic Markdown task cards (`tk-001-*.md` ).\n- Creates `<vault>/bases/tasks.base` with 5 pre-configured Obsidian 1.14 Base views:\n  1. **Kanban Board** (grouped by`status` :`ready` ,`in-progress` ,`pending-close` ,`blocked` ,`done` )\n  2. **Pending Close (Sign-Off Queue)** (`status == \"pending-close\"` )\n  3. **Your Personal Queue** (`owner == \"<you>\"` )\n  4. **Agent Queues** (`owner != \"<you>\"` )\n  5. **Completed Tasks** (`status == \"done\"` )\n- Safely merges task property types (`id` ,`status` ,`priority` ,`owner` ,`project` ,`due` ,`dod` ,`eval` ,`eval_status` ) into`.obsidian/types.json` without overwriting your existing vault properties.\n- Writes `~/.config/tkmd/config.toml` so`tk o` opens`bases/tasks.base` directly in Obsidian.\n\n```\ntk init --cli --path ~/.local/share/tkmd\n```\n\nWhat this configures automatically:\n\n- Creates `~/.local/share/tkmd/tasks/` for Markdown task cards and`.events.jsonl` .\n- Disables Obsidian URI calls and Daily Note mutations (`mode = \"cli\"` ).\n- Routes `tk o` (`tk open` ) and`tk e <id>` (`tk edit` ) directly to your`$EDITOR` (defaults to Helix`hx` ).\n\n```\ntk init -L\n```\n\nWhat this configures automatically:\n\n- Writes `.tkmd.toml` in your current repository root.\n- Creates `./tasks/` and`./tasks/.events.jsonl` local to the project.\n- Automatically detected by `tk` commands in that directory or its subdirectories.\n- Retains instant access to the central global vault via `-G` or merged view via`-A` .\n\n`tkmd` seamlessly manages both local project-level backlogs and central global backlogs:\n\n| Flag | Scope | Description | \n|---|---|---|\n| *(default)* | Auto | Uses `./tasks` if inside a project with`.tkmd.toml` or`tasks/` ; otherwise uses global vault | \n| `-L, --local` | Local | Force operation strictly on the current repository's `./tasks` backlog | \n| `-G, --global` | Global | Force operation strictly on the global central vault ( `~/Documents/tasks` ) | \n| `-A, --all-scopes` | Merged | Aggregate local and global tasks across dashboards, CPM schedules, and telemetry | \n\nIn merged view (`tk -A`), task IDs display distinct scope indicators (` tk-001L` for local, `tk-001G` for global) without column drift. Mutative commands (`tk d`, `tk c`, `tk r`) target the exact card on disk regardless of active working directory.\n\n| Command | Shortcut | Action | \n|---|---|---|\n| `tk` | `tk` | Render the responsive terminal dashboard + `pending-close` review banner | \n| `tk watch` | `tk w` | Live auto-resizing dashboard (reflows on pane resize or file change) | \n| `tk review` | `tk r` | Dedicated sign-off dashboard displaying pending local and global tasks | \n| `tk review 1 -n \"All checks green\"` | `tk r 1` | Move task to `pending-close` (auto-runs`eval` gate) | \n| `tk done 1 -n \"Verified\"` | `tk d 1` | Sign off and close task ( `status: done` + Daily Note entry in Obsidian mode) | \n| `tk add p1 Fix auth +app @ken due:tomorrow` | `tk a ...` | Create a task card using `todo.txt` shorthand (`p0` /`p1` /`p2` ,`+project` ,`sid:<id>` ) | \n| `tk claim 1 --owner claude -s 8y9380573586` | `tk c 1` | Claim `tk-001` (`status: in-progress` ) and attach agent`session_id` | \n| `tk resume 1` | `tk u 1` | Resume the AI agent session attached to `tk-001` (`claude -r <id>` ,`codex resume <id>` , etc.) | \n| `tk eval 1` | `tk eval 1` | Execute the card's `eval` shell command and log`[PASS]` /`[FAIL]` | \n| `tk find [query]` /`tk find -i` | `tk f` | Fuzzy search tasks (inline table or interactive `fzf` picker +`bat` preview) | \n| `tk history [id]` | `tk h` | Event audit log from `tasks/.events.jsonl` with step duration deltas | \n| `tk stats` | `tk st` | Flow telemetry: Little's Law, MTTC, P50/P90/TPM90, agent split, yield | \n| `tk tree` | `tk tree` | Render dependency DAG tree for active tasks (also `tk dep tree` ) | \n| `tk dep [id] --needs [ids]` | `tk dep` | Dependencies: CPM table ( `--cpm` ), text summaries (`--short` ,`--long` ,`--summary` ), colored JSON (`--json` ), tree, DSM (`--dsm` ), Gantt (`--gantt` ), AON (`--aon` ) | \n| `tk archive [id]` | `tk archive` | Move completed tasks to `tasks/archive/` (preserves`.events.jsonl` DB) | \n| `tk prune [id] [-f]` | `tk prune` | Remove completed/archived cards from disk (preserves `.events.jsonl` DB) | \n| `tk set 1 -t \"Title\" -p p0` | `tk set 1` | Update title, priority, owner, due, DoD, or eval directly from CLI | \n| `tk edit 1` | `tk e 1` | Edit the Markdown card in `$EDITOR` (`hx` ) | \n| `tk open` /`tk open 1` | `tk o` /`tk o 1` | Open `bases/tasks.base` (or`tk-001` ) in Obsidian (or`$EDITOR` in CLI mode) | \n\n`tkmd mcp` runs a dual-framing JSON-RPC 2.0 MCP server over `stdio` (auto-detecting both newline-delimited JSON and `Content-Length` headers for universal compatibility across Claude Desktop, Codex, Gemini CLI, Cursor, Zed, OpenCode, and Pi).\n\nAdd this to your agent's MCP configuration:\n\n```\n{\n  \"mcpServers\": {\n    \"tkmd\": {\n      \"command\": \"tkmd\",\n      \"args\": [\"mcp\"]\n    }\n  }\n}\n```\n\n`tkmd` ships with a pre-configured agent skill in `skills/tkmd/SKILL.md` (and `skills/tkmd/agents/openai.yaml`).\n\nInstall it into your agent workspace:\n\n```\n# For Codex, Claude, Antigravity, OpenCode, Pi:\nmkdir -p ~/.agents/skills\ncp -r skills/tkmd ~/.agents/skills/\n```\n\nThis enforces the task governance harness across all your agents:\n\n- Automatic session registration (`-s <session_id>` ) for instant resumption (`tk u <id>` ).\n- Mandatory review gate: agents must submit completed tasks to `pending-close` (`tk r` ) instead of`done` .\n- Automated eval assertion passes before review submission (`tk eval` ).\n- DoD deliverable note links (`[[wikilinks]]` ).\n\n`tk` records every state transition, eval verification, and agent session in an append-only, newline-delimited JSON stream (`tasks/.events.jsonl`).\n\n`tk st` and `tk h` parse this file natively without any external database. However, because it is standard `.jsonl`, users with `duckdb` installed can run instant SQL analytics with zero setup or database importing:\n\n```\n# Recent event transitions\nduckdb -c \"SELECT timestamp, id, action, actor, from_status, to_status, eval_passed FROM read_json_auto('~/Documents/tasks/.events.jsonl') ORDER BY timestamp DESC;\"\n\n# Agent review yield\nduckdb -c \"SELECT actor, count(*) as reviews, count(CASE WHEN eval_passed THEN 1 END) as passed FROM read_json_auto('~/Documents/tasks/.events.jsonl') WHERE action = 'pending-close' GROUP BY actor;\"\n```\n\n`tkmd` is dual-licensed under:\n\n- **MIT License** ([LICENSE-MIT](https://github.com/ktreharrison/tkmd/blob/main/LICENSE-MIT) )\n- **Apache License, Version 2.0** ([LICENSE-APACHE](https://github.com/ktreharrison/tkmd/blob/main/LICENSE-APACHE) )\n\nYou may choose either license at your option. Copyright © 2026 Ken Harrison.", "url": "https://wpnews.pro/news/tkmd-a-local-cli-task-manager-and-mcp-server-with-ai-agent-review-gates", "canonical_source": "https://github.com/ktreharrison/tkmd", "published_at": "2026-10-18 22:27:30+00:00", "updated_at": "2026-10-18 22:48:37.941325+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-tools", "agent-protocols", "ai-safety"], "entities": ["tkmd", "Claude Code", "Codex", "Gemini", "OpenCode", "Obsidian", "DuckDB", "Rust"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/tkmd-a-local-cli-task-manager-and-mcp-server-with-ai-agent-review-gates", "markdown": "https://wpnews.pro/news/tkmd-a-local-cli-task-manager-and-mcp-server-with-ai-agent-review-gates.md", "text": "https://wpnews.pro/news/tkmd-a-local-cli-task-manager-and-mcp-server-with-ai-agent-review-gates.txt", "jsonld": "https://wpnews.pro/news/tkmd-a-local-cli-task-manager-and-mcp-server-with-ai-agent-review-gates.jsonld"}}