{
  "slug": "io-github-docling-project-docling-mcp",
  "name": "io.github.docling-project/docling-mcp",
  "title": "Docling MCP",
  "description": "Convert PDFs and other documents to structured formats via Docling, for AI applications.",
  "version": "3.4.0",
  "publishedAt": "2026-10-27T21:39:42.613162Z",
  "updatedAt": "2026-10-27T21:39:42.613162Z",
  "repoUrl": "https://github.com/docling-project/docling-mcp",
  "websiteUrl": null,
  "namespace": {
    "type": "github",
    "owner": "docling-project"
  },
  "kind": "local",
  "packages": [
    {
      "registryType": "pypi",
      "identifier": "docling-mcp",
      "version": "3.4.0",
      "transport": "stdio",
      "runtimeHint": "uvx"
    }
  ],
  "remotes": [],
  "envVars": [
    {
      "name": "DOCLING_MCP_CONVERSION_MODE",
      "isSecret": false,
      "isRequired": false,
      "description": "Conversion mode: 'remote' (default) or 'local' (requires docling-mcp[local] extra)."
    },
    {
      "name": "DOCLING_MCP_SERVICE_URL",
      "isSecret": false,
      "isRequired": false,
      "description": "Base URL of the Docling Serve instance. Required when conversion mode is remote."
    },
    {
      "name": "DOCLING_MCP_SERVICE_API_KEY",
      "isSecret": true,
      "isRequired": false,
      "description": "API key for authenticating with Docling Serve."
    },
    {
      "name": "DOCLING_MCP_SERVICE_TIMEOUT",
      "isSecret": false,
      "isRequired": false,
      "description": "Request timeout in seconds for the remote Docling Serve API. Default: 300.0."
    },
    {
      "name": "DOCLING_MCP_SERVICE_MAX_RETRIES",
      "isSecret": false,
      "isRequired": false,
      "description": "Maximum number of retry attempts for remote API requests. Default: 3."
    },
    {
      "name": "DOCLING_MCP_FALLBACK_TO_LOCAL",
      "isSecret": false,
      "isRequired": false,
      "description": "Set to 'true' to fall back to local conversion when Docling Serve is unreachable."
    },
    {
      "name": "DOCLING_MCP_KEEP_IMAGES",
      "isSecret": false,
      "isRequired": false,
      "description": "Set to 'true' to retain page images in converted documents. Default: false."
    },
    {
      "name": "DOCLING_MCP_IMAGES_SCALE",
      "isSecret": false,
      "isRequired": false,
      "description": "Image scale factor (e.g. 1.0, 2.0). Increase to avoid tensor batching errors. Default: 1.0."
    },
    {
      "name": "DOCLING_MCP_DO_OCR",
      "isSecret": false,
      "isRequired": false,
      "description": "Set to 'false' to disable the OCR pipeline. Default: true."
    },
    {
      "name": "DOCLING_MCP_DO_TABLE_STRUCTURE",
      "isSecret": false,
      "isRequired": false,
      "description": "Set to 'false' to disable table structure detection. Default: true."
    },
    {
      "name": "DOCLING_MCP_DO_PICTURE_DESCRIPTION",
      "isSecret": false,
      "isRequired": false,
      "description": "Set to 'true' to run a vision-language model to generate textual descriptions for figures and pictures. Requires a VLM to be available on the conversion backend. Default: false."
    },
    {
      "name": "DOCLING_MCP_PICTURE_DESCRIPTION_PRESET",
      "isSecret": false,
      "isRequired": false,
      "description": "Preset ID for the picture-description VLM (e.g. 'smolvlm', 'granite_vision'). When unset the backend default is used. Only applies when DOCLING_MCP_DO_PICTURE_DESCRIPTION=true."
    },
    {
      "name": "DOCLING_MCP_IMAGE_EXPORT_MODE",
      "isSecret": false,
      "isRequired": false,
      "description": "Controls how images are rendered when exporting to Markdown. Accepted values: 'placeholder' (default, emits <!-- image -->), 'embedded' (base64 data-URI), 'referenced' (file path / URL)."
    },
    {
      "name": "DOCLING_MCP_CACHE_MAX_DOCUMENTS",
      "isSecret": false,
      "isRequired": false,
      "description": "Maximum number of documents to keep in the in-memory cache. Oldest (least-recently-used) documents are evicted when the limit is reached. Default: 10."
    }
  ],
  "category": "files-docs",
  "subcategory": "more",
  "company": "",
  "categoryAuto": true,
  "checks": [
    {
      "id": "source-linked",
      "label": "Source repository linked",
      "result": "pass",
      "detail": "https://github.com/docling-project/docling-mcp"
    },
    {
      "id": "version-pinned",
      "label": "Version pinned",
      "result": "pass",
      "detail": "Every package has an explicit version"
    },
    {
      "id": "secrets-requested",
      "label": "Secrets requested",
      "result": "info",
      "detail": "Asks for 1 secret: DOCLING_MCP_SERVICE_API_KEY"
    },
    {
      "id": "known-registry",
      "label": "Known package registry",
      "result": "pass",
      "detail": "All packages come from npm, PyPI, OCI, NuGet or MCPB"
    },
    {
      "id": "namespace",
      "label": "Namespace ownership",
      "result": "info",
      "detail": "Name verified via GitHub account docling-project"
    },
    {
      "id": "meta-text",
      "label": "Registry text aimed at the AI",
      "result": "pass",
      "detail": "Description and settings contain no hidden characters or instructions to the AI"
    },
    {
      "id": "install-scripts",
      "label": "Install scripts",
      "result": "pass",
      "detail": "docling-mcp 3.4.0 has no setup.py; nothing runs at install"
    },
    {
      "id": "code-flags",
      "label": "Code red flags",
      "result": "pass",
      "detail": "Read 33 files in docling-mcp 3.4.0: no obfuscation, encoded execution, credential reads or data-collection endpoints found"
    },
    {
      "id": "ai-text",
      "label": "Text aimed at the AI",
      "result": "pass",
      "detail": "No hidden characters or instructions to the AI in 33 files, including comments and the README"
    }
  ],
  "scannedAt": "2026-10-29",
  "level": "Scanned",
  "install": [
    {
      "label": "Claude Desktop (pypi)",
      "kind": "claude_desktop_json",
      "text": "{\n  \"mcpServers\": {\n    \"docling-mcp\": {\n      \"command\": \"uvx\",\n      \"args\": [\n        \"docling-mcp==3.4.0\"\n      ]\n    }\n  }\n}"
    }
  ],
  "curated": true,
  "stars": 779,
  "archived": false,
  "pushedAt": "2026-10-27T21:38:56Z",
  "review": {
    "package": "docling-mcp",
    "version": "3.4.0",
    "at": "2026-10-31",
    "files": 31,
    "lines": 3301,
    "verdict": "pass-with-notes",
    "summary": "Converts PDFs, Office files, web pages and images into structured documents your AI can read, search, edit and save. By default it sends each document to a Docling conversion service you must point it at. In local mode it converts on your machine but downloads AI models from Hugging Face first. Watch out: it can read any file or folder path the AI gives it. It also runs as a local web server on port 8000 unless you choose stdio.",
    "hosts": [
      {
        "host": "DOCLING_MCP_SERVICE_URL (user-set docling-serve instance; default conversion mode is 'remote')",
        "when": "when a conversion tool is called (health check + convert)",
        "sends": "the document: local files are uploaded, http(s) URLs are passed for the service to fetch, object-storage bodies are uploaded from memory; plus DOCLING_MCP_SERVICE_API_KEY"
      },
      {
        "host": "any http(s) URL given as 'source'",
        "when": "convert tool in local mode (fetched by docling's DocumentConverter on this machine)",
        "sends": "an HTTP GET request for the document"
      },
      {
        "host": "s3:// gs:// gcs:// abfs:// az:// object storage via fsspec",
        "when": "convert tool with such a URI (optional extras)",
        "sends": "read requests signed with ambient cloud credentials (env/config files/instance roles)"
      },
      {
        "host": "HuggingFace Hub (docling layout/OCR/table models, optional VLM preset)",
        "when": "first local conversion; done by the docling library, not package code",
        "sends": "model download requests"
      },
      {
        "host": "huggingface.co (BAAI/bge-base-en-v1.5 embedding model)",
        "when": "at startup only if the optional llama-index-rag tool group is enabled",
        "sends": "model download requests"
      },
      {
        "host": "DOCLING_MCP_LI_API_BASE (default http://127.0.0.1:1234/v1, OpenAI-compatible LLM)",
        "when": "search_documents tool (optional llama-index-rag group)",
        "sends": "the query plus retrieved document chunks"
      },
      {
        "host": "DOCLING_MCP_LLS_URL (default http://localhost:8321, Llama Stack)",
        "when": "insert_document_to_vectordb / information_extraction (optional llama-stack groups)",
        "sends": "document chunks or the full document markdown plus the extraction prompt"
      },
      {
        "host": "huggingface.co (sentence-transformers/<DOCLING_MCP_LLS_VDB_EMBEDDING> tokenizer)",
        "when": "insert_document_to_vectordb (optional)",
        "sends": "tokenizer download request"
      },
      {
        "host": "localhost:8000 (listens; default transport is streamable-http)",
        "when": "for the whole time the server runs unless --transport stdio",
        "sends": "serves MCP tool calls; no authentication layer in package code"
      }
    ],
    "env": [
      {
        "name": "DOCLING_MCP_SERVICE_URL",
        "sent_to": "remote converter target; logged at INFO"
      },
      {
        "name": "DOCLING_MCP_SERVICE_API_KEY",
        "sent_to": "the docling-serve instance only; not logged"
      },
      {
        "name": "DOCLING_MCP_CONVERSION_MODE / FALLBACK_TO_LOCAL / KEEP_IMAGES / IMAGES_SCALE / DO_OCR / DO_TABLE_STRUCTURE / DO_PICTURE_DESCRIPTION / PICTURE_DESCRIPTION_PRESET / IMAGE_EXPORT_MODE / CACHE_MAX_DOCUMENTS / SERVICE_TIMEOUT / SERVICE_MAX_RETRIES",
        "sent_to": "local config (pipeline options also sent to docling-serve in remote mode)"
      },
      {
        "name": "DOCLING_MCP_LI_API_BASE / DOCLING_MCP_LI_API_KEY / DOCLING_MCP_LI_MODEL_ID / DOCLING_MCP_LI_EMBEDDING_MODEL",
        "sent_to": "the configured OpenAI-compatible endpoint (optional group)"
      },
      {
        "name": "DOCLING_MCP_LLS_URL / DOCLING_MCP_LLS_VDB_EMBEDDING / DOCLING_MCP_LLS_EXTRACTION_MODEL",
        "sent_to": "the configured Llama Stack server (optional group)"
      },
      {
        "name": "CACHE_DIR",
        "sent_to": "local only: where saved .md/.json/.png files go"
      },
      {
        "name": "Cloud credentials for s3/gcs/azure (ambient, read by fsspec providers)",
        "sent_to": "the matching object-storage provider"
      },
      {
        "name": ".env file in the working directory",
        "sent_to": "read by pydantic-settings for all of the above"
      }
    ],
    "local": "By design, convert_document_into_docling_document reads any local file path the AI passes, and convert_directory_files_into_docling_document lists and reads every file in any directory. The content is returned to the AI and, in remote mode, uploaded to docling-serve. save_docling_document and get_page_thumbnail write <key>.md, <key>.json and <key>-<page>.png into a _cache directory. That directory is CACHE_DIR, or by default sits next to the installed package (e.g. site-packages/_cache). Filenames come from existing cache keys, so tool input cannot cause path traversal on write. The optional llama-index group creates ./milvus_demo.db in the working directory (overwrite=True). Object-storage sources are copied to a temp file that is deleted afterwards.",
    "exec": "None in package code: no subprocess, os.system, eval or exec. Optional tool groups are imported by fixed module names.",
    "telemetry": "None in package code.",
    "tools": [
      "check_document_in_local_cache",
      "remove_document_from_local_cache",
      "convert_document_into_docling_document",
      "convert_directory_files_into_docling_document",
      "list_cached_documents",
      "create_new_docling_document",
      "export_docling_document_to_markdown",
      "save_docling_document",
      "get_page_thumbnail",
      "add_title_to_docling_document",
      "add_section_heading_to_docling_document",
      "add_paragraph_to_docling_document",
      "open_list_in_docling_document",
      "close_list_in_docling_document",
      "add_list_items_to_list_in_docling_document",
      "add_table_in_html_format_to_docling_document",
      "get_overview_of_document_anchors",
      "search_for_text_in_document_anchors",
      "get_text_of_document_item_at_anchor",
      "update_text_of_document_item_at_anchor",
      "delete_document_items_at_anchors",
      "export_docling_document_to_vector_db (optional llama-index-rag)",
      "search_documents (optional llama-index-rag)",
      "insert_document_to_vectordb (optional llama-stack-rag)",
      "information_extraction (optional llama-stack-ie)"
    ],
    "toolText": "clean. Seven MCP prompts (Convert document, Convert and summarize, Convert directory, Author structured document, Convert and rewrite, Review and edit, Find and replace) only tell the AI to call this server's own tools. 'Find and replace' even tells the AI to confirm with the user before applying keyword-only matches. No hidden or invisible text.",
    "deps": [
      "mcp",
      "typer",
      "pydantic",
      "pydantic-settings",
      "docling-core",
      "docling (or docling-slim; [local] extra)",
      "fsspec + s3fs / gcsfs / adlfs (optional extras)",
      "llama-index-core",
      "llama-index-embeddings-huggingface",
      "llama-index-llms-openai-like",
      "llama-index-node-parser-docling",
      "llama-index-vector-stores-milvus",
      "llama-stack-client",
      "transformers"
    ],
    "findings": [
      {
        "severity": "note",
        "at": "docling_mcp/tools/conversion.py:116-192",
        "what": "Conversion tools accept any local file or directory path, so the AI can read any file the user's account can read. This is the server's purpose, but it is reachable from prompt-injected content too."
      },
      {
        "severity": "note",
        "at": "docling_mcp/settings/service_client.py:41-61 + tools/converters/remote.py:28-50",
        "what": "The default conversion mode is 'remote'. Once DOCLING_MCP_SERVICE_URL is set, documents (including local files) are uploaded to that docling-serve instance. Until it is set, conversion fails with a clear error. No default remote host is hard-coded."
      },
      {
        "severity": "note",
        "at": "docling_mcp/servers/mcp_server.py:38-40",
        "what": "The default transport is streamable-http on localhost:8000, and the package adds no authentication. Any local process (and any page that gets past the SDK's DNS-rebinding protection) can call the file-reading tools. Use --transport stdio for single-client desktop use."
      },
      {
        "severity": "note",
        "at": "docling_mcp/tools/converters/local.py:73-100",
        "what": "In local mode, docling downloads its layout/OCR/table models (HuggingFace Hub) on first use and fetches http(s) source URLs from this machine. This is dependency behaviour, not package code."
      },
      {
        "severity": "note",
        "at": "docling_mcp/docling_cache.py:54-81",
        "what": "With CACHE_DIR unset, saved files go to a _cache folder next to the installed package (inside the Python environment), which users may not expect."
      },
      {
        "severity": "note",
        "at": "docling_mcp/tools/llama_index/_shared.py:12-27",
        "what": "The optional llama-index-rag group downloads an embedding model at import time and creates ./milvus_demo.db in the working directory with overwrite=True, wiping any previous file of that name."
      },
      {
        "severity": "info",
        "at": "docling_mcp/tools/converters/sources.py:68-71",
        "what": "Object-storage credentials are deliberately taken only from the provider's standard chain, never from MCP client config."
      },
      {
        "severity": "info",
        "at": "docling_mcp/tools/manipulation.py:259-353",
        "what": "update/delete tools only modify the in-memory cached copy (annotated destructiveHint=True); original files are never modified."
      },
      {
        "severity": "info",
        "at": "package",
        "what": "Line counts: the manifest counts the trailing newline as a line. All 31 files read in full, total 3301 matches the manifest."
      }
    ]
  },
  "health": {
    "score": 74,
    "parts": {
      "popularity": 0.6954175284211643,
      "activity": 0.6,
      "issues": 0.7391304347826086,
      "security": 1
    },
    "fail": 0,
    "warn": 0,
    "raw": {
      "stars": 781,
      "forks": 143,
      "downloads": 6411,
      "hn": {
        "n": 0,
        "pts": 0,
        "t": []
      },
      "issuesOpen": 12,
      "issuesClosed": 34,
      "prsMerged": 85,
      "commits90": 0,
      "release": "2026-10-27T21:38:57Z",
      "pushed": "2026-10-27T21:38:56Z",
      "growth": null,
      "growthDays": null,
      "archived": false
    },
    "at": "2026-10-31T07:35:52.424Z"
  }
}
