Metadata-Version: 2.4
Name: kontrol-freek-mcp
Version: 1.1.0
Summary: AI Assumption Firewall — MCP server that catches assumptions, checks past decisions, detects contradictions, and gates human approval.
Author: Berk
License-Expression: MIT
Requires-Python: >=3.11
Requires-Dist: fastmcp>=2.10.0
Requires-Dist: pydantic>=2.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Provides-Extra: full
Requires-Dist: fastapi>=0.115; extra == 'full'
Requires-Dist: httpx>=0.27; extra == 'full'
Requires-Dist: sentence-transformers>=3.0; extra == 'full'
Requires-Dist: uvicorn>=0.30; extra == 'full'
Provides-Extra: lite
Requires-Dist: fastapi>=0.115; extra == 'lite'
Requires-Dist: httpx>=0.27; extra == 'lite'
Requires-Dist: uvicorn>=0.30; extra == 'lite'
Description-Content-Type: text/markdown

# 🔥 Kontrol Freek

**AI assumption firewall** — an MCP server that catches AI assumptions, verifies them against a project decision log, detects contradictions, scores risk, and gates human approval before the AI proceeds.

## What It Does

```
AI: "I'll use PostgreSQL" (assumption!)
     ↓
check_assumption("Use PostgreSQL", risk="medium", category="architecture")
     ↓
Kontrol Freek: Check past decisions → Contradictions? → Risk score
     ↓
├─ Low risk + past approval → ✅ Auto-approve
├─ Medium risk → 🔍 Ask human (Telegram/Slack/Web/Terminal)
└─ Contradiction or critical → ⛔ Block + notify human
```

## Beyond Existing MCP Servers

| Feature | clarify-mcp | CONTINUITY | mcp-human-loop | VantaGate | **Kontrol Freek** |
|---------|:-----------:|:----------:|:--------------:|:---------:|:-----------------:|
| ctx.elicit() support | ✅ | ❌ | ❌ | ❌ | ✅ |
| SQLite decision log | ❌ | ✅ | ❌ | ❌ | ✅ |
| Risk scoring | ❌ | ❌ | ✅ | ❌ | ✅ |
| Semantic similarity | ❌ | ❌ | ❌ | ❌ | ✅ |
| Contradiction detection | ❌ | ❌ | ❌ | ❌ | ✅ |
| Cryptographic audit | ❌ | ❌ | ❌ | ✅ | ✅ |
| Time-based decay | ❌ | ❌ | ❌ | ❌ | ✅ |
| Multi-channel | ❌ | ❌ | ❌ | ✅ | ✅ |
| Project context analysis | ❌ | ✅ | ❌ | ❌ | ✅ |
| Adaptive policy engine | ❌ | ❌ | Basic | Static | **Adaptive** |

---

## Installation

### Quick Install (pip)

```bash
pip install kontrol-freek-mcp
```

### One-Command Setup (Mac / Linux / Windows)

```bash
git clone https://github.com/berkbayri/kontrol-freek-mcp.git
cd kontrol-freek-mcp
python install.py
```

This will:
1. Install the Python package
2. Generate a `.env` with a random HMAC secret
3. Register a system service (auto-starts on boot, auto-restarts on crash)
4. Configure Claude Code and Claude Desktop

### Manual Install

```bash
pip install -e ".[full]"     # Full: Telegram + Web + Embeddings
# or
pip install -e ".[lite]"     # Lite: Telegram + Web (no embeddings)
# or
pip install -e .             # Minimal: stdio only
```

### Claude Code Config

The installer uses the Claude Code CLI to register the server globally (works across all projects):

```bash
claude mcp add kontrol-freek /path/to/kontrol-freek \
  -e KF_HMAC_SECRET=your-secret \
  -e KF_DB_PATH=/home/you/.kontrol-freek/decisions.db \
  -e KF_AUDIT_PATH=/home/you/.kontrol-freek/audit.jsonl \
  -e KF_TELEGRAM_TOKEN=BOT_TOKEN \
  -e KF_TELEGRAM_CHAT_ID=CHAT_ID \
  --scope user
```

This writes to `~/.claude.json` (the correct global config file). The old `~/.claude/claude_code_config.json` path is **not read** by Claude Code and should not be used.

### Claude Desktop Config

macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
Windows: `%APPDATA%/Claude/claude_desktop_config.json`

```json
{
  "mcpServers": {
    "kontrol-freek": {
      "command": "python",
      "args": ["-m", "kontrol_freek_mcp"],
      "env": { "KF_HMAC_SECRET": "your-secret" }
    }
  }
}
```

