원문 캡처 · github.com
원문 캡처 · github.com

tkmd는 작업을 로컬 마크다운 파일로 관리하고, 의존성 일정 계산과 AI 에이전트의 검증·사람 승인 절차를 제공하는 CLI 작업 관리 도구이자 MCP 서버다. Rust 단일 바이너리로 동작하며, Obsidian 연동 또는 독립 CLI 방식으로 사용할 수 있다.

기능과 작업 흐름

tkmd는 각 작업을 tasks/tk-XXX-*.md 경로의 YAML 프런트매터가 포함된 마크다운 카드로 저장한다. 임계 경로법(Critical Path Method, CPM)과 설계 구조 행렬(Design Structure Matrix, DSM)을 이용해 일정을 계산하고, 일정 여유와 순환 의존성으로 인한 교착 상태를 표시한다.

Claude Code, Codex, Gemini, OpenCode 같은 AI 코딩 에이전트와 함께 사용할 때는 에이전트가 작업을 곧바로 done으로 바꾸지 못하게 한다. 에이전트는 셸 검증 명령을 eval로 통과한 뒤 pending-close 상태로 검토를 요청해야 한다. 작업을 완료 처리하려면 사람이 직접 승인하거나 에이전트에 대리 승인을 지시해야 한다.

도구 제작자는 다음 기능을 제시한다.

  • 완전한 로컬·오프라인 실행: 클라우드 계정, 구독, 백그라운드 데몬 없이 사용한다. POSIX 권고 파일 잠금을 사용하는 Rust 단일 바이너리다.
  • 에이전트 작업 통제: 에이전트는 검증과 검토 요청을 거치지 않고 작업을 완료할 수 없다.
  • 일정 계산: tk dep --cpm으로 조기 시작·조기 종료 시점, 일정 여유, 임계 경로를 계산한다.
  • 차단 작업과 순환 의존성 확인: tk tree로 의존성 트리를, tk dep --dsm으로 순환 교착 상태를 터미널에서 확인한다.
  • 세션 재개: tk u <id>로 작업에 연결된 AI 터미널 세션을 다시 연다.
  • 여러 저장 방식: 저장소별 작업 목록이나 중앙 Obsidian 칸반 보드를 관리할 수 있다.

Obsidian 연동 방식은 bases/tasks.base 칸반 보드와 작업을 1:1로 동기화하고, .obsidian/types.json을 갱신하며, 완료한 작업을 데일리 노트의 ## Task List 아래에 기록한다. 독립 CLI 방식은 Obsidian 없이 ~/.local/share/tkmd/tasks 또는 ~/tasks에 일반 마크다운 카드를 저장하고 $EDITOR에서 연다. 기본 편집기로는 hx, nvim, micro, vim 등을 사용할 수 있다.

tkmd는 네트워크·HTTP 요청과 원격 측정 비콘을 보내지 않는다고 설명한다. 계정, 클라우드 동기화, 추적 기능도 없다고 밝힌다. 작업은 로컬의 .md 파일이고 이벤트는 .jsonl 기록이다. tk st는 Little's Law, MTTC, TPM90을 Rust에서 계산한다. 실행에 DuckDB가 필요하지는 않지만, 표준 JSONL 로그를 DuckDB로 선택적으로 조회할 수 있다.

여러 에이전트의 작업 관리

도구는 여러 AI 하위 에이전트가 작업할 때 순환 의존성, 조정되지 않은 동시 쓰기, 성급한 완료 처리를 다루도록 설계됐다고 제작자는 설명한다. 작업 흐름은 다음과 같다.

  • 계획과 분해: 리드 설계자나 사람이 큰 작업을 세부 작업으로 나누고 의존성을 지정한다. tk dep --dsm은 의존성 행렬에서 순환을 찾아 개발 시작 전 교착 상태를 확인한다.
  • 일정 배정: tk dep --cpm은 조기 시작(ES), 늦은 종료(LF), 일정 여유를 계산한다. 오케스트레이터는 여유가 없는 임계 경로 작업을 우선 배정한다.
  • 동시 실행: 여러 하위 에이전트가 별도 터미널 창이나 CLI 프로세스에서 서로 독립된 작업을 tk c <id>로 맡는다. POSIX 권고 파일 잠금으로 데이터베이스 서버 없이 쓰기 충돌을 방지한다.
  • 검증과 검토: 자율 실행하는 하위 에이전트도 pending-close 단계를 건너뛸 수 없다. tk eval <id>로 자동 검증을 실행하고 tk r <id>로 검토를 요청해야 한다. 사람의 승인이 있어야 작업이 done이 된다.
  • 차단 해제와 세션 재개: 사람이 차단 작업을 tk d <id>로 완료 처리하면, 후속 작업은 자동으로 ready 상태가 된다. 하위 에이전트가 멈추면 tk u <id>로 연결된 대화를 재개한다.

설치와 초기 설정

독립 바이너리는 Rust 없이 설치할 수 있다.

sh
curl -fsSL https://raw.githubusercontent.com/ktreharrison/tkmd/main/install.sh | sh

