Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

crapkit

PYPI · CRAPKIT · SCANNED SEP 22

Twelve tools to inspect CRAP scores, find work, and check edited functions against their ceiling.

Available components

+15 this week 68 Trust /100
Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →

Supply Chain Security100
  • No malware found by supply-chain analysis.Pass
  • No known CVEs affecting this package version or its production dependencies.Pass
  • Runs setuptools.build_meta at install time, a recognised native-build step with no shell scripting around it. View diagnostics → Pass
  • 0 of 3 dependencies flagged as unhealthy. View diagnostics → Pass
Provenance & Transparency48
  • Source repository is publicly reachable at the declared URL. View diagnostics → Pass
  • Provenance check failed: no build-provenance attestation is published. See how to fix → View diagnostics → Fail
  • Clear OSI-approved license (MIT).Pass
  • Actively maintained (last published 0 days ago).Pass
  • Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability69
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 2325 tokens (~193/item across 12 items; 12 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management0
  • Stability check failed: the tool surface changed between 0.4.15 and 0.7.6: 9 tool removals, 0 breaking changes, 12 additions. See how to fix → Fail
Tool Coverage100
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 100% of tool parameters carry a description.Pass
  • Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety100
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • We read all 12 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
  • An AI judge read all 13 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities60
  • Spec-recency check failed: implements MCP spec 2025-06-18; the latest is 2026-07-28. See how to fix → Fail
Install

How do I install the crapkit MCP server?

crapkit runs locally as a PyPI package, launched with uvx crapkit. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

pypi · crapkit

# add to Claude Code
claude mcp add jeanfrancoisgagne-crapkit -- uvx crapkit
// .cursor/mcp.json
{
  "mcpServers": {
    "jeanfrancoisgagne-crapkit": {
      "command": "uvx",
      "args": [
        "crapkit"
      ]
    }
  }
}
// .vscode/mcp.json
{
  "servers": {
    "jeanfrancoisgagne-crapkit": {
      "command": "uvx",
      "args": [
        "crapkit"
      ]
    }
  }
}
# add to Codex CLI
codex mcp add jeanfrancoisgagne-crapkit -- uvx crapkit
// opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "jeanfrancoisgagne-crapkit": {
      "type": "local",
      "command": [
        "uvx",
        "crapkit"
      ],
      "enabled": true
    }
  }
}
# add to OpenClaw
openclaw mcp add jeanfrancoisgagne-crapkit --command uvx --arg crapkit
# ~/.hermes/config.yaml
mcp_servers:
  jeanfrancoisgagne-crapkit:
    command: "uvx"
    args: ["crapkit"]
// ~/.netclaw/config/netclaw.json
{
  "McpServers": {
    "jeanfrancoisgagne-crapkit": {
      "Transport": "stdio",
      "Command": "uvx",
      "Arguments": [
        "crapkit"
      ]
    }
  }
}
# add to Vellum
assistant mcp add jeanfrancoisgagne-crapkit -t stdio -c uvx -a crapkit
// mcp.json
{
  "mcpServers": {
    "jeanfrancoisgagne-crapkit": {
      "command": "uvx",
      "args": [
        "crapkit"
      ]
    }
  }
}
Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 22 Sept 26 +15
    • Malware scan: unverified → pass security
  • 21 Sept 26 −15
    • Malware scan: pass → unverified security
    • Package version: 0.7.5 → 0.7.6 functional
  • 17 Sept 26 +15
    • Malware scan: unverified → pass security
  • 16 Sept 26 0
    • Package version: 0.7.4 → 0.7.5 functional
  • 15 Sept 26 −15
    • Malware scan: pass → unverified security
    • Package version: 0.7.3 → 0.7.4 functional
  • 12 Sept 26 0
    • Stability: fail → unverified security
    • Tool safety: pass → unverified security
    • Capabilities: fail → unverified functional
    • Tool coverage: 100 → unverified functional
    • First check of Schema quality: unverified functional
    • Package version: 0.7.2 → 0.7.3 functional
  • 9 Sept 26 +15
    • Stability: fail → unverified security
    • Tool safety: pass → unverified security
    • Malware scan: unverified → pass security
    • Capabilities: fail → unverified functional
    • Tool coverage: 100 → unverified functional
    • First check of Schema quality: unverified functional
    • Package version: 0.7.0 → 0.7.2 functional
  • 8 Sept 26 −16
    • Malware scan: pass → unverified security
    • Package version: 0.6.0 → 0.7.0 functional
Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 22 Sept 2026 · Analysed pypi/crapkit@0.7.6

