mcp-office-tools

fastbs/mcp-office-tools

3.1

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.

Tools
3
Resources
0
Prompts
0

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

VariableDefaultDescription
PORT3101Server port
MINIO_ENDPOINTminioMinIO server hostname
MINIO_PORT9000MinIO server port
MINIO_ACCESS_KEYminioadminMinIO access key
MINIO_SECRET_KEYminioadminMinIO secret key
MINIO_USE_SSLfalseUse HTTPS for MinIO

MCP Tools

office_fill_template

Generate document from template with data.

Parameters:

  • template_path (string) - Path to template in Nextcloud
  • data (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

  1. Add office tool to agent in LibreChat UI
  2. Create chat with agent
  3. Ask: "Заполни шаблон contract.docx с данными: клиент ООО Тест, дата 17.01.2025"
  4. 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

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