mcpField
H
honestcode

honestcode

本地服务
github.com/Fengrru开发工具06 天前更新

关于 honestcode

HonestCode 是一个本地 MCP 服务,用于依据代码库中的符号和 API 检查编码 Agent 编写的 Python 代码。它通过 AST 验证并返回可采取行动的证据,无需调用大模型或访问网络。

主要功能

  1. 01检测虚构 API 和错误调用
  2. 02依据代码库解析符号
  3. 03返回结构化问题与证据
  4. 04提供结构性类型检查
  5. 05防止重试造成外部副作用重复

适用场景

  1. 01在编码 Agent 继续工作前验证其代码
  2. 02查找项目中不存在的方法
  3. 03向 Agent 提供问题证据以便修复
  4. 04工具调用重试时避免重复执行副作用

MCP 相关

HonestCode 向 MCP 客户端提供 `scan_file`、`verify_file` 等代码验证工具。可选工具还包括项目索引、符号检查和结构性类型验证。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"fengrru-honestcode": {
"command": "uvx",
"args": [
"honestcode"
]
}
}
}
启动命令uvx honestcode

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypihonestcode0.5.1

工具

2

收录的工具列表 · 更新于 6 天前

参数类型必填说明
file_pathstring是

详细介绍

HonestCode

面向 AI 编码 Agent 的确定性验证层。

在 Agent 继续执行之前,捕获虚构的 API、未定义的符号、错误的调用以及其他代码幻觉。

HonestCode 虚构 API 演示

CI 许可证:MIT


问题

AI 编码 Agent 会产生幻觉。它们会虚构函数名、捏造库 API,并调用不存在的方法。

HonestCode 会将 Agent 刚刚编写的内容与其应当依据的代码仓库进行核对。

Agent
  ↓
writes code
  ↓
HonestCode
  ↓
evidence
  ↓
Agent fixes
  ↓
verified code

不调用大模型。不联网。纯 AST + 符号解析。


演示

要求 Agent “使用现有的 UserClient 添加身份验证”。 它生成了:

client.refresh_token()

实际项目中只有:

class UserClient:
    def refresh(self): ...
    def refresh_access_token(self): ...

HonestCode 会以确定性方式捕获问题:

✗ verification failed — 1 issue in app/login_broken.py

  [invented_api] app/login_broken.py:9
  `UserClient.refresh_token()` does not exist.
  did you mean: refresh_access_token()?
  available methods:
    - refresh()
    - refresh_access_token()
  confidence: deterministic · action: revise

亲自运行:

cd demos/invented-api
python run.py

为什么不直接使用 Ruff / Pyright?

HonestCode 并非替代品——它是一个验证层,用于回答一个具体问题:Agent 编写的代码是否确实来自这个代码仓库?

错误RuffPyrightHonestCode
语法错误✓✓✓
类型不匹配—✓仅结构检查
未定义符号✓✓✓
虚构的 API部分支持部分支持核心功能
错误的方法调用—部分支持核心功能
Agent 生成的 API 不匹配——核心功能

关键区别在于以代码仓库为依据。Ruff 检查文件。Pyright 检查调用的类型。HonestCode 检查该调用是否解析到 Agent 正在编辑的代码库中实际存在的符号。(HonestCode 不会进行完整的类型推断——其结构检查能够捕获参数数量不匹配、遍历 None 和调用常量等问题,但无法发现一般的类型错误。)

调用点会根据接收者类型的已知方式进行检查:注解(client: UserClient)、构造函数赋值(client = UserClient())、self/cls 以及内联构造函数(UserClient().refresh())都会被解析。由工厂函数生成的接收者(make_client().refresh())不会被判定——函数签名在表层模型中不包含返回类型,在这种情况下进行推测会以误报代替漏报。


安装

一行命令——无需克隆仓库,也无需虚拟环境:

claude mcp add honestcode -- uvx honestcode-mcp

uvx 会在首次使用时将服务下载到隔离环境中;如果尚未安装 uv,请先安装。从检出目录运行(用于修改代码,或如果你不想使用 uv):

