Docling
DoclingTools converts a local document through Docling. TnsAI does not bundle Docling, Python or models. You run one of these yourself:
- the Docling MCP server, on a machine that can read the same file paths as the JVM;
- the
doclingCLI, installed locally.
DoclingTools lives in tnsai-tools, in the package com.tnsai.tools.document.docling.
Register a configured toolkit
Build the toolkit with a provider and pass the instance to toolPojos(...):
import com.tnsai.agents.AgentBuilder;
import com.tnsai.tools.document.docling.DoclingProvider;
import com.tnsai.tools.document.docling.DoclingTools;
DoclingTools docling = DoclingTools.builder()
.docling(DoclingProvider.subprocess("docling"))
.build();
agentBuilder.toolPojos(docling);BuiltInTool.DOCLING_TOOLS and new DoclingTools() create the toolkit with DoclingProvider.noOp(). That toolkit registers, but every call throws IOException.
The model sees one tool, docling_parse. It takes a local path and returns Markdown, cut at 100,000 characters. For tables, formulas, figures or the Docling JSON, call parse(Path) from Java.
Choose a provider
DoclingProvider.mcp(McpClient) | DoclingProvider.subprocess(command) | |
|---|---|---|
| Runtime | A Docling MCP server, reached through a TnsAI McpClient | A local docling process, started without a shell |
| Setup | You create, connect and initialize the client. The server must read the same paths as the JVM. | docling installed, with its Python environment and models |
available() | True while the client is connected and initialized | The result of docling --version, run once with a 5-second timeout and cached |
| When unavailable | parse throws IOException | parse throws IOException |
| Concurrency | Two conversions per client, at least 200 ms apart. A call waits up to 30 seconds for a slot. | Two conversions per JVM. A call waits up to 30 seconds for a slot. |
| Limits | Markdown up to 1,000,000 characters | 5 minutes per conversion, 64 MiB of temporary output, 10 MiB per output file |
Page images for PdfTools | Not supported | Supported |
DoclingTools.parse admits the path through the file guard first. The guard applies a FileGuardConfig and DoclingTools.DEFAULT_EXTENSIONS: PDF, Office, HTML, Markdown, AsciiDoc, CSV, JSON, text, common image formats, WAV, MP3, VTT, XML and LaTeX. Pass your own FileGuardConfig with builder().fileGuard(...).
Use the MCP server
import com.tnsai.mcp.client.McpClient;
import com.tnsai.tools.document.docling.DoclingProvider;
import com.tnsai.tools.document.docling.DoclingTools;
import com.tnsai.tools.document.docling.DocumentResult;
import java.nio.file.Path;
client.connect();
client.initialize();
DoclingTools tools = DoclingTools.builder()
.docling(DoclingProvider.mcp(client))
.build();
DocumentResult result = tools.parse(Path.of("/data/paper.pdf"));
String markdown = result.markdown();
boolean structured = result.hasStructuredContent();client is an McpClient built for your server's transport. See MCP client. The provider calls the server's convert_document_into_docling_document tool, then export_docling_document_to_markdown.
Use the CLI
import com.tnsai.tools.document.docling.DoclingProvider;
import com.tnsai.tools.document.docling.DoclingTools;
import com.tnsai.tools.document.docling.DocumentResult;
import java.nio.file.Path;
DoclingTools tools = DoclingTools.builder()
.docling(DoclingProvider.subprocess("docling"))
.build();
DocumentResult result = tools.parse(Path.of("/data/paper.pdf"));subprocess takes the executable name or its full path. The provider runs docling convert --to md --to json and reads both outputs.
DocumentResult
| Accessor | Contents |
|---|---|
markdown() | The document as Markdown |
tables() | Tables from the Docling JSON, or from the Markdown when the JSON has none |
formulas() | Formulas from the Docling JSON, or display formulas in the Markdown |
figures() | Pictures from the Docling JSON, or image references in the Markdown |
doclingJson() | Docling's JSON output. The MCP provider leaves it empty. |
hasStructuredContent() | True when there is at least one table, formula or figure |
PdfTools fallback
PdfTools renders PDF pages with PDFBox. Give it a Docling provider and it falls back to Docling when PDFBox cannot open the file:
import com.tnsai.tools.document.docling.DoclingProvider;
import com.tnsai.tools.file.FileGuardConfig;
import com.tnsai.tools.file.PdfTools;
PdfTools pdf = new PdfTools(
FileGuardConfig.defaults(),
DoclingProvider.subprocess("docling"));Only the CLI provider renders pages. Without a provider, or with the MCP provider, the PDFBox error is thrown.