Skip to main content
Glama

MCP Mistral OCR

An MCP server that provides OCR capabilities using Mistral AI's OCR API. Supports stdio (for Claude Desktop / Smithery) and streamable HTTP (for remote clients). Runs with or without Docker.

Features

  • Dual transport: streamable HTTP (default) or stdio for Claude Desktop / Smithery

  • Process local files (images and PDFs) and files from URLs

  • Primary flow: Call process_url_file with a URL to get OCR output (markdown or full JSON)

  • No Docker required: run locally with uv run and optional OCR_DIR

  • Results saved as timestamped .json (full Mistral response) and .md (extracted markdown) in OCR_DIR/output/ (optional; set OCR_SAVE_RESULTS=false to disable). When saving is on, the tool returns only the download links (over HTTP) or file paths (over stdio): no full content in the response. Over streamable HTTP, use the returned URLs to download the JSON and Markdown files (e.g. http://127.0.0.1:8000/output/<filename>.json).

  • Docker optional for deployment

Usage

The main use case is URL in, OCR out. Call the process_url_file tool with a document or image URL. You can omit file_type if the URL has a .pdf or image extension (e.g. .jpg, .png). Use output_format="markdown" to get only the extracted text, or output_format="full" (default) for the full Mistral response JSON.

Download URLs: To get clickable "Download JSON" and "Download Markdown" URLs in the tool response, set OCR_DOWNLOAD_BASE_URL (e.g. in .env). Use a different port than the MCP server (e.g. 8001) so they don't conflict. One-command start: from the project root run uv run python run_servers.py to start both the file server (8001) and the MCP server (8000); Ctrl+C stops both.

Google Drive: View/share links (e.g. https://drive.google.com/file/d/FILE_ID/view?usp=sharing) are supported. The server rewrites them to the direct-download URL so the OCR API receives the file content. For Drive links, file_type can be omitted and defaults to pdf; for images in Drive, pass file_type="image". URLs are trimmed before detection. File type inference: If the URL has no extension and is not a known Drive link, the server sends a HEAD request to the URL and infers type from the Content-Type header (e.g. application/pdf → pdf); if still unknown, it defaults to pdf so the first API call usually succeeds without requiring file_type.

Environment Variables

Variable

Required

Default

Description

MISTRAL_API_KEY

Yes

Your Mistral AI API key

OCR_DIR

No

./ocr_data

Directory for local files and output/ subdir

OCR_SAVE_RESULTS

No

true

Set to false to disable saving results to OCR_DIR/output/

OCR_DOWNLOAD_BASE_URL

No

Base URL for download links. Use a port other than MCP (e.g. http://127.0.0.1:8001). Run python -m http.server 8001 --directory ocr_data from project root so GET /output/&lt;filename&gt; serves the files.

MCP_TRANSPORT

No

streamable-http

stdio or streamable-http

MCP_HTTP_HOST

No

127.0.0.1

Bind host when using streamable HTTP

MCP_HTTP_PORT

No

8000

Port when using Streamable HTTP or SSE

MCP_HTTP_PATH

No

mcp

URL path (e.g. /mcphttp://host:8000/mcp)

Running without Docker

Python: This project uses Python 3.10–3.13 (not 3.14+) so dependencies like pydantic-core use pre-built wheels. If you only have Python 3.14, install 3.12 (e.g. from python.org) and run:

uv sync --python 3.12

Stdio (e.g. Claude Desktop, Smithery)

  1. Install uv and run:

cd mistral-ocr-mcp
uv sync
  1. Set MISTRAL_API_KEY and optionally OCR_DIR (defaults to ./ocr_data).

  2. Run the server (stdio):

# Windows (PowerShell)
$env:MISTRAL_API_KEY="your_key"
uv run python -m src.main

# Windows (CMD) / Unix
set MISTRAL_API_KEY=your_key          # CMD
export MISTRAL_API_KEY=your_key      # Bash
uv run python -m src.main

Or with a custom OCR directory:

export OCR_DIR=/path/to/your/files   # or set on Windows
uv run python -m src.main

Streamable HTTP (for MCP Inspector, HTTP clients)

Start the server with streamable HTTP:

export MISTRAL_API_KEY=your_key
export MCP_TRANSPORT=streamable-http
export MCP_HTTP_PORT=8000
uv run python -m src.main

Then connect clients to http://127.0.0.1:8000/mcp (Streamable HTTP; e.g. MCP Inspector: npx -y @modelcontextprotocol/inspector).

Optional: bind all interfaces and custom path:

export MCP_TRANSPORT=streamable-http
export MCP_HTTP_HOST=0.0.0.0
export MCP_HTTP_PORT=8000
export MCP_HTTP_PATH=/mcp
uv run python -m src.main

Claude Desktop configuration

Option A: No Docker (stdio)

Point Claude to the project and use stdio:

{
  "mcpServers": {
    "mistral-ocr": {
      "command": "uv",
      "args": ["run", "python", "-m", "src.main"],
      "cwd": "C:\\path\\to\\mistral-ocr-mcp",
      "env": {
        "MISTRAL_API_KEY": "<YOUR_MISTRAL_API_KEY>",
        "MCP_TRANSPORT": "stdio",
        "OCR_DIR": "C:\\path\\to\\your\\files"
      }
    }
  }
}

(Adjust cwd and OCR_DIR for your machine. Omit OCR_DIR to use default ./ocr_data.)

Option B: Docker (stdio)

{
  "mcpServers": {
    "mistral-ocr": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e",
        "MISTRAL_API_KEY",
        "-e",
        "OCR_DIR",
        "-v",
        "C:/path/to/your/files:/data/ocr",
        "mcp-mistral-ocr:latest"
      ],
      "env": {
        "MISTRAL_API_KEY": "<YOUR_MISTRAL_API_KEY>",
        "OCR_DIR": "C:/path/to/your/files"
      }
    }
  }
}

Build and run:

docker build -t mcp-mistral-ocr .
docker run -e MISTRAL_API_KEY=your_key -e OCR_DIR=/data/ocr -v C:/path/to/files:/data/ocr mcp-mistral-ocr

Smithery

Install via Smithery (stdio):

npx -y @smithery/cli install @everaldo/mcp/mistral-crosswalk --client claude

Available tools

  • process_url_file(url, file_type=None, output_format="full", pages=None, table_format=None, extract_header=False, extract_footer=False) – Primary tool: process a file from a URL. file_type is optional if the URL has a .pdf or image extension. output_format: "full" (default) returns full JSON; "markdown" returns only the extracted text. pages: optional list of 0-based page indices to process. table_format: "markdown" or "html" for tables. extract_header / extract_footer: set to True to extract header/footer.

  • process_local_file(filename, output_format="full", pages=None, table_format=None, extract_header=False, extract_footer=False) – Process a file from OCR_DIR (e.g. document.pdf, image.png). Same optional parameters as above.

Limits: 50MB max file size, 1000 pages (Mistral API).

Output

When OCR_SAVE_RESULTS is true (default), results are written to OCR_DIR/output/ as JSON:

  • Local: {filename_stem}_{YYYYMMDD_HHMMSS}.json

  • URL: {url_path_stem}_{timestamp}.json or url_document_{timestamp}.json

Set OCR_SAVE_RESULTS=false to return OCR only to the client without writing files.

Supported file types

  • Images: JPG, JPEG, PNG, GIF, WebP

  • Documents: PDF and other formats supported by Mistral OCR

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/charley-forey/mistral-ocr-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server