Skip to main content
Glama

Charlie Work

A code-health tool that surfaces — and dignifies — the toil in your repo. An MCP server and a CLI and a CI gate.

The un-fun, load-bearing maintenance work everyone ignores until it bites: flaky tests, a TLS cert nine days from death, known-vulnerable dependencies, committed secrets, dead feature flags, TODO rot, scripts nobody owns. Charlie Work scans your repo with real parsers and real vulnerability data, ranks the findings by where your team actually bleeds time, and keeps a credit ledger so the invisible work finally shows up in standup.

Named after the episode where the gang realizes Charlie has been quietly holding Paddy's together the whole time.


THIS IS CHARLIE WORK. Nobody else will do it. That's why it's yours.

The jokes are a toggle, not a tax — pass mode="plain" (or set CHARLIE_VOICE=off) and every response is flavor-free, paste-into-a-ticket clean. CI and SARIF output are always plain.

Use it with any agent

Charlie is a stdio MCP server, so it drops into every MCP client — Claude Code, Codex, Cursor, VS Code, Claude Desktop, Windsurf, Zed, Gemini, Cline. The universal config is one block:

{
  "mcpServers": {
    "charlie-work": { "command": "uvx", "args": ["charlie-work-mcp"] }
  }
}

Add to Cursor

Don't hand-write it — let Charlie wire himself in:

uvx --from charlie-work-mcp charlie-work install --client cursor --write   # or: codex, claude-code, vscode, …

install knows each client's dialect and prints (or, for project-local clients, --writes) the exact config. Run install --client all to see every one.

Claude Code — claude mcp add --transport stdio charlie-work -- uvx charlie-work-mcp (or the block above in .mcp.json).

OpenAI Codex CLI — ~/.codex/config.toml:

[mcp_servers.charlie-work]
command = "uvx"
args = ["charlie-work-mcp"]

Cursor (.cursor/mcp.json), Claude Desktop (claude_desktop_config.json), Windsurf, Gemini CLI, Cline — the universal mcpServers block above.

VS Code — .vscode/mcp.json uses servers (not mcpServers):

{ "servers": { "charlie-work": { "type": "stdio", "command": "uvx", "args": ["charlie-work-mcp"] } } }

Zed — settings.json uses context_servers:

{ "context_servers": { "charlie-work": { "source": "custom", "command": "uvx", "args": ["charlie-work-mcp"] } } }

Teach every agent the drill — write a Charlie section into AGENTS.md (the cross-vendor rules file read by Codex, Cursor, Copilot, Gemini, Aider, Windsurf, Zed; Claude reads it too):

uvx --from charlie-work-mcp charlie-work init

As a CLI:

uvx --from charlie-work-mcp charlie-work scan     # the prioritized toil queue
charlie-work next                                 # the single next best fix, as a patch
charlie-work fix --top 5 | git apply              # patch the safe ones
charlie-work summary                              # toil budget + A–E grade

As a CI gate — fail a PR only when it introduces new high-severity toil ("Clean as You Code"):

- uses: Falcon305/charlie-work-mcp@master
  with:
    severity: "4"

As a scheduled watchman — some toil is time-based: a cert quietly ticks toward expiry, a TODO ages, a new CVE lands against a dep you already shipped. A nightly scan catches it before it pages you:

on:
  schedule: [{ cron: "0 7 * * *" }]
jobs:
  charlie:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: uvx --from charlie-work-mcp charlie-work sarif -o charlie.sarif
      - uses: github/codeql-action/upload-sarif@v3
        with: { sarif_file: charlie.sarif }

Until the PyPI release lands, replace uvx charlie-work-mcp with uvx --from git+https://github.com/Falcon305/charlie-work-mcp charlie-work-mcp (and likewise --from git+… for the CLI).

Related MCP server: skillhub

Trustworthy detection (not regex theater)

Every scanner is backed by a parser or an authoritative data source, and every finding carries a confidence tier (verified / high / heuristic) so CI gates on facts, not guesses.

Kind

How it's detected

vulnerable_dep

Lockfiles → OSV.dev (free, no key). Emits the CVE + the exact fixed version.

secret_leak

