From 785da52f32a2bf1da32c0d019940d2d568b383c4 Mon Sep 17 00:00:00 2001 From: Kevin van Zonneveld Date: Tue, 17 Feb 2026 10:04:34 +0100 Subject: [PATCH 1/5] docs(mcp-server): sync README with product docs and add contributing --- packages/mcp-server/README.md | 256 ++++++++++++++++--------- packages/mcp-server/src/server-card.ts | 2 +- 2 files changed, 162 insertions(+), 96 deletions(-) diff --git a/packages/mcp-server/README.md b/packages/mcp-server/README.md index d2e4d5f8..601feafa 100644 --- a/packages/mcp-server/README.md +++ b/packages/mcp-server/README.md @@ -1,7 +1,6 @@ # @transloadit/mcp-server -Transloadit MCP server (Streamable HTTP + stdio). This package is thin glue over -`@transloadit/node` and shared libraries. +Transloadit MCP Server (Streamable HTTP + stdio), built on top of `@transloadit/node`. ## Install @@ -9,12 +8,50 @@ Transloadit MCP server (Streamable HTTP + stdio). This package is thin glue over npm install @transloadit/mcp-server ``` -## Quick start (agents) +## Quick start (self-hosted, recommended) -Most users add the MCP server to their agent client. The client starts the server -automatically (via `npx -y @transloadit/mcp-server stdio`). +For most teams, self-hosted MCP is the simplest happy path: run the server where your agent runs, +set `TRANSLOADIT_KEY` and `TRANSLOADIT_SECRET`, and the server handles API auth automatically. -Claude Code: +### Stdio (recommended) + +```bash +TRANSLOADIT_KEY=MY_AUTH_KEY TRANSLOADIT_SECRET=MY_SECRET_KEY npx -y @transloadit/mcp-server stdio +``` + +### HTTP + +```bash +TRANSLOADIT_KEY=MY_AUTH_KEY TRANSLOADIT_SECRET=MY_SECRET_KEY \ +transloadit-mcp http --host 127.0.0.1 --port 5723 +``` + +When binding HTTP mode to non-localhost hosts, `TRANSLOADIT_MCP_TOKEN` is required. + +## Hosted endpoint + +If you cannot run `npx` where the agent runs, use the hosted endpoint: + +```text +https://api2.transloadit.com/mcp +``` + +Use `Authorization: Bearer `. Mint a token with: + +```bash +npx -y @transloadit/node auth token --aud mcp +``` + +or `POST https://api2.transloadit.com/token` (HTTP Basic Auth with key/secret). + +Bearer tokens satisfy signature auth on API2 requests; signature checks apply to key/secret +requests. + +## Agent client setup + +Most users add the server to their MCP client and let the client start it automatically via stdio. + +### Claude Code ```bash claude mcp add --transport stdio transloadit \ @@ -23,9 +60,7 @@ claude mcp add --transport stdio transloadit \ -- npx -y @transloadit/mcp-server stdio ``` -For non-interactive runs (e.g. `claude -p`), explicitly allow MCP tools. Claude MCP -tools are named `mcp____`, so `mcp__transloadit__*` allows all tools -from this server. +For non-interactive runs (for example `claude -p`), explicitly allow MCP tools: ```bash claude -p "List templates" \ @@ -33,7 +68,7 @@ claude -p "List templates" \ --output-format json ``` -Codex CLI: +### Codex CLI ```bash codex mcp add transloadit \ @@ -42,7 +77,7 @@ codex mcp add transloadit \ -- npx -y @transloadit/mcp-server stdio ``` -To allowlist tools, add `enabled_tools` for the server in `~/.codex/config.toml`: +Allowlist tools in `~/.codex/config.toml`: ```toml [mcp_servers.transloadit] @@ -51,7 +86,7 @@ args = ["-y", "@transloadit/mcp-server", "stdio"] enabled_tools = ["transloadit_list_templates"] ``` -Gemini CLI: +### Gemini CLI ```bash gemini mcp add --scope user transloadit npx -y @transloadit/mcp-server stdio \ @@ -59,7 +94,7 @@ gemini mcp add --scope user transloadit npx -y @transloadit/mcp-server stdio \ --env TRANSLOADIT_SECRET=... ``` -To allowlist tools, set `includeTools` for the server in `~/.gemini/settings.json`: +Allowlist tools in `~/.gemini/settings.json`: ```json { @@ -77,7 +112,9 @@ To allowlist tools, set `includeTools` for the server in `~/.gemini/settings.jso } ``` -Cursor (`~/.cursor/mcp.json`): +### Cursor + +`~/.cursor/mcp.json`: ```json { @@ -94,7 +131,9 @@ Cursor (`~/.cursor/mcp.json`): } ``` -OpenCode (`~/.config/opencode/opencode.json`): +### OpenCode + +`~/.config/opencode/opencode.json`: ```json { @@ -111,10 +150,6 @@ OpenCode (`~/.config/opencode/opencode.json`): } ``` -If you cannot install packages where the agent runs (locked‑down or hosted environments), -use the hosted MCP endpoint (`https://api2.transloadit.com/mcp`) with bearer tokens. This -is a fallback — self‑hosted MCP is the default recommendation. - ## Run the server manually HTTP: @@ -129,56 +164,54 @@ Stdio: transloadit-mcp stdio ``` -## MCP vs skills/CLI - -MCP is best for **embedded runtime** use: long‑lived or autonomous agent pipelines where -Transloadit runs repeatedly (uploads → assemblies → polling → results). - -Skills/CLI are best for **human‑directed, one‑off work**: setting up integrations, -generating templates, scaffolding code, or running a single processing task locally with -full repo/tool access. - -These are guidelines, not hard rules. Some systems (for example Open Claw) can work -beautifully with skills, and MCP can also be great for interactive, human‑in‑the‑loop -flows. The right choice depends on your environment and preferences — and we’ll keep -supporting both. - ## Auth model -**Hosted (api2.transloadit.com/mcp)** +### Hosted (`https://api2.transloadit.com/mcp`) -- Mint a token via `POST https://api2.transloadit.com/token` (HTTP Basic Auth with key+secret). -- Use `Authorization: Bearer ` on API2 requests. -- Bearer tokens **satisfy signature auth**; signature checks apply only to key/secret requests. +- Mint token via `POST https://api2.transloadit.com/token`. +- Send `Authorization: Bearer `. +- Bearer auth satisfies signature auth; signature checks apply to key/secret requests. -**Self-hosted** +### Self-hosted -- stdio and localhost HTTP require no MCP auth by default. +- Stdio and localhost HTTP need no MCP auth by default. - Non-localhost HTTP requires `TRANSLOADIT_MCP_TOKEN`. -- API calls use `TRANSLOADIT_KEY` + `TRANSLOADIT_SECRET`, or bearer tokens if provided. +- Live Transloadit API calls use: + - incoming Bearer token from MCP request headers, or + - `TRANSLOADIT_KEY` + `TRANSLOADIT_SECRET`. ## Configuration -Environment: +### Environment variables - `TRANSLOADIT_KEY` - `TRANSLOADIT_SECRET` - `TRANSLOADIT_MCP_TOKEN` - `TRANSLOADIT_ENDPOINT` (optional, default `https://api2.transloadit.com`) - `TRANSLOADIT_MCP_METRICS_PATH` (optional, default `/metrics`) +- `TRANSLOADIT_MCP_METRICS_USER` (optional) +- `TRANSLOADIT_MCP_METRICS_PASSWORD` (optional) -CLI: +### CLI flags -- `transloadit-mcp http --host 127.0.0.1 --port 5723 --endpoint https://api2.transloadit.com` +- `transloadit-mcp http --host 127.0.0.1 --port 5723` +- `transloadit-mcp http --endpoint https://api2.transloadit.com` - `transloadit-mcp http --config path/to/config.json` -## Metrics +## Tool surface + +- `transloadit_lint_assembly_instructions` +- `transloadit_create_assembly` +- `transloadit_get_assembly_status` +- `transloadit_wait_for_assembly` +- `transloadit_list_robots` +- `transloadit_get_robot_help` +- `transloadit_list_templates` + +`transloadit_list_templates` supports: -- Prometheus-compatible metrics are exposed at `GET /metrics` by default. -- Customize the path via `TRANSLOADIT_MCP_METRICS_PATH` or config `metricsPath`. -- Disable by setting `metricsPath: false` in the config or when creating the server/router. -- Optional basic auth via `TRANSLOADIT_MCP_METRICS_USER` + - `TRANSLOADIT_MCP_METRICS_PASSWORD` or config `metricsAuth`. +- `include_builtin`: `all`, `latest`, `exclusively-all`, `exclusively-latest` +- `include_content`: include parsed `steps` in each template item ## Input files @@ -203,66 +236,99 @@ export type InputFile = ## Limits -These limits apply only to inline JSON/base64 payloads. Small files can be sent inline, but large -files should be passed as `path` or `url`. The MCP server uploads those via tus (the default), so -the request body stays small and no extra MCP/LLM token budget is consumed. - -- Hosted default request body limit: **1 MB** (JSON). -- Hosted default `maxBase64Bytes`: **512_000** (decoded bytes). -- Self-hosted default request body limit: **10 MB** (configurable). - -## URL inputs - -- By default URL files are **downloaded and uploaded via tus**. This keeps instructions unchanged - and avoids large inline payloads (the transfer happens out-of-band). -- If instructions already contain an `/http/import` step, the MCP server sets/overrides its `url`. - - If multiple URLs and a single `/http/import` step exists, it supplies a `url` array. -- When `template_id` is used, the MCP server fetches the template and - chooses the safest URL path: - - If the merged template contains a `/http/import` step, it overrides that step’s `url`. - - If the template expects uploads (`:original` / `/upload/handle`), it downloads and uploads via - tus. - - If the template doesn’t take inputs (for example `/html/convert` with a `url`), URL inputs are - ignored and a warning is returned. - - If `allow_steps_override=false` and the template only supports `/http/import`, URL inputs are - rejected (no safe override path). +These limits apply to inline JSON/base64 payloads. For larger files, prefer `path` or `url`. + +- Hosted default request body limit: **1 MB** +- Hosted `maxBase64Bytes`: **512,000** decoded bytes +- Self-hosted default request body limit: **10 MB** (configurable) + +## URL inputs and template behavior + +For URL inputs, behavior depends on the template/instructions: + +- If an `/http/import` Step exists, MCP sets/overrides that Step's `url`. +- If the template expects uploads (`:original` or `/upload/handle`), MCP downloads then uploads via + tus. +- If the template does not take input files, URL inputs are ignored and a warning is returned. +- If `allow_steps_override=false` and only `/http/import` would work, URL inputs are rejected. ## Local vs hosted file access -- `path` inputs only work when the MCP server can read the same filesystem (local/stdio). -- Hosted MCP cannot access your disk. Use `url`/`base64` for small files, or upload locally with: - `npx -y @transloadit/node upload ./file.ext --create-upload-endpoint --assembly --field :original` -- For remote flows, create the Assembly with `expected_uploads` so it stays open for out‑of‑band - tus uploads. +- `path` inputs require filesystem access from the MCP process (local/self-hosted). +- Hosted MCP cannot read local disk. +- For remote workflows, use `url`, small `base64`, or upload locally with + `npx -y @transloadit/node upload`. +- Use `expected_uploads` to keep an Assembly open for out-of-band tus uploads. ## Resume behavior -If `assembly_url` is provided, the MCP server resumes uploads using Assembly status -(`tus_uploads` + `uploads`). This requires stable, unique `field` names and file metadata -(`filename` + `size`). Only **path-based** inputs resume; non-file inputs start fresh uploads. +If `assembly_url` is provided, MCP resumes uploads using Assembly status (`tus_uploads` + +`uploads`). This requires stable field names and file metadata (`filename` + `size`). +Path-based file inputs can be resumed. -## Tool surface +## Metrics and server card -- `transloadit_create_assembly` -- `transloadit_get_assembly_status` -- `transloadit_wait_for_assembly` -- `transloadit_lint_assembly_instructions` -- `transloadit_list_robots` -- `transloadit_get_robot_help` -- `transloadit_list_templates` +- Prometheus metrics at `GET /metrics` by default. +- Configure via `TRANSLOADIT_MCP_METRICS_PATH` or `metricsPath`. +- Disable via `metricsPath: false`. +- Optional metrics basic auth via `TRANSLOADIT_MCP_METRICS_USER` + + `TRANSLOADIT_MCP_METRICS_PASSWORD` or `metricsAuth`. +- Public discovery endpoint at `/.well-known/mcp/server-card.json`. + +## MCP vs skills/CLI + +- Use MCP for embedded runtime execution (uploads, Assemblies, polling, results). +- Use skills/CLI for human-directed and one-off workflows (setup, scaffolding, local automation). + +These are guidelines, not strict rules. Many teams use both. ## Verify MCP clients -Run a local smoke test that uses the latest published MCP server and your installed CLIs -(Claude Code, Codex CLI, Gemini CLI). Requires `TRANSLOADIT_KEY` + `TRANSLOADIT_SECRET` and -active CLI auth. The script fetches a template id directly, then asks each client to return that -id via `transloadit_list_templates` (so it can’t pass without MCP). Missing CLIs are skipped. -Override the per-command timeout with `MCP_VERIFY_TIMEOUT_MS`. +Run a local smoke test with published MCP server and installed CLIs (Claude Code, Codex CLI, +Gemini CLI). Requires `TRANSLOADIT_KEY` + `TRANSLOADIT_SECRET` and active CLI auth. ```bash node scripts/verify-mcp-clients.ts ``` -## Roadmap +Set `MCP_VERIFY_TIMEOUT_MS` to override command timeout. + +## Docs + +- Website docs: https://transloadit.com/docs/sdks/mcp-server/ +- API token docs: https://transloadit.com/docs/api/token-post/ + +## Contributing + +### Prerequisites + +- Node.js 22+ +- Corepack-enabled Yarn 4 + +### Install dependencies + +From repo root: + +```bash +corepack yarn install +``` + +### Validate changes + +```bash +corepack yarn --cwd packages/mcp-server check +``` + +### Run e2e tests + +`test:e2e` requires valid Transloadit credentials in your environment. + +```bash +corepack yarn --cwd packages/mcp-server test:e2e +``` + +### Submit a change -- Next.js Claude Web flow to mint and hand off bearer tokens for MCP. +- Add or update tests with behavior changes. +- Keep README and website docs aligned for user-facing behavior. +- Open a PR in `transloadit/node-sdk`. diff --git a/packages/mcp-server/src/server-card.ts b/packages/mcp-server/src/server-card.ts index c0aa7af6..d29acf29 100644 --- a/packages/mcp-server/src/server-card.ts +++ b/packages/mcp-server/src/server-card.ts @@ -165,7 +165,7 @@ export const buildServerCard = ( }, description: 'Agent-native media processing: video encoding, image manipulation, document conversion, and more via 86+ Robots.', - documentationUrl: 'https://transloadit.com/docs/topics/ai-agents/', + documentationUrl: 'https://transloadit.com/docs/sdks/mcp-server/', iconUrl: 'https://transloadit.com/favicon.ico', transport: { type: 'streamable-http', From 9aa12ab42f088dd3df2b67e89f97a4a2d5b810e1 Mon Sep 17 00:00:00 2001 From: Kevin van Zonneveld Date: Tue, 17 Feb 2026 10:21:06 +0100 Subject: [PATCH 2/5] docs(mcp-server): explain self-hosted TRANSLOADIT_MCP_TOKEN --- packages/mcp-server/README.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/mcp-server/README.md b/packages/mcp-server/README.md index 601feafa..869ffdf8 100644 --- a/packages/mcp-server/README.md +++ b/packages/mcp-server/README.md @@ -28,6 +28,23 @@ transloadit-mcp http --host 127.0.0.1 --port 5723 When binding HTTP mode to non-localhost hosts, `TRANSLOADIT_MCP_TOKEN` is required. +### `TRANSLOADIT_MCP_TOKEN` explained + +`TRANSLOADIT_MCP_TOKEN` is a self-hosted MCP transport token. It protects your own HTTP MCP endpoint +(`transloadit-mcp http`), not API2. + +- Set it yourself to any high-entropy secret. +- Send it from your MCP client as `Authorization: Bearer `. +- It is **not** minted via `/token`. +- It is separate from API2 Bearer tokens used for `https://api2.transloadit.com/mcp`. + +Generate one, then start HTTP mode: + +```bash +export TRANSLOADIT_MCP_TOKEN=\"$(openssl rand -hex 32)\" +transloadit-mcp http --host 0.0.0.0 --port 5723 +``` + ## Hosted endpoint If you cannot run `npx` where the agent runs, use the hosted endpoint: @@ -175,7 +192,7 @@ transloadit-mcp stdio ### Self-hosted - Stdio and localhost HTTP need no MCP auth by default. -- Non-localhost HTTP requires `TRANSLOADIT_MCP_TOKEN`. +- Non-localhost HTTP requires `TRANSLOADIT_MCP_TOKEN` (a static secret you define). - Live Transloadit API calls use: - incoming Bearer token from MCP request headers, or - `TRANSLOADIT_KEY` + `TRANSLOADIT_SECRET`. From 4f28fde631cf4ae8c9f2730ddceadcce000ce4af Mon Sep 17 00:00:00 2001 From: Kevin van Zonneveld Date: Tue, 17 Feb 2026 10:25:04 +0100 Subject: [PATCH 3/5] docs(mcp-server): add roadmap note under contributing --- packages/mcp-server/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/mcp-server/README.md b/packages/mcp-server/README.md index 869ffdf8..8993635b 100644 --- a/packages/mcp-server/README.md +++ b/packages/mcp-server/README.md @@ -349,3 +349,7 @@ corepack yarn --cwd packages/mcp-server test:e2e - Add or update tests with behavior changes. - Keep README and website docs aligned for user-facing behavior. - Open a PR in `transloadit/node-sdk`. + +### Roadmap + +- Next.js Claude Web flow to mint and hand off bearer tokens for MCP. From 3e3b9d3f6ed1f4442320318b9bc9a43df4a8f5aa Mon Sep 17 00:00:00 2001 From: Kevin van Zonneveld Date: Tue, 17 Feb 2026 10:53:47 +0100 Subject: [PATCH 4/5] docs(mcp-server): fix quickstart npx and token export example --- packages/mcp-server/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/mcp-server/README.md b/packages/mcp-server/README.md index 8993635b..4652876e 100644 --- a/packages/mcp-server/README.md +++ b/packages/mcp-server/README.md @@ -23,7 +23,7 @@ TRANSLOADIT_KEY=MY_AUTH_KEY TRANSLOADIT_SECRET=MY_SECRET_KEY npx -y @transloadit ```bash TRANSLOADIT_KEY=MY_AUTH_KEY TRANSLOADIT_SECRET=MY_SECRET_KEY \ -transloadit-mcp http --host 127.0.0.1 --port 5723 +npx -y @transloadit/mcp-server http --host 127.0.0.1 --port 5723 ``` When binding HTTP mode to non-localhost hosts, `TRANSLOADIT_MCP_TOKEN` is required. @@ -31,7 +31,7 @@ When binding HTTP mode to non-localhost hosts, `TRANSLOADIT_MCP_TOKEN` is requir ### `TRANSLOADIT_MCP_TOKEN` explained `TRANSLOADIT_MCP_TOKEN` is a self-hosted MCP transport token. It protects your own HTTP MCP endpoint -(`transloadit-mcp http`), not API2. +(`npx -y @transloadit/mcp-server http`), not API2. - Set it yourself to any high-entropy secret. - Send it from your MCP client as `Authorization: Bearer `. @@ -41,8 +41,8 @@ When binding HTTP mode to non-localhost hosts, `TRANSLOADIT_MCP_TOKEN` is requir Generate one, then start HTTP mode: ```bash -export TRANSLOADIT_MCP_TOKEN=\"$(openssl rand -hex 32)\" -transloadit-mcp http --host 0.0.0.0 --port 5723 +export TRANSLOADIT_MCP_TOKEN="$(openssl rand -hex 32)" +npx -y @transloadit/mcp-server http --host 0.0.0.0 --port 5723 ``` ## Hosted endpoint @@ -172,13 +172,13 @@ Allowlist tools in `~/.gemini/settings.json`: HTTP: ```bash -transloadit-mcp http --host 127.0.0.1 --port 5723 +npx -y @transloadit/mcp-server http --host 127.0.0.1 --port 5723 ``` Stdio: ```bash -transloadit-mcp stdio +npx -y @transloadit/mcp-server stdio ``` ## Auth model @@ -211,9 +211,9 @@ transloadit-mcp stdio ### CLI flags -- `transloadit-mcp http --host 127.0.0.1 --port 5723` -- `transloadit-mcp http --endpoint https://api2.transloadit.com` -- `transloadit-mcp http --config path/to/config.json` +- `npx -y @transloadit/mcp-server http --host 127.0.0.1 --port 5723` +- `npx -y @transloadit/mcp-server http --endpoint https://api2.transloadit.com` +- `npx -y @transloadit/mcp-server http --config path/to/config.json` ## Tool surface From d3230d954d47c61a1cdbddcaaf744f0d2ae20cfe Mon Sep 17 00:00:00 2001 From: Kevin van Zonneveld Date: Tue, 17 Feb 2026 11:07:16 +0100 Subject: [PATCH 5/5] docs(mcp-server): clarify node sdk token minting prerequisite --- packages/mcp-server/README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/mcp-server/README.md b/packages/mcp-server/README.md index 4652876e..f07720f1 100644 --- a/packages/mcp-server/README.md +++ b/packages/mcp-server/README.md @@ -59,7 +59,13 @@ Use `Authorization: Bearer `. Mint a token with: npx -y @transloadit/node auth token --aud mcp ``` -or `POST https://api2.transloadit.com/token` (HTTP Basic Auth with key/secret). +Generate this token in a trusted environment (backend, CI, or local shell), then hand it to the +agent runtime. You can mint it via: + +- CLI: `npx -y @transloadit/node auth token --aud mcp` +- API: `POST https://api2.transloadit.com/token` (HTTP Basic Auth with key/secret) +- Node SDK: instantiate `Transloadit` with `authKey` + `authSecret`, then call + `client.mintBearerToken({ aud: 'mcp' })` Bearer tokens satisfy signature auth on API2 requests; signature checks apply to key/secret requests.