Skip to main content
Glama
Convert-Online

convert-online-mcp

Official
README.md
# Convert.Online MCP Server

Convert files between **400+ formats** — images, video, audio, documents, spreadsheets,
ebooks, fonts, CAD and 3D — from inside a conversation with an AI assistant.
**37,500 conversion pairs**, OCR, and no account needed to try it.

There are two ways in, and they expose the same five tools.

**Hosted** — nothing to install, nothing to run:

```
https://mcp.convert.online
```

**Local** — for clients that launch a command rather than speak OAuth to a URL:

```
npx -y convert-online-mcp
```

> **What this repository is.** Two things: the **stdio server** in `src/`, MIT-licensed
> and published to npm as [`convert-online-mcp`](https://www.npmjs.com/package/convert-online-mcp),
> and the documentation for the hosted endpoint. The local server is a thin **client** —
> it calls the public REST API and converts nothing itself, so no file ever passes through
> it. The conversion pipeline behind both is [convert.online](https://convert.online) and
> is not open source. Issues and questions are welcome here.

---

## Connect

### OAuth (recommended)

Clients with connector support — Claude, ChatGPT and others — need only the URL. The
server supports **dynamic client registration**, so nothing has to be provisioned in
advance: add `https://mcp.convert.online` as a custom connector and approve the sign-in
when it appears.

The flow is authorization code with **PKCE (S256 required)**. Access tokens last one hour,
refresh tokens ninety days, and every connected application can be revoked from the
account dashboard — revocation takes effect immediately for both tokens.

Discovery metadata:

| Document | URL |
| --- | --- |
| Protected resource | `https://mcp.convert.online/.well-known/oauth-protected-resource` |
| Authorization server | `https://convert.online/.well-known/oauth-authorization-server` |

### API key

Clients configured from a file can send a key instead. Create one at
[Dashboard → API Keys](https://convert.online/dashboard#apiKeys).

`examples/claude-desktop.json`:

```json
{
  "mcpServers": {
    "convert-online": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote", "https://mcp.convert.online",
        "--header", "Authorization: Bearer YOUR_API_KEY"
      ]
    }
  }
}
```

Any MCP client works the same way: point it at `https://mcp.convert.online` and send
`Authorization: Bearer YOUR_API_KEY`.

### Local stdio server

Clients that launch a command — Cursor, Zed, Continue, and anything reading a config file
— can run this package instead, with no `mcp-remote` shim in between:

```json
{
  "mcpServers": {
    "convert-online": {
      "command": "npx",
      "args": ["-y", "convert-online-mcp"],
      "env": { "CONVERT_ONLINE_API_KEY": "YOUR_API_KEY" }
    }
  }
}
```

It needs Node 18 or newer, and nothing else. Files are never read by this process: a
source given as `source_url` is fetched by our server, and a local file is uploaded
straight to storage from wherever you run the PUT.

| Variable | Default | What it is for |
| --- | --- | --- |
| `CONVERT_ONLINE_API_KEY` | — | Required. |
| `CONVERT_ONLINE_API_BASE` | `https://api.convert.online` | Point it elsewhere for testing. |
| `CONVERT_ONLINE_JOB_WAIT_MS` | `120000` | How long `convert` waits before handing back a job id to poll. |
| `CONVERT_ONLINE_UPLOAD_WAIT_MS` | `60000` | How long `convert` waits for bytes that have not arrived yet. |

Building from source: `npm install && npm run build`, then `node dist/index.js`.

---

## Tools

Five, and the annotations are set so a client can reason about them before calling.

### `list_formats` — *read-only*

Lists supported formats. With no argument, every input format; with `input_format`, the
formats that one converts to.

| Argument | Type | Required |
| --- | --- | --- |
| `input_format` | string | no |

### `list_options` — *read-only*

Lists the settings a given conversion accepts — resize, quality, codecs, bitrate, trim,
crop — with their exact names, so `convert` can be called with settings that exist rather
than guessed.

| Argument | Type | Required |
| --- | --- | --- |
| `input_format` | string | yes |
| `output_format` | string | yes |

### `create_upload`

Returns somewhere to put a local file. The right choice for any file that is not already
at a URL, whatever its size: it hands back an upload URL and an `import_id`. `PUT` the
bytes to that URL, then pass the `import_id` to `convert`.

| Argument | Type | Required |
| --- | --- | --- |
| `output_format` | string | yes |
| `filename` | string | no |
| `input_format` | string | no |

### `convert` — *not read-only, open-world*

Converts a file and returns a download link. Takes **one of** `source_url` (any URL the
server can fetch) or `import_id` (from `create_upload`).

| Argument | Type | Required |
| --- | --- | --- |
| `output_format` | string | yes |
| `source_url` | string | one of |
| `import_id` | string | one of |
| `input_format` | string | no |
| `filename` | string | no |
| `options` | object | no |

`options` is keyed by the names `list_options` returns for that pair.

### `get_job` — *read-only*

Status of a conversion job, and its download link once finished.

| Argument | Type | Required |
| --- | --- | --- |
| `job_id` | string | yes |

---

## A worked exchange

> **You:** Convert these HEIC photos to JPG.

The assistant calls `convert` with `input_format: "heic"`, `output_format: "jpg"`, and
gets back:

```
Conversion finished.
Download: https://convert.online/download/…
Job id: 7f3c9a2e…
```

For a file already on the web, one call is enough:

```json
{
  "source_url": "https://example.com/report.docx",
  "output_format": "pdf"
}
```

For a local file it is three: `create_upload` → `PUT` the bytes → `convert` with the
`import_id`.

---

## The same engine over REST

Everything the MCP server does is also a plain HTTP API, and the server builds exactly the
same job envelope internally — a job is a named chain of tasks:

```json
{
  "tasks": {
    "import-1": { "operation": "import/upload" },
    "convert-1": {
      "operation": "convert",
      "input": "import-1",
      "input_format": "heic",
      "output_format": "jpg"
    },
    "export-1": { "operation": "export/url", "input": ["convert-1"] }
  }
}
```

Note that `tasks` is an **object of named steps**, not an array — each step refers to the
one before it by name, which is what lets a job branch.

- OpenAPI 3.1 — https://api.convert.online/openapi.json
- API documentation — https://convert.online/api-docs
- Authentication, all three levels — https://convert.online/auth.md
- Job Builder, which writes the request for you — https://convert.online/api-job-builder

See [`examples/rest-quickstart.md`](examples/rest-quickstart.md) for the five calls end to end.

---

## Limits and cost

A free tier exists and needs no credit card. Anonymous conversion through the website
needs no account at all. Quotas and paid plans are at
[convert.online/plans](https://convert.online/plans).

## License

The documentation and examples in this repository are MIT licensed — see [LICENSE](LICENSE).
The hosted service has its own [terms](https://convert.online/terms) and
[privacy policy](https://convert.online/privacy).