Open-source project
docling-project/docling-mcp avatar
docling-project/docling-mcp

docling-mcp: exposing Docling document conversion as MCP tools

Making docling agentic through MCP

776 stars144 forksPythonMIT

At a glance

What is it?
docling-mcp is a Model Context Protocol server that puts Docling's PDF to structured document conversion in front of an agent, with a remote mode that calls a Docling Serve API, a local mode that runs conversion in process, and a hybrid mode that falls back to local when the service is unreachable. It suits teams building retrieval or document ingestion pipelines, but the local and remote modes have different capabilities and the cache holds only ten documents by default.
Who is it for?
Adopt docling-mcp when an agent in your stack needs to turn PDFs into structured documents and you would rather not wire Docling into the agent runtime yourself, and pick the mode that matches where the conversion happens.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The MCP server that wraps Docling's document converter

docling-mcp is a Model Context Protocol server built around the Docling library. The project description is blunt about its goal, running Docling as an agent using tools, and the overview describes it as a service that provides tools for document conversion, processing and generation, using the Docling library to convert PDF documents into structured formats with a caching mechanism to improve performance.

The functions it exposes fall into two groups. The conversion tools turn a PDF into a structured JSON representation called DoclingDocument. The generation tools work in the other direction, producing a document in DoclingDocument form that can then be exported to multiple formats. The project also lists local file and URL sources, memory management for large documents, a logging system for debugging and monitoring, and RAG support with Milvus upload and retrieval.

The server itself is a small Python package, `docling_mcp/`, at the root of a repository that also carries `docs/`, `examples/`, `tests/`, a `Makefile`, a `MIGRATION.md`, a `server.json` and a `glama.json` for registry metadata. There is a `mcpb/` directory and the package is listed in the MCP Registry.

The examples directory shows the intended client shapes: `examples/llama-index/`, `examples/llama-stack/`, `examples/mellea/`, `examples/pydanticai/` and `examples/smolagents/`. So the server is not tied to one agent framework, which is the point of using MCP rather than a bespoke integration.

The package is MIT licensed, published on PyPI as `docling-mcp`, built with hatchling, and the project metadata names six authors and maintainers with affiliations at IBM Research and Red Hat.

Three conversion modes and the environment variables that pick one

The interesting design decision is that conversion can happen in three places, and the choice is made entirely through environment variables prefixed `DOCLING_MCP_`.

Remote mode is the recommended and lightest option. It requires a Docling Serve instance, which the documentation says you can deploy from published container images or find as a managed offering, and the server then calls that API:

bash
pip install docling-mcp
bash
export DOCLING_MCP_SERVICE_URL=https://your-docling-service.example.com
export DOCLING_MCP_SERVICE_API_KEY=your-api-key-here
export DOCLING_MCP_CONVERSION_MODE=remote

Local mode runs the conversion in your own process, which the documentation gives as the option for people who need local conversion or have no access to Docling Serve:

bash
pip install docling-mcp[local]
bash
export DOCLING_MCP_CONVERSION_MODE=local

Hybrid mode is remote with a local safety net, and the documentation calls it the best of both. It needs the local extra installed, and it enables the fallback flag:

bash
pip install docling-mcp[local]
bash
export DOCLING_MCP_SERVICE_URL=https://your-docling-service.example.com
export DOCLING_MCP_CONVERSION_MODE=remote
export DOCLING_MCP_FALLBACK_TO_LOCAL=true

Settings can be provided as environment variables, in a `.env` file in the working directory, or through the `env` block of an MCP client config, and the repository ships a `.env.example` to copy as a starting point. The remote settings also include `DOCLING_MCP_SERVICE_TIMEOUT`, defaulting to 300.0 seconds for a whole conversion job, and `DOCLING_MCP_SERVICE_MAX_RETRIES`, defaulting to 3.

The fallback is worth understanding precisely. It fires when the service is unreachable, so a network outage degrades to slower local conversion rather than an error, but it says nothing about the case where the service is reachable and returns a bad conversion.

The pipeline switches, and what a vision model costs you

