Skip to main content
Glama
README.md
# PDF Generator API — MCP Server

Model Context Protocol (MCP) server for the [PDF Generator API](https://pdfgeneratorapi.com), generated from the OpenAPI v4 specification.

## Overview

This server supports **both** stdio and HTTP transports:
- **Stdio mode** (default): For local MCP client integration (Claude Desktop, Claude Code, Cline, etc.)
- **HTTP mode**: For production deployment, marketplaces, and multiple clients

## Quick Start

### Local Development (Stdio Mode)

**Install and build**:
```bash
npm install
npm run build
```

**MCP Client Configuration Example**:
```json
{
  "mcpServers": {
    "pdf-generator-api": {
      "command": "node",
      "args": ["/path/to/mcp-server/build/index.js"],
      "env": {
        "API_BASE_URL": "https://us1.pdfgeneratorapi.com/api/v4",
        "BEARER_TOKEN_JWT": "your-jwt-token-here"
      }
    }
  }
}
```

**Note**: Replace `/path/to/mcp-server` with your actual path and `your-jwt-token-here` with your PDF Generator API JWT token (see [JWT Token Generation](#jwt-token-generation) below).

**Common config locations**:
- **Claude Desktop**: Settings > Developer > Edit Config
- **Claude Code (CLI)**: `~/.claude/mcp_config.json`
- **Cline/Roo-Codeium**: `.vscode/mcp_config.json`
- **Continue**: `~/.continue/config.json`

### Remote MCP Server (Streamable HTTP)

If you have a deployed MCP server (e.g. `https://mcp.example.com`), you can connect to it directly from your MCP client without running anything locally.

**Claude Code** (`~/.claude/mcp_config.json`):
```json
{
  "mcpServers": {
    "pdf-generator-api": {
      "type": "streamable-http",
      "url": "https://mcp.pdfgeneratorapi.com/mcp",
      "headers": {
        "Authorization": "Bearer your-jwt-token-here"
      }
    }
  }
}
```

**Claude Desktop** (`claude_desktop_config.json`):

Claude Desktop does not support `streamable-http` directly. Use [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) as a bridge:
```json
{
  "mcpServers": {
    "pdf-generator-api": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://mcp.pdfgeneratorapi.com/mcp",
        "--header",
        "Authorization: Bearer your-jwt-token-here"
      ]
    }
  }
}
```

**Note**: For remote servers, use a long-lived JWT token (e.g. `--expiresIn 30d`) to avoid mid-session expiration. See [JWT Token Generation](#jwt-token-generation) for how to create one. Restart your MCP client after updating the config.

### Production Deployment (HTTP Mode)

**Run locally**:
```bash
npm install
npm run start:http
# Server runs on http://localhost:3000
# MCP endpoint: http://localhost:3000/mcp
# Health check: http://localhost:3000/health
```

**Docker**:
```bash
docker compose -f deploy/docker-compose.yml up -d
# MCP endpoint: http://localhost:3001/mcp
```

## Authentication

**Stdio Mode**: Pass the JWT token via the `BEARER_TOKEN_JWT` environment variable in your MCP client config.

**HTTP Mode**: Pass the JWT token in the `Authorization` header with each request:
```bash
curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "Authorization: Bearer your-jwt-token-here" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize",...}'
```

## JWT Token Generation

You need a JWT token to authenticate with the PDF Generator API. Get your credentials from the [PDF Generator API dashboard](https://app.pdfgeneratorapi.com) under **Account Settings > API Integration**.

You'll need three values:
- **Workspace ID** (`iss` claim) — your numeric workspace identifier
- **Workspace Identifier** (`sub` claim) — your workspace email or unique key
- **Secret Key** — the signing key for your JWT (keep this secret)

See: https://docs.pdfgeneratorapi.com/v4#section/Authentication/Creating-a-JWT

### Node.js

```javascript
const jwt = require('jsonwebtoken');

const token = jwt.sign(
  {
    iss: 'YOUR_WORKSPACE_ID',       // e.g. "12345"
    sub: 'YOUR_WORKSPACE_IDENTIFIER' // e.g. "user@example.com"
  },
  'YOUR_SECRET_KEY',
  {
    algorithm: 'HS256',
    expiresIn: '24h'  // Token lifetime — see notes below
  }
);

console.log(token);
```

### Quick one-liner (npx)

```bash
npx jsonwebtoken-cli -- sign \
  '{"iss":"YOUR_WORKSPACE_ID","sub":"YOUR_WORKSPACE_IDENTIFIER"}' \
  'YOUR_SECRET_KEY' \
  --algorithm HS256 \
  --expiresIn 24h
```

### Token Expiration (TTL)

Choose a TTL that matches your use case:

| Use case | Recommended TTL | Why |
|----------|----------------|-----|
| Local MCP (stdio) | `24h` or longer | MCP sessions can be long-lived; avoids mid-session expiration |
| Production (HTTP) | `1h` | Shorter-lived tokens reduce risk if leaked |
| CI/CD or scripts | `5m` – `15m` | Minimal exposure window for automated tasks |

The PDF Generator API validates the token on every request. If the token expires mid-session, subsequent API calls will return `401 Unauthorized` — generate a new token and restart the MCP client.

### Security Best Practices

- **Never commit tokens or secret keys** to version control
- Use **environment variables** or a secrets manager to store your `BEARER_TOKEN_JWT`
- **Rotate secret keys** periodically in the PDF Generator API dashboard
- For HTTP mode, use **HTTPS** in production to protect tokens in transit

See: [PDF Generator API Authentication Docs](https://docs.pdfgeneratorapi.com/v4#section/Authentication/Creating-a-JWT)

## Environment Variables

| Variable | Mode | Default | Description |
|----------|------|---------|-------------|
| `API_BASE_URL` | Both | `https://us1.pdfgeneratorapi.com/api/v4` | PDF Generator API base URL |
| `BEARER_TOKEN_JWT` | Stdio | — | JWT token for authentication |
| `PORT` | HTTP | `3000` | Server port |
| `LOG_LEVEL` | Both | `info` | Logging level (`debug`, `info`, `warn`, `error`) |
| `SESSION_TTL_MINUTES` | HTTP | `30` | Session idle timeout in minutes |
| `CORS_ORIGIN` | HTTP | `*` (all origins) | Comma-separated allowed origins |

Create a `.env` file in the repo root:
```bash
cp .env.example .env
```

## Regenerating

To regenerate after OpenAPI spec changes:
```bash
# Place the updated spec at docs/apiv4.json, then:
./scripts/generate-mcp.sh

# Or specify a custom input:
./scripts/generate-mcp.sh --input /path/to/apiv4.json
```

**Note:** After regeneration, custom patches may need to be re-applied.

## Testing

```bash
npm run build
npm test
```

Test stdio mode manually:
```bash
BEARER_TOKEN_JWT="your-token" echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | npm run start:stdio
```

Test HTTP mode:
```bash
npm run start:http
curl http://localhost:3000/health
```

## Resources

- [MCP Documentation](https://modelcontextprotocol.io)
- [PDF Generator API Documentation](https://docs.pdfgeneratorapi.com/v4)
- [OpenAPI MCP Generator](https://github.com/anthropics/openapi-mcp-generator)