Mistral OCR MCP connector
README.md
# Mistral OCR MCP connector
Удалённый MCP-сервер (Streamable HTTP + OAuth 2.1), который распознаёт сканы PDF и изображения через Mistral OCR и отдаёт результат в трёх видах: PDF с невидимым текстовым слоем (страницы оригинала сохраняются), Markdown и JSON с координатами блоков. Опционально распознанный текст вычитывает Mistral Large и исправляет ошибки OCR.
## Как это устроено
```
Claude (web / desktop / Cowork / Claude Code)
│ MCP over HTTPS, Bearer-токен OAuth
▼
app/server.py ── инструменты MCP ──┐
│ │
│ /upload /files /login │ app/ocr.py: Mistral OCR → JSON → Markdown → searchable PDF
▼ │ → (опция) Mistral Large: вычитка
веб-консоль (drag-and-drop) │
│ ▼
volume /data ← документы, задания, результаты; удаление через RETENTION_DAYS
```
Инструменты MCP:
| Инструмент | Назначение |
| --- | --- |
| `ocr_document(source, verify, pages, table_format, text_layer, include_images, wait_seconds)` | Запуск OCR по `doc_…` или публичному URL. Возвращает статус, статистику, ссылки на скачивание и Markdown |
| `get_job(job_id)` | Статус и результат задания (опрашивается для длинных документов) |
| `get_text(job_id, page_from, page_to, format)` | Постраничное чтение текста (Markdown) или блоков с координатами |
| `list_documents()` | Загруженные документы и последние задания |
| `create_upload_token()` | Одноразовый токен и готовая команда `curl` для загрузки локального файла (Cowork, Claude Code) |
| `delete_document(doc_id)` | Удаление документа и результатов |
Как файл попадает на сервер:
1. Веб-консоль по адресу сервера: вход по паролю, перетаскивание файла, получение `doc_…`. Дальше в Claude: «распознай doc_…».
2. Публичный URL: `ocr_document("https://…/file.pdf")`.
3. Из агента с shell (Cowork, Claude Code): `create_upload_token` → выполнить `curl` → `ocr_document(doc_id)`.
## Переменные окружения
| Переменная | Обязательна | Описание |
| --- | --- | --- |
| `MISTRAL_API_KEY` | да | ключ Mistral (OCR и вычитка) |
| `ADMIN_PASSWORD` | да | пароль входа (OAuth-подключение из Claude и веб-консоль) |
| `PUBLIC_URL` | да | внешний адрес сервиса, например `https://xxx.up.railway.app` |
| `DATA_DIR` | нет | каталог хранения, по умолчанию `/data` (сюда монтируется volume) |
| `RETENTION_DAYS` | нет | срок хранения файлов и результатов, по умолчанию 7 |
| `OCR_MODEL` | нет | по умолчанию `mistral-ocr-latest` |
| `VERIFY_MODEL` | нет | по умолчанию `mistral-large-latest` |
| `MAX_UPLOAD_MB` | нет | предел размера файла, по умолчанию 200 |
| `SECRET_KEY` | нет | ключ подписи ссылок и сессий; если не задан, генерируется и хранится в `DATA_DIR` |
## Развёртывание на Railway
1. Создать сервис из этого репозитория (Dockerfile определяется автоматически, `railway.toml` задаёт healthcheck `/health`).
2. Подключить volume к пути `/data`.
3. Задать переменные `MISTRAL_API_KEY`, `ADMIN_PASSWORD`, `PUBLIC_URL`.
4. Сгенерировать домен. Адрес MCP: `https://<домен>/mcp`.
## Подключение в Claude
Web и desktop: Настройки → Коннекторы → Добавить пользовательский коннектор → URL `https://<домен>/mcp`. При подключении откроется страница входа сервера, ввести `ADMIN_PASSWORD`.
Claude Code: `claude mcp add --transport http mistral-ocr https://<домен>/mcp`, затем `/mcp` для авторизации.
## Локальный запуск
```
python -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt
export MISTRAL_API_KEY=… ADMIN_PASSWORD=… PUBLIC_URL=http://127.0.0.1:8080 DATA_DIR=./data
uvicorn app.server:app --port 8080
```
## Ограничения
Mistral OCR возвращает координаты на уровне абзацев (блоков), а не слов. Текстовый слой размещается по прямоугольнику блока с подбором размера шрифта, поэтому поиск и копирование работают по всему тексту, а подсветка найденного фрагмента совпадает с оригиналом с точностью до строки.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues