Skip to main content
Glama

Pandoc Bridge

CI/CD Pipeline License: MIT Python 3.12+

A document format conversion service using Pandoc, supporting both REST (OpenAPI 3.1) and MCP (Model Context Protocol) interfaces.

Features

  • 40+ Format Support: Convert between Markdown, HTML, LaTeX, DOCX, PDF, and many more formats

  • Dual Protocol: REST API with OpenAPI documentation and MCP server for AI assistants

  • Bearer Token Auth: Shared JWT authentication across both protocols

  • Streaming Support: Server-Sent Events for progress tracking

  • Rate Limiting: Built-in protection against abuse

  • Docker Ready: Production-ready containerization with multi-arch support

Documentation

Quick Start

Using Docker Compose

# Start the service
docker-compose up -d

# Check health
curl http://localhost:8000/health

Local Development

# Install dependencies
pip install -e ".[dev]"

# Run the server
uvicorn src.main:app --reload

# Or use the CLI
pandoc-bridge

API Endpoints

Public Endpoints

Endpoint

Description

GET /

Service information

GET /health

Health check with Pandoc version

GET /api/v1/formats

List supported formats

GET /docs

Swagger UI documentation

Protected Endpoints (Require Bearer Token)

Endpoint

Description

POST /api/v1/convert/text

Convert text content

POST /api/v1/convert/file

Convert uploaded file

POST /api/v1/convert/stream

Stream conversion with SSE

MCP Endpoint

Endpoint

Description

POST /mcp

MCP Streamable HTTP transport

Usage Examples

Convert Text (REST)

# Get a token (for development, tokens are pre-configured)
TOKEN="your-jwt-token"

# Convert Markdown to HTML
curl -X POST http://localhost:8000/api/v1/convert/text \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "# Hello World\n\nThis is **bold** text.",
    "from_format": "markdown",
    "to_format": "html"
  }'

Convert File (REST)

curl -X POST http://localhost:8000/api/v1/convert/file \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@document.md" \
  -F "to_format=docx" \
  -o converted.docx

Using with Claude Desktop (MCP)

Add to your Claude Desktop configuration:

{
  "mcpServers": {
    "pandoc-bridge": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "http://localhost:8000/mcp"]
    }
  }
}

Or with authentication:

{
  "mcpServers": {
    "pandoc-bridge": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "--header", "Authorization: Bearer ${PANDOC_TOKEN}",
        "http://localhost:8000/mcp"
      ]
    }
  }
}

MCP Tools

Tool

Description

convert_text

Convert text between formats

convert_file_base64

Convert base64-encoded files

list_formats

Get supported formats

get_service_info

Get version information

MCP Resources

Resource

Description

formats://list

JSON list of supported formats

formats://matrix

Format conversion compatibility matrix

Authentication

Scopes

Scope

Description

formats:read

Query formats (public)

convert:text

Text conversion

convert:file

File conversion

admin

Full access

Token Format

{
    "sub": "client-id",
    "scopes": ["formats:read", "convert:text", "convert:file"],
    "exp": 1735600000,
    "iat": 1735513600
}

Configuration

Environment variables (see .env.example):

Variable

Default

Description

HOST

0.0.0.0

Server host

PORT

8000

Server port

LOG_LEVEL

INFO

Logging level

ENVIRONMENT

development

Environment (development/production)

JWT_SECRET_KEY

(required in prod)

JWT signing key (min 32 chars)

JWT_EXPIRE_HOURS

24

Token expiration time

MAX_FILE_SIZE_MB

50

Maximum file size

CONVERSION_TIMEOUT

60

Conversion timeout in seconds

⚠️ Security Note: Always set JWT_SECRET_KEY in production. Generate one with:

python -c "import secrets; print(secrets.token_urlsafe(32))"

Development

Run Tests

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run with coverage
pytest --cov=src --cov-report=html

Lint Code

# Run ruff
ruff check src tests
ruff format src tests

Type Check

mypy src

Security Scan

# Install security tools
pip install bandit safety

# Run security scan
bandit -r src -ll

# Check dependencies
safety check

CI/CD

The project uses GitHub Actions for continuous integration and deployment:

  • CI Pipeline (pipeline.yml):

    • Runs on Python 3.12 and 3.13

    • Linting with ruff

    • Type checking with mypy

    • Tests with pytest and coverage

    • Security scanning with bandit

    • Deploys documentation to GitHub Pages

  • Container Publishing (publish-container.yml):

    • Triggered on version tags (v*.*.*)

    • Multi-arch builds (amd64, arm64)

    • Publishes to GitHub Container Registry

Running Locally

# Copy environment template
cp .env.example .env

# Edit .env with your settings
vim .env

# Start with Docker
docker-compose up --build

Architecture

┌─────────────────────────────────────────────────────┐
│                    FastAPI App                       │
│                   (Port 8000)                        │
├─────────────────────┬───────────────────────────────┤
│   REST API          │         MCP Server            │
│   /api/v1/*         │         /mcp                  │
│   (OpenAPI 3.1)     │    (Streamable HTTP)          │
├─────────────────────┴───────────────────────────────┤
│              Shared Auth (Bearer Token)              │
├─────────────────────────────────────────────────────┤
│              ConversionService (Core)                │
├─────────────────────────────────────────────────────┤
│                    Pandoc CLI                        │
└─────────────────────────────────────────────────────┘

License

MIT License - see LICENSE for details.

-
security - not tested
A
license - permissive license
-
quality - not tested

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Fu-Jie/MCP-OPENAPI-Pandoc'

If you have feedback or need assistance with the MCP directory API, please join our Discord server