Beyond the mode selection, the pipeline is configured by booleans that apply in both remote and local mode. `DOCLING_MCP_DO_OCR` defaults to true, `DOCLING_MCP_DO_TABLE_STRUCTURE` defaults to true, `DOCLING_MCP_KEEP_IMAGES` defaults to false, and `DOCLING_MCP_IMAGES_SCALE` defaults to 1.0.

That last one has a specific reason attached to it in the configuration table. The image scale factor is there to increase to avoid tensor padding errors, which is the kind of detail that only shows up on a specific model and a specific document size.

The expensive switch is `DOCLING_MCP_DO_PICTURE_DESCRIPTION`, which defaults to false and runs a vision-language model to generate textual descriptions for figures and pictures. The documentation carries an explicit warning: enabling it adds a VLM inference step for every figure in the document, and on resource-constrained hardware such as a laptop running the model on CPU it can significantly increase conversion time.

When it is enabled, `DOCLING_MCP_PICTURE_DESCRIPTION_PRESET` selects the model by preset ID, with `smolvlm` and `granite_vision` named as examples, and when it is unset the backend default is used. This flag applies only when picture description is on.

The two modes have a second, subtler difference that the documentation does not spell out in one sentence. The remote service has a five minute default timeout for a whole job, and the documentation notes that the MCP client itself may also enforce its own request timeout, giving LM Studio's `mcp.json` as the place to set it in milliseconds. So a long conversion can fail at either layer, and both need raising.

A separate group of settings handles Markdown export. `DOCLING_MCP_IMAGE_EXPORT_MODE` controls how images are rendered in Markdown output: `placeholder` is the default and emits an HTML comment, `embedded` produces a base64 data URI, and `referenced` writes a file path or URL.

The in-memory cache holds ten documents and evicts the oldest

The caching mechanism gets a short entry in the feature list, but the environment file spells out the behaviour, and it is worth reading before you rely on it.

`DOCLING_MCP_CACHE_MAX_DOCUMENTS` sets the maximum number of documents kept in the in-memory cache, and the default is 10. When the limit is reached, the least recently used document is evicted. Three properties follow from that. The cache is in memory, so it does not survive a restart. It is small, so a batch job that converts twenty documents in sequence will be evicting as it goes. And it is a cache of converted documents, not of raw files, so a hit avoids the expensive part, the model inference, not merely the download.

For an agent that converts the same PDF repeatedly, this is a large saving. For a pipeline that sweeps a directory of distinct documents, the benefit is smaller than the name suggests, and the ten document default is the number to raise first if you see repeated work.

The repository also has a `.env.example` section devoted to a LlamaIndex RAG tool, which lines up with the RAG feature listed in the README, covering Milvus upload and retrieval. The excerpt of that file is truncated in what is available here, so the specific variable names for that integration are not fully visible.

The `DOCLING_MCP_IMAGE_EXPORT_MODE` setting deserves a second mention because it interacts with caching. A cached document exported in `embedded` mode carries base64 image data inside it, which is considerably larger than the `placeholder` representation, so the choice of export mode affects both the size of your responses and how much of the ten document cache you fill.

MCP SDK v2 broke the tool contract for existing clients

The compatibility table is the most important paragraph in the README for anyone running this in production.

| docling-mcp | MCP Python SDK | |---|---| | `>=3.0.0` | `mcp>=2.0.0` | | `>=2.0.0,<3.0.0` | `mcp>=1.9.4,<2.0.0` |

docling-mcp 3.0.0 and above need the second generation of the MCP Python SDK, while the 2.x line of docling-mcp is pinned to the 1.9.4 and earlier SDK line. These are not compatible with each other, which means the version of the server you install is determined by your client, not by preference.

The documentation gives the escape hatch for clients that have not migrated yet:

bash
pip install "docling-mcp<3.0.0"

and points at `MIGRATION.md` for the full migration guide, which is a separate file in the repository root.

The release history shows how fast this has been moving: v3.3.0 on 2026-10-06, v3.2.1 on 2026-09-24 and v3.2.0 on 2026-09-01, with the last push on 2026-10-19. Three releases in five weeks across a major version boundary is a fast-moving project, which is good for bug fixes and awkward for a pinned deployment.

