Mistral OCR MCP Server
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Mistral OCR MCP Serverextract markdown from /Users/me/documents/report.pdf"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Mistral OCR MCP Server
A Model Context Protocol (MCP) server that provides tools for extracting text and images from PDF and image files using the Mistral OCR API.
Features
Local & URL Extraction: Extract markdown from local files or remote URLs
Image Handling on Demand: Optionally save embedded images to disk with proper relative links
Advanced OCR: Page selection, table format control, model selection
Health Check: Built-in API status endpoint
Security Sandbox: Restricts file writes to a configured allowed directory
Zero-Install Deployment: Run with
uvxwithout prior installationSupported Formats: PDF (
.pdf), PNG (.png), JPEG (.jpg,.jpeg), WebP (.webp), GIF (.gif)
Related MCP server: Lizeur
Client Configuration
Claude Desktop
Add this to your claude_desktop_config.json:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"mistral-ocr": {
"command": "uvx",
"args": ["mistral-ocr-mcp"],
"env": {
"MISTRAL_API_KEY": "your-api-key-here",
"MISTRAL_OCR_ALLOWED_DIR": "/absolute/path/to/allowed/directory"
}
}
}
}OpenCode
Add this to the mcp section of your configuration file:
{
"mcp": {
"mistral-ocr": {
"type": "local",
"command": ["uvx", "mistral-ocr-mcp"],
"enabled": true,
"environment": {
"MISTRAL_API_KEY": "your-api-key-here",
"MISTRAL_OCR_ALLOWED_DIR": "/absolute/path/to/allowed/directory"
}
}
}
}Codex
If you use the Codex CLI, you can add the server with:
codex mcp add mistral-ocr -- uvx mistral-ocr-mcpMake sure the environment variables MISTRAL_API_KEY and MISTRAL_OCR_ALLOWED_DIR are set in your shell environment.
Configuration
Required Environment Variables
Variable | Description | Example |
| Your Mistral API key (never logged) |
|
| Absolute path to allowed write directory |
|
Security Sandbox
The server enforces a write directory sandbox to prevent unauthorized file writes.
When include_images is True, the output_dir parameter must be within
MISTRAL_OCR_ALLOWED_DIR. Text-only extraction (include_images=False)
is read-only and has no sandbox restrictions.
Validation Examples:
|
| Result |
|
| ✅ Allowed |
|
| ✅ Allowed (exact match) |
|
| ❌ Rejected |
|
| ❌ Rejected (resolves outside) |
Security Notes:
All paths are canonicalized (symlinks resolved,
..eliminated) before validationImage filenames are sanitized to prevent path traversal attacks
Tool Reference
Tool 1: extract_markdown
Extract markdown from a local file, optionally saving embedded images to disk.
Arguments:
Parameter | Type | Required | Default | Description |
|
| Yes | — | Absolute path to input file (PDF or image) |
|
| No |
| Absolute path to output parent directory. Required when |
|
| No |
| When |
Returns (text-only):
{"result": "# Document Title\n\nExtracted markdown content..."}Returns (with images):
{
"output_directory": "/absolute/path/to/output/report",
"markdown_file": "/absolute/path/to/output/report/content.md",
"images": ["img_abc123.png", "img_def456.jpeg"]
}Behavior (with images):
Creates a subdirectory named after the input file stem (e.g.,
reportforreport.pdf)If the subdirectory already exists, appends a timestamp:
report_20260102_143022Saves all extracted images as
<sanitized_id>.<ext>(e.g.,img_abc123.png)Saves markdown to
content.mdwith relative image links (e.g.,)
Output Structure:
/Users/username/workdir/extracted/
quarterly-report/
content.md # Markdown with relative image links
img_abc123.png # First extracted image
img_def456.jpeg # Second extracted imageTool 2: extract_markdown_from_url
Extract markdown from a publicly accessible URL, optionally saving embedded images to disk.
Arguments:
Parameter | Type | Required | Default | Description |
|
| Yes | — | Public URL to a PDF or image |
|
| No |
| Absolute path to output parent directory. Required when |
|
| No |
| When |
Returns (text-only):
{"result": "# Document Title\n\nExtracted markdown content..."}Returns (with images):
{
"output_directory": "/absolute/path/to/output/doc",
"markdown_file": "/absolute/path/to/output/doc/content.md",
"images": ["img_abc123.png"]
}Tool 3: extract_markdown_advanced
Extract markdown with advanced OCR options.
Arguments:
Parameter | Type | Required | Default | Description |
|
| Yes | — | Absolute path to input file (PDF or image) |
|
| No |
| Page numbers to process (1-indexed, e.g. |
|
| No |
| Table output format ( |
|
| No |
| OCR model to use |
Returns:
{"result": "# Document\n\n| Col 1 | Col 2 |\n|-------|-------|\n..."}Tool 4: ocr_status
Check API connectivity and key validity.
Arguments: none
Returns:
{
"status": "ok",
"message": "API key is working"
}Example Client Usage
Here's a minimal Python example using the MCP SDK to call the tools:
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def extract_document():
server_params = StdioServerParameters(
command="mistral-ocr-mcp",
env={
"MISTRAL_API_KEY": "your-api-key",
"MISTRAL_OCR_ALLOWED_DIR": "/Users/username/workdir"
}
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
# Text-only extraction
result = await session.call_tool(
"extract_markdown",
arguments={"file_path": "/path/to/document.pdf"}
)
print(result.content[0].text)
# Extraction with images
result = await session.call_tool(
"extract_markdown",
arguments={
"file_path": "/path/to/document.pdf",
"include_images": True,
"output_dir": "/Users/username/workdir/output"
}
)
print(result.content[0].text)
# Extract from URL
result = await session.call_tool(
"extract_markdown_from_url",
arguments={"file_url": "https://example.com/doc.pdf"}
)
print(result.content[0].text)
# Check API status
result = await session.call_tool("ocr_status", arguments={})
print(result.content[0].text)
asyncio.run(extract_document())Troubleshooting
Error | Cause | Solution |
|
| Set the environment variable before running the server |
|
| Set the environment variable to an absolute path |
| Relative path provided (e.g., | Use an absolute path (e.g., |
| Directory does not exist on filesystem | Create the directory first: |
| Path points to a file, not a directory | Ensure the path is a directory |
| Relative path provided for input file | Use an absolute path (e.g., |
| Input file does not exist | Check the file path and ensure the file exists |
| File extension not supported | Use |
| Output directory does not exist | Create the directory first: |
| Path points to a file, not a directory | Ensure the path is a directory |
| Output directory exists but is not writable | Check directory permissions: |
|
| Use a path within the allowed directory |
| Invalid API key | Check your |
| Rate limit exceeded | Wait and retry, or check your API quota |
Development
Setup
Clone the repository and install with development dependencies:
git clone https://github.com/ORDIS-Co-Ltd/mistral-ocr-mcp
cd mistral-ocr-mcp
pip install -e '.[dev]'Run the server locally:
MISTRAL_API_KEY="your-key" \
MISTRAL_OCR_ALLOWED_DIR="/path/to/allowed/dir" \
python -m mistral_ocr_mcpRun Tests
pytestProject Structure
mistral-ocr-mcp/
├── src/
│ └── mistral_ocr_mcp/
│ ├── __init__.py
│ ├── __main__.py # Entry point
│ ├── server.py # MCP server and tool definitions
│ ├── config.py # Configuration loading and validation
│ ├── extraction.py # OCR orchestration logic
│ ├── mistral_client.py # Mistral API client
│ ├── images.py # Image parsing and saving
│ ├── markdown_rewrite.py # Markdown link rewriting
│ └── path_sandbox.py # Path validation and sandbox enforcement
├── tests/ # Unit tests
├── pyproject.toml # Package configuration
└── README.md # This fileLicense
MIT
Contributing
Contributions are welcome! Please open an issue or submit a pull request.
Links
GitHub Repository: https://github.com/ORDIS-Co-Ltd/mistral-ocr-mcp
MCP Specification: https://modelcontextprotocol.io
Mistral AI: https://mistral.ai
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityDmaintenanceOCR images or pdfs, locally or by URLs by using Mistral OCR API (paid)40MIT
- AlicenseBqualityDmaintenanceEnables AI assistants to extract and read content from PDF documents using Mistral AI's OCR capabilities. Provides intelligent caching and returns clean markdown text for easy integration with AI workflows.21MIT
- AlicenseAqualityDmaintenanceConverts PDF files from local storage or URLs to structured Markdown format using Mistral AI's OCR API, preserving document structure and extracting images.21MIT
- FlicenseAqualityDmaintenanceExtracts text content from PDFs and images using Mistral's OCR API, enabling OCR capabilities in MCP-compatible clients like Cursor and Claude Desktop.18
Related MCP Connectors
OCR, transcription, file extraction, and image generation for AI agents via MCP.
Turn any PDF into structured JSON via AI + OCR: invoices, bank statements, contracts.
File conversion: PDF, DOCX, STT, TTS, watermarking
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/ORDIS-Co-Ltd/mistral-ocr-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server