Wrong-answer vaccine system for AI agents — learns error patterns and prevents repeated mistakes via MCP
Project description
OdabNote — Wrong-Answer Vaccine System for AI Agents
Teach AI agents to never repeat the same coding mistake twice.
OdabNote is a local MCP (Model Context Protocol) server that captures error patterns, stores verified solutions, and automatically matches future errors against its database — acting as an immune system for AI coding agents.
Why OdabNote?
AI coding agents (Claude Code, Codex, Cursor, Gemini, etc.) repeatedly make the same mistakes across sessions. They forget what went wrong last time. OdabNote solves this by:
- Recording error patterns with their verified fixes
- Matching new errors against the database in real-time
- Preventing the same mistake from happening again
- Tracking which AI models make which mistakes (model-specific blacklists)
- Decaying outdated patterns so the knowledge stays fresh
Quick Start
Prerequisites
- Python 3.10+
- pip
Installation
git clone https://github.com/hacker3699-max/OdabNote.git
cd OdabNote
python3 -m venv .venv
.venv/bin/pip install -e .
Verify Installation
.venv/bin/odab --help
Expected output:
Usage: odab [OPTIONS] COMMAND [ARGS]...
OdabNote CLI - Manage wrong-answer notes for AI Agents.
Commands:
add Add a new wrong-answer note manually (auto-verified).
approve Approve a wrong-answer note (Veto Pass).
decay Manually apply time-decay to decrease weights of obsolete notes.
delete Delete a wrong-answer note.
graph Visualize relations and conflicts of wrong-answer notes.
link Link two notes with relation (triggers or conflict).
list List all wrong-answer notes.
resolve Interactively resolve conflict between Note A and Note B.
run-server Run the OdabNote MCP server.
show Show details of a specific wrong-answer note.
Usage Guide
How It Works (Natural Language)
You don't need to type CLI commands. Just talk to your AI agent in natural language.
Step 1 — Agent makes a mistake. You say: 오답 넣어 or odab pull
You asked the agent to modify
config.yaml, but it created a newconfig_new.yamlinstead.
You: Why did you create a new file? I said modify the existing one. odab pull
Agent: ✅ Recorded (ID: 13, Model: claude-opus-4.6)
Keyword: Created_New_File_Instead_Modifying
Mistake: User asked to modify existing file but agent created a new file instead
Fix: When user says 'modify', always edit the existing file in place.
Never create a new file unless explicitly asked.
Step 2 — Not happy with the note? Say: 오답 수정 or odab fix
You: odab fix I meant you should always back up config files before editing them
Agent: 📝 Revised note (ID: 13)
Keyword: Config_File_Backup_First
Mistake: Modified config file without creating a backup first
Fix: Always create a backup copy before modifying any config file
Step 3 — Want to remove it entirely? Say: 오답 삭제 or odab del
You: odab del
Agent: 🗑️ Deleted note (ID: 13)
Keyword: Config_File_Backup_First
Was: Modified config file without creating a backup first
That's it. Three phrases to remember:
| Korean | English | What it does |
|---|---|---|
오답 넣어 |
odab pull |
Record the last mistake |
오답 수정 |
odab fix |
Revise the note |
오답 삭제 |
odab del |
Delete the note |
CLI Reference
1. Record a Mistake
When you encounter an error and fix it, record it:
odab add \
-k "ZeroDivisionPrevention" \
-e "ZeroDivisionError: division by zero" \
-f "Check if denominator == 0 before dividing and return a safe default value" \
-m "all"
| Flag | Description |
|---|---|
-k |
Keyword name for this mistake (unique identifier) |
-e |
Error pattern (supports regex) |
-f |
The correct fix / solution |
-m |
Target model (all, gemini-3.5-flash, claude-3.5-sonnet, etc.) |
2. List All Mistakes
odab list
ID | Keyword | Model | Count | Verified | Error Pattern
-----------------------------------------------------------------------------------------------
1 | ZeroDivisionPrev... | all | 1 | Yes | ZeroDivisionError: division by...
2 | Surface_Only_Fix | gemini-3.5-flash | 1 | Yes | Fixed surface only, left old refs...
3. View Details
odab show 1
4. Visualize Relations
odab graph
[ Odab-Note Dependency & Conflict Graph 🕸️ ]
● [ID: 1] ZeroDivisionPrevention (Count: 1, Verified: ✓)
└── (No active relations)
● [ID: 2] Surface_Only_Fix (Count: 1, Verified: ✓)
└── 🔗 [Triggers] -> [ID: 3] No_Full_Audit_Before_Done
5. Link Related Mistakes
odab link 2 3 --type triggers
6. Resolve Conflicts
When two notes contradict each other:
odab resolve 1 2 --solution-c "Merged solution that combines both approaches"
7. Apply Time Decay
Decrease weight of notes not triggered in N days:
odab decay --days 30
MCP Server Integration
For Gemini (Antigravity)
Add to ~/.gemini/antigravity/mcp_config.json:
{
"odab-note": {
"command": "/path/to/OdabNote/.venv/bin/python",
"args": ["-m", "odab_note.server"],
"env": {
"PYTHONPATH": "/path/to/OdabNote/src"
}
}
}
For Claude Code / Cursor / Cline
Add to your MCP settings (e.g. .cursor/mcp.json or claude_desktop_config.json):
{
"mcpServers": {
"odab-note": {
"command": "/path/to/OdabNote/.venv/bin/python",
"args": ["-m", "odab_note.server"],
"env": {
"PYTHONPATH": "/path/to/OdabNote/src"
}
}
}
}
Available MCP Tools
| Tool | Description |
|---|---|
query_notes(keywords) |
Search past mistakes by keyword before starting work |
match_error_trace(error_trace, target_model) |
Match a stack trace against the database to find a known fix |
record_mistake(keyword, error_pattern, solution, target_model) |
Record a new mistake with its solution |
propose_conflict_resolution(note_id_a, note_id_b, proposed_solution_c) |
Propose resolution for conflicting notes |
resolve_conflict_merge(keep_id, delete_id, merged_solution, merged_keyword) |
Execute a conflict merge |
register_skill(name, cmd, desc) |
Save a verified workflow command for reuse |
Testing
Run the E2E Verification Script
cd OdabNote
.venv/bin/python tests/test_mcp.py
Expected output:
🔍 [TEST 1] Query Notes with keyword 'SMC'...
Result:
Found 2 wrong-answer notes:
...
🔍 [TEST 2] Match Error Trace for SMC Timeout...
Result:
Found 1 matching wrong-answer notes:
...
🔍 [TEST 3] Match ZeroDivisionError Trace...
Result:
Found 1 matching wrong-answer notes:
- Target Keyword: ZeroDivisionPrevention
- Correct Solution: Check if denominator == 0 before dividing...
Manual End-to-End Test
-
Create a bug:
echo 'print(1/0)' > /tmp/bad.py python3 /tmp/bad.py # ZeroDivisionError
-
Record it:
odab add -k "DivByZero" -e "ZeroDivisionError" -f "Guard with if x != 0" -m "all"
-
Verify it matches:
.venv/bin/python -c " from odab_note.server import match_error_trace print(match_error_trace('ZeroDivisionError: division by zero')) "
-
Confirm the vaccine is prescribed — the output should show the fix you recorded.
Project Structure
OdabNote/
├── src/odab_note/
│ ├── __init__.py
│ ├── server.py # FastMCP server with 6 tools
│ ├── database.py # SQLite DB with regex matching, decay, relations
│ └── cli.py # Click CLI with 10 subcommands
├── tests/
│ ├── test_mcp.py # E2E MCP tool verification
│ └── buggy_script.py # Intentional bug for testing
├── docs/ # PRD, philosophy, tier matrix
├── SKILL.md # Agent instruction file (for Claude Code, Codex, etc.)
├── pyproject.toml
└── README.md
Database Location
The SQLite database is stored at:
~/.gemini/antigravity/odab_note.db
License
© Logan's Company. All rights reserved.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file odab_note-0.1.0.tar.gz.
File metadata
- Download URL: odab_note-0.1.0.tar.gz
- Upload date:
- Size: 22.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0a30986939595b12d3181a478330b19057091425f96f5ec5f67e5c1b3868c4d
|
|
| MD5 |
6c1a885d6c9da355867de27b5c176cb3
|
|
| BLAKE2b-256 |
fe3b044e2b8767e2c88e5f9e996511e454d5202683c4ff8c03abc972c237a3e1
|
File details
Details for the file odab_note-0.1.0-py3-none-any.whl.
File metadata
- Download URL: odab_note-0.1.0-py3-none-any.whl
- Upload date:
- Size: 14.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
27ed64b4358800ff280b599676f193ada797160928818f3490400a148900d8d2
|
|
| MD5 |
fffff8dc2b83b1a661a91f2595cb268f
|
|
| BLAKE2b-256 |
67662517011f7bd6e71a7d972c67128e887c23a145609270c96f7b138eda22cf
|