fastbs/mcp-office-tools
If you are the rightful owner of mcp-office-tools and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
The MCP Office Tools Server is a Model Context Protocol server designed for generating and converting office documents using Carbone templates and LibreOffice.
MCP Office Tools Server
Model Context Protocol server for generating Office documents (Word, Excel, PowerPoint, PDF) using Carbone templates.
Status: 🚧 Alpha (Phase 1 complete - infrastructure working, Phase 2 pending - actual document generation)
Features
- 📄 Template-based document generation - Fill DOCX, XLSX, PPTX templates with JSON data using Carbone
- 🔄 Format conversion - Convert between 160+ document formats via LibreOffice
- 📊 Template analysis - Extract placeholders (
{d.variable}) from templates - 🗄️ MinIO integration - Automatic S3-compatible file storage
- 🌐 HTTP API - StreamableHTTP transport for MCP protocol
- ☁️ Nextcloud ready - Designed for integration with Nextcloud file storage via WebDAV
Architecture
LibreChat Agent → MCP Client → HTTP → MCP Office Tools Server
↓
Carbone Engine
↓
LibreOffice (format conversion)
↓
MinIO Storage
Tech Stack:
- Node.js 20 (Alpine)
- TypeScript 5.3
- Carbone 3.5.6 (template engine)
- LibreOffice (format conversion)
- MinIO 7.1.0 (S3 storage)
- @modelcontextprotocol/sdk 1.0.4
Quick Start
Development (Local)
# Install dependencies
npm install
# Build TypeScript
npm run build
# Start server
npm start
Production (Docker)
# Build image
docker build -t mcp-office-tools .
# Run container
docker run -d \
--name mcp-office-tools \
-p 3101:3101 \
-e MINIO_ENDPOINT=minio \
-e MINIO_ACCESS_KEY=minioadmin \
-e MINIO_SECRET_KEY=minioadmin \
mcp-office-tools
Docker Compose (with LibreChat)
See in parent project.
Environment Variables
| Variable | Default | Description |
|---|---|---|
PORT | 3101 | Server port |
MINIO_ENDPOINT | minio | MinIO server hostname |
MINIO_PORT | 9000 | MinIO server port |
MINIO_ACCESS_KEY | minioadmin | MinIO access key |
MINIO_SECRET_KEY | minioadmin | MinIO secret key |
MINIO_USE_SSL | false | Use HTTPS for MinIO |
MCP Tools
office_fill_template
Generate document from template with data.
Parameters:
template_path(string) - Path to template in Nextclouddata(object) - JSON data matching template placeholders{d.key}output_format(string) - Output format:docx,xlsx,pptx,pdf, etc.output_filename(string, optional) - Custom filename
Example (LibreChat agent prompt):
Создай договор на основе шаблона contract.docx. Используй данные:
- Номер договора: 456/2025
- Заказчик: ООО "Рога и Копыта"
- Дата: 17.01.2025
- Сумма: 150 000 руб.
Tool call (actual JSON sent by LibreChat):
{
"template_path": "/templates/contract.docx",
"data": {
"contract_number": "456/2025",
"client_name": "ООО \"Рога и Копыта\"",
"date": "17.01.2025",
"total_amount": "150 000"
},
"output_format": "docx"
}
Current Response (Phase 1 - placeholder):
{
"content": [{
"type": "text",
"text": "Tool office_fill_template called successfully (implementation pending)"
}]
}
Future Response (Phase 2 - actual generation):
{
"content": [{
"type": "text",
"text": "✅ Document generated: contract_456-2025.docx\n📥 Download: http://minio:9000/documents/abc123.docx"
}]
}
office_convert_document
Convert document between formats using LibreOffice.
Parameters:
source_url(string) - Source file URL (Nextcloud WebDAV or MinIO)target_format(string) - Target format (pdf, docx, xlsx, html, etc.)output_filename(string, optional) - Custom filename
Example:
{
"source_url": "http://nextcloud/remote.php/dav/files/user/report.docx",
"target_format": "pdf",
"output_filename": "report_final.pdf"
}
office_analyze_template
Analyze Carbone template and extract required placeholders.
Parameters:
template_path(string) - Path to template in Nextcloud
Example:
{
"template_path": "/templates/invoice.xlsx"
}
Response:
{
"content": [{
"type": "text",
"text": "Template analysis:\n- {d.invoice_number}\n- {d.client_name}\n- {d.items[i].description}\n- {d.items[i].quantity}\n- {d.total_amount}"
}]
}
Workflow Examples (Composition Pattern)
Architecture principle: MCP Office Tools provides pure document processing. Storage operations are delegated to specialized MCP servers (mcp-nextcloud for WebDAV, future mcp-minio, etc.).
Example 1: Fill Template + Save to Nextcloud
// LLM Agent orchestrates multiple MCP servers:
// Step 1: Read template from Nextcloud (mcp-nextcloud)
const templateToken = await nextcloud.webdav_read_file_binary({
path: 'templates/contract.docx'
});
// Returns: { buffer_token: "uuid-1234", size_bytes: 50240, ... }
// Step 2: Fill template with data (mcp-office-tools)
const filledToken = await office.fill_template({
buffer_token: templateToken.buffer_token,
data: {
client_name: "ООО Ромашка",
contract_date: "17.01.2025",
amount: 150000
},
output_format: 'docx'
});
// Returns: { buffer_token: "uuid-5678", size_bytes: 52100, ... }
// Step 3: Write result to Nextcloud (mcp-nextcloud)
await nextcloud.webdav_write_file_binary({
buffer_token: filledToken.buffer_token,
path: 'contracts/contract_2025_romashka.docx',
auto_cleanup: true // Delete buffer after upload
});
// Returns: { success: true, url: "http://nextcloud/.../contract_2025_romashka.docx" }
Example 2: Fill + Convert to PDF + Save
// Step 1: Read template
const templateToken = await nextcloud.webdav_read_file_binary({
path: 'templates/invoice.xlsx'
});
// Step 2: Fill with data
const filledToken = await office.fill_template({
buffer_token: templateToken.buffer_token,
data: {
invoice_number: "INV-2025-001",
items: [
{ name: "Service A", quantity: 10, price: 5000 },
{ name: "Service B", quantity: 5, price: 8000 }
],
total: 90000
},
output_format: 'xlsx',
auto_cleanup: false // Keep template buffer for reuse
});
// Step 3: Convert to PDF
const pdfToken = await office.convert_document({
buffer_token: filledToken.buffer_token,
source_format: 'xlsx',
target_format: 'pdf',
auto_cleanup: true // Delete XLSX buffer, keep only PDF
});
// Step 4: Save PDF to Nextcloud
await nextcloud.webdav_write_file_binary({
buffer_token: pdfToken.buffer_token,
path: 'invoices/INV-2025-001.pdf',
auto_cleanup: true // Final cleanup
});
Example 3: Analyze Template Structure
// Step 1: Read template
const templateToken = await nextcloud.webdav_read_file_binary({
path: 'templates/report.docx'
});
// Step 2: Analyze placeholders
const analysis = await office.analyze_template({
buffer_token: templateToken.buffer_token
});
// Returns: {
// placeholders: ['{d.company}', '{d.date}', '{d.items[i].name}'],
// structure: { company: 'string', date: 'date', items: ['array'] }
// }
// Note: analyze_template always deletes buffer (read-only operation)
Why Composition Instead of Monolithic Tools?
❌ Bad (monolithic):
// Hypothetical monolithic tool (NOT implemented):
office.fill_and_save_to_nextcloud({
template_path: '/templates/contract.docx',
data: {...},
output_path: '/contracts/contract.docx'
});
// Problems:
// - Tight coupling between office processing and Nextcloud
// - Cannot save to MinIO or other storage
// - Cannot chain operations (fill → convert → save)
// - Duplicates WebDAV client code
✅ Good (composition):
// Each MCP server has single responsibility:
// - mcp-nextcloud: Nextcloud integration (WebDAV, Notes, Calendar)
// - mcp-office-tools: Document processing (Carbone, LibreOffice)
// - LLM Agent: Orchestration and workflow logic
// Flexible workflows:
template → fill → save // Basic
template → fill → convert → save // With conversion
template → fill → save + email + archive // Complex multi-step
API Endpoints
POST /mcp- MCP StreamableHTTP endpoint (session-based)GET /health- Health check{"status":"ok","service":"mcp-office-tools","version":"1.0.0","tools":3,"uptime":1234.56}GET /- Server info
Integration with LibreChat
Add to librechat.yaml:
mcpServers:
office:
url: "http://mcp-office-tools:3101/mcp"
transport: "streamable-http"
sessionConfig:
timeout: 300000
icon: "/images/office.svg"
Development
Local Development
# Install dependencies
npm install
# Build TypeScript
npm run build
# Start server
npm start
# Watch mode (with nodemon)
npm run dev
Docker Development
# Build image
docker-compose build mcp-office-tools
# Start container with volume mounts (live editing)
docker-compose up -d mcp-office-tools
# View logs
docker logs mcp-office-tools -f --tail 100
# Rebuild after changes
docker exec mcp-office-tools sh -c "cd /app && npm run build"
Testing in LibreChat
- Add office tool to agent in LibreChat UI
- Create chat with agent
- Ask: "Заполни шаблон contract.docx с данными: клиент ООО Тест, дата 17.01.2025"
- Check logs:
docker logs mcp-office-tools --tail 50
Current Implementation Status
Phase 1: Infrastructure (✅ Complete)
- TypeScript project structure
- Docker image with LibreOffice
- MCP HTTP server with StreamableHTTP transport
- 3 tool definitions (office_fill_template, office_convert_document, office_analyze_template)
- Session management
- Health checks
- Detailed logging
- Integration with LibreChat
Phase 2: Core Implementation (⏳ Pending)
- Carbone template filling logic
- MinIO file upload/download
- Nextcloud WebDAV integration for templates
- LibreOffice format conversion
- Error handling and validation
- Cleanup of temporary files
Phase 3: Advanced Features (📋 Planned)
- Template caching
- Batch document generation
- Custom fonts support
- PDF watermarks
- Document merging
- Statistics and monitoring
Supported Formats
Input Templates: docx, xlsx, pptx, odt, ods, odp
Output Formats: Same as input + pdf, html, txt, csv, xml, rtf, and 150+ more
Carbone engine provides 160+ format combinations through LibreOffice.
Carbone Template Syntax
{d.variable} - Simple variable
{d.date:formatD('DD.MM.YYYY')} - Date formatting
{d.amount:formatN('0,0.00')} - Number formatting
{d.field:ifEQ(true):show('Yes'):hide()} - Conditions
{d.items[i].name} - Array iteration
See for full example.
Logging
Detailed logging at all levels:
[HTTP 2025-11-17T09:39:55.903Z] 📨 POST /mcp - Incoming request
[MCP] 🔧 tools/call: office_fill_template
[MCP] Arguments: {"template_path": "/templates/contract.docx", "data": {...}}
[HTTP 2025-11-17T09:39:55.903Z] ✅ POST /mcp - Request completed
See for complete logging guide.
Troubleshooting
LibreOffice not found
# Check LibreOffice installation in container
docker exec mcp-office-tools which libreoffice
# Should return: /usr/bin/libreoffice
MinIO connection failed
# Verify MinIO environment variables
docker exec mcp-office-tools printenv | grep MINIO
MCP connection timeout
# Increase timeout in librechat.yaml
mcpServers:
office:
sessionConfig:
timeout: 300000 # 5 minutes for large documents
License
MIT
Links
- Carbone: https://carbone.io/documentation.html
- MCP Protocol: https://modelcontextprotocol.io
- LibreChat: https://librechat.ai
- Implementation Plan:
Contributing
This is part of LibreChat ecosystem. For bugs/features, open issue in this repository.
Repository: https://github.com/devatiywork/fastbs-mcp-office-tools
Parent Project: https://github.com/devatiywork/fastbs-LibreChat