gitleaks-style provider regexes + Shannon-entropy gate + allowlists.

skipped_test / flaky_test / focused_test

Python AST and tree-sitter (JS/TS/Go) — never matches a string or a comment.

debug_leftover

AST calls: breakpoint(), pdb.set_trace, debugger, console.log.

dead_flag

Flags read but never set anywhere (the Pepe Silvia case), via AST literal extraction.

expiring_cert

Real X.509 parsing — .pem/.crt within 30 days of expiry, or already dead.

outdated_dep

Registry queries (PyPI/npm/crates/Go) → majors-behind.

todo_rot

TODO/FIXME/HACK in real comments, aged by git blame.

dependency_risk / unowned_runbook

Unpinned deps; operational scripts with no owner or CODEOWNERS.

The difference from regex, in one line: the Python string "pytest.mark.skip" and a # breakpoint() comment are not flagged. Only real code is.

Where your team actually bleeds — hotspots + a toil budget

Charlie ranks by churn × complexity (CodeScene-style): debt in a file edited 40× this quarter outranks the same debt in one untouched for years. charlie-work summary rolls it into a toil budget — total remediation minutes, a SQALE-style debt ratio, and an A–E grade. Google SRE says keep toil under 50%.

Not just a reporter — a doer

Charlie returns patches, not prose. charlie_next hands the agent the single highest-value item — where it is, why it matters (hotspot × severity), and a ready-to-apply unified diff when it's safely fixable:

$ charlie-work next
breakpoint() left in the code at pay.py:88 — severity 4, in a hotspot (2.1x). [auto-safe]
--- a/pay.py
+++ b/pay.py
@@ -85,7 +85,6 @@
-    breakpoint()

Every patch is a diff you (or CI) apply with git apply — the server never edits your files. Fixes are labelled auto-safe (mechanical: delete a breakpoint()) or needs-review (changes behaviour: un-skip a test, delete a stale TODO). Secrets, certs, and dependency bumps are surfaced for a human, never auto-patched.

Tool

What it does

charlie_next

The single next best fix, as a patch + why + follow-up actions.

charlie_fix

Unified-diff patches for a finding (or the top N), labelled auto-safe / needs-review.

charlie_scan_toil

Prioritized, paginated toil queue (structured output).

charlie_summary

Toil budget: score, debt ratio, A–E grade.

charlie_triage

Top-N action plan for an agent to work through.

charlie_explain

Why a finding is debt — evidence, hotspot, owner, fix.

charlie_trend

Records a snapshot and reports the delta over time.

charlie_did_it / charlie_ledger

The credit ledger — who cleared what, Champion of the Grease Trap.

Plus toil://queue + toil://item/{id} resources and four prompts (slash commands in any client): triage_toil, fix_next, pre_pr_check, charlie_rules. Things a dashboard can't do: "fix the next thing, run the tests, and credit me in the ledger."

Not a toy: token discipline + evals

  • The heavy work happens server-side. An agent finding this toil itself would read the whole repo into context; Charlie returns only a compact ranked queue. The raw files never enter the model's context.

  • A reproducible eval harness (evals/run.py) plants known toil and asserts the end state — recall and ranking — plus a token-cost measurement. There's also an optional model-graded tool-selection eval (evals/agentic.py).

$ uv run evals/run.py
kinds recalled : 9/9  (100% recall)   top item is the cert : True
naive: read whole repo : 1881 tokens
charlie work queue     : 1353 tokens  →  28% fewer tokens
RESULT: PASS

That 28% is on a tiny fixture; the gap widens fast — naive cost grows with the repo, the queue stays bounded to one page.

Configuration & suppression

Zero-config to start. Tune via [tool.charlie] in pyproject.toml (or charlie.toml):

[tool.charlie]
exclude = ["vendor/**"]
disable = ["charlie/todo-rot"]
min_confidence = "high"
[tool.charlie.per-file-ignores]
"tests/**" = ["secret_leak"]

Plus inline # charlie: ignore[rule], a .charlieignore, and a committed baseline (charlie-work baseline) so a fresh install starts at "0 new."

Development

uv sync --extra dev
uv run ruff check . && uv run mypy && uv run pytest -q
uv run python evals/run.py