The `server.json` and `glama.json` files, and the MCP Registry listing badge, mean the server is discoverable through the standard registries, so a client may be able to resolve its configuration rather than hard-coding the command line.

Development workflow built on uv, Ruff, prek and ty

The Makefile is short enough to read as a summary of how the project is developed. There are nine targets.

`setup` installs the development environment the way CI does, with `uv sync --frozen --all-extras`. `hooks-install` installs the git hooks through prek. `check` runs the read-only local checks: Ruff format check, Ruff lint, the type checker `ty`, and a check that the lock file is current. `validate` runs the hooks on whatever has changed in the working tree, and `validate-all` runs them across every file. `fix` applies Ruff formatting and autofixes, `typecheck` runs `ty` on its own, and `test` runs the suite with coverage:

bash
	uv run pytest --cov=docling_mcp --cov-report=xml tests

The tooling is worth noting because it is all pre-commit oriented. Ruff does both formatting and linting, `ty` handles type checking, and prek runs the hooks, with a `.pre-commit-config.yaml` in the repository root. There is no separate CI-only lint step, because the same hooks run in both places.

The package metadata confirms the toolchain: the badges point at uv, Ruff, Pydantic v2 and prek, and the classifiers list Python 3.10 through 3.14 with `requires-python = >=3.10`. The `uv.lock` file is committed, which is what makes `uv sync --frozen` meaningful and reproducible.

The `CITATION.cff` file, `CODE_OF_CONDUCT.md`, `CONTRIBUTING.md` and `MAINTAINERS.md` round out the repository. The `Makefile` targets assume a POSIX shell, since several of them use `$(...)` and `$$(...)` constructs, so on Windows the make invocation itself will need a POSIX environment.

Editorial conclusion

Adopt docling-mcp when an agent in your stack needs to turn PDFs into structured documents and you would rather not wire Docling into the agent runtime yourself, and pick the mode that matches where the conversion happens. Do not adopt it if you need a stable tool contract, since the package has already crossed a major version boundary with an MCP SDK v2 migration, and check first that your client has moved to mcp 2.0 or pin docling-mcp below 3.0.0 as the compatibility table requires.

Frequently asked questions

What does docling-mcp do?

It is a Model Context Protocol server that exposes Docling's document conversion, processing and generation as tools, converting PDFs into structured DoclingDocument JSON with caching, and supporting local files and URLs as sources.

How do I install docling-mcp in local mode?

Run `pip install docling-mcp[local]` and set `DOCLING_MCP_CONVERSION_MODE=local`. Local mode runs a bundled DocumentConverter in your own process and is the option for people without access to a Docling Serve instance.

What is the difference between docling-mcp 3.x and 2.x?

docling-mcp 3.0.0 and above require the MCP Python SDK 2.0 or newer, while the 2.x line pins to mcp 1.9.4 and below. If your client has not migrated to SDK v2, install `docling-mcp<3.0.0` and see MIGRATION.md.

How large is the document cache in docling-mcp?

The in-memory cache keeps at most 10 documents by default, controlled by `DOCLING_MCP_CACHE_MAX_DOCUMENTS`, and the least recently used document is evicted when the limit is reached. The cache does not survive a restart.

What does DOCLING_MCP_DO_PICTURE_DESCRIPTION cost?

It runs a vision-language model for every figure in the document, and the documentation warns that on resource-constrained hardware such as a CPU-only laptop it can significantly increase conversion time. The preset is chosen with `DOCLING_MCP_PICTURE_DESCRIPTION_PRESET`, for example smolvlm or granite_vision.

Is docling-mcp still being developed?

The repository is not archived and the last push was on 2026-10-19. Recent releases include v3.3.0 on 2026-10-06, v3.2.1 on 2026-09-24 and v3.2.0 on 2026-09-01, and the package is MIT licensed.

Official sources

  1. docling-project/docling-mcp on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/docling-project-docling-mcp.svg)](https://hysenlabs.com/projects/docling-project-docling-mcp)

Was this useful?