git clone https://github.com/Fengrru/honestcode
cd honestcode
pip install -e .
claude mcp add honestcode -- honestcode-mcp

Cursor / VS Code / Claude Desktop: honestcode install 命令会探测这些客户端的配置文件,并为你注册服务:

honestcode install            # all detected clients
honestcode install --client cursor --dry-run   # preview without writing

需要 Python >= 3.10。100% 本地运行。


使用 Claude Code,30 秒完成设置

# Add HonestCode as an MCP server
claude mcp add honestcode -- honestcode-mcp

也可以手动将其添加到 Claude Code 配置中(macOS/Linux 上为 ~/.claude.json,Windows 上为 %USERPROFILE%\.claude.json):

{
  "mcpServers": {
    "honestcode": {
      "command": "honestcode-mcp",
      "args": []
    }
  }
}

重启 Claude Code。现在你可以使用两个验证工具:

  • scan_file(path) — 旧版工具,返回 issues 以及新的证据结构。
  • verify_file(path) — 面向 Agent 的工具,返回包含 evidence 的 status、findings,以及易于阅读的 text 摘要。

试着向 Claude 提示:

Add a login endpoint using the existing UserClient, then run verify_file on the
file you just wrote and fix anything it reports.

HonestCode 会根据文件路径自动发现项目根目录、为代码库建立索引,并返回有据可依的证据。

自动执行(无需规范提示词)

只有模型选择调用时,MCP 工具才会运行。若要确保无条件验证,请将 scripts/claude_hook.py 钩子接入 Claude Code 的 PostToolUse 事件——Agent 写入的每个 .py 文件都会经过验证,发现的问题会阻止编辑,并将证据直接反馈到对话中:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "python /absolute/path/to/honestcode/scripts/claude_hook.py"
          }
        ]
      }
    ]
  }
}

将其放入 ~/.claude/settings.json(适用于所有项目)或 .claude/settings.json(适用于单个项目)。钩子自身发生故障时绝不会阻止操作:输入无法读取、文件不是 Python 文件以及验证崩溃时,都会静默退出,因此绝不会变成阻止每次编辑的障碍。


实际示例

# auth/client.py
class UserClient:
    def refresh_access_token(self): ...

# auth/login.py
from auth.client import UserClient

def login(client: UserClient):
    client.refresh_token()  # invented API
>>> from honestcode.mcp.tools import verify_file
>>> verify_file("auth/login.py")
{
  "status": "fail",
  "file": "auth/login.py",
  "findings": [
    {
      "line": 7,
      "kind": "invented_api",
      "symbol": "refresh_token",
      "owner": "UserClient",
      "message": "`UserClient.refresh_token()` does not exist.",
      "evidence": {
        "available_methods": ["refresh", "refresh_access_token"],
        "did_you_mean": "refresh_access_token"
      },
      "confidence": "deterministic",
      "action": "revise"
    }
  ],
  "text": "✗ verification failed — 1 issue in auth/login.py\n  ..."
}

Agent 输出协议

verify_file 返回的是 Agent 可直接采取行动的证据,而不只是错误消息:

{
  "status": "fail",
  "file": "auth/client.py",
  "line": 42,
  "kind": "invented_api",
  "symbol": "refresh_token",
  "owner": "UserClient",
  "message": "UserClient.refresh_token() does not exist.",
  "evidence": {
    "available_methods": ["refresh", "refresh_access_token"]
  },
  "confidence": "deterministic",
  "action": "revise"
}

工作原理

  1. 自动索引项目(或复用缓存的符号索引)。
  2. 使用标准库 ast 模块解析目标文件。
  3. 将每个调用点解析为具体符号:
    • 根据注解、构造函数和导入推断接收者类型;
    • 根据仓库 AST 重建类的成员范围;
    • 当无法解析基类或类定义了 __getattr__ 时,将成员范围标记为未知。
  4. 生成问题发现结果,其中包含 kind、owner、evidence、confidence 和 action。

此流程具有确定性,且可审计。

范围与局限