Provenance No attestation

The registry publishes no build provenance for this version, so there is nothing to verify.

Result No attestation
Ecosystem pypi

Background: How many MCP packages publish verified provenance →

Install scripts 1 script
Hook Tier Command
build_backend allowlisted setuptools.build_meta

Background: Why install scripts are a supply-chain risk →

Dependencies 3 packages
Packages resolved 3
Tree resolution Complete

Background: SBOMs and build attestations, explained →

MCP tools · 12 exposed · ~2,173 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
check_config ~137

Checks that crapkit.toml agrees with the repo: typo keys, empty scopes, missing lane cwds, runners that fail to start. Run it first when any tool answers strangely or the ranking misses a file, and list_runs when only the history is in question. It needs no run, probes each runner once, runs no lane, and any problem arrives with isError true. repo can be any directory under the checkout, and one with no crapkit.toml above it answers a pointer, never a parent's config.

NameTypeReqDescription
repostringpath to the scored repo's root (default: the repo the server was started in)
NameTypeReqDescription
analysis_versionintegerthe analysis semantics version; with the lizard version it stamps every ratchet mark, so a bump refuses old marks until the repo re-seeds
lanesarrayper declared lane
newest_runobject|nullthe newest run, or null when nothing has run
problemsarrayFAIL findings as sentences naming the fix; non-empty is exit 1 and the result carries isError true
resourcesobjecteffective resource policy; limits and estimates, not sampled utilization
schemaintegerpayload schema version, 1
storeobjectthe run store
versionsobjectthe tools behind every number
warningsarrayWARN findings: unmeasured directories, scopes with a lane but no scoped_tests template, artifacts written outside .crapkit, lanes without results_artifact; exit stays 0

No examples provided.

check_gate ~171

Checks whether an edited file clears the hook's commit gate: fresh ccn per changed function against its scope's ceiling less pardoned ratchet debt. Call it after an edit once get_function_brief states the rule. CLI verify gives the repo-wide verdict. It runs no tests, and a breach reads gate.ok false, not an error. path is repo-relative or absolute inside repo, outside or missing is a config error. A tracked file is judged on its diff from HEAD, an untracked one in full, an unchanged or unscoped one judges 0. repo may be any directory under the checkout.

NameTypeReqDescription
pathstringyesrepo-relative source file to judge as edited
repostringpath to the scored repo's root (default: the repo the server was started in)
NameTypeReqDescription
baseline_commitstringthat run's commit, full sha
baseline_runintegerid of the run whose coverage was reused
functionsarrayevery function in the file, rescored
gateobjectthe verdict block
notestringfixed reminder that coverage is the baseline run's and complexity the working tree's; crapkit verify gives the real verdict
schemaintegerpayload schema version, 1

No examples provided.

get_function_brief ~222

Returns one function's start-editing packet from the newest trusted run: scored row, uncovered lines and the refresh, test, gate and verify command lines, none of them run. Use it once a function is chosen. Skip it for picking what to fix, that is get_next_item, and for a score across runs, get_function_history. Every call shingles the repo for twins, seconds on a large corpus. name must live in path. name takes the long name, a bare identifier, a start line or NAME#2, exact match first. A miss lists the file's functions instead of erroring.

