Kontrol Freek — AI Assumption Firewall for MCP Agents
   
Kontrol Freek is an open-source Model Context Protocol (MCP) server that acts as an AI safety guardrail for autonomous agents. It intercepts AI assumptions before they cause irreversible mistakes, verifies every decision against a persistent project log, detects contradictions, scores risk, and routes human approval requests through Telegram, Slack, or native MCP elicitation — all without blocking your workflow.
Gate every AI assumption. Keep humans in the loop. Prevent agentic mistakes before they happen.
---
Why Kontrol Freek?
AI agents and coding assistants make implicit assumptions constantly — about architecture choices, file locations, API designs, and deployment targets. Without a structured checkpoint, these assumptions silently accumulate into hard-to-reverse technical debt or outright mistakes.
Kontrol Freek solves the human-in-the-loop problem for MCP agents: it sits between your AI agent and every risky decision, comparing new assumptions against your project's history, flagging contradictions, and routing approval requests to you — wherever you are.
Kontrol Freek adds a decision firewall between your AI agent and every risky action:
AI: "I'll use PostgreSQL for this project" ← assumption
↓
check_assumption("Use PostgreSQL", risk="medium", category="architecture")
↓
Kontrol Freek: query past decisions → detect contradictions → score risk
↓
├─ Low risk + past approval match → ✅ Auto-approve, continue
├─ Medium risk / new decision → 🔍 Notify human (Telegram / Slack / elicit)
└─ Contradiction or critical risk → ⛔ Block + require explicit approval
---
Key Features
| Feature | Description | |---------|-------------| | Assumption interception | Catches AI guesses before they execute | | SQLite decision log | Persists every decision per project | | Semantic similarity | Finds related past decisions using TF-IDF or sentence-transformers | | Contradiction detection | Blocks decisions that conflict with approved history | | Risk scoring | Adaptive policy engine — auto-approve low risk, gate high risk | | Time-based decay | Old decisions lose weight; prevents stale approvals | | Telegram polling | Background loop processes /kf approve/reject/answer commands | | Multi-channel routing | ctx.elicit() → Telegram → Slack → Web dashboard | | HMAC-SHA256 audit trail | Cryptographically signed, hash-chained decision log | | Per-project isolation | Each project gets its own DB, audit log, and config | | MCP native | Works with any MCP-compatible client |
---
How It Compares
| Feature | clarify-mcp | CONTINUITY | mcp-human-loop | VantaGate | Kontrol Freek | |---------|:-----------:|:----------:|:--------------:|:---------:|:-----------------:| | ctx.elicit() support | ✅ | ❌ | ❌ | ❌ | ✅ | | SQLite decision log | ❌ | ✅ | ❌ | ❌ | ✅ | | Risk scoring | ❌ | ❌ | ✅ | ❌ | ✅ | | Semantic similarity | ❌ | ❌ | ❌ | ❌ | ✅ | | Contradiction detection | ❌ | ❌ | ❌ | ❌ | ✅ | | Cryptographic audit trail | ❌ | ❌ | ❌ | ✅ | ✅ | | Time-based decision decay | ❌ | ❌ | ❌ | ❌ | ✅ | | Telegram interactive approval | ❌ | ❌ | ❌ | ❌ | ✅ | | Per-project isolation | ❌ | ❌ | ❌ | ❌ | ✅ | | Adaptive policy engine | ❌ | ❌ | Basic | Static | Adaptive |
---
Installation
pip (recommended)
pip install kontrol-freek-mcp
One-command setup (macOS / Linux / Windows)
git clone https://github.com/berkbayri/kontrol-freek-mcp.git
cd kontrol-freek-mcp
python install.py
The installer:
- Installs the Python package
- Generates a
.envwith a random HMAC secret - Registers a system service (auto-start on boot, crash recovery)
- Registers the MCP server with compatible clients automatically
Manual install
pip install -e ".[full]" # Full: Telegram + Web + sentence-transformers embeddings
pip install -e ".[lite]" # Lite: Telegram + Web (no embeddings)
pip install -e . # Minimal: stdio only
---
Configuration
MCP client config
Add to your MCP client's server configuration (mcpServers block):
{
"mcpServers": {
"kontrol-freek": {
"command": "kontrol-freek",
"env": {
"KF_HMAC_SECRET": "your-secret",
"KF_TELEGRAM_TOKEN": "your-bot-token",
"KF_TELEGRAM_CHAT_ID": "your-chat-id"
}
}
}
}
Or using python -m if installed without the entry point:
{
"mcpServers": {
"kontrol-freek": {
"command": "python",
"args": ["-m", "kontrol_freek_mcp"],
"env": {
"KF_HMAC_SECRET": "your-secret"
}
}
}
}
Per-project config (.kontrol-freek.json)
Place this file in your project root to override global credentials and set a project name:
{
"project_name": "my-app",
"telegram_token": "bot-token-override",
"telegram_chat_id": "chat-id-override",
"slack_webhook": ""
}
Per-project config is detected automatically — no restart required when the file changes.
HTTP server mode (remote / multi-user)
kontrol-freek --transport streamable-http --port 8765
{
"mcpServers": {
"kontrol-freek": {
"transport": "streamable-http",
"url": "http://localhost:8765/mcp"
}
}
}
---
Telegram Setup
- Message @BotFather →
/newbot→ copy the token - Start a DM with your bot or add it to a group
- Get your chat ID:
https://api.telegram.org/bot<TOKEN>/getUpdates - Set credentials in
.envor.kontrol-freek.json
Telegram commands
/kf approve <id> Approve a pending assumption
/kf reject <id> [reason] Reject with an optional reason
/kf answer <id> <answer> Answer a direct question
Kontrol Freek runs a background long-poll loop — no webhook setup needed. Commands are processed in real time while the MCP server is running.
---
MCP Tools Reference
Always pass project_root as your current working directory so decisions are isolated per project.
| Tool | When to use | |------|-------------| | check_assumption | At every decision point — architecture, file paths, API choices, etc. | | confirm_decision | To record a finalized decision; set is_irreversible=True for destructive actions | | ask_human | When genuinely uncertain — prompts human via Telegram/Slack/elicitation | | query_decisions | At the start of a task — load prior context before making new decisions | | revoke_decision | When a past decision is no longer valid — prevents it from influencing future auto-approvals | | get_firewall_stats | View approval rates, total decisions, and activity by category | | healthcheck | Verify DB, audit chain, and notification channel health | | setup_project | Initialize per-project config on first use |
check_assumption response statuses
| Status | Meaning | Agent should… | |--------|---------|---------------| | auto_approved | Low risk, matches prior approved decision | Proceed | | pending_review | Human review recommended (architecture / security / deployment) | Proceed with caution — call confirm_decision() when task is done | | blocked | Contradiction detected or critical risk | Stop — do not proceed without explicit human approval | | human_approved | Human approved via Telegram/Slack | Proceed | | human_rejected | Human rejected | Stop and reconsider |
---
How It Works
Decision flow
AI calls check_assumption(assumption, risk_level, category, project_root)
│
├── Query SQLite for similar past decisions
├── Compute semantic similarity score (TF-IDF or sentence-transformers)
├── Run contradiction analysis
├── Policy engine → auto_approve / review / block
│
├── auto_approve → log, return status: "auto_approved"
├── pending_review → log, return status: "pending_review" (non-blocking)
│ optionally notify Telegram/Slack in background
└── block → log, return status: "blocked"
if Telegram/Slack configured → notify + wait (3 min max)
│
├── Telegram bot (/kf approve/reject <id>)
└── Slack webhook (text instructions)
Policy rules
| Condition | Verdict | |-----------|---------| | critical risk | ⛔ Block — always requires human approval | | Contradiction with approved decision | ⛔ Block | | Category: security, architecture, deployment | 🔍 Human review | | Low risk + ≥78% similarity + prior approval | ✅ Auto-approve | | high risk | 🔍 Human review | | Default | 🔍 Human review |
Time-based decision decay
Older decisions carry less weight in similarity matching, preventing stale approvals from auto-approving new assumptions:
| Age | Weight | |-----|--------| | 0 days | 1.00 | | 30 days | 0.72 | | 90 days | 0.37 | | 180 days | 0.14 |
Cryptographic audit trail
Every action is written to an HMAC-SHA256 signed, hash-chained JSONL file:
{
"action": "human_approve",
"text": "Use PostgreSQL",
"detail": "Approved via Telegram",
"decision_id": 42,
"ts": "2025-01-15T14:30:00Z",
"prev": "a1b2c3...",
"hash": "d4e5f6..."
}
Verify audit chain integrity:
from kontrol_freek_mcp.audit import AuditTrail
trail = AuditTrail("~/.kontrol-freek/projects/my-app/audit.jsonl", "your-secret")
valid, count = trail.verify_chain()
print(f"Chain valid: {valid} — {count} entries")
---
Auto-Start & Crash Recovery
python install.py configures an OS-native service:
| Platform | Mechanism | Details | |----------|-----------|---------| | macOS | LaunchAgent | ~/Library/LaunchAgents/com.kontrol-freek.mcp.plist — starts at login, KeepAlive restarts on crash | | Linux | systemd user service | ~/.config/systemd/user/kontrol-freek.service — Restart=on-failure, persists across logouts via loginctl enable-linger | | Windows | Task Scheduler | schtasks — triggers at logon |
The wrapper script includes exponential backoff (5s → 10s → 20s → ..., max 10 restarts).
python install.py --status # Health check
python install.py --uninstall # Clean removal
---
Project Structure
kontrol-freek-mcp/
├── src/kontrol_freek_mcp/
│ ├── server.py # MCP server — 7 tools, 2 resources, 1 prompt
│ ├── db.py # SQLite decision database
│ ├── policy.py # Adaptive policy engine (risk scoring, decay)
│ ├── similarity.py # Semantic similarity (TF-IDF + sentence-transformers)
│ ├── notifier.py # Multi-channel routing + Telegram polling loop
│ ├── audit.py # HMAC-SHA256 hash-chain audit trail
│ └── web.py # FastAPI approval dashboard
├── tests/
├── install.py # One-command installer
├── pyproject.toml
├── .env.example
└── README.md
---
License
MIT — free to use, modify, and distribute.