Rust의 Cargo로 설치하거나, 저장소를 복제한 뒤 로컬에서 빌드할 수도 있다.

sh
# Install directly from crates.io (or git):
cargo install tkmd

# Or build locally from cloned repository:
cargo install --path .

Cargo.toml은 tkmd와 tk 두 바이너리를 선언한다. cargo install tkmd는 두 바이너리를 모두 ~/.cargo/bin/에 설치한다.

sh
tkmd --help
# Or use the ergonomic 2-letter alias:
tk --help

tk 명령 이름은 다른 도구도 사용한다. wedow/ticket은 Git 기반 마크다운 이슈 추적기로 tk 바이너리를 설치하고, Grafana Tanka는 Kubernetes Jsonnet 설정 도구로 공식 Homebrew 패키지가 /opt/homebrew/bin/tk를 설치한다. 이름 충돌과 PATH 덮어쓰기를 피하기 위해 크레이트와 기본 바이너리 이름은 tkmd로 정하고, tk를 함께 설치한다. 모든 명령·플래그·MCP 기능은 두 이름에서 동일하게 동작한다. 이미 Grafana Tanka나 wedow/ticket이 설치돼 있다면 tkmd를 직접 실행하거나 다음과 같이 별칭을 설정할 수 있다.

sh
alias tkm="tkmd"

tkmd는 Zsh, Bash, Fish, PowerShell, Elvish용 셸 자동 완성 스크립트를 생성한다. Zsh에서는 다음 명령으로 tkmd와 tk 모두의 탭 완성을 설정한다.

sh
# Zsh (add to ~/.zshrc for instant completion):
eval "$(tkmd completions zsh)"

# Or persist to your Zsh completion directory:
tkmd completions zsh > ~/.zfunc/_tkmd

# Bash:
source <(tkmd completions bash)

# Fish:
tkmd completions fish > ~/.config/fish/completions/tkmd.fish

대화형 설정 마법사는 언제든 tk init으로 실행할 수 있다.

sh
tk init

명령행 플래그로 대화형 절차 없이 초기화하는 방법도 있다.

  • Obsidian 1.14와 CLI를 함께 쓰는 권장 설정:
sh
tk init --obsidian --path ~/Vault --base bases/tasks.base --daily journals/daily

이 설정은 <vault>/tasks/에 tk-001-*.md 같은 작업 카드를 만들고, <vault>/bases/tasks.base에 Obsidian 1.14용 뷰 5개를 구성한다. 뷰는 상태별 칸반 보드(ready, in-progress, pending-close, blocked, done), 검토 대기(status == "pending-close"), 개인 작업 대기열(owner == "<you>"), 에이전트 대기열(owner != "<you>"), 완료 작업(status == "done")이다. 기존 볼트 속성을 덮어쓰지 않고 .obsidian/types.json에 id, status, priority, owner, project, due, dod, eval, eval_status 속성 유형을 병합한다. 또한 ~/.config/tkmd/config.toml을 작성해 tk o가 bases/tasks.base를 Obsidian에서 열도록 설정한다.

  • Obsidian 없이 독립 CLI 방식으로 설정:
sh
tk init --cli --path ~/.local/share/tkmd

~/.local/share/tkmd/tasks/에 마크다운 작업 카드와 .events.jsonl을 만든다. Obsidian URI 호출과 데일리 노트 수정은 비활성화하며(mode = "cli"), tk o(tk open)와 tk e <id>(tk edit)는 $EDITOR에서 연다. 기본 편집기는 Helix hx다.

  • 현재 저장소의 프로젝트 작업 목록 설정:
sh
tk init -L

현재 저장소 루트에 .tkmd.toml을 쓰고 ./tasks/와 ./tasks/.events.jsonl을 만든다. 해당 디렉터리나 하위 디렉터리에서 실행하는 tk 명령은 이 설정을 자동으로 찾는다. -G로 중앙 전역 볼트에 접근하거나 -A로 병합된 뷰를 사용할 수 있다.

작업 범위와 명령

tkmd는 프로젝트별 작업 목록과 중앙 전역 작업 목록을 함께 관리한다. 범위를 지정하지 않으면 .tkmd.toml 또는 tasks/가 있는 프로젝트 안에서는 ./tasks를 사용하고, 그렇지 않으면 전역 볼트를 사용한다. -L, --local은 현재 저장소의 작업 목록만, -G, --global은 전역 중앙 볼트(~/Documents/tasks)만 대상으로 한다. -A, --all-scopes는 대시보드, CPM 일정, 원격 측정 정보에서 로컬과 전역 작업을 합쳐 보여준다.

병합 뷰(tk -A)에서는 로컬 작업 ID를 tk-001L, 전역 작업 ID를 tk-001G처럼 표시한다. 열 정렬은 유지된다. tk d, tk c, tk r 같은 변경 명령은 현재 작업 디렉터리와 관계없이 디스크의 정확한 작업 카드를 대상으로 한다.

자주 쓰는 명령과 별칭은 다음과 같다.

