Docling.Serve.Client
1.0.0
dotnet add package Docling.Serve.Client --version 1.0.0
NuGet\Install-Package Docling.Serve.Client -Version 1.0.0
<PackageReference Include="Docling.Serve.Client" Version="1.0.0" />
<PackageVersion Include="Docling.Serve.Client" Version="1.0.0" />
<PackageReference Include="Docling.Serve.Client" />
paket add Docling.Serve.Client --version 1.0.0
#r "nuget: Docling.Serve.Client, 1.0.0"
#:package Docling.Serve.Client@1.0.0
#addin nuget:?package=Docling.Serve.Client&version=1.0.0
#tool nuget:?package=Docling.Serve.Client&version=1.0.0
Docling .NET SDK
A typed, high-performance .NET SDK for Docling — providing a client over the docling-serve REST API, the full DoclingDocument data model, a Microsoft.Extensions.DataIngestion document reader, Model Context Protocol (MCP) server tools with asynchronous MCP Tasks support, and an AI context provider for the Microsoft Agent Framework.
Table of Contents
- Overview & Architecture
- Artifacts & Packages
- Prerequisites
- Quick Start
- Feature Deep Dive
- 1. REST Client & Document Conversion (
Docling.Serve.Client) - 2. Document Chunking for RAG / Vector Search
- 3. Streaming ZIP Archives & Large Document Handling
- 4. Structured Data Extraction (
Docling.Core) - 5. Model Context Protocol Server (
Docling.Serve.Mcp) - 6. Document Ingestion Pipelines (
Docling.Ingestion) - 7. Microsoft Agent Framework Integration (
Docling.Agents.AI)
- 1. REST Client & Document Conversion (
- Dependency Injection Setup
- Security & Source Access Control
- Error Handling & Diagnostics
- Enterprise Samples
- Building, Testing & CI/CD
- Contributing & License
Overview & Architecture
flowchart TD
subgraph Apps["Consumer Applications & Hosts"]
Web["ASP.NET Core / Web API"]
AgentApp["Agentic AI Application"]
McpClient["Claude / VS Code / Cursor (MCP)"]
RagPipeline["Data Ingestion Pipeline"]
end
subgraph SDK["Docling .NET SDK (net10.0)"]
Agents["Docling.Agents.AI\n(AIContextProvider)"]
Mcp["Docling.Serve.Mcp\n(MCP Tools + Tasks)"]
Ingestion["Docling.Ingestion\n(IngestionDocumentReader)"]
Client["Docling.Serve.Client\n(DoclingServeClient + DI)"]
Api["Docling.Serve.Api\n(IDoclingServeApi & DTOs)"]
Core["Docling.Core\n(DoclingDocument Model)"]
end
subgraph Backend["Docling Server Infrastructure"]
Serve["docling-serve (REST API / Docker)"]
end
Web --> Client
AgentApp --> Agents
Agents --> Api
McpClient --> Mcp
Mcp --> Api
RagPipeline --> Ingestion
Ingestion --> Core
Ingestion --> Api
Client --> Api
Api --> Core
Client -->|HTTP / JSON / Streams| Serve
Artifacts & Packages
Every package in the suite is built for .NET 10.0 with strict nullable reference types, analyzers enabled, XML documentation generated, and SourceLink enabled.
| Package | Purpose | Target Framework |
|---|---|---|
Docling.Core |
Strongly typed DoclingDocument object model mirroring the Python docling-core JSON schema (text items, tables, pictures, layout hierarchy, geometry, and DoclingJson). |
net10.0 |
Docling.Serve.Api |
Framework-agnostic contracts (IDoclingServeApi, IDoclingServeConvertApi, IDoclingServeChunkApi, IDoclingServeTaskApi, IDoclingServeClearApi, IDoclingServeExtendedApi), DTOs, polymorphic requests/targets, and security policies (DoclingSourceAccessPolicy). |
net10.0 |
Docling.Serve.Client |
Resilient HttpClient implementation of IDoclingServeApi with fluent builder (DoclingServeClient.CreateBuilder()), content-type sniffing (ZIP streams vs. JSON), automatic task polling, HTTP/1.1 enforcement, and DI extensions (AddDoclingServeClient). |
net10.0 |
Docling.Serve.Mcp |
Model Context Protocol (MCP) server tools (get_health, convert_document, chunk_document) supporting both Stdio and Streamable HTTP transports, with SEP-2663 MCP Tasks execution. |
net10.0 |
Docling.Ingestion |
DoclingIngestionReader implementing Microsoft.Extensions.DataIngestion.IngestionDocumentReader, transforming converted DoclingDocument trees into structured IngestionDocument elements (headers, paragraphs, pipe tables, base64 images). |
net10.0 |
Docling.Agents.AI |
DoclingDocumentContextProvider for the Microsoft Agent Framework (Microsoft.Agents.AI), supporting proactive message scanning (BeforeAIInvoke) and on-demand tool calling (OnDemandFunctionCalling). |
net10.0 |
Prerequisites
To execute conversions and chunking, you need a running docling-serve instance:
docker run -it --rm -p 5001:5001 ghcr.io/docling-project/docling-serve@sha256:09fc953cbe973b0a3a3db437479949a7290728ca00b2db93d56a53d01e6f7bd0
Verify that the server is up:
curl http://localhost:5001/health
# {"status":"ok"}
Quick Start
1. Install Packages
dotnet add package Docling.Serve.Client
2. Convert a Document to Markdown
using Docling.Serve.Api;
using Docling.Serve.Client;
// Build the client using the fluent builder
using DoclingServeClient client = DoclingServeClient.CreateBuilder()
.WithBaseUrl("http://localhost:5001")
.WithApiKey("optional-api-key") // Sent via X-Api-Key
.WithAsyncOptions(pollInterval: TimeSpan.FromSeconds(1), timeout: TimeSpan.FromMinutes(5))
.Build();
// Check server health
HealthCheckResponse health = await client.GetHealthAsync();
Console.WriteLine($"Server status: {health.Status}");
// Submit a conversion request
ConvertDocumentRequest request = new()
{
Sources = [new HttpSource { Url = new Uri("https://arxiv.org/pdf/2408.09869") }],
Target = new InBodyTarget(),
Options = new ConvertDocumentOptions
{
ToFormats = [OutputFormat.Markdown]
}
};
InBodyConvertDocumentResponse response =
(InBodyConvertDocumentResponse)await client.ConvertSourcePollingAsync(request);
Console.WriteLine("--- Converted Markdown ---");
Console.WriteLine(response.Document?.MarkdownContent);
Feature Deep Dive
1. REST Client & Document Conversion (Docling.Serve.Client)
The client supports both synchronous conversion (server holds connection open) and asynchronous conversion with automatic polling.
Converting Local Files with Base64 Source
using Docling.Serve.Api;
using Docling.Serve.Client;
using DoclingServeClient client = DoclingServeClient.CreateBuilder()
.WithBaseUrl("http://localhost:5001")
.Build();
// Using the FileSource helper
ConvertDocumentRequest request = new()
{
Sources = [FileSource.FromFile("annual-report.pdf")],
Target = new InBodyTarget(),
Options = new ConvertDocumentOptions
{
ToFormats = [OutputFormat.Markdown, OutputFormat.Json],
DoOcr = true,
DoTableStructure = true
}
};
InBodyConvertDocumentResponse response =
(InBodyConvertDocumentResponse)await client.ConvertSourcePollingAsync(request);
Console.WriteLine($"Document title: {response.Document?.JsonContent?.Name}");
Multi-Part File Uploads
For large payloads or binary streams, use MultipartDocumentRequest:
await using FileStream fileStream = File.OpenRead("document.docx");
MultipartDocumentRequest multipart = new()
{
Files =
[
new MultipartFileItem
{
Content = fileStream,
Filename = "document.docx",
ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
}
]
};
InBodyConvertDocumentResponse response =
(InBodyConvertDocumentResponse)await client.ConvertFileAsync(multipart);
2. Document Chunking for RAG / Vector Search
docling-serve exposes two specialized chunkers:
- Hierarchical Chunker: Understands document layout, sections, headings, and nesting.
- Hybrid Chunker: Combines structural hierarchy with token boundaries for embedding models.
using Docling.Serve.Api;
using Docling.Serve.Client;
using DoclingServeClient client = DoclingServeClient.CreateBuilder()
.WithBaseUrl("http://localhost:5001")
.Build();
HybridChunkDocumentRequest chunkRequest = new()
{
Sources = [FileSource.FromFile("policy.pdf")],
ChunkingOptions = new HybridChunkerOptions
{
MaxTokens = 512,
Tokenizer = "sentence-transformers/all-MiniLM-L6-v2",
MergePeers = true
}
};
ChunkDocumentResponse response = await client.ChunkHybridPollingAsync(chunkRequest);
foreach (DoclingChunk chunk in response.Chunks ?? [])
{
Console.WriteLine($"[Tokens: {chunk.Meta?.DocItems?.Count}] {chunk.Text}");
if (chunk.Meta?.Headings is { Count: > 0 } headings)
{
Console.WriteLine($" Heading: {string.Join(" > ", headings)}");
}
}
3. Streaming ZIP Archives & Large Document Handling
When converting multiple files or requesting embedded images with a ZipTarget, the server returns an application/zip stream. DoclingServeClient sniffs the Content-Type header and streams the response directly without buffering the entire payload in memory:
ConvertDocumentRequest request = new()
{
Sources =
[
FileSource.FromFile("report-part1.pdf"),
FileSource.FromFile("report-part2.pdf")
],
Target = new ZipTarget()
};
using ConvertDocumentResponse response = await client.ConvertSourceAsync(request);
if (response is ZipArchiveConvertDocumentResponse zipResponse)
{
Console.WriteLine($"ZIP Filename: {zipResponse.Filename}");
await using FileStream outputStream = File.Create("converted_docs.zip");
await zipResponse.Content!.CopyToAsync(outputStream);
}
4. Structured Data Extraction (Docling.Core)
Docling.Core contains strongly typed C# records mirroring the docling-core schema.
using Docling.Core;
// Parsing DoclingDocument JSON
DoclingDocument? doc = response.Document?.JsonContent;
if (doc is not null)
{
// 1. Iterate over extracted tables
foreach (TableItem table in doc.Tables ?? [])
{
Console.WriteLine($"Table with {table.Data?.NumRows} rows and {table.Data?.NumCols} cols:");
if (table.Data?.Grid is not null)
{
for (int r = 0; r < table.Data.Grid.Count; r++)
{
var rowCells = table.Data.Grid[r].Select(c => c?.Text ?? "");
Console.WriteLine($"| {string.Join(" | ", rowCells)} |");
}
}
}
// 2. Access pictures and data URIs
foreach (PictureItem picture in doc.Pictures ?? [])
{
Console.WriteLine($"Picture on page {picture.Prov?.FirstOrDefault()?.PageNo}: {picture.Image?.Uri}");
}
}
5. Model Context Protocol Server (Docling.Serve.Mcp)
Expose document conversion and chunking as tools to LLM assistants (e.g. Claude Desktop, VS Code, Cursor) using the Model Context Protocol.
Tools Provided
| Tool Name | Description | MCP Task Mode (SEP-2663) |
|---|---|---|
get_health |
Checks docling-serve reachability and readiness | Synchronous |
convert_document |
Converts URLs or local files to Markdown, HTML, or plain text | Optional Task (Backgroundable) |
chunk_document |
Chunks documents using hierarchical or hybrid chunkers | Optional Task (Backgroundable) |
Stdio Transport (Claude Desktop / Cursor)
samples/Docling.Mcp.StdioSample:
using Docling.Serve.Api;
using Docling.Serve.Mcp;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
// Enforce source access boundary
builder.Services.AddSingleton<IDoclingSourceAccessPolicy>(new DoclingSourceAccessPolicy(
allowedHosts: ["arxiv.org", "github.com"],
allowedRoots: ["/data/docs", "C:\\docs"]));
builder.Services
.AddDoclingMcpServer(options => options.BaseUrl = new Uri("http://localhost:5001"))
.WithStdioServerTransport();
builder.Logging.AddConsole(consoleOptions =>
{
// stdout carries the MCP protocol; route all logs to stderr
consoleOptions.LogToStandardErrorThreshold = LogLevel.Trace;
});
await builder.Build().RunAsync();
Connecting in claude_desktop_config.json:
{
"mcpServers": {
"docling": {
"command": "dotnet",
"args": ["run", "--project", "path/to/Docling.Mcp.StdioSample.csproj"],
"env": {
"DOCLING_SERVE_URL": "http://localhost:5001"
}
}
}
}
6. Document Ingestion Pipelines (Docling.Ingestion)
DoclingIngestionReader implements Microsoft.Extensions.DataIngestion.IngestionDocumentReader, seamlessly bridging docling into modern RAG ingestion architectures.
using Docling.Ingestion;
using Docling.Serve.Client;
using Microsoft.Extensions.DataIngestion;
using DoclingServeClient api = DoclingServeClient.CreateBuilder()
.WithBaseUrl("http://localhost:5001")
.Build();
DoclingIngestionReader reader = new(api, new DoclingIngestionReaderOptions
{
IncludeImages = true,
AllowPartialResults = true,
MaxInputBytes = 64 * 1024 * 1024
});
// Read file or Stream into IngestionDocument
IngestionDocument document = await reader.ReadAsync(
new FileInfo("quarterly-report.pdf"),
TestContext.Current.CancellationToken);
foreach (IngestionDocumentElement element in document.EnumerateContent())
{
switch (element)
{
case IngestionDocumentHeader header:
Console.WriteLine($"[H{header.Level} Page {header.PageNumber}] {header.Text}");
break;
case IngestionDocumentTable table:
Console.WriteLine($"[Table Page {table.PageNumber}]\n{table.Text}");
break;
case IngestionDocumentImage img:
Console.WriteLine($"[Image Page {img.PageNumber}] {img.AlternativeText} ({img.Content?.Length} bytes)");
break;
case IngestionDocumentParagraph p:
Console.WriteLine($"[Paragraph] {p.Text}");
break;
}
}
7. Microsoft Agent Framework Integration (Docling.Agents.AI)
Give LLM agents document comprehension capabilities via DoclingDocumentContextProvider (Microsoft.Agents.AI.AIContextProvider).
using Docling.Agents.AI;
using Docling.Serve.Client;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using DoclingServeClient doclingClient = DoclingServeClient.CreateBuilder()
.WithBaseUrl("http://localhost:5001")
.Build();
// 1. Configure the Provider
DoclingDocumentContextProvider contextProvider = new(
doclingClient,
new DoclingDocumentContextProviderOptions
{
Mode = DoclingDocumentContextMode.BeforeAIInvoke, // Proactively scans user messages
RecentMessagesToScan = 3,
MaxDocumentsPerInvocation = 2,
CacheTtl = TimeSpan.FromMinutes(15)
});
// 2. Wire into your agent
AIAgent agent = chatClient.AsAIAgent(new ChatClientAgentOptions
{
Name = "ResearchAssistant",
ChatOptions = new ChatOptions
{
Instructions = "You are an analytical researcher. Always cite sources from the provided document context."
},
AIContextProviders = [contextProvider]
});
// 3. Invoke: The provider detects the URL, converts it via docling-serve, and injects it into context
AgentResponse response = await agent.RunAsync("What are the key conclusions in https://arxiv.org/pdf/2408.09869 ?");
Console.WriteLine(response.Message.Text);
Dependency Injection Setup
In ASP.NET Core or Generic Host apps:
// Program.cs
builder.Services.AddDoclingServeClient(options =>
{
options.BaseUrl = new Uri(builder.Configuration["Docling:BaseUrl"] ?? "http://localhost:5001");
options.ApiKey = builder.Configuration["Docling:ApiKey"];
options.ConnectTimeout = TimeSpan.FromSeconds(10);
options.ReadTimeout = TimeSpan.FromMinutes(5);
options.AsyncOptions = new DoclingServeAsyncOptions
{
PollInterval = TimeSpan.FromSeconds(1),
Timeout = TimeSpan.FromMinutes(10)
};
});
Inject IDoclingServeApi into your services or controllers:
public class DocumentService(IDoclingServeApi doclingApi, ILogger<DocumentService> logger)
{
public async Task<string> ExtractMarkdownAsync(string filePath, CancellationToken ct)
{
var response = (InBodyConvertDocumentResponse)await doclingApi.ConvertSourcePollingAsync(
new ConvertDocumentRequest
{
Sources = [FileSource.FromFile(filePath)],
Target = new InBodyTarget()
},
cancellationToken: ct);
return response.Document?.MarkdownContent ?? string.Empty;
}
}
Security & Source Access Control
To protect your services from Server-Side Request Forgery (SSRF) and local file traversal attacks, configure IDoclingSourceAccessPolicy:
using Docling.Serve.Api;
// Define strict host allowlists and local filesystem roots
IDoclingSourceAccessPolicy policy = new DoclingSourceAccessPolicy(
allowedHosts: ["internal.corporation.com", "storage.googleapis.com"],
allowedRoots: ["/var/data/uploads", "C:\\AppStorage\\Ingest"]);
// Validates scheme, domain, canonical path, and prevents directory traversal or symlink escapes
policy.Validate("https://internal.corporation.com/files/spec.pdf"); // Allowed
policy.Validate("/var/data/uploads/contract.pdf"); // Allowed
policy.Validate("/etc/passwd"); // Throws UnauthorizedAccessException
Error Handling & Diagnostics
The SDK maps all HTTP and task states to explicit, strongly typed exceptions:
try
{
var response = await client.ConvertSourcePollingAsync(request);
}
catch (DoclingServeValidationException vex)
{
// HTTP 422 Unprocessable Entity
Console.WriteLine($"Validation error: {vex.Message}");
foreach (var detail in vex.Errors ?? [])
{
Console.WriteLine($" Field: {string.Join(".", detail.Loc ?? [])} -> {detail.Msg}");
}
}
catch (DoclingServeClientException cex)
{
// HTTP 4xx/5xx or conversion task failure
Console.WriteLine($"Client error (HTTP {cex.StatusCode}): {cex.Message}");
Console.WriteLine($"Response body: {cex.ResponseBody}");
}
catch (OperationCanceledException)
{
Console.WriteLine("The conversion timed out or was cancelled by the caller.");
}
Enterprise Samples
Explore the fully implemented, runnable enterprise samples in the samples/ directory:
Docling.Claims.Samples: Motor insurance claims processing pipeline illustrating parallel intake, tabular invoice extraction, policy document hybrid-chunk RAG, and claim adjudication.Docling.Serve.Samples: End-to-end REST API tour including sync, polled, batch, multipart, chunking, and streaming ZIP responses.Docling.Agents.Samples: Microsoft Agent Framework integration with document context injection and OpenAI chat models.Docling.Mcp.StdioSample: Production-grade Stdio MCP server host for desktop clients.Docling.Mcp.HttpSample: Streamable HTTP MCP server host for remote web agents.
Building, Testing & CI/CD
Building Locally
# Restore and build entire solution
dotnet build Docling.slnx --configuration Release
# Run the comprehensive test suite (137 tests)
dotnet test --configuration Release
Packaging
# Packs all 6 libraries into artifacts/packages
dotnet pack --configuration Release --output artifacts/packages
GitHub Actions CI/CD Pipeline
The repository includes enterprise-grade GitHub Actions workflows:
- CI & Beta Preview (
.github/workflows/ci.yml):- Triggered on pull requests and pushes to
main. - Restores, builds, and verifies all unit/integration tests on Linux runners.
- Generates
.nupkgand.snupkgartifacts for all 6 packages. - Automatically publishes preview beta packages to GitHub Packages on
mainmerges.
- Triggered on pull requests and pushes to
- Release GA (
.github/workflows/release.yml):- Triggered on Git tags (
v*) or manualworkflow_dispatch. - Runs full test suites and packs release packages matching the tag version.
- Deploys to NuGet.org using OIDC Trusted Publishing (
NuGet/login@v1) orNUGET_API_KEY. - Creates a GitHub Release with auto-generated release notes and attached
.nupkg/.snupkgbundles.
- Triggered on Git tags (
Contributing & License
Contributions, bug reports, and PRs are warmly welcome! Please submit issues and pull requests to docling-csharp-sdk/docling-csharp-sdk.
Licensed under the MIT License.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Docling.Serve.Api (>= 1.0.0)
- Microsoft.Extensions.DependencyInjection (>= 10.0.12)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.12)
- Microsoft.Extensions.Http (>= 10.0.12)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.12)
- Microsoft.Extensions.Options (>= 10.0.12)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Docling.Serve.Client:
| Package | Downloads |
|---|---|
|
Docling.Serve.Mcp
Model Context Protocol (MCP) server tools exposing docling-serve conversion and chunking. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 119 | 9/25/2026 |