AgentSeed
The anti-hallucination gate for AI coding agents.
AI agents invent APIs. They claim "all tests pass" without running anything.They ship confident, fabricated code. AgentSeed is the gate that stops it —a zero-dependency plugin that verifies code before it is marked done, so"done" means observed fact, not self-report.
English · 中文 · 日本語
⭐ Like this project? Star it — it helps developers find guardrails before they ship hallucinated code.
Why you need this
LLMs hallucinate — and in code that means invented APIs, undefinedidentifiers, fake test passes, and confident overclaims:
- 15.1% of code hallucinations call APIs that don't exist or were never imported (arXiv:2404.00971).
- <10% of hallucinated code fails tests — ~90% slips past CI (arXiv:2404.00971).
- 60%+ of model-output errors are unverifiable on their face (FAVA, SoK).
Prompt-only guardrails are soft: a model can agree to verify and then skipit. AgentSeed binds the instruction to a hard gate — the evidence comesfrom running code, not from the model's own word.
What AgentSeed is — in 30 seconds
A drop-in Agent Plugins 1.0.0 plugin(Skill + MCP server + optional client hook + CI gate) that makes threepromises:
| Promise | How it's kept |
|---|---|
| 🚫 No invented APIs | verify_code parses your code in 17 languages and flags any symbol that is called but never defined or imported |
| 🚫 No fake "done" | scan_hallucination catches stubs, overclaims, and fabricated claims in English and CJK; sandbox_run proves runtime claims by actually running them |
| 🚫 No skipped verification | the Skill gates the workflow, the client hook blocks Write/Edit on files that don't pass, and guard_cli gate enforces the same rules in CI with exit codes |
It also fills the two gaps the 1.0.0 spec deliberately leaves open:
| Gap in Agent Plugins 1.0.0 | AgentSeed's answer |
|---|---|
| No enforcement mechanism (skills are optional to follow) | verify-before-code skill + optional client-enforced hook make verification non-skippable |
| No official conformance linter | check_plugin is the first strict 1.0.0 linter — and AgentSeed passes its own linter (ok: true) |
See it catch a hallucination
# Your coding agent just "finished" this — it calls magic_unknown(),
# an API that doesn't exist and was never imported:
def f():
return magic_unknown() # ← hallucinated API
# AgentSeed, before the task can be marked done:
$ verify_code(source=..., language="python")
{
"language": "python",
"suspects": ["magic_unknown"] # ← caught, blocking
}
# And the agent's completion claim doesn't survive either:
"The feature is production ready, all tests pass. Trust me."
$ scan_hallucination(source=...)
{
"hits": [
{"word": "all tests pass", "group": "oversold", "line": 1},
{"word": "production ready", "group": "oversold", "line": 1},
{"word": "trust me", "group": "oversold", "line": 1}
],
"clean": false # ← caught, blocking
}
The verdict is measured, not promised: on a seeded synthetic corpus(5 defect classes, 100 defective + 40 clean modules) AgentSeed scoresprecision 1.0 · recall 1.0 (tp=100, fp=0, fn=0) — locked in by aregression test. Methodology and honest limits:docs/BENCHMARK.md.
How the gate works
- Before coding — load the SDD contract and state it in one sentence.
- Implement — real code only: no placeholders, no invented APIs.
- Before "done" — run
verify_code+scan_hallucination; prove runtimeclaims withsandbox_run; validate structure withschema_validate. - Language audit — completion reports attach evidence; overclaimvocabulary is banned.
- Only when all checks pass may the task be marked complete.
Quick start
Option A — download a release (no git needed):
# grab the latest asset from https://github.com/Morningstar202604/agentseed-mcp/releases
# or use the installer, which wires it into your client:
bash install.sh --client auto --hooks # macOS / Linux
./install.ps1 -Client auto -Hooks # Windows PowerShell
# --client: claude | opencode | cursor | manual
# --hooks / -Hooks: also register the Claude Code enforcement hook
Option B — clone:
git clone https://github.com/Morningstar202604/agentseed-mcp.git
# mirrors: https://gitee.com/badhope/agentseed-mcp · https://gitcode.com/badhope/agentseed-mcp
- Drop the cloned
agentseed-mcp/directory into any Agent Plugins–capable client(Cursor, VS Code, Claude Code, Copilot…). No build, no install. - The client auto-discovers the
verify-before-codeskill and theagentseedMCP server fromplugin.json+mcp.json. - That's it. Every coding task is now gated: contract → implement →verify → evidence.
Run it standalone or gate a human PR with the same rules:
python3 server/guard_engine.py # self-check demo
python3 -m unittest discover -s server # full unit-test suite
python3 server/guard_cli.py gate --root . # CI-equivalent hard gate
python3 server/guard_cli.py check . --ci # plugin conformance only
python3 server/guard_cli.py verify src/app.go # language inferred from the suffix
python3 server/guard_cli.py scan src/app.py --strict # inline or file, hallucination signals
python3 server/guard_cli.py scan . --baseline baseline-scan.json # tree sweep, new signals only
Windows note:
mcp.jsonmay only name one literal interpreter, and itshipspython3(right for macOS/Linux/WSL). On Windows run./install.ps1, which rewritescommandtopythonin the installed copy,or edit it by hand as"command": "python"with"args": ["server/guard_server.py"]—commandis a string, the arraybelongs toargs.npx agentseed-mcpneeds no editing at all: the npm shimpicks the interpreter per platform.
The 8 MCP tools
Zero required dependencies — pure Python standard library; optional extrasupgrade two tools to industry-standard engines (see below).
| Tool | Catches | Technique |
|---|---|---|
verify_code |
Invented APIs / undefined symbols | Python AST + config-driven lexical passes (17 languages) |
check_contract |
Code violates a written spec | requires/prohibits contract check |
check_imports |
Hallucinated packages (slopsquatting) | stdlib + known-packages allowlist check |
scan_hallucination |
Placeholder code, overclaims, fabricated content | 28+ signals in 3 groups, EN + CJK |
check_plugin |
Non-conformant plugin packaging | Strict 1.0.0 linter |
sandbox_run |
"Tests pass" without running anything | Deterministic execution channel (bounded-memory output) |
schema_validate |
Invalid structured output | JSON Schema validation |
record_verification |
No persistent evidence trail | JSONL audit trail under PLUGIN_DATA |
Language coverage (honest scope)
| Language | verify_code analysis |
|---|---|
| Python | full AST scope walk (+ pyflakes when installed), line numbers |
| TypeScript / JavaScript | lexical regex pass (documented false-positive classes) |
| Go · Rust · Java · C · C++ · C# · PHP · Ruby · Kotlin · Swift | config-driven generic lexical pass |
| Dart · Lua · R · Zig | config-driven generic lexical pass |
| any other language | add a LangSpec registry entry — no engine change |
Honest limits: attribute calls (obj.m()), macros, and cross-file symbolsare not analyzed; Ruby's paren-less calls are supported.
Honest limits: attribute calls (obj.m()), macros, and cross-file symbolsare not analyzed; Ruby's paren-less calls are supported.
It really catches other languages — live-tested
The same rule applies to every registered language: a bare call to a symbolthat is never defined is a hallucination, whatever the syntax:
# Go detect_undefined_symbols("func main() { process_data() }", "go") -> ["process_data"]
# Rust fn main() { let x = load_config() } -> ["load_config"]
# Java class A { void m() { connect_db() } } -> ["connect_db"]
# C int main() { ghost(); return 0; } -> ["ghost"]
# Kotlin fun main() { fetch_users() } -> ["fetch_users"]
# Swift func run() { connect() } -> ["connect"]
# Ruby def run; authenticate; end -> ["authenticate"]
# TypeScript function run() { connectDb() } -> ["connectDb"]
Verified across Go · Rust · Java · C · C++ · C# · PHP · Ruby · Kotlin ·Swift · TypeScript · Dart · Lua · R · Zig — every language flags itsinvented call, and clean code in each language reports zero falsepositives.
Client-enforced hook mode
Skills persuade; hooks enforce at the client boundary. Register AgentSeedas a Claude Code hook and every Write/Edit/MultiEdit is scannedautomatically — no prompt can skip it:
python3 server/guard_hook.py register --client claude # idempotent, merges settings
python3 server/guard_hook.py --file path/to/source.py # scan any file directly
- PreToolUse inspects the incoming content before it lands on disk; ablocking finding exits
2, and the agent must fix the flagged lines. - PostToolUse re-checks saved files on write paths without inline content.
- Failure policy (honest): infrastructure problems (bad stdin, unreadablefiles) never block work — fail-open; only positive scan findings block.
Platform support
| Client | Status | Notes |
|---|---|---|
| Claude Code | ✅ verified | skills + MCP + optional enforcement hook |
| opencode | ✅ verified | ~/.config/opencode/opencode.json |
| Cursor | ⚪ spec-compatible* | copy into project; no stable plugin dir yet |
| VS Code (+Copilot) | ⚪ spec-compatible* | MCP support rolling out |
| Cline / Windsurf | ⚪ spec-compatible* | stdio server entry maps directly |
* honest states: formats are spec-compatible and expected to work, but not yetexercised by the maintainers. If you verify one, open a PR updating this table.
Optional dependencies
pip install -r server/requirements.txt
| Extra | Upgrades | Without it |
|---|---|---|
jsonschema |
schema_validate → full Draft 2020-12 |
built-in subset validator |
pyflakes |
verify_code → pyflakes F821 analysis |
built-in AST walk |
pyyaml |
SKILL.md frontmatter → full YAML | built-in lite parser |
Configuration (agentseed.config.json)
| Key | Effect |
|---|---|
allowlist |
scan exclusions (replaces built-in test-idiom list) |
severities |
per-group severity override (error | warning | info) |
timeout |
default sandbox_run timeout, seconds (1–120) |
extra_tokens |
extend the hallucination word pool at runtime |
suppress_symbols |
names verify_code never flags (reported in suppressed) |
known_packages |
packages check_imports treats as known (stdlib + common + this list) |
sandbox_allowed_prefixes |
allowlist of executables sandbox_run may launch; PATH-resolved, separator-boundary enforced (absent = unrestricted) |
sandbox_env |
"inherit" | "scrub" — scrub drops credential-looking env vars |
Unknown keys are warned on stderr — a typo is never silently ignored.
⚠️ Security note:
sandbox_runexecutes real processes with your user'spermissions. Gate it behind user approval; setsandbox_allowed_prefixesinshared/CI environments. Commands resolve throughPATHto absolute pathsbefore execution, so a hostilecwdcannot shadow an allowlisted binary;unmatched commands are refused (exit -10) without running.
Compatibility & graceful degradation
| Host capability | What you get |
|---|---|
| Full Agent Plugins | drop-in: skill + MCP auto-discovered, ${PLUGIN_DATA} config honored |
| MCP-capable client | all 8 tools via registration |
| Skills-only client | skill workflow; verification degrades to guard_cli.py via shell |
| Plain terminal / CI | CLI gates with exit codes |
Built-in guardrail library (EN / 中文 / 日本語)
PROMPT-POOL (copy-paste guardrail prompts) · HALLUCINATION-PATTERNS(failure-mode catalog) · VERIFICATION-CHECKLIST (executable end-of-taskchecklist) · SDD-CONTRACT (the contract every task must satisfy) ·DEFAULT-NORMS (senior-engineer operating norms, mapped to the gate thatenforces each; English only) · VENDOR-SOLUTIONS (adoption map of vendortechniques). Every library lives underskills/verify-before-code/references/, and the SKILL files list them.
Why AgentSeed vs. alternatives
| Prompt-only guardrail skills | Static import linters (MCP) | AgentSeed | |
|---|---|---|---|
| Touches code | ❌ prompt only | ✅ import graphs | ✅ AST + lexical (registry-wide) |
| Runs verification tools | ❌ | lint gates | ✅ 8 MCP tools incl. sandbox |
| Hallucination-language scan | ❌ | ❌ | ✅ stub/oversold/fabricated, EN + CJK |
| Enforcement | soft (skill text) | CI gate | hard: skill + MCP + hook + CLI exit codes |
| 1.0.0 conformance linter | ❌ | ❌ | ✅ first |
FAQ
Does it need a specific LLM? No — client-agnostic and model-agnostic; thegate is enforced by skill + MCP + hooks + CI, not by any model.
Zero dependencies? Yes. The MCP server is pure Python standard library.
Does it work with our existing AGENTS.md / CLAUDE.md? Yes — itcomplements them. Those files carry project facts (prose, persuasive);AgentSeed carries the behavior contract and the hard enforcement.
How do I extend it to another language? Add a LangSpec registry entry inserver/engine/symbols.py — one config, no engine change.
Contributing
Issues, PRs and ideas welcome — or open an issue for a hallucination patternwe haven't catalogued yet. See CONTRIBUTING.md.
License
Apache-2.0 © AgentSeed. See LICENSE.
⭐ If AgentSeed saved you from shipping hallucinated code, star the repo — it's the best signal that guardrails matter.