Skip to main content
Glama
Tausifonly001

FactAnchor-MCP

README.md
# ๐Ÿ”— FactAnchor-MCP

> **Reduce AI Hallucinations by up to ~80% (informal estimate) using Local Context Anchoring.**

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org)
[![Zero Cost](https://img.shields.io/badge/cost-%E2%82%B90-2ea44f.svg)](https://modelcontextprotocol.io)
[![MCP](https://img.shields.io/badge/MCP-ready-orange.svg)](https://modelcontextprotocol.io)

**FactAnchor-MCP** is a **zero-cost, fully local** [Model Context Protocol](https://modelcontextprotocol.io) server that grounds your AI assistant (Claude Desktop, Cursor, VS Code, Claude Code) in real, fetched web text โ€” and forces it to answer **only** from that text.

- ๐Ÿ’ธ **โ‚น0 Hosting Cost** โ€” runs entirely on your machine. No cloud, no paid API keys.
- ๐Ÿ›ก๏ธ **Strict Guardrails** โ€” the LLM must cite sources or say *"I cannot find a verified source for this information."*
- ๐Ÿ”Ž **Free Web Fetching** โ€” uses DuckDuckGo's free search + page scraping (no Serper/Google keys).
- ๐Ÿง  **Smart Chunking** โ€” BM25 semantic relevance scoring keeps only the most useful paragraphs.
- ๐Ÿ’พ **Persistent Cache** โ€” SQLite disk cache (`~/.factanchor/cache.db`) survives server restarts.
- โšก **Zero-config setup** โ€” `pip install -e .` + connect your MCP client. Browser auto-installs on first start.

> โญ **If FactAnchor-MCP helps you ship more reliable, hallucination-free AI, please consider [starring the repository](https://github.com/Tausifonly001/FactAnchor-MCP).** It takes one click and helps more developers discover a truly zero-cost way to ground their agents. Thank you! ๐Ÿ™

---

## ๐Ÿš€ 1-Minute Quick Start

### Option A โ€” Recommended (cross-platform, no path editing)

```bash
git clone https://github.com/Tausifonly001/FactAnchor-MCP.git
cd FactAnchor-MCP
pip install -e .          # installs the `factanchor-mcp` command
```

Then add this to your `claude_desktop_config.json` (Settings โ†’ Developer โ†’ Edit Config):

```json
{
  "mcpServers": {
    "FactAnchor-MCP": {
      "command": "factanchor-mcp"
    }
  }
}
```

### Option B โ€” Simple (use the script path directly)

```bash
git clone https://github.com/Tausifonly001/FactAnchor-MCP.git
cd FactAnchor-MCP
pip install -r requirements.txt
```

Add the **absolute path** to `server.py`:

```json
{
  "mcpServers": {
    "FactAnchor-MCP": {
      "command": "python",
      "args": ["/absolute/path/to/FactAnchor-MCP/server.py"]
    }
  }
}
```

<details>
<summary>๐Ÿ“‚ Per-OS path examples</summary>

- **Windows:** `"C:\\Users\\you\\FactAnchor-MCP\\server.py"`
- **macOS / Linux:** `"/Users/you/FactAnchor-MCP/server.py"` or `"/home/you/FactAnchor-MCP/server.py"`

</details>

### 3. Restart your client
You'll now see the **`fetch_verified_context`** tool available. Ask a factual question and watch the assistant ground its answer in live, cited sources.

> โœ… **Zero-config:** on first launch, FactAnchor silently installs the Playwright Chromium browser in the background. No `crawl4ai-setup` or manual browser commands required.
>
> ๐Ÿ’ก Want `uv` instead of pip? `uv pip install -e .` works identically, and the `factanchor-mcp` command lands on your PATH.

---

## ๐Ÿงฉ Supported Clients (drop-in configs)

FactAnchor-MCP is a **standard MCP server**, so it works with **any MCP-compatible client**. Below are ready-to-paste configs. Every client uses the same two shapes:

- **Option A (recommended):** `"command": "factanchor-mcp"` โ€” needs `pip install -e .` (so the command is on your PATH).
- **Option B (path-based):** `"command": "python"` + `"args": ["/abs/path/server.py"]` โ€” use this if the `factanchor-mcp` command isn't found.

<details open>
<summary>๐Ÿ’ฌ Claude Desktop</summary>

File: `claude_desktop_config.json` (Settings โ†’ Developer โ†’ Edit Config)

```json
{
  "mcpServers": {
    "FactAnchor-MCP": { "command": "factanchor-mcp" }
  }
}
```
Restart Claude Desktop. Tool appears in the tools list.

</details>

<details open>
<summary>๐Ÿ–ฅ๏ธ opencode</summary>

File: `.opencode.jsonc` (project root)

```jsonc
{
  "mcpServers": {
    "FactAnchor-MCP": { "command": "factanchor-mcp" }
  }
}
```
Verify with `/mcp` โ€” `fetch_verified_context` should be listed.

</details>

<details open>
<summary>โŒจ๏ธ Claude Code / Kimi Code / Qwen Code / Cline / Roo Code</summary>

These are Claude-Code-style clients. Use a project `.mcp.json`:

```json
{
  "mcpServers": {
    "FactAnchor-MCP": { "command": "factanchor-mcp" }
  }
}
```

Or add it from the CLI (runs the same server):

```bash
claude mcp add factanchor -- factanchor-mcp
# Kimi/Qwen/Cline equivalents use the same `mcp add` subcommand
```

</details>

<details open>
<summary>๐ŸŒ€ Cursor</summary>

File: `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (project)

```json
{
  "mcpServers": {
    "FactAnchor-MCP": { "command": "factanchor-mcp" }
  }
}
```
Enable it in **Settings โ†’ MCP** and restart Cursor.

</details>

<details open>
<summary>๐Ÿ“ VS Code (Copilot / MCP extension)</summary>

File: `.vscode/mcp.json` (note: VS Code uses a `"servers"` key)

```json
{
  "servers": {
    "FactAnchor-MCP": {
      "type": "stdio",
      "command": "factanchor-mcp"
    }
  }
}
```
Open the Command Palette โ†’ **MCP: List Servers** to confirm it's connected.

</details>

<details open>
<summary>๐ŸŒŸ Gemini CLI / Antigravity (Google)</summary>

File: `.gemini/settings.json`

```json
{
  "mcpServers": {
    "FactAnchor-MCP": { "command": "factanchor-mcp" }
  }
}
```
Or: `gemini mcp add factanchor -- factanchor-mcp`

</details>

<details open>
<summary>๐Ÿ”ง Generic MCP client (path-based fallback)</summary>

If the `factanchor-mcp` command isn't on your PATH, use the absolute path to `server.py` on every client above:

```json
{
  "mcpServers": {
    "FactAnchor-MCP": {
      "command": "python",
      "args": ["/absolute/path/to/FactAnchor-MCP/server.py"]
    }
  }
}
```

Per-OS path examples:
- **Windows:** `"C:\\Users\\you\\FactAnchor-MCP\\server.py"`
- **macOS:** `"/Users/you/FactAnchor-MCP/server.py"`
- **Linux:** `"/home/you/FactAnchor-MCP/server.py"`

</details>

---

## ๐Ÿ› ๏ธ How It Works

```
[Claude Desktop / Cursor / VS Code]
       โ”‚ (Asks a factual query)
       โ–ผ
[FactAnchor MCP Server]
       โ”‚
       โ”œโ”€โ”€โ–บ [Free DuckDuckGo Search] (URL Discovery)
       โ”‚
       โ”œโ”€โ”€โ–บ [Persistent Cache: ~/.factanchor/cache.db] (Fast Repeat Queries)
       โ”‚
       โ”œโ”€โ”€โ–บ [Crawl4AI in Isolated Subprocess] (Page Scraping)
       โ”‚
       โ”œโ”€โ”€โ–บ [BM25 Semantic Chunking] (Smart Paragraph Selection)
       โ”‚
       โ””โ”€โ”€โ–บ [Strict Guardrail Injection] (Verified Context Block)
              โ”‚
              โ–ผ
[Assistant answers ONLY from verified context โ†’ ~0% Hallucination]
```

1. **Free Search** โ€” `fetch_verified_context(query)` runs a free DuckDuckGo search to discover URLs. No API keys required.
2. **Persistent Caching** โ€” results are cached in `~/.factanchor/cache.db` (SQLite) for 24 hours, so repeat queries return instantly even after server restarts.
3. **Page Scraping** โ€” **Crawl4AI** runs in an isolated subprocess (`crawl_worker.py`) to scrape discovered URLs into clean, LLM-optimized Markdown (navbars, ads, and footers auto-stripped).
4. **Semantic Chunking** โ€” BM25 relevance scoring extracts only the paragraphs most relevant to your query, maximizing information density within the context window.
5. **Guardrail Injection** โ€” the fetched text is wrapped in a strict directive (see `guardrail.py`):
   - Answer **only** from `<verified_context>`.
   - If unanswerable, reply exactly: *"I cannot find a verified source for this information."*
   - Cite every claim in brackets like `[Source: ...]`.
   - Never fall back to pre-trained knowledge.
6. **Local-Only** โ€” the server uses the `stdio` transport, so all processing stays on your machine.

---

## ๐Ÿ“ฆ Project Structure

| File | Purpose |
|------|---------|
| `server.py` | The MCP server + `fetch_verified_context` tool (FastMCP). |
| `crawl_worker.py` | Headless-scrape worker (Crawl4AI) run in an isolated subprocess for robust MCP stdio. |
| `search_backends.py` | Free DuckDuckGo search (no API keys required). |
| `disk_cache.py` | Persistent SQLite cache (`~/.factanchor/cache.db`) for repeat queries. |
| `semantic_chunker.py` | BM25 relevance scoring to extract the most useful paragraphs. |
| `guardrail.py` | The strict fact-anchoring prompt template. |
| `text_cleaner.py` | Markdown cleaning + truncation for Crawl4AI output. |
| `pyproject.toml` | Packaging + `factanchor-mcp` console command. |
| `requirements.txt` | Dependencies (`mcp`, `ddgs`/`duckduckgo_search`, `crawl4ai`). |
| `claude_desktop_config.example.json` | Copy-paste config snippet. |

---

## ๐Ÿงฐ Requirements

- Python **3.10+**
- Internet access (for the free search/scrape)

## ๐Ÿ”ง Tool Reference

```
fetch_verified_context(query: str, max_results: int = 3) -> str
```

| Param | Default | Notes |
|-------|---------|-------|
| `query` | โ€” | The factual topic or question to ground. |
| `max_results` | `3` | Sources to pull (clamped 1โ€“5). |

---

## ๐Ÿ› Troubleshooting

- **`command not found: factanchor-mcp`** โ†’ you used Option A but didn't `pip install -e .`, or your venv isn't on PATH. Use Option B (script path) instead.
- **Pages return only short snippets (first run)** โ†’ Chromium is still installing in the background. Wait ~1โ€“2 minutes and retry; subsequent runs are instant.
- **"Browser executable doesn't exist" on Linux** โ†’ install OS deps once: `sudo playwright install-deps chromium` (or `sudo apt install libnss3 libatk-bridge2.0-0 libdrm2 libxkbcommon0 libgbm1 libasound2`).
- **Rate-limit system note from the tool** โ†’ DuckDuckGo is throttling free search. Wait a few minutes and retry. The server never crashes; it returns a clean system note for the LLM.
- **Tool not appearing in client** โ†’ restart the client fully after editing the config, and check its MCP/Developer panel for errors.

---

## ๐Ÿ“ˆ Virality Strategy

- **Before vs After video** (X/Twitter & LinkedIn): show the assistant hallucinating a fake npm feature, then enable FactAnchor-MCP and watch it correctly say *"I cannot find a verified source for this information."* Tag `@AnthropicAI` with `#MCP` and `#AI`.
- **Open-source launch**: submit to the [official MCP servers list](https://github.com/modelcontextprotocol/servers) and `awesome-mcp` collections.

---

## ๐Ÿ“Š Evaluation

The "~80%" figure is an **informal estimate**. A small, hand-runnable eval
set lives in [`eval/sample_queries.json`](eval/sample_queries.json) โ€” see
[`eval/README.md`](eval/README.md) for how to reproduce it. Contributions of
more queries (or a CI assertion) are very welcome.

## ๐Ÿค Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md). Keep it **zero-cost** and **local-first**.

## ๐Ÿ“‹ Success Metrics (v1.0)

> โš ๏ธ **Honesty note:** The "~80% reduction" is an **informal estimate** from manual testing against a small set of factual queries (see [`eval/sample_queries.json`](eval/sample_queries.json)) โ€” it is **not** a benchmarked or statistically validated result. The guardrail is a *prompt directive*, not a hard infrastructure constraint, so an LLM can occasionally drift from it in long conversations. FactAnchor reduces hallucination but does not eliminate it; always verify critical claims against the cited sources.

- ๐Ÿงช **Up to ~80%** fewer made-up facts observed in informal test queries.
- โœ… **<3 min** user setup time (clone โ†’ install โ†’ config).
- โœ… **โ‚น0.00** server maintenance bill.

## ๐Ÿ“œ License

[MIT](LICENSE) ยฉ FactAnchor-MCP contributors.

TDQS

A4.7/5.0

Scored across 1 tool

Disambiguation5/5

With only one tool, there is no possibility of confusion between tools. The single tool has a clearly distinct purpose.

Naming Consistency5/5

The single tool name 'fetch_verified_context' follows a clear snake_case convention and is descriptive. Consistency is not an issue with only one tool.

Tool Count4/5

One tool is slightly below the typical 3-15 range, but it is appropriate for this narrowly scoped server. The tool covers the entire workflow of fetching and anchoring factual context.

Completeness5/5

The single tool effectively covers the entire domain of fact-anchoring: fetching verified context and enforcing strict answer rules. No obvious gaps exist for its stated purpose.

Maintenance

ActivitySlowing
ResponsivenessNo issues