在无法证明目标不存在时,验证器会保持静默——这是它的特性,但也意味着检测存在已知边界:

  • 不会判断装饰类是否使用了虚构成员。 任何类装饰器(包括 @dataclass)都可能添加或重写成员,因此不会报告这类对象上的虚构方法调用。未装饰的类会进行完整检查。
  • 不会检查标准库成员调用。 from typing import TypeVarr(虚构的导入)会被捕获,但 os.path.joinn()(对真实模块进行的虚构调用)不会——检查范围涵盖第三方成员和项目成员。
  • 不会判断工厂函数的接收者。 make_client().refresh() 会被跳过;注解、构造函数赋值、self/cls 和内联构造函数(UserClient().refresh())都会被解析。
  • undefined_symbol 的置信度为 confidence: high,而不是 deterministic。 只有成员范围声明(针对已完整枚举的类所作的虚构 API 判断)才能通过仓库证明;名称不存在的判断依赖语法绑定模型,因此置信度较低。同一作用域内类型会发生变化的变量会被视为未知,绝不会进行判断。
  • 图工具以最近一次索引的项目为准。 scan_file / verify_file 会逐个文件解析项目根目录(包括单体仓库中的子项目);find_dead_code、explore_call_graph、search_code 等工具则会操作最近一次传入 index_project 的项目。
  • check_api 会按需导入基础包——但仅限该包确实已安装(或属于标准库)的情况。直接放入工作区的文件绝不会被导入,因此 Agent 编写的代码无法通过此工具在服务端执行。

MCP 工具

默认情况下会公开 scan_file 和 verify_file。设置 HONESTCODE_TOOLS=all 可启用完整工具集,包括:

工具用途
scan_file扫描文件,查找虚构的 API、未定义的调用和错误的参数数量。
verify_file返回面向 Agent 的结构化证据协议。
index_project构建或复用项目符号索引。
load_project_deps从 requirements.txt / pyproject.toml 加载依赖 API。
check_symbol验证符号是否已定义。
check_api验证库 API 调用是否存在。
validate_types进行结构类型检查。

依赖清单(requirements.txt、pyproject.toml)会在首次扫描时自动声明,因此,即使依赖未安装在 MCP 服务的解释器中,其导入也会被视为可信,而不会报告为虚构内容。设置 HONESTCODE_AUTO_DEPS=0 可禁用此功能。

完整列表请参阅下方的旧版工具参考。


崩溃安全的副作用

verify_file 会在代码运行前检查代码。guards/ 则处理运行之后的情况:如果 Agent 重试工具调用,可能会重复扣款;没有任何持久化执行引擎能防止这种情况——Temporal 和 Restate 都保证编排过程的确定性重放,并将外部副作用的恰好一次执行留给应用程序处理。

from honestcode.guards import EffectStore, SideEffectGuard, durable_scope

guard = SideEffectGuard(session_id="run-42", store_path=".agent/effects.db")

outcome = guard.run(
    "charge",
    target="cus_123",
    payload={"cents": 4200},
    execute=lambda: charge_card("cus_123", 4200),
    approve_irreversible=True,
    scope=durable_scope("order-4711", "charge", "cus_123"),
)

outcome.executed     # False on the retry — a receipt, not a second charge
outcome.effect_id    # stable across a restart, because the key is on disk

关键在于 scope 的作用。传入它后,副作用的身份由作用域而非会话决定——这就是重试会被识别,而不是导致客户被重复扣款的区别,因为重启意味着新的会话 ID。不传入任何内容时,防护机制仍按会话限定。

默认策略是拒绝:无法识别的操作会被视为不可逆,而非幂等;不可逆副作用需要明确批准。如果运行在调用完成、记录尚未写入时终止,该副作用会保留为 executing,下一次尝试会报告结果未知,而不是自行推测——这正是阻止重试的机制。可通过 guard.recover(scope=durable_scope(...)) 恢复限定作用域的副作用,并通过 guard.effects(scope=...) / guard.summary(scope=...) 查看;记录存储在由作用域派生的命名空间下,因此重启后仍能找到。

