Document MCP
README.md
# Document MCP
ChatGPT-style chatbot plus a **Document MCP** server. You register folder paths and a local LiteLLM model in **Settings**. Questions go to LiteLLM with MCP tools; the server reads only those folders, using **pywin32 COM** for Word / Excel / PowerPoint (same Office path as Model Council).
```
Chat UI → LiteLLM /v1/chat/completions (+ tools)
↑ tool_calls (search_documents, read_document, …)
MCP host → Document MCP (stdio JSON-RPC)
→ allowlisted folders
→ win32com Word / Excel / PowerPoint
```
Claude Desktop, Claude Code, and Cursor attach to the **same** MCP server and the **same** folder list.
## Quick start
1. Run your LiteLLM proxy.
2. Double-click `start.bat`.
3. Open [http://127.0.0.1:7860](http://127.0.0.1:7860).
4. **Settings → LiteLLM**: paste base URL (e.g. `http://localhost:4000`), API key, **Load models** or **Add model**, then Save.
5. **Settings → Folders**: paste Windows folder paths. `sample_docs` is registered on first run.
6. Ask anything those files can answer.
### Manual
```bat
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt
copy .env.example .env
python -m app
```
## Settings
| Tab | What it does |
| --- | --- |
| LiteLLM | Base URL, key, load `/v1/models`, add a local model name that is not in the list, test connection |
| Folders | MCP roots (allowlist). Same idea as Model Council `OFFICE_ALLOWED_ROOTS` |
| Claude MCP | Copy Claude Desktop / Claude Code / Cursor snippets, or write Claude Desktop config for you |
URLs can be pasted as `http://host:4000`, `http://host:4000/v1`, or `.../v1/chat/completions` — they are normalized like Model Council.
## How LiteLLM + MCP work here
Taken from Model Council’s in-app MCP loop:
1. Host calls MCP `tools/list` and converts schemas to OpenAI tools.
2. Host POSTs `chat/completions` to LiteLLM with those tools (`tool_choice: auto`).
3. If the model returns `tool_calls`, the host runs MCP `tools/call` (stdio).
4. Tool JSON is appended as `role: tool` and the loop repeats until a normal answer.
The model never sees files unless it calls a tool. Roots are allowlisted. Office files prefer COM so Windows-unlocked / IRM files can still be read.
## MCP tools
| Tool | Purpose |
| --- | --- |
| `ping` | Health, engines, folder count |
| `list_folders` | Registered roots |
| `add_folder` / `remove_folder` | Change roots |
| `list_documents` | Inventory |
| `search_documents` | Name + extracted text |
| `read_document` | Extract (COM first, library fallback) |
Prompt: `ask_documents`.
## Claude Desktop / Claude Code / Cursor
In the chatbot: **Settings → Claude MCP → Add to Claude Desktop** (writes `%APPDATA%\Claude\claude_desktop_config.json`). Restart Claude, then ask it to `ping` Document MCP.
Or copy this shape (paths are filled in by Settings):
```json
{
"mcpServers": {
"document-mcp": {
"command": "D:\\\\AntigravityCodes\\\\Document-MCP\\\\.venv\\\\Scripts\\\\python.exe",
"args": ["-m", "document_mcp"],
"cwd": "D:\\\\AntigravityCodes\\\\Document-MCP",
"env": {
"PYTHONUTF8": "1",
"DOCUMENT_MCP_ROOTS": "D:\\\\AntigravityCodes\\\\Document-MCP\\\\data\\\\folders.json"
}
}
}
}
```
Claude Code:
```bat
claude mcp add-json document-mcp "{...stdio server json from Settings...}"
```
Cursor: repo `mcp.json`, or **Settings → Claude MCP** copy the Cursor snippet.
HTTP (LiteLLM MCP gateway):
```bat
start_mcp_http.bat
```
Then add `http://127.0.0.1:8765/mcp`.
## pywin32 / Office
- `Word.Application` → `.doc` / `.docx`
- `Excel.Application` → `.xls` / `.xlsx` / `.xlsm`
- `PowerPoint.Application` → `.ppt` / `.pptx`
Fallback: `python-docx` / `openpyxl` / `python-pptx`. PDFs: PyMuPDF. Legacy binary Office still needs Microsoft Office.
```bat
python -m document_mcp.reader sample_docs\mena_rhq_overview.md
```
## Layout
```
app/ FastAPI chat host (MCP client + UI)
document_mcp/ FastMCP server, COM readers, Claude install helper
sample_docs/ Starter files
data/ folders.json, settings, extract cache (local)
```
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues