This guide covers everything you need to connect an MCP host to the server and start converting documents.
- Choose a transport mode
- Start the server
- Connect your MCP host
- Call the convert_document tool
- Conversion examples
- Working with protected documents
- Overwriting existing output
- File size and timeout limits
- Health checks
- Troubleshooting
The server supports two MCP transports, selected with the MCP_TRANSPORT environment variable.
| Mode | Value | Best for |
|---|---|---|
| STDIO | stdio (default) |
Claude Desktop, local MCP hosts, development |
| HTTP | http |
Docker, remote access, multi-client setups |
# Minimum required: set your input and output folders
export MCP_TRANSPORT=stdio
export INPUT_ROOT=/home/user/documents/input
export OUTPUT_ROOT=/home/user/documents/output
export WORK_ROOT=/tmp/gdconv
mkdir -p $INPUT_ROOT $OUTPUT_ROOT $WORK_ROOT
dotnet run --project src/GroupDocs.Conversion.McpServerThe process will stay open, reading MCP messages from stdin and writing responses to stdout.
# Clone and enter the repo
git clone https://github.com/groupdocs-conversion/groupdocs-conversion-mcp.git
cd groupdocs-conversion-mcp
# (Optional) add your GroupDocs license
mkdir -p docker/secrets
cp /path/to/your.lic docker/secrets/groupdocs-license.lic
# Put source documents in samples/input
cp /path/to/mydoc.docx samples/input/
# Start
docker compose -f docker/docker-compose.yml up -dThe server is now available at http://localhost:8080/mcp.
docker run -d \
--name gdconv-mcp \
-p 8080:8080 \
-e MCP_TRANSPORT=http \
-e INPUT_ROOT=/data/in \
-e OUTPUT_ROOT=/data/out \
-e WORK_ROOT=/data/work \
-v /srv/gdconv/in:/data/in:ro \
-v /srv/gdconv/out:/data/out \
-v /srv/gdconv/work:/data/work \
groupdocs/groupdocs-conversion-mcp:1.0.0Open claude_desktop_config.json (location: ~/Library/Application Support/Claude/ on macOS, %APPDATA%\Claude\ on Windows) and add:
{
"mcpServers": {
"groupdocs-conversion": {
"command": "dotnet",
"args": [
"run",
"--project",
"/absolute/path/to/src/GroupDocs.Conversion.McpServer"
],
"env": {
"MCP_TRANSPORT": "stdio",
"INPUT_ROOT": "/home/user/documents/input",
"OUTPUT_ROOT": "/home/user/documents/output",
"WORK_ROOT": "/tmp/gdconv"
}
}
}
}Restart Claude Desktop. The convert_document tool will appear in the tool list.
{
"mcpServers": {
"groupdocs-conversion": {
"url": "http://localhost:8080/mcp"
}
}
}In your VS Code settings.json:
{
"mcp.servers": {
"groupdocs-conversion": {
"url": "http://localhost:8080/mcp"
}
}
}In .cursor/mcp.json in your project root:
{
"mcpServers": {
"groupdocs-conversion": {
"url": "http://localhost:8080/mcp"
}
}
}Send a standard MCP tools/call request to http://localhost:8080/mcp:
POST /mcp HTTP/1.1
Host: localhost:8080
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "convert_document",
"arguments": {
"sourcePath": "reports/q1.docx",
"targetFormat": "pdf",
"outputPath": "converted/q1.pdf"
}
}
}| Parameter | Type | Required | Description |
|---|---|---|---|
sourcePath |
string | Yes | Relative path to the source file inside INPUT_ROOT |
targetFormat |
string | Yes | Target format string (see table below) |
outputPath |
string | Yes | Relative path for the output file inside OUTPUT_ROOT |
overwrite |
boolean | No | Overwrite output if it already exists. Default: false |
password |
string | No | Password to open a protected source document |
| Value | Output type |
|---|---|
pdf |
PDF document |
docx |
Word document |
xlsx |
Excel spreadsheet |
pptx |
PowerPoint presentation |
html |
HTML page |
txt |
Plain text |
jpg |
JPEG image |
png |
PNG image |
When the MCP server is connected, you can instruct the AI naturally:
"Convert the file
reports/q1.docxto PDF and save it asconverted/q1.pdf."
"Turn
slides/deck.pptxinto a PDF."
"Convert
data/export.xlsxto HTML and put the result inweb/export.html."
"I have a password-protected Word file at
contracts/nda.docxwith passwordsecret123. Convert it to PDF."
The AI will call convert_document with the appropriate arguments and report back the result.
{
"sourcePath": "documents/report.docx",
"targetFormat": "pdf",
"outputPath": "pdf/report.pdf"
}Success response:
{
"success": true,
"sourcePath": "documents/report.docx",
"outputPath": "pdf/report.pdf",
"targetFormat": "pdf",
"durationMs": 934,
"outputExists": true,
"outputSizeBytes": 204800
}{
"sourcePath": "scanned/invoice.pdf",
"targetFormat": "docx",
"outputPath": "editable/invoice.docx"
}{
"sourcePath": "data/budget.xlsx",
"targetFormat": "pdf",
"outputPath": "exports/budget.pdf"
}{
"sourcePath": "presentations/deck.pptx",
"targetFormat": "pdf",
"outputPath": "exports/deck.pdf"
}{
"sourcePath": "articles/post.docx",
"targetFormat": "html",
"outputPath": "web/post.html"
}{
"sourcePath": "thumbnails/cover.docx",
"targetFormat": "png",
"outputPath": "images/cover.png"
}If the source document is password-protected, pass the password in the password field:
{
"sourcePath": "contracts/nda.docx",
"targetFormat": "pdf",
"outputPath": "exports/nda.pdf",
"password": "MySecretPassword"
}Note: The password is used only to open the source document. It is not applied to the output file.
By default, if the output file already exists the tool returns an error:
{
"success": false,
"errorCode": "output_exists",
"message": "Output file already exists: 'exports/report.pdf'"
}To overwrite, set overwrite to true:
{
"sourcePath": "documents/report.docx",
"targetFormat": "pdf",
"outputPath": "exports/report.pdf",
"overwrite": true
}You can also enable overwrite globally for all requests by setting the environment variable ALLOW_OVERWRITE=true when starting the server.
| Limit | Default | Environment variable |
|---|---|---|
| Maximum source file size | 200 MB | MAX_INPUT_FILE_MB |
| Conversion timeout | 300 seconds | CONVERSION_TIMEOUT_SECONDS |
| Max parallel conversions | 2 | MAX_CONCURRENT_CONVERSIONS |
If a file exceeds the size limit:
{
"success": false,
"errorCode": "input_too_large",
"message": "Source file exceeds maximum size of 200 MB."
}If conversion times out:
{
"success": false,
"errorCode": "conversion_timeout",
"message": "Conversion timed out."
}These endpoints are available in HTTP transport mode.
curl http://localhost:8080/health/live
# 200 OK — process is runningcurl http://localhost:8080/health/ready
# 200 OK — storage roots exist and work folder is writable
# 503 — one or more roots are missing or not writableUse /health/ready as the Docker or Kubernetes readiness probe.
The file path is relative to INPUT_ROOT. Check that:
- The file exists at the correct path under
INPUT_ROOT - The Docker volume is mounted and the file is visible inside the container
# Verify the file is accessible inside the container
docker exec gdconv-mcp ls /data/in/documents/The path contains .., is absolute, or escapes the configured root. Use only relative paths that stay inside INPUT_ROOT / OUTPUT_ROOT:
{ "sourcePath": "subfolder/file.docx" } // correct
{ "sourcePath": "../other/file.docx" } // rejected
{ "sourcePath": "/absolute/file.docx" } // rejectedOnly the formats listed in section 4 are supported. Check spelling; the value is case-insensitive (PDF, pdf, and Pdf all work).
The server creates intermediate output directories automatically. You do not need to pre-create them.
This means the server is running without a GroupDocs license. Supply a license file:
# Docker
-v /path/to/your.lic:/run/secrets/groupdocs-license.lic:ro
-e GROUPDOCS_LICENSE_PATH=/run/secrets/groupdocs-license.lic# Docker
docker logs gdconv-mcp --follow
# Local
dotnet run --project src/GroupDocs.Conversion.McpServer 2>&1 | tee conversion.logEach conversion request is logged with a short correlation ID, source path, target format, duration, and result code.
- Increase
CONVERSION_TIMEOUT_SECONDSfor large or complex documents - Reduce
MAX_CONCURRENT_CONVERSIONSif the host is memory-constrained (each GroupDocs conversion can use significant RAM for large files) - Ensure
WORK_ROOTis on fast local storage, not a network share