对于框架,integrations/ 会将防护机制绑定到 pydantic-ai,在此场景下,已提交的副作用会替代工具结果,而不是重新运行工具。请参阅 honestcode/integrations/README.md。


基准测试

HonestCode 包含四套基准测试,它们会在每次向 main 推送或提交拉取请求时,在 CI 中自动运行:

Agent 准确率基准测试

benchmarks/agent_accuracy/ 是一个确定性的、无需 LLM 的基准测试,用于衡量 HonestCode 捕获常见 Agent 幻觉的能力(召回率)。

每项任务都是一个微型 Agent 会话:Agent 编写一个有问题的文件,HonestCode 对其进行验证,然后用修复后的文件替换该文件并再次验证。

cd benchmarks/agent_accuracy
python run.py

当前结果(6 项任务,确定性验证):

任务预期问题检测到问题文件修复后干净问题文件耗时(毫秒)修复后耗时(毫秒)
invented_methodinvented_api(UserClient.refresh_token)是是4.183.78
invented_module_attrinvented_api(Connection.query)是是4.193.95
undefined_importundefined_symbol(delete_user)是是2.693.55
wrong_signaturewrong_call(add())是是3.563.35
cross_file_new_symbolinvented_api(fly)是是3.852.45
dep_alias_and_pypi_nameinvented_api(toll)是是3.442.9

**摘要:**精确率 1.0、召回率 1.0、F1 1.0、假阳性率 0.0;在笔记本电脑上的中位验证耗时为 4–7 毫秒。

上方每项任务的毫秒数是某次运行的输出,并非保证值——同一台机器上不同运行之间会有几十个百分点的波动。基准测试实际稳定且作为门槛依据的,是前四列以及摘要中的计数。

摘要行直接取自 python benchmarks/agent_accuracy/run.py 的原样输出,而不是复制到此文件中的数值,因为此处引用的耗时会在代码变快的瞬间过时——之前就发生过这种情况。使用 --format markdown 即可复现。

cross_file_new_symbol 任务锁定 Agent 会话流程(先写入一个模块,再写入导入该模块的文件——索引必须是最新的,绝不能过时);dep_alias_and_pypi_name 任务锁定通过别名子模块和 PyPI 命名的依赖项进行依赖依据验证(PyYAML → yaml)。

真实场景假阳性基准测试

benchmarks/realworld_fp/ 用于衡量真实代码上的精确率:它扫描 psf/requests 的一份 vendored 快照(19 个文件,约 6.4k 行代码,Apache-2.0),并断言 HonestCode 报告的发现数为零。真实代码会用到合成任务从未涉及的结构——标准库导入、关键字调用风格、@staticmethod 成员、继承标准库 ABC 的类、兼容性重新导出模块——按定义,此代码库中的任何发现都属于假阳性。

同一轮运行还会扫描 benchmarks/realworld_fp/regressions/:每种在实际使用中发现的假阳性类型各对应一个微型项目(跨类型重新绑定的接收者、with ... as 绑定、monorepo 子项目导入、本地绑定形式)。如果回归问题再次出现,基准测试会按名称标出失败的场景。

python benchmarks/realworld_fp/run.py
# files: 25  findings: 0  elapsed: 0.7s (~26 ms/file)

发现数量才是要验证的主张;耗时仅供参考,且会随机器而变化。

值漂移基准测试

benchmarks/value_drift/ 关注另一个问题:当一个容忍格式差异的编辑匹配器解析搜索字符串时,编辑是否落在调用方指定的区域,还是悄无声息地落在带有不同值的近似匹配项上?该基准测试在有保护和无保护的匹配器级联中运行十种场景,并将每次编辑归类为 correct、silent_drift、no_match 或 wrong_span。有保护的匹配器必须在每种场景中都完成预期编辑;no_match 表示拒绝匹配,并不算通过。

python benchmarks/value_drift/run.py            # human-readable
python benchmarks/value_drift/run.py --json     # machine-readable (status on stderr)
性能基准测试

scripts/benchmark.py 测量核心操作(索引、扫描、图谱、死代码检测、相似性搜索)在仓库本身上的延迟。