CI runs ruff + mypy(typed) + pytest + evals across Python 3.11–3.13. Releases publish to PyPI via OIDC Trusted Publishing.

The gang (roadmap)

Each ships as its own standalone MCP server: The Implication (auth & dark-pattern auditor), Pepe Silvia (dead-code tracer), The D.E.N.N.I.S. System (rollout comms planner).

License

Code: MIT. The hero image is a still from It's Always Sunny in Philadelphia (© FX Networks), used for identification and commentary; it is not covered by the MIT license. An original vector rendition ships at assets/hero.svg.

Available Tools

7 tools
charlie_did_itCharlie: I did itA

Record that someone cleared a piece of toil, by its toil_id from a scan. Persists to a local ledger so the invisible work becomes visible. Rescans to resolve the item's title.

Inputs: who (required), toil_id (required), mode, note, +1 more. Returns: report, credits, entries, minutes, +1 more

charlie_explainCharlie: explain thisA
Read-only

Explain why a specific finding (by its toil id) is real debt, with evidence and a fix.

Inputs: finding_id (required), repo, online. Returns: item, found, report

charlie_ledgerCharlie: the ledgerA
Read-only

Report the credit ledger for standup or retro: who cleared what toil, the current Champion of the Grease Trap, and how much is still open.

Inputs: mode, repo. Returns: report, credits, entries, minutes, +1 more

charlie_scan_toilCharlie: scan for toilA
Read-only

Scan a repository for toil — the un-fun, load-bearing maintenance work everyone ignores: flaky, skipped, and focused tests; TODO/FIXME/HACK rot; expiring TLS certs; feature flags read but never set; unpinned dependencies; unowned operational scripts; and stray debug statements. Returns a prioritized queue. Set mode='plain' for a flavor-free report.

Inputs: mode, repo, kinds, limit, +4 more. Returns: count, items, total, offset, +3 more

charlie_summaryCharlie: the toil budgetB
Read-only

Report the repo's toil budget: total estimated remediation minutes, a debt ratio, an A-E maintainability grade, and counts by kind. Google SRE says keep toil under 50 percent.

Inputs: repo, online. Returns: loc, count, grade, counts, +4 more

charlie_trendCharlie: the trendC

Record a toil snapshot and report how the toil budget has moved since last time.

Inputs: repo, online. Returns: delta, report, current

charlie_triageCharlie: triageB
Read-only

Return the top-N highest-priority toil items as an action plan for an agent to work through.

Inputs: repo, top_n, online. Returns: items, report

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.6/5.0

    Scored across 7 tools

    Disambiguation5/5

    Each tool has a clearly distinct purpose: scanning for toil, explaining a finding, recording clearance, reporting the ledger, summarizing budget, tracking trends, and triaging priorities. No overlap.

    Naming Consistency5/5

    All tools follow a consistent 'charlie_verb' pattern with clear action words: scan_toil, explain, did_it, ledger, summary, trend, triage. The naming is predictable and informative.

    Tool Count5/5

    Seven tools cover the core workflow of toil management without excess. The count is well-scoped for the domain, providing essential functions without unnecessary duplication.

    Completeness4/5

    The tool set covers discovery, explanation, resolution recording, and reporting. Minor gaps might include a tool to manually add toil items or update details, but the surface is largely complete for typical toil management.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      D
      maintenance
      Enables AI agents to scan codebases for prioritized findings (TODO, FIXME, XXX) and retrieve results in table, JSON, or SARIF format via MCP.
      -
    • F
      license
      Not graded
      quality
      D
      maintenance
      Enables AI agents to scan codebases for TODO/FIXME/XXX patterns and get prioritized results over MCP, supporting CI gates and multiple output formats.
      -
    • A
      license
      Not graded
      quality
      D
      maintenance
      Scans codebases for TODOs, FIXMEs, code complexity, file stats, and dependencies, generating a health report with a letter grade. Zero configuration required.
      13 npm
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Scans repositories to produce a readiness score and actionable fixes across positioning, tryability, community, MCP, and monetization, plus generates launch assets and sponsor-tier ideas.
      7 npm
      MIT