
abcop
io.github.adrianov由 GitHub 账号 adrianov 发布v0.23.0更新于 Oct 24, 2026
ABC complexity gate for AI-written code with an MCP inspection tool.
概览
abcop 是面向 AI 生成代码的 ABC 复杂度检查工具,通过一个 MCP 工具 abcop_inspection 让助手在改代码时即时检查复杂度与无用局部变量。
- 可以做什么
- 分析复杂度与无用局部变量:对项目路径或内联源码调用 abcop_inspection,返回精简的问题 JSON,含规则、行、列、消息,ABC 规则另含 score 与 vector。
- 把关函数与模块规模:标记超过 ABC 上限(默认 17)的函数和超过模块上限(默认 120)的模块,只报告相对 HEAD 上升的分数。
- 发现未用局部变量:报告编辑过的函数中只写一次读一次、或写入后从未读取的局部变量。
- 覆盖多种语言:Ruby、Rust、Python、Go、PHP、Java、C#、Dart、JavaScript、TypeScript、C、C++、Objective-C、Swift、Solidity、Zig 与 Haskell,以及模板中的内嵌 JS,均由单一二进制完成。
- 适用场景
- 适合助手编写或重构代码时,希望在同一轮对话内得到复杂度反馈,而不是等到之后的 CI 才发现问题。也适合希望对函数与模块 ABC 规模设置可维护性门槛、并获得提取方法或拆分模块提示的团队。
- 运行要求
- 以本地 stdio 进程运行,需用 --mcp 参数启动;必须先安装 abcop 二进制(Homebrew、cargo install 或发布包)。未声明任何账号、API 密钥或环境变量。默认与 HEAD 比较需要 git 仓库,调用工具时应显式传入项目路径。
安装
在 SourceWeft 中
- 打开 控制台中的 abcop,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
abcop
A must-have gate for AI-written code. Agents ship faster than humans can re-read; abcop keeps that code understandable by gating function and module ABC complexity so every unit fits a human head and an LLM context window. Diagnostics are also a hook for automated refactoring — extract a method, split a module — so CI rejects bad growth and points agents at concrete maintainability fixes.
One self-contained binary across Ruby, Rust, Python, Go, PHP, Java, C#, Dart, JavaScript, TypeScript, C, C++, Objective-C, Swift, Solidity, Zig and Haskell — no runtimes, no plugins, no per-language installs. Written in Rust for speed: one parse per file, one walk per metric, grammars compiled in; whole trees in milliseconds.
Install
macOS (.tar.gz from GitHub Releases; binary + man):
Ubuntu / Debian (.deb from GitHub Releases; amd64, Ubuntu 22.04+ / Debian bookworm+):
Example run
Why ABC, not line counts
Line counts lie. The ABC metric
(Jerry Fitzpatrick, C++ Report, June 1997) counts what does work —
assignments (A), branches (B), conditions (C) — as sqrt(A² + B² + C²).
Fitzpatrick defined both method and module scope; abcop gates both:
A sparse wrapper and a dense god-object can share a line count; ABC separates them. Complexity is the gate — never a line budget. UsedOnce / NeverUsed are secondary.
Built for AI workflows
- Understandable by construction. AbcSize 17 and ModuleAbcSize 120 keep every new unit inside a human head and an LLM context window. An existing unit may stay over that ceiling when the edit does not raise its score. Models edit small units reliably; when something breaks, the blast radius is tiny.
- Refactoring hook. Exit code
1plus stable JSON/JSONL diagnostics (rule,score,vector,message) feed agents and scripts: split oversized modules, extract hot methods. Each finding is an actionable maintainability step, not a style nit. - Fast enough for every push. Sub-second whole-tree scans — including code an agent will never re-read tomorrow.
- Signal only. No formatting or style cops. Vendored, generated and
test trees are skipped by default. Knobs:
--max-abcand--max-module-abc.--fulland--everythingreport every hit, not only the current edit. - Prefer MCP with LLMs.
abcop --mcpis the best way to use abcop from an agent: the model gets offenses as soon as it writes, so it can fix complexity and dead locals in the same turn and ship effective code right away — not after a later CLI/CI pass. Official RustrmcpSDK; toolabcop_inspection. Listed on the MCP Registry asio.github.adrianov/abcop(crates.io package + each GitHubv*tag).
Inspired by RuboCop (Ruby AbcSize
parity and # rubocop:disable directives) and
lizard (one tool, many languages).
Ruby method counting matches RuboCop 1.89 byte-for-byte
(scripts/compare_parity.py). A block outside a method (match do,
before do, a class-level each) is its own unit; each / map /
select still roll into the block that contains them.
Advantages
- ~850k–940k LOC/s per core (Apple M1 Pro). RuboCop's lib tree
(943 files, 110k LOC): 0.13 s — ~39× faster than
rubocop --only Metrics/AbcSize(cache off), ~140× a full rubocop run. - One binary, zero deps — grammars and an embedded result cache
(
cache.redb) compiled in; works on clean CI images with no language toolchains. - Deterministic — same findings every run; text / JSON / JSONL stream
as files finish;
--sort-by-scorebuffers for worst-first emit.
Usage
Exit codes: 0 clean, 1 findings, 2 usage error.
JSON diagnostics include file, line, column, severity, rule,
message, plus score / vector for ABC rules:
Scope selection
Named paths — those targets only. Findings still follow the edit filter below.
Omitted — narrowest useful scope, announced on stderr:
- uncommitted work vs
HEADif the tree is dirty - else current MR (
--mrforces this) - else the tree (outside a repo)
Default walks prune test/fixture trees, vendored/build output
(vendor/, node_modules/, target/, …), db/migrate/, route tables
(config/routes.rb, config/routes/*.rb), and generated names
(*.min.js, *_pb.go, …). Name a path explicitly to scan it anyway.
Rails schema dumps (db/schema.rb, db/*_schema.rb, db/schema_*.rb)
are never scanned, even when named.
Third-party, route-table, and fixture paths are never scoped review
surface — a diff through vendor/ or tests/fixtures/ does not make
that material owned code.
On a dirty tree the bare default is uncommitted-only; --mr takes the
full branch union. Commits straight to main use a 36-hour window when no
branch base applies. --uncommitted fails outside a repository instead
of silently widening.
What a normal scan reports
Every scan except --full and --everything compares the working tree
to HEAD:
- AbcSize reports a method over
--max-abconly when its score is strictly higher than the same method inHEAD(same name, source order). A score that stayed the same or fell stays quiet, including a legacy method that was already over the ceiling. A method that exists only in the working tree counts as an increase. The message asks to return to the previous score when that score was already over the ceiling (rose from 20 to 21 -- back to 20 or below). WhenHEADwas under the ceiling, the target is the ceiling (rose from 16.28 to 21.28 -- back to 17 or below). - UsedOnce / NeverUsed report only inside a function whose text
changed against
HEAD. A local in a function the edit did not touch stays quiet. Locals outside any function still report. - ModuleAbcSize reports a module over
--max-module-abconly when its whole-file score is strictly higher than that file inHEAD. A score that stayed the same or fell stays quiet, including a legacy module already over the ceiling. A file that does not exist inHEADis held to the ceiling. The message asks to return to the previous score when that score was already over the ceiling (rose from 200 to 210 -- back to 200 or below). WhenHEADwas under the ceiling, the target is the ceiling. - No
HEADblob (not a git checkout, or an untracked file) reports every method over the ceiling, every local, and every module over the ceiling.
--uncommitted and --mr also drop function and local findings on lines
the diff did not touch.
Whole-tree report
--full and --everything report every method over --max-abc, every
local, and every production module over --max-module-abc. ModuleAbcSize
still exempts test trees on those runs. --full keeps the default skips.
--everything lifts gitignore, hidden directories, and vendored/generated/test
pruning. ignore in the user config still applies to both.
User config
One file holds user options. It is $XDG_CONFIG_HOME/abcop when that
variable is set, otherwise ~/.config/abcop. $ABCOP_CONFIG replaces
the path. Nothing is written into the project.
ignore is a gitignore pattern, one option per line, applied in every
project relative to that project's root. A directory pattern covers
everything inside it. Naming the path, --full, and --everything do
not bring a match back. An MCP inspection of a matched path is empty.
Directives
Everywhere except Rust, RuboCop-style # / // suppressions work
(trailing and block; bare Metrics allowed). rubocop:disable-next is
ignored, matching rubocop.
MCP (Model Context Protocol)
Preferred for LLM / agent workflows. Wire abcop as an MCP server so the
model can call abcop_inspection while it edits: feedback arrives in the
same turn, the agent corrects soon, and it writes maintainable code on the
first pass instead of discovering ABC / UsedOnce / NeverUsed only in CI.
abcop --mcp runs a long-lived MCP server on stdio — same idea as
RuboCop’s MCP
and rrubocop, with no Ruby mcp
gem. Tool:
- MCP Registry name:
mcp-name: io.github.adrianov/abcop
Metadata lives in server.json, which is part of the
Cargo package on crates.io. Each GitHub
v* release tag publishes that listing to the
MCP Registry (after the
crates.io upload).
Example client config (Cursor / VS Code / Windsurf):
Claude Code:
Intended for MCP clients, not interactive use.
Caching
Content-addressed cache under $XDG_CACHE_HOME/abcop (or ~/.cache/abcop;
override with ABCOP_CACHE_DIR). Warm reruns ~5× faster. Keys cover
contents, version, rule revision, threshold, checks and path — no
cross-project collisions. Auto-pruned to 20 000 entries; --no-cache
disables. Nothing is written inside the project.
Supported languages
Seventeen languages plus embedded JS in HTML/templates, four rules each, one CI gate.
Named declarations are measured units; anonymous function-likes roll into
the enclosing unit; nested units never double-count. C-family: file-scope
globals are out of single-file reach; loop-head locals are protocol;
field writes also read the object; export-macro class forms
(class UTIL_EXPORT Foo) are skipped for variable rules.
Benchmarks
Apple M1 Pro, warm cache:
¹ --cache false — rubocop's own cache otherwise makes repeats look free.
Development
Shared engine: src/scope_model/ (backend, walk, eval); language
collectors sit beside each backend (clike/, sollang/, …). Probe
grammar nodes with abcop --dump-tree FILE. Parity:
scripts/compare_parity.py.
License
GNU GPL v3 or later (SPDX: GPL-3.0-or-later). See LICENSE.
Copyright © 2026 Peter Adrianov. All rights reserved.
来源:README.md,提交 0f8afd1
工具
0版本历史
2- v0.23.0最新Oct 23, 2026
- v0.19.1Sep 16, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分