python scripts/benchmark.py                          # text output
python scripts/benchmark.py --format markdown        # table for README
python scripts/benchmark.py --repo psf/requests      # benchmark a real-world repo

所有四项基准测试都会在 CI(.github/workflows/ci.yml)中作为独立作业运行: benchmark-accuracy、benchmark-realworld、benchmark-value-drift 和 benchmark-performance。准确性作业要求精确率和召回率保持在 1.0,真实场景作业要求没有任何发现或扫描失败,价值漂移作业要求每个受保护场景都能正确命中。性能作业只报告数值,不会据此设定门槛。

数据集格式以及如何添加新的准确性任务,请参阅 benchmarks/agent_accuracy/README.md。


架构

honestcode/
├── verify/        # Evidence protocol + repository-grounded verification
├── mcp/           # MCP server layer
├── honest/        # Symbol index + project binding
├── graph/         # Persistent call graph (SQLite)
├── structure/     # AST extraction
├── sandbox/       # Sandboxed execution
├── guards/        # Crash-safe side effects (stdlib-only, extractable)
├── integrations/  # Framework bindings — pydantic-ai today
└── cli.py         # Command-line interface

verify_file 是 Agent 接口。默认情况下,scan_file 也会与它一同开放,并同时返回新的证据结构和旧版 issues 列表。

其中两个目录回答的问题与其他目录不同。guards/ 以上的所有内容都在问:这段代码是否与仓库一致? guards/ 则在问:这个效果是否已经发生? Agent 在崩溃后重试工具调用,可能会重复扣款;而持久化执行引擎会将外部效果的恰好一次执行交给应用处理。integrations/ 将守护机制绑定到框架;pydantic-ai 的 wrap_tool_execute 是首个集成,如果效果已经提交,则会替换工具结果,而不是重新运行工具。

guards/ 有意仅依赖标准库,不依赖此软件包的协议,因此可以提取为独立发行包。tests/test_guards.py 通过 AST 导入检查确保这一点。


路线图

v0.1 — 仓库依据(已完成)
  • 符号 / API / 函数 / 类 / 方法 / 导入 / 调用验证
  • 检测虚构 API 并提供结构化证据
  • 在 scan_file 中自动建立索引
路线图之外 — 崩溃安全的副作用(当前)

这不是验证层,因此不属于下文 v0.2/v0.3 的迭代顺序: guards/ 可确保效果在崩溃后仍具幂等性,integrations/ 则将其绑定到 pydantic-ai。它回答的是“这件事是否已经发生”,这是一个运行时问题,而非静态问题。

v0.2 — 语义契约验证
  • 函数需要 UserID,Agent 却传入 User → 可疑
v0.3 — 执行验证
  • 静态验证 → 测试 → 运行时证据
v1.0 — 面向编码 Agent 的验证运行时
                 Coding Agent
                      │
              ┌───────▼───────┐
              │   HonestCode  │
              │ Verification  │
              │    Runtime    │
              └───────┬───────┘
                      │
       ┌──────────────┼──────────────┐
       ↓              ↓              ↓
   Static          Semantic       Runtime
 Verification     Verification   Verification
       │              │              │
       └──────────────┼──────────────┘
                      ↓
                   Evidence
                      ↓
                     Agent

开发

git clone https://github.com/Fengrru/honestcode.git
cd honestcode
python -m venv .venv
.venv\Scripts\activate  # Windows
# source .venv/bin/activate  # macOS/Linux
pip install -e ".[dev]"
pytest
ruff check honestcode tests scripts

在本地运行基准测试:

# Accuracy benchmark
python benchmarks/agent_accuracy/run.py

# Performance benchmark
python scripts/benchmark.py

拉取请求指南请参阅 CONTRIBUTING.md。


安全

漏洞报告请参阅 SECURITY.md。


遥测

HonestCode 不收集任何遥测数据。 没有分析库、 后台服务或回传数据的端点。


许可证

MIT - 版权所有 (c) 2026 HonestCode Team

MCP Registry:mcp-name: io.github.Fengrru/honestcode

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。