NameTypeReqDescription
namestringyesthe bare identifier (classify, or route for a Rust `route cmd : & Cmd`) or the whole long_name get_next_item printed (classify( score , late )); both resolve, exact match first
pathstringyesrepo-relative source file, forward slashes
repostringpath to the scored repo's root (default: the repo the server was started in)
NameTypeReqDescription
attemptsarrayevery claim ever taken on this function, oldest first; [] on a first attempt, and a row with closed null is a claim still open
churnobject|nullthe file's churn, or null when it had no commits in the window
commandsobjectthe rest of the loop as whole command lines for this file and scope; run them as given
commitstringthat run's commit, full sha
couplingarrayup to 5 change-coupling partners at support 5 and confidence 0.5, strongest first; empty when none qualify; list_coupled_files has the repo-wide list
duplication_twinsarrayup to 10 near-duplicate functions at similarity 0.8, best first; empty is normal; list_duplicate_functions has the repo-wide pairs
est_splitsinteger0 when ccn <= target, else ceil(ccn / target)
est_uncovered_pathsintegerround((1 - cov) x ccn)
file_functionsarrayevery scored function in the same file: where an extracted helper lands, and which names are taken
file_totalsobjectthe file rolled up
functionstringthe resolved lizard long name, whichever name form was asked with
gate_ruleobjectwhat check_gate will judge this edit by
handlestringshort name form: the bare identifier or (anonymous)#N, the same value get_next_item prints
laneobject|nullthe lane whose artifact produced cov and uncovered_lines, verbatim from the config; null when no lane covers the scope
notesobjectprose the config carries for whoever edits here
paramsarrayparameters in declaration order, so a test can call the function without opening the file
pathstringthe resolved file, repo-relative
ratchet_marknumber|nullthe committed ratchet mark, or null when the function carries none or the repo has no ratchet file
regrowthobjectdid this get fixed before
remedystringdecompose, split-lines, add-tests or ok: the branch the session takes; scored.remedy carries the same value
run_idintegerid of the run these numbers come from: the newest trusted run (a coverage run, or a verify run whose verdict passed)
schemaintegerpayload schema version, 1
scoredobjectthe whole scored row from the run
sourcestringthe function's own text, start to end inclusive, newlines intact: editable without reading the file
stalebooleantrue when the run's commit is not HEAD, so every number here describes an older tree; run commands.refresh first
targetintegerthis scope's effective ccn ceiling, the same value as gate_rule.ceiling
uncovered_linesarray|nullline numbers no test ran; [] when the span is fully covered; null when no artifact could answer, then uncovered_lines_note says why
uncovered_lines_notestringpresent only when uncovered_lines is null: the reason and the move (stale artifact, no test imports the file, coverage_optional scope)
versionsobjectwhat produced these numbers

No examples provided.

get_function_history ~257

Returns one function's ccn, coverage, crap and flag in every run that measured it, oldest first, plus its ratchet mark. Use it to tell improving from decaying or regrown, and get_function_brief instead to start an edit. history true spawns git log -L capped at 10 commits, and tests true is null unless the lane recorded contexts. name resolves off the newest run that scored path, so a substring such as "eval" fans out to one entry per long name matched, and repo may be any directory under the measured checkout.

NameTypeReqDescription
historybooleanalso list the commits that touched this function (git log -L), as commits
namestringyesthe bare identifier (classify, or route for a Rust `route cmd : & Cmd`) or the whole long_name get_next_item printed (classify( score , late )); both resolve, exact match first
pathstringyesrepo-relative source file, forward slashes
repostringpath to the scored repo's root (default: the repo the server was started in)
testsbooleanalso list the tests covering this function (coverage.py contexts), as tests
NameTypeReqDescription
functionsarraythe functions name resolved to, in store order
namestringthe name argument as given
pathstringthe file asked about
schemaintegerpayload schema version, 1

No examples provided.

get_next_item ~220

Returns the next function to fix as a work packet, the newest trusted run's worst row by crap. Use it to start a fix, list_worklist to survey the same run by risk, and get_function_brief once a function is chosen. It runs no tests, and empty true means the queue is spent, not the work, so read reasons. Filters cut before top counts: top 3 with exclude ["tests/"] returns the three worst rows outside tests, and an unknown scope name is a config error.