### HTTP Server Mode (remote access)

```bash
kontrol-freek --transport streamable-http --port 8765
```

```json
{
  "mcpServers": {
    "kontrol-freek": {
      "transport": "streamable-http",
      "url": "http://localhost:8765/mcp"
    }
  }
}
```

---

## Telegram Bot Setup

1. Message **@BotFather** → `/newbot` → get token
2. Add bot to a group or DM it
3. Get chat ID: `https://api.telegram.org/bot<TOKEN>/getUpdates`
4. Set in `.env`:
   ```
   KF_TELEGRAM_TOKEN=123456:ABC-DEF...
   KF_TELEGRAM_CHAT_ID=987654321
   ```

### Bot Commands
```
/kf approve abc123         → Approve assumption
/kf reject abc123 Wrong    → Reject with reason
/kf answer abc123 Yes      → Answer a question
/kf stats                  → Show statistics
/kf recent                 → Recent decisions
```

---

## How It Works

### Decision Flow

```
AI → check_assumption(assumption, risk, category)
         │
         ├── Query past decisions (SQLite)
         ├── Compute semantic similarity (TF-IDF or sentence-transformers)
         ├── Contradiction analysis
         ├── Policy engine → auto_approve / review / block
         │
         ├── auto_approve → Log, continue
         ├── review → Ask human → Wait → Log
         └── block → Notify human → Wait for approval/rejection → Log
                         │
                         ├── ctx.elicit() (native MCP)
                         ├── Telegram bot
                         ├── Slack webhook
                         ├── Web dashboard
                         └── Terminal input (fallback)
```

### Policy Rules

| Condition | Verdict |
|-----------|---------|
| Critical risk | ⛔ Block — always requires human approval |
| Contradiction with past decision | ⛔ Block |
| security/architecture/deployment category | 🔍 Review |
| Low risk + ≥78% similarity + past approval | ✅ Auto-approve |
| High risk | 🔍 Review |
| Default | 🔍 Review |

### Time Decay

Older decisions carry less weight:
- 0 days → 1.0 (fully valid)
- 30 days → 0.72
- 90 days → 0.37
- 180 days → 0.14

This prevents stale approvals from auto-approving new assumptions.

### Audit Chain

Every action is logged to an HMAC-SHA256 signed, hash-chained JSONL file:
```json
{"action": "human_approve", "text": "Use PostgreSQL", "detail": "Go ahead",
 "decision_id": 42, "ts": "2025-01-15T14:30:00Z", "prev": "a1b2...", "hash": "d4e5..."}
```

Verify chain integrity:
```python
from kontrol_freek_mcp.audit import AuditTrail
trail = AuditTrail("./audit.jsonl", "your-secret")
valid, count = trail.verify_chain()
print(f"Valid: {valid}, Entries: {count}")
```

---

## Auto-Start & Crash Recovery

`python install.py` sets up:

| Platform | Mechanism | Details |
|----------|-----------|---------|
| **macOS** | LaunchAgent | `~/Library/LaunchAgents/com.kontrol-freek.mcp.plist` — runs at login, `KeepAlive` on crash |
| **Linux** | systemd user service | `~/.config/systemd/user/kontrol-freek.service` — `Restart=on-failure`, survives logout via `linger` |
| **Windows** | Task Scheduler | `schtasks` — runs at logon |

The wrapper script includes **exponential backoff** crash recovery (5s → 10s → 20s → ..., max 10 restarts).

```bash
python install.py --status     # Health check
python install.py --uninstall  # Clean removal
```

---

## Project Structure

```
kontrol-freek-mcp/
├── src/kontrol_freek_mcp/
│   ├── __init__.py          # Package
│   ├── __main__.py          # python -m support
│   ├── server.py            # Main MCP server — 7 tools + 2 resources + 1 prompt
│   ├── db.py                # SQLite decision database
│   ├── policy.py            # Policy engine (risk, decay, rules)
│   ├── similarity.py        # Semantic similarity (embeddings + TF-IDF)
│   ├── notifier.py          # Multi-channel notification routing
│   ├── audit.py             # HMAC-SHA256 hash-chain audit trail
│   ├── web.py               # FastAPI approval dashboard
│   └── telegram_bot.py      # Telegram bot handler
├── tests/test_core.py
├── install.py               # One-command installer (Mac/Linux/Windows)
├── pyproject.toml
├── CLAUDE.md
├── .env.example
└── README.md
```

## License

MIT
