Start a server in one minute#
pip install "docling-serve[ui]"
docling-serve run --enable-ui # API: http://127.0.0.1:5001 · docs: /docs · UI: /uidocker run -p 5001:5001 -e DOCLING_SERVE_ENABLE_UI=1 \
quay.io/docling-project/docling-serve-cpudocling-serve run listens on all interfaces (host 0.0.0.0); docling-serve dev binds to 127.0.0.1 and auto-reloads for development. Image choice and GPU variants are on the Docker page.
How a request flows#
Endpoints#
| Method & path | Purpose |
|---|---|
POST /v1/convert/source | Convert from URLs or cloud sources, wait for the result |
POST /v1/convert/file | Convert uploaded files (multipart), wait for the result |
POST /v1/convert/source/async, /v1/convert/file/async | Start a job, return a task_id immediately |
POST /v1/convert/source/batch | Submit several sources as one batch |
POST /v1/chunk/{hybrid|hierarchical}/{source|file}[/async] | Convert and chunk in one call |
GET /v1/status/poll/{task_id} | Job status (pending, started, success, failure…) |
WS /v1/status/ws/{task_id} | Push status updates over a WebSocket |
GET /v1/result/{task_id} | Fetch the finished result |
GET /health, /ready, /version, /v1/capabilities | Health, readiness, versions, enabled features |
GET /docs, /scalar, /ui | Swagger docs, Scalar docs, playground UI |
Paths read from docling_serve/app.py in 1.38.2. Management endpoints (/v1/clear/*, /v1/memory/*) exist but are off unless DOCLING_SERVE_ENABLE_MANAGEMENT_ENDPOINTS is set.
Convert a URL#
curl -X POST http://localhost:5001/v1/convert/source \
-H 'Content-Type: application/json' \
-d '{
"sources": [{"kind": "http", "url": "https://arxiv.org/pdf/2408.09869"}],
"options": {"to_formats": ["md", "json"], "do_ocr": false}
}'The response is a ConvertDocumentResponse: document (with md_content, json_content, html_content, text_content, doctags_content for the formats you asked for), status, errors, processing_time, timings and confidence.
Source kinds accepted in 2.143.1's request model: http, file (base64), s3, azure_blob, google_cloud_storage and google_drive.
Upload a file#
curl -X POST http://localhost:5001/v1/convert/file \
-F 'files=@report.pdf' \
-F 'to_formats=md' \
-F 'do_ocr=false' \
-F 'table_mode=fast'Options become form fields with the same names as in the JSON body; repeat a field for lists (-F to_formats=md -F to_formats=json). The config builder writes these requests for you.
Long documents: async jobs#
import time, requests
BASE = "http://localhost:5001"
job = requests.post(f"{BASE}/v1/convert/source/async", json={
"sources": [{"kind": "http", "url": "https://arxiv.org/pdf/2408.09869"}],
"options": {"to_formats": ["md"]},
}).json()
task_id = job["task_id"]
while True:
status = requests.get(f"{BASE}/v1/status/poll/{task_id}").json()
if status["task_status"] in ("success", "partial_success", "failure"):
break
time.sleep(2)
result = requests.get(f"{BASE}/v1/result/{task_id}").json()
print(result["document"]["md_content"][:300])Options you will actually use#
The JSON options object is ConvertDocumentsOptions. The most common fields and their defaults in 2.143.1:
| Field | Default | Note |
|---|---|---|
to_formats | ["md"] | md, json, html, text, doctags, … |
image_export_mode | placeholder | Unlike the CLI, which defaults to embedded |
do_ocr / force_ocr | true / false | |
ocr_preset / ocr_lang | auto / none | Preset IDs are the CLI engine names; ocr_engine still works but is deprecated. A pip-installed server has no onnxruntime, so the rapidocr preset fails — auto works. With tesseract, always set ocr_lang (eng or iso:en worked; plain en did not). |
pipeline | standard | vlm with vlm_pipeline_preset |
table_mode | accurate | fast is quicker |
page_range | all pages | [1, 10] |
document_timeout | none | Seconds per document |
images_scale | 2.0 | Server caps it at DOCLING_SERVE_MAX_IMAGES_SCALE (2.0) |
do_formula_enrichment, do_code_enrichment, do_picture_description, do_chart_extraction | false | Enrichment models |
Server settings#
All settings are environment variables with the DOCLING_SERVE_ prefix (or a YAML/JSON file given by DOCLING_SERVE_CONFIG_FILE). Uvicorn settings use UVICORN_.
| Variable | Default | What it does |
|---|---|---|
DOCLING_SERVE_ENABLE_UI | false | Serve the playground at /ui |
DOCLING_SERVE_API_KEY | empty (no auth) | Require X-Api-Key |
DOCLING_SERVE_MAX_SYNC_WAIT | 120 | Seconds a sync request waits |
DOCLING_SERVE_ENG_KIND | local | local, rq (Redis queue) or ray |
DOCLING_SERVE_ENG_LOC_NUM_WORKERS | 2 | Parallel jobs in the local engine |
DOCLING_SERVE_MAX_NUM_PAGES, …_MAX_FILE_SIZE | unlimited | Reject oversized documents |
DOCLING_SERVE_MAX_SOURCES_PER_REQUEST | 3 | Sources per call |
DOCLING_SERVE_LOAD_MODELS_AT_BOOT | true | Warm models at start-up |
DOCLING_SERVE_ARTIFACTS_PATH | none | Pre-downloaded models (offline) |
DOCLING_SERVE_ENABLE_REMOTE_SERVICES | false | Allow API-based models |
DOCLING_SERVE_SINGLE_USE_RESULTS, …_RESULT_REMOVAL_DELAY | true, 300 | Delete results after fetching |
DOCLING_SERVE_CORS_ORIGINS | ["*"] | Tighten for browser clients |
Defaults read from docling_serve/settings.py (1.38.2).
Python clients#
Docling ships its own client. It mirrors DocumentConverter, so switching between local and remote conversion is a one-line change.
from docling.datamodel.service.options import ConvertDocumentsOptions
from docling.service_client import DoclingServiceClient
with DoclingServiceClient(url="http://localhost:5001") as client: # api_key="..." if set
result = client.convert(
"https://arxiv.org/pdf/2408.09869",
options=ConvertDocumentsOptions(do_ocr=False, to_formats=["md"]),
)
print(result.document.export_to_markdown()[:300])Install it without PyTorch via pip install "docling-slim[service-client]"; the same extra adds the docling convert-remote command (see the CLI reference).
MCP: Docling for AI agents#
docling-mcp exposes conversion and document tools to MCP clients such as Claude Desktop or LM Studio. In version 3.x the default conversion mode is remote, so point it at a docling-serve instance — or install the local extra.
{
"mcpServers": {
"docling": {
"command": "uvx",
"args": ["--from=docling-mcp", "docling-mcp-server"],
"env": {
"DOCLING_MCP_CONVERSION_MODE": "remote",
"DOCLING_MCP_SERVICE_URL": "http://localhost:5001"
}
}
}
}uvx --from "docling-mcp[local]" docling-mcp-server --transport stdio
# with DOCLING_MCP_CONVERSION_MODE=local in the environmentTransports: stdio (desktop clients), sse and streamable-http (containers). docling-mcp 3.x requires MCP SDK 2.x; pin docling-mcp<3.0.0 for clients that have not migrated.
Production checklist#
- Set
DOCLING_SERVE_API_KEYand restrictDOCLING_SERVE_CORS_ORIGINS. - Use the async endpoints for anything over a few pages; sync calls are capped at 120 s.
- Cap input with
DOCLING_SERVE_MAX_NUM_PAGESandDOCLING_SERVE_MAX_FILE_SIZE. - Pre-download models into the image (
DOCLING_SERVE_ARTIFACTS_PATH) so pods start without internet. - Scale out with
DOCLING_SERVE_ENG_KIND=rqand Redis workers when one machine is not enough.
Frequently asked questions
What port does docling-serve use?
5001 by default. The API is at http://127.0.0.1:5001, interactive API docs at /docs and, when enabled with --enable-ui or DOCLING_SERVE_ENABLE_UI=1, a playground UI at /ui.
How do I add authentication to docling-serve?
Set DOCLING_SERVE_API_KEY to a secret. Clients must then send it in the X-Api-Key header.
Why does my synchronous docling-serve request time out?
Synchronous endpoints wait up to DOCLING_SERVE_MAX_SYNC_WAIT seconds (120 by default). For long documents use the /async endpoints and poll for the result, or raise the limit.
Can I fetch a docling-serve result twice?
Not by default. DOCLING_SERVE_SINGLE_USE_RESULTS is true, so a result is deleted after it is fetched (after a 300-second delay). Set it to false if clients may retry.
How do I connect Docling to Claude Desktop or another MCP client?
Use docling-mcp: add a server entry that runs uvx --from docling-mcp docling-mcp-server. Since docling-mcp 3.x the default mode is remote, so set DOCLING_MCP_SERVICE_URL to your docling-serve, or install docling-mcp[local] and set DOCLING_MCP_CONVERSION_MODE=local.
Sources
- docling-serve 1.38.2 source: app.py, settings.py, auth.py
- docling-serve documentation
- docling 2.143.1: ConvertDocumentsOptions (docling/datamodel/service/options.py)
- docling-mcp 3.3.0 README