Spec Driven Development
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
作者による説明(英語の原文)
Twelve tools to inspect CRAP scores, find work, and check edited functions against their ceiling.
この3つを1つのスコアにまとめることはしません。意見、測定、人気はそれぞれ別のものだからです。
このサーバーのやさしい解説はまだ書いていません。以下はレジストリから読み取った事実です。
使っているAIアプリを選んで、設定をコピーしてください。
必要なもの
どのアプリを使っていますか?
上でアプリを選んでください。選んだアプリを覚えておくので、次からはボタンに「…にインストール」と表示されます。
Claude Desktop → Settings → Developer → Edit Config を開き、claude_desktop_config.json にこれを貼り付けます
{
"mcpServers": {
"crapkit": {
"command": "uvx",
"args": [
"crapkit",
"mcp"
]
}
}
}ターミナルでこれを実行します
claude mcp add crapkit -- uvx crapkit mcpプロジェクトの .cursor/mcp.json、または ~/.cursor/mcp.json に貼り付けます
{
"mcpServers": {
"crapkit": {
"command": "uvx",
"args": [
"crapkit",
"mcp"
]
}
}
}ブラウザがアプリを開いてよいか確認し、そのあとアプリが設定を表示して確認を求めます。キーの値は空欄のままなので、自分で入力してください。
プロジェクトの .vscode/mcp.json に貼り付けます
{
"servers": {
"crapkit": {
"type": "stdio",
"command": "uvx",
"args": [
"crapkit",
"mcp"
]
}
}
}ブラウザがアプリを開いてよいか確認し、そのあとアプリが設定を表示して確認を求めます。キーの値は空欄のままなので、自分で入力してください。
これはパソコンで動くサーバーですが、ChatGPTがつなげるのはインターネット上のサーバーだけです。ほかのアプリを選んでください。
選んだアプリは、この端末のCookieに保存されます。アカウントは不要です。
この設定は、作者のレジストリ登録情報から作成しています。READMEと違う場合は、READMEに従ってください。
パソコンで動くサーバーです。インストールすると、ツール一覧がAIアプリに表示されます。
誰でも見られる情報をチェックしており、コードは読んでいません。当てはまらない項目は数に入れていません。 · 2026年11月8日にチェック
レジストリ名は、リポジトリを所有するGitHubアカウント JeanFrancoisGagne で確認済みです
このリポジトリはまだGitHubから読み取っていません
このリポジトリはまだGitHubから読み取っていません
これはパソコンで動くため、インターネット上のエンドポイントはありません
パソコンで動き、代わりにローカルの設定を使います
パソコンで動くサーバーです。ツール一覧を読み取れるのは、インターネット上のエンドポイントがある場合だけです
レジストリでこのカテゴリにある有効なすべてのサーバーと比較しています。スターは、公開者がリポジトリの所有者である場合だけ数えます。
当てはまる基本チェック1項目のうち1項目に合格しました。コードは読んでいません。キーやトークンを追加する前に、サーバーがどんなアクセスを求めているかを確認し、必要な権限だけを持つキーを使ってください。
レジストリには必須のキーは載っていません。ただし、最初に使うときにサインインを求めるサーバーもあります。
あなたのパソコンで動きます。必要なときにAIアプリが起動し、データは作者のサーバーを通りません(サーバー自体がオンラインサービスを呼び出す場合を除きます)。
GitHubリポジトリの最終更新は–、最新バージョン(0.8.1)がレジストリに届いたのは37 日前です。
Claude Desktop、Claude Code、Cursor、VS CodeなどのMCP対応アプリで使えます。パソコンにPython (uv)も必要です。
同じカテゴリには:Spec Driven Development, Remote Desktop Commander, A1RO — Irish employment tools
同じカテゴリで、ほかの作者が作ったサーバー。スターの多い順。
カードの見方:★ GitHubスターi3つの柱:レビュー · チェック · 利用状況i更新=最新バージョンをレジストリに公開した日i
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
Irish temp worker cost, public holiday pay and holidays, and SafeHandle certificate checks.
作者のリポジトリから書かれたとおりにコピーしたものです。PopNx MCPは内容を確認・推奨していません。HTML、画像、スクリプトは取り除いています。リンクはこのサイトの外へ移動します。
crapkit scores every function in your repo on complexity times uncovered risk, ranks the worst ones by how often the file changes, and blocks commits that add more. It reads Python, TypeScript, TSX, JavaScript, Swift, Go, Rust, shell, PowerShell, C and C++, Objective-C, Vue, Java and Zig through lizard, and joins per-function branch coverage from the istanbul or coverage.py artifact your own test command already writes. JSON commands use sorted keys and a versioned schema for scripts, coding agents and the optional MCP server.
CRAP = ccn^2 * (1 - cov)^3 + ccn
The name is not ours: C.R.A.P. (Change Risk Anti-Patterns) was coined for crap4j by Alberto Savoia and Bob Evans in 2007.
ccn is the smaller of standard and modified cyclomatic complexity, both read off one lizard pass. cov is branch coverage inside the function's span; with no branches it falls back to statement coverage, and with no statements to invoked-or-not, so a half-executed straight-line function never reads as fully covered.
Above the ceiling, coverage cannot save you. Decompose. At the default ceiling of 6, a function at ccn 7 with 100% coverage still scores 7 and still fails the gate. The only move that clears it is splitting the function.
Why 6 and not 30. crap4j's conventional threshold of 30 is a CRAP score: it lets an untested ccn 5 through (25 + 5 = 30) and a fully covered ccn 30 too. crapkit's default is a complexity ceiling, because coverage can at best collapse CRAP to ccn, and a function you cannot cover past ccn 6 is one you decompose. Set target = 30 in crapkit.toml if you want the crap4j number. A repo with existing debt does not need to: ratchet seed marks today's over-ceiling functions at today's score, the gate then judges only the functions a change touches, and marks may only fall, so adoption never starts with a wall of red. Next to crap4py, radon, xenon, wily and SonarQube: docs/comparison.md.
crapkit scores git-tracked files only. Source you have not git added is invisible to it; init and verify name the first three such files they find.
| Start with | When |
|---|---|
| Install and the 60-second start | You want the first score in an existing Git repository. |
| Python or TypeScript quickstart | You want a worked example from setup through a passing verify. |
| Adoption | You need to choose scopes, wire tests or introduce a ratchet to existing debt. |
| Upgrading | You already have saved runs, ratchet marks or an installed plugin. |
| Subcommands and JSON/MCP reference | You are scripting commands or connecting a coding agent. |
pip install crapkit
cd your-repo crapkit init # write crapkit.toml and ignore measurement output crapkit doctor # check scopes, test commands and coverage dependencies crapkit coverage # runs the lane, joins coverage, stores a scored run crapkit worklist # the ranked risk map crapkit ratchet seed git add crapkit.toml crapkit-ratchet.tsv .gitignore git commit -m "adopt crapkit" crapkit verify # the first passing verdict
Not a Python repo? uvx crapkit init runs the same commands and adds nothing to your manifest: see A repo that is not Python. A Python repo skips uvx and installs crapkit as above, or with uv tool install or pipx install; that section says why. pip stops with externally-managed-environment? See When pip refuses.
coverage measures a commit, so a fresh git init repo needs its first commit before it. Until then it exits 4 and says so:
$ crapkit coverage
crapkit: the git repository at /repo has no commit yet: crapkit measures a commit, so make the first one (git add, then git commit) and run it again
init detects pytest, Vitest and Jest from the repository's own files. Review the generated config before running its commands. When detection leaves a commented lane, fill it in using the lane recipes. Commit the adoption files, then run crapkit verify to establish a passing verdict. Install the commit gate when the config and ratchet are ready. Each step prints the next one: init names coverage, coverage names worklist, worklist names ratchet seed, and ratchet seed names the commit and verify.
coverage scores, worklist ranks:
$ crapkit coverage
run 1 @ fae4db93108: 2 functions scored: 2 measured, 1 over ceiling 6, CRAP load 41.0, grade F -> next: crapkit worklist
$ crapkit worklist worklist @ fae4db93108 (run 1, floor ccn>=5, churn 12mo) - 1 of 1 active (worklist_top 50), 0 dormant risk 14.0 ccn 14 crap 38.5 cov 50% 1c/1a calc/grade.py:7 classify( score , attempts , late , bonus ) no crapkit-ratchet.tsv yet: seed marks each function over its ceiling at today's score, and from then on a mark may only fall -> next: crapkit ratchet seed
risk 14.0 is ccn times a churn weight of one: a one-commit repo has no spread of commits to weight, so each commit counts once and the ranking is complexity order until the history grows (Risk). crap 38.5 and cov 50% are the score and the coverage behind it.
ratchet seed signs today's debt at today's score. From then on marks only ever fall, so the repo can get better and never worse while you burn it down.
One thing stops most first runs: the coverage plugin. init writes a lane that shells out to your own test runner, and the runner needs its coverage package installed: pytest-cov for pytest, @vitest/coverage-v8 (pinned to your vitest major) for vitest. Without it the lane produces no artifact and coverage exits 5 quoting the runner's own error. A pytest lane also needs coverage.py 7.13.1 or newer, which writes the function start lines crapkit reads; an older one fails the lane at exit 5. For pytest, init probes the python its lane will run and prints the install command when pytest_cov is missing; pip install "crapkit[py]" pulls the plugin alongside crapkit when the two share a venv. On a Windows PATH holding only the py launcher it writes py, not a python3 the lane could never run, and when cmd.exe cannot start the interpreter at all (exit 9009, the Store alias) it names that instead of guessing at pytest-cov. A repo that pins no lockfile and carries its own .venv gets that venv's interpreter in the lane, when that interpreter can import pytest, rather than whichever python the shell answers with. The two quickstarts below walk a real repo end to end.
On Windows a lane command is read by cmd.exe, the shell that will run it, not by sh. Double quotes are the portable quoting. A single-quoted value is refused at config load with exit 3, because cmd.exe would hand pytest five words and the lane would write no artifact:
# the lane in crapkit.toml
command = "python -m pytest -m 'not live and not perf' --cov=calc --cov-branch --cov-report=json:.crapkit/cov/py.json"
$ crapkit doctor crapkit: lane 'py': positional argument 'live' narrows a full-suite coverage run; drop it, attach it to the flag it belongs to (-n8, --numprocesses=8), or set full_suite = false deliberately (cmd.exe does not treat ' as a quote: write the value in double quotes); a suite whose testpaths cannot be collected in one process needs one lane per testpath, each with full_suite = false and its own artifact
Write it -m "not live and not perf". Carets, && and | segments, redirections and empty quoted arguments all read the way the shell reads them, so a chained lane (cd tests && python -m pytest --cov ...) is checked one segment at a time. doctor reads a lane the same way, and FAILs one whose runner will not start.
pip install crapkit
That is the release on PyPI. For the unreleased tip of main, or from a local clone (run at the clone root):
pip install git+https://github.com/JeanFrancoisGagne/crapkit.git
pip install .
Commits on main between two releases carry the same version string, and pip keeps an installed crapkit whose version matches, so running the git line again after a new commit leaves the old code in place. This line replaces it with the tip:
pip install --force-reinstall --no-deps git+https://github.com/JeanFrancoisGagne/crapkit.git
pip install . in a clone rebuilds on every run and needs no flag.
Debian 12, Ubuntu 23.04 and later, Homebrew and uv mark the Python they install as theirs (PEP 668), and pip refuses to write into it with error: externally-managed-environment:
$ pip install crapkit
error: externally-managed-environment
Give crapkit an environment of its own. Either line installs it into one and puts a crapkit command in ~/.local/bin (%USERPROFILE%\.local\bin on Windows), the command the agent plugins start:
pipx install crapkit
uv tool install crapkit
When that directory is not on PATH yet, the installer says so and names the fix: pipx ensurepath, or uv tool update-shell. Open a new shell after either. The python on PATH does not hold this install, and the commit hook runs the crapkit command before it tries python, so it reaches either install as printed.
A Python repo can carry crapkit in its own venv instead, beside the test dependencies its lane runs:
python3 -m venv .venv
. .venv/bin/activate pip install "crapkit[py]"
The same from cmd.exe on Windows:
python -m venv .venv
.venv\Scripts\activate pip install "crapkit[py]"
--break-system-packages makes pip write into the system Python anyway, where the next OS package update can break crapkit or the OS's own tools. None of the routes above needs it.
crapkit is a command-line tool, never a dependency of the code it scores. A TypeScript, Go or Rust repo adds nothing to its own manifest. With uv on the machine, uvx fetches crapkit into a cache of its own and runs it:
$ uvx crapkit init
wrote crapkit.toml with 1 scope(s): src detected 1 lane(s) from this repo's own files: js - next: run uvx crapkit coverage added to .gitignore: .crapkit/
$ uvx crapkit coverage $ uvx crapkit worklist
uvx puts no crapkit on PATH, so every next step crapkit prints under uvx starts with uvx crapkit. The lane still runs your own test runner, so Vitest or Jest and its coverage package come from the repo's node_modules as t
冒頭だけを表示しています。続きはリポジトリで読めます