명령별칭동작
tktk반응형 터미널 대시보드와 pending-close 검토 배너를 표시한다.
tk watchtk w창 크기나 파일 변경에 맞춰 다시 배치되는 실시간 대시보드를 표시한다.
tk reviewtk r로컬·전역 검토 대기 작업의 승인 대시보드를 연다.
tk review 1 -n "All checks green"tk r 1작업을 pending-close로 옮기고 eval 검증을 자동 실행한다.
tk done 1 -n "Verified"tk d 1작업을 승인해 완료 처리한다. Obsidian 모드에서는 데일리 노트에도 기록한다.
tk add p1 Fix auth +app @ken due:tomorrowtk a ...todo.txt 형식의 축약 표기(p0/p1/p2, +project, sid:<id>)로 작업 카드를 만든다.
tk claim 1 --owner claude -s 8y9380573586tk c 1tk-001을 in-progress로 맡고 에이전트 session_id를 연결한다.
tk resume 1tk u 1tk-001에 연결된 에이전트 세션을 재개한다(예: claude -r <id>, codex resume <id>).
tk eval 1tk eval 1카드의 eval 셸 명령을 실행하고 [PASS] 또는 [FAIL]을 기록한다.
tk find [query] / tk find -itk f작업을 유사 검색한다. 인라인 표 또는 fzf 선택기와 bat 미리보기를 사용할 수 있다.
tk history [id]tk htasks/.events.jsonl의 이벤트 감사 로그와 단계별 소요 시간 차이를 표시한다.
tk statstk stLittle's Law, MTTC, P50/P90/TPM90, 에이전트 분할, 수율 등 흐름 정보를 표시한다.
tk treetk tree활성 작업의 의존성 DAG 트리를 표시한다. tk dep tree로도 실행할 수 있다.
tk dep [id] --needs [ids]tk dep의존성을 관리한다. --cpm 표, --short, --long, --summary 요약, --json, 트리, --dsm, --gantt, --aon을 지원한다.
tk archive [id]tk archive완료 작업을 tasks/archive/로 옮기며 .events.jsonl은 보존한다.
tk prune [id] [-f]tk prune디스크에서 완료·보관 작업 카드를 제거하며 .events.jsonl은 보존한다.
tk set 1 -t "Title" -p p0tk set 1CLI에서 제목, 우선순위, 담당자, 기한, DoD, eval을 변경한다.
tk edit 1tk e 1마크다운 카드를 $EDITOR에서 편집한다. 기본값은 hx다.
tk open / tk open 1tk o / tk o 1Obsidian 모드에서는 bases/tasks.base 또는 tk-001을 Obsidian에서 연다. CLI 모드에서는 $EDITOR에서 연다.

AI 에이전트 연결과 이벤트 기록

tkmd mcp 또는 tk mcp는 표준 입출력(stdio)을 통해 JSON-RPC 2.0 MCP 서버를 실행한다. 줄바꿈으로 구분된 JSON과 Content-Length 헤더 방식을 자동으로 감지한다. 제작자는 Claude Desktop, Codex, Gemini CLI, Cursor, Zed, OpenCode, Pi와 호환된다고 설명한다. 에이전트의 MCP 설정에 다음 내용을 추가한다.

json
{
 "mcpServers": {
 "tkmd": {
 "command": "tkmd",
 "args": ["mcp"]
 }
 }
}

저장소에는 skills/tkmd/SKILL.md와 skills/tkmd/agents/openai.yaml에 미리 설정된 에이전트 스킬도 포함된다. Codex, Claude, Antigravity, OpenCode, Pi의 에이전트 작업 공간에 설치하는 명령은 다음과 같다.

sh
# For Codex, Claude, Antigravity, OpenCode, Pi:
mkdir -p ~/.agents/skills
cp -r skills/tkmd ~/.agents/skills/

이 스킬은 모든 에이전트에 작업 관리 절차를 적용한다. 세션 ID(-s <session_id>)를 자동 등록해 tk u <id>로 재개하고, 에이전트가 작업을 done으로 처리하지 않고 pending-close 검토를 요청하도록 한다. 검토 제출 전에 tk eval을 실행하며, 완료 조건(DoD) 산출물 메모의 링크에는 [[wikilinks]]를 사용한다.

tk는 모든 상태 전환, eval 검증, 에이전트 세션을 추가 전용 줄바꿈 구분 JSON 스트림 tasks/.events.jsonl에 기록한다. tk st와 tk h는 외부 데이터베이스 없이 이 파일을 읽는다. DuckDB가 설치돼 있으면 데이터베이스로 가져오지 않고 SQL로 조회할 수도 있다.

sh
# Recent event transitions
duckdb -c "SELECT timestamp, id, action, actor, from_status, to_status, eval_passed FROM read_json_auto('~/Documents/tasks/.events.jsonl') ORDER BY timestamp DESC;"

# Agent review yield
duckdb -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;"

tkmd는 MIT 라이선스와 Apache License 2.0 중 하나를 선택해 사용할 수 있다. 저작권 표기는 © 2026 Ken Harrison다.