NameTypeReqDescription
excludearrayskip rows whose path or long function name contains any of these fragments (one --exclude each)
repostringpath to the scored repo's root (default: the repo the server was started in)
scopearrayrestrict the ranking to these declared scopes (exact [[scope]] names from crapkit.toml, one --scope each)
topintegerreturn the next N packets as items instead of one item (N >= 1, default 1)
NameTypeReqDescription
commitstringthat run's commit, full sha
emptybooleantrue when the queue has nothing to hand out; then reasons is present and item and items are absent
itemobjectthe one packet, present when empty is false and top is absent or 1
itemsarrayup to top packets in crap-descending order, present when empty is false and top is above 1
reasonsobjectwhy the queue is empty, present only when empty is true; the stop condition is empty true with skipped_claimed and no_lane_over_target both 0 or absent
run_idintegerid of the run these numbers come from: the newest trusted run (a coverage run, or a verify run whose verdict passed)
schemaintegerpayload schema version, 1
skipped_claimedintegerrows another session's claim hid; present only when non-zero, and list_claims names the holders
skipped_no_laneintegerrows above the floor that no lane measures, kept out of the ranking because their cov 0 is a tooling gap, not a testing gap
stalebooleantrue when the run's commit is not HEAD, so cov, crap and uncovered_lines describe an older tree; crapkit coverage --reuse-unchanged (get_function_brief's commands.refresh) clears it

No examples provided.

get_ratchet_report ~135

Reports the ratchet debt burn-down: open marks with their age, repayments and policy findings. Use it to judge whether marked debt is repaid or piling up, and get_function_history for one function's mark. It reads the marks file and its git log only, ages count back from the newest commit touching that file, never the clock, and no marks file means zeros. repo can be any directory under a measured checkout, and an unmeasured one answers isError true with the setup pointer.

NameTypeReqDescription
repostringpath to the scored repo's root (default: the repo the server was started in)
NameTypeReqDescription
anchor_tsintegerunix seconds of the newest commit that touched the ratchet file; every age and window counts back from here, never from the wall clock; 0 with no ratchet history
dropped_last_30dintegermarks repaid in the 30 days before anchor_ts
dropped_last_90dintegermarks repaid in the 90 days before anchor_ts
dropped_totalintegermarks repaid over the whole committed history
oldestarrayup to 20 open marks, oldest first
openintegermarks open on disk, working tree included: an uncommitted seed counts
policy_violationsarray|nullnull when no debt policy is configured, [] when the policy ran clean, else the findings as sentences
schemaintegerpayload schema version, 1
uncommittedintegermarks the working tree and the newest committed ratchet file disagree on: added, repaid or tightened but not committed

No examples provided.

get_trend ~145

Returns per-run totals for every trusted run, oldest first, with a grade per scope. Use it for the whole repo's trajectory. Use get_function_history for one function and get_ratchet_report for marked debt. It runs no lane and spawns no git. The first call on a large store sums every run into a rollup cache and takes seconds. Later calls read the cache back. repo may be any directory under a checkout where crapkit init and crapkit coverage have run. An unmeasured one answers isError true with the setup pointer.

NameTypeReqDescription
repostringpath to the scored repo's root (default: the repo the server was started in)
NameTypeReqDescription
runsarrayone row per trusted run, oldest first
schemaintegerpayload schema version, 1
targetintegerthe [crapkit] target: the default ccn ceiling every scope inherits unless it sets its own

No examples provided.

list_claims ~152

Lists open claims on queue items, oldest first. Use it when get_next_item answers empty or skipped_claimed above 0, and use get_function_brief to see one function's own attempts. No tool here writes a claim: the CLI releases a stale one with crapkit claims release PATH NAME, and verify closes one at the ceiling. repo may be any directory under the checkout, since the server walks up to the nearest crapkit.toml. No crapkit.toml above it answers an init pointer, and a checkout never scored answers a coverage pointer, both as isError true.

NameTypeReqDescription
repostringpath to the scored repo's root (default: the repo the server was started in)
NameTypeReqDescription
claimsarrayopen claims, oldest first
openintegernumber of open claims
schemaintegerpayload schema version, 1

No examples provided.

list_coupled_files ~203

Lists file pairs that keep landing in the same commits over the churn window, strongest first, at most 50. Use it before editing a file to learn what an edit drags along. Use list_duplicate_functions for copied code rather than co-change. It reads git log once per call, not the scored run. An empty list means no pair cleared both thresholds, not a missing run. A pair must clear both thresholds: min_support 5 needs five shared commits, min_confidence 0.5 means the rarer file moved with its partner half the time. repo defaults to the server's own root.

NameTypeReqDescription
min_confidencenumberminimum P(pair changes together), 0 to 1 (default 0.5)
min_supportintegerminimum shared commits before a pair counts (default 5)
repostringpath to the scored repo's root (default: the repo the server was started in)
NameTypeReqDescription
pairsarraypairs clearing both thresholds, ordered by support x confidence descending, at most 50
schemaintegerpayload schema version, 1
window_monthsintegermonths of git history the pairs were counted over (the config's churn_window_months)

No examples provided.

list_duplicate_functions ~172

Lists near-duplicate function pairs in the newest run, at most 50. Use it before a refactor so twins are folded together, and get_function_brief for one function's twins. It shingles source on every call, seconds on a large repo, skips functions under 8 lines and same-file pairs, and an empty list means no pair reached similarity. similarity is shared shingles over the smaller function: 1.0 admits only a function found whole inside another, 0.8 four lines in five, and repo may be any directory under the checkout.

NameTypeReqDescription
repostringpath to the scored repo's root (default: the repo the server was started in)
similaritynumbercontainment threshold, shared over smaller, 0 to 1 (default 0.8)
NameTypeReqDescription
pairsarraypairs at or above similarity, best containment first, at most 50
run_idintegerthe newest run whose rows were compared
schemaintegerpayload schema version, 1

No examples provided.

list_runs ~154

Lists every run in the store, oldest first by id. Use it to date the store or to see which commit the other tools answer from. Use get_trend for per-run totals and get_function_history for one function's scores per run. It reads the store only and spawns no git. repo may be any directory under the checkout, because the server walks up to the nearest crapkit.toml, and a relative path resolves from the server's start directory. No crapkit.toml above it answers an init pointer, and a checkout never scored answers a coverage pointer, both as isError true.

NameTypeReqDescription
repostringpath to the scored repo's root (default: the repo the server was started in)
NameTypeReqDescription
runsarrayevery run in the store, oldest first
schemaintegerpayload schema version, 1

No examples provided.

list_worklist ~205

Lists the newest trusted run's whole risk ranking, every admitted function ordered by ccn times recency-weighted churn. Use it to survey a repo or split work by file, and get_next_item for the one crap-ranked packet to fix now. It runs no tests, keeps finished rows so it never empties, and reads the churn cache, not git. scope narrows before top caps, so scope ["core"] with top 20 returns the 20 riskiest in core, an unknown scope name is a config error, and repo may be any directory under the measured checkout.

NameTypeReqDescription
repostringpath to the scored repo's root (default: the repo the server was started in)
scopearrayrestrict the ranking to these declared scopes (exact [[scope]] names from crapkit.toml, one --scope each)
topintegercap the active list (default: the config's worklist_top, 50)
NameTypeReqDescription
activearraythe ranking: functions in files with churn in the window, risk descending, cut at top or worklist_top
active_totalintegeractive rows admitted before the cap: what top or worklist_top hid
churn_window_monthsintegermonths of git history the churn weights cover
commitstringthat run's commit, full sha
dormant_countintegerranked functions whose file had no commits in the window
dormant_toparraythe first 10 dormant functions, same shape as active: sleeping hazards kept out of the queue
floorintegerthe effective worklist_floor: rows under this ccn are listed only when over their ceiling or in a hot file
run_idintegerid of the run these numbers come from: the newest trusted run (a coverage run, or a verify run whose verdict passed)
schemaintegerpayload schema version, 1
stalebooleantrue when the run's commit is not HEAD, so cov, crap and uncovered_lines describe an older tree; crapkit coverage --reuse-unchanged (get_function_brief's commands.refresh) clears it

No examples provided.

Common questions

What is the crapkit MCP server?

crapkit is an MCP server listed in the public MCP registry as io.github.JeanFrancoisGagne/crapkit. Twelve tools to inspect CRAP scores, find work, and check edited functions against their ceiling. This page covers its PyPI package (crapkit).

Is the crapkit MCP server safe to use?

crapkit scores 68 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 22 September 2026. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the crapkit MCP server expose?

crapkit exposes 12 tools: get_next_item, list_worklist, list_runs, get_trend, get_function_brief, and 7 more. Their descriptions and schemas cost roughly 2,173 tokens of context every time the server is loaded.

Is the crapkit MCP server still maintained?

crapkit is still listed as active in the MCP registry. We last reached this channel on 22 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

What licence is the crapkit MCP server under?

crapkit declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.