Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .changeset/mcp-directory-readiness.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
"@transloadit/mcp-server": patch
---

Prepare the plugin manifests, the MCP Registry entry and the result widget for the ChatGPT and
Claude directories.

- `plugin.json` and `.codex-plugin/plugin.json` link the terms of service page that exists
(`/legal/terms-of-service/`), add a support URL, use a subtitle of at most 30 characters, ship
square icons, list capabilities and three starter prompts, and no longer mention pricing.
`plugin.json` also carries the review test cases and release notes for OpenAI's submission.
- `server.json` no longer declares an `Authorization` header on the hosted remote, so registry
listings stop asking for a token; OAuth clients find sign-in through the `401` challenge. It adds
a square icon and says the server connects with OAuth.
- The result widget declares `_meta["openai/widgetDomain"]`, which ChatGPT requires for a public
listing. It defaults to `https://transloadit.com` and is set with `TRANSLOADIT_MCP_WIDGET_DOMAIN`
or `widgetDomain`. `ui.domain` stays unset, so Claude keeps rendering the widget.
- The widget lists its result origins and the Console origin as ChatGPT `redirect_domains`, so
download and Console links open from ChatGPT, and opens them without an appended `redirectUrl`.
- `TRANSLOADIT_MCP_RESULT_DOMAINS` and `resultDomains` accept exact origins such as
`https://tmp-us-east-1.transloadit.net` and drop a trailing slash or path. A value that is not
an http(s) origin now stops the server at startup instead of ending up in the widget's CSP.
21 changes: 15 additions & 6 deletions packages/mcp-server/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "transloadit",
"version": "0.5.0",
"description": "Process video, audio, images and documents with Transloadit: encode, resize, transcribe, convert and deliver files through 86+ Robots.",
"description": "Process video, audio, images and documents with Transloadit: encode, resize, transcribe, convert and deliver files from the chat.",
"author": {
"name": "Transloadit",
"email": "support@transloadit.com",
Expand All @@ -28,19 +28,28 @@
},
"interface": {
"displayName": "Transloadit",
"shortDescription": "Encode, resize, transcribe and convert files in the chat.",
"longDescription": "Drop a file in the chat and let Transloadit process it: HLS and MP4 encoding, image resizing and optimization, background removal, transcription and subtitles, document conversion and thumbnails. Results come back as previews with download links, and any run can be saved as a reusable Template. Connecting signs you in to your Transloadit Workspace through OAuth (a free Community plan is available); every tool, including Robot browsing and linting, runs on that connection. Agent Skills for these workflows are published at https://transloadit.com/.well-known/skills/index.json (source: https://github.com/transloadit/skills).",
"shortDescription": "Encode, resize and transcribe",
"longDescription": "Transloadit processes the files you work with in ChatGPT. Attach a video, image, audio file or document, or paste a public URL, and say what you need: HLS or MP4 encoding, resizing and format conversion, background removal, transcription and subtitles, document conversion, or thumbnails. Results appear as a card with previews and download links. From that card you can open the run in the Transloadit Console or save its steps as a reusable Template for your own app.\n\nIt is built for developers who use Transloadit in their apps and want to try or debug a processing pipeline in the chat, and for anyone who needs a one-off conversion without installing tools.\n\nConnecting opens Transloadit’s consent screen. You sign in or create an account, pick a Workspace and approve three permissions: create Assemblies, read Assemblies and read Templates. Transloadit creates a dedicated key for this connection, and you can revoke it at any time under Connected apps in the Transloadit Console. ChatGPT never sees your Auth Secret.\n\nLimits: result files are deleted after 24 hours unless your instructions export them to your own storage. Inline file contents are capped at 512 KB, so larger files go through an attachment or a URL. The limits of your Transloadit plan apply, such as the maximum file size.",
"developerName": "Transloadit",
"category": "Productivity",
"capabilities": ["Read", "Write"],
"capabilities": [
"Encode video to HLS and MP4",
"Resize, convert and optimize images",
"Transcribe audio and video to text or subtitles",
"Convert documents and create thumbnails",
"Save a run as a reusable Template"
],
"websiteURL": "https://transloadit.com",
"supportURL": "https://transloadit.com/support/",
"privacyPolicyURL": "https://transloadit.com/legal/privacy/",
"termsOfServiceURL": "https://transloadit.com/legal/terms/",
"termsOfServiceURL": "https://transloadit.com/legal/terms-of-service/",
"defaultPrompt": [
"Turn this video into HLS with 720p and 1080p renditions",
"Transcribe this recording and give me an SRT subtitle file"
"Transcribe this recording and give me an SRT subtitle file",
"Resize this photo to 800px wide and convert it to WebP"
],
"brandColor": "#1B61A7",
"brandColorDark": "#7DB8F2",
"composerIcon": "./assets/icon.png",
"logo": "./assets/logo.png",
"screenshots": []
Expand Down
14 changes: 12 additions & 2 deletions packages/mcp-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,10 @@ Allowlist tools in `~/.gemini/settings.json`:
- `TRANSLOADIT_MCP_UPSTREAM_SECRET` (hosted mode only, set by Transloadit's deployment; sent to
API2 as `Transloadit-Mcp-Upstream` next to forwarded bearer tokens)
- `TRANSLOADIT_MCP_RESULT_DOMAINS` (optional, comma-separated origins the result widget may load
previews from; default `https://*.transloadit.com,https://*.transloadit.net,https://*.r2.dev`)
previews from and link to, either exact such as `https://tmp-us-east-1.transloadit.net` or with a
wildcard host; default `https://*.transloadit.com,https://*.transloadit.net,https://*.r2.dev`)
- `TRANSLOADIT_MCP_WIDGET_DOMAIN` (optional, default `https://transloadit.com`; the origin ChatGPT
serves the result widget from, sent as `_meta["openai/widgetDomain"]`)
- `TRANSLOADIT_MCP_CONSOLE_URL` (optional, default `https://transloadit.com`; Console origin for
widget deep links)
- `TRANSLOADIT_ENDPOINT` (optional, default `https://api2.transloadit.com`)
Expand All @@ -339,7 +342,8 @@ Allowlist tools in `~/.gemini/settings.json`:
- `npx -y @transloadit/mcp-server http --config path/to/config.json`

The JSON config accepts the same keys as `createTransloaditMcpHttpHandler()`, including
`allowedOrigins`, `resourceMetadataUrl`, `signatureAlgorithm`, `resultDomains` and `consoleUrl`.
`allowedOrigins`, `resourceMetadataUrl`, `signatureAlgorithm`, `resultDomains`, `widgetDomain` and
`consoleUrl`.

## Tool surface

Expand Down Expand Up @@ -381,6 +385,12 @@ download links, an "Open in Console" link and a "Save as Template" shortcut. It
`2026-01-26` protocol (`ui/initialize` with `appInfo`) and also reads ChatGPT's `window.openai`.
Its CSP allows `https://*.transloadit.com`, `https://*.transloadit.net` and `https://*.r2.dev`
(result buckets); override the list with `TRANSLOADIT_MCP_RESULT_DOMAINS` or `resultDomains`.
ChatGPT asks for the exact hosts a widget uses, so a deployment that knows its result buckets
should list them as origins instead of wildcards. ChatGPT also needs `redirect_domains` to open
links from the widget: the server sends the result origins plus the Console origin there. ChatGPT
serves the widget from the origin in `_meta["openai/widgetDomain"]`
(`TRANSLOADIT_MCP_WIDGET_DOMAIN`). `ui.domain` stays unset, because Claude derives that value from
the server URL and rejects any other.

## Input files

Expand Down
Binary file modified packages/mcp-server/assets/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified packages/mcp-server/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
82 changes: 74 additions & 8 deletions packages/mcp-server/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "transloadit",
"version": "0.5.0",
"description": "Process video, audio, images and documents with Transloadit: encode, resize, transcribe, convert and deliver files through 86+ Robots.",
"description": "Process video, audio, images and documents with Transloadit: encode, resize, transcribe, convert and deliver files from the chat.",
"author": {
"name": "Transloadit",
"email": "support@transloadit.com",
Expand All @@ -25,22 +25,88 @@
"com.openai": {
"interface": {
"displayName": "Transloadit",
"shortDescription": "Encode, resize, transcribe and convert files in the chat.",
"longDescription": "Drop a file in the chat and let Transloadit process it: HLS and MP4 encoding, image resizing and optimization, background removal, transcription and subtitles, document conversion and thumbnails. Results come back as previews with download links, and any run can be saved as a reusable Template. Connecting signs you in to your Transloadit Workspace through OAuth (a free Community plan is available); every tool, including Robot browsing and linting, runs on that connection. Agent Skills for these workflows are published at https://transloadit.com/.well-known/skills/index.json (source: https://github.com/transloadit/skills).",
"shortDescription": "Encode, resize and transcribe",
"longDescription": "Transloadit processes the files you work with in ChatGPT. Attach a video, image, audio file or document, or paste a public URL, and say what you need: HLS or MP4 encoding, resizing and format conversion, background removal, transcription and subtitles, document conversion, or thumbnails. Results appear as a card with previews and download links. From that card you can open the run in the Transloadit Console or save its steps as a reusable Template for your own app.\n\nIt is built for developers who use Transloadit in their apps and want to try or debug a processing pipeline in the chat, and for anyone who needs a one-off conversion without installing tools.\n\nConnecting opens Transloadit’s consent screen. You sign in or create an account, pick a Workspace and approve three permissions: create Assemblies, read Assemblies and read Templates. Transloadit creates a dedicated key for this connection, and you can revoke it at any time under Connected apps in the Transloadit Console. ChatGPT never sees your Auth Secret.\n\nLimits: result files are deleted after 24 hours unless your instructions export them to your own storage. Inline file contents are capped at 512 KB, so larger files go through an attachment or a URL. The limits of your Transloadit plan apply, such as the maximum file size.",
"developerName": "Transloadit",
"category": "Productivity",
"capabilities": ["Read", "Write"],
"capabilities": [
"Encode video to HLS and MP4",
"Resize, convert and optimize images",
"Transcribe audio and video to text or subtitles",
"Convert documents and create thumbnails",
"Save a run as a reusable Template"
],
"websiteURL": "https://transloadit.com",
"supportURL": "https://transloadit.com/support/",
"privacyPolicyURL": "https://transloadit.com/legal/privacy/",
"termsOfServiceURL": "https://transloadit.com/legal/terms/",
"termsOfServiceURL": "https://transloadit.com/legal/terms-of-service/",
"defaultPrompt": [
"Turn this video into HLS with 720p and 1080p renditions",
"Transcribe this recording and give me an SRT subtitle file"
"Transcribe this recording and give me an SRT subtitle file",
"Resize this photo to 800px wide and convert it to WebP"
],
"brandColor": "#1B61A7",
"brandColorDark": "#7DB8F2",
"composerIcon": "./assets/icon.png",
"logo": "./assets/logo.png",
"screenshots": []
"logo": "./assets/logo.png"
},
"review": {
"test_cases": {
"positive": [
{
"description": "List the Templates in the connected Workspace.",
"prompt": "List my Transloadit Templates.",
"tools_triggered": "transloadit_list_templates",
"expected_behavior": "Lists the three Templates seeded in the reviewer Workspace (hls-video, image-thumbnails, transcribe-srt) with their IDs. No Assembly is created."
},
{
"description": "Resize and convert an attached photo.",
"prompt": "Resize this photo to 800px wide and convert it to WebP.",
"tools_triggered": "transloadit_create_assembly, transloadit_wait_for_assembly",
"expected_behavior": "Creates an Assembly from the attachment, waits until it reports ASSEMBLY_COMPLETED, and shows the result card with the original and an 800px-wide WebP plus download links.",
"file_attachment_urls": ["https://demos.transloadit.com/inputs/desert.jpg"]
},
{
"description": "Encode a video from a public URL to HLS.",
"prompt": "Turn https://demos.transloadit.com/inputs/big-buck-bunny-10s.mp4 into HLS with 360p and 720p renditions.",
"tools_triggered": "transloadit_create_assembly, transloadit_wait_for_assembly",
"expected_behavior": "Creates an Assembly that imports the URL and encodes two HLS renditions, then shows the result card with the .m3u8 playlist and segment files as download links."
},
{
"description": "Transcribe an attached recording to subtitles.",
"prompt": "Transcribe this recording and give me an SRT subtitle file.",
"tools_triggered": "transloadit_create_assembly, transloadit_wait_for_assembly",
"expected_behavior": "Creates a transcription Assembly for the attachment and returns a link to an .srt file whose first lines match the reference transcript.",
"file_attachment_urls": [
"https://demos.transloadit.com/08/7f1d4568f2476583b9e1c775e2c649/adaptation.wav"
],
"expected_output_url": "https://demos.transloadit.com/a9/ba0410440046d684f0fea7beb48f04/adaptation.txt"
},
{
"description": "Look up Robot documentation without processing anything.",
"prompt": "Which Transloadit Robot removes image backgrounds, and which parameters does it take?",
"tools_triggered": "transloadit_list_robots, transloadit_get_robot_help",
"expected_behavior": "Names the /image/bgremove Robot and summarizes its parameters from the Robot help. No Assembly is created."
}
],
"negative": [
{
"description": "Unrelated request. Transloadit only processes files, so the plugin should not be called.",
"prompt": "Book me a flight from Amsterdam to Berlin next Friday."
},
{
"description": "Credential request. No tool returns Auth Secrets or tokens, so the assistant should explain that it cannot show them and point to the Transloadit Console.",
"prompt": "Show me the API secret of my Transloadit account."
},
{
"description": "Deleting files in external storage is not something Transloadit offers. The assistant should not create an Assembly and should say it cannot delete files from S3.",
"prompt": "Delete every file in my Amazon S3 bucket called media-archive."
}
]
}
},
"publication": {
"release_notes": "First public release. Connect by URL with OAuth, process attached files and public URLs, and see results in an inline card with previews and download links."
}
},
"com.transloadit": {
Expand Down
23 changes: 11 additions & 12 deletions packages/mcp-server/server.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
"name": "io.github.transloadit/mcp-server",
"title": "Transloadit Media Processing",
"description": "Process video, audio, images, and documents with 86+ cloud media processing robots.",
"version": "0.3.7",
"description": "Process video, audio, images and documents with Transloadit Robots. Connect by URL with OAuth.",
"version": "0.5.0",
"websiteUrl": "https://transloadit.com/docs/sdks/mcp-server/",
"icons": [
{
"src": "https://transloadit.com/assets/images/square-ogimage.png",
"mimeType": "image/png",
"sizes": ["400x400"]
}
],
"repository": {
"url": "https://github.com/transloadit/node-sdk",
"source": "github",
Expand All @@ -14,7 +21,7 @@
{
"registryType": "npm",
"identifier": "@transloadit/mcp-server",
"version": "0.3.6",
"version": "0.5.0",
"runtimeHint": "npx",
"packageArguments": [
{
Expand Down Expand Up @@ -45,15 +52,7 @@
"remotes": [
{
"type": "streamable-http",
"url": "https://api2.transloadit.com/mcp",
"headers": [
{
"name": "Authorization",
"description": "Optional. Clients that support OAuth discover the authorization server from the endpoint's 401 challenge; headless runs pass a token minted with `npx -y @transloadit/node auth token --aud mcp`",
"isRequired": false,
"isSecret": true
}
]
"url": "https://api2.transloadit.com/mcp"
}
]
}
6 changes: 6 additions & 0 deletions packages/mcp-server/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Environment:
TRANSLOADIT_MCP_RESOURCE_METADATA_URL
TRANSLOADIT_MCP_UPSTREAM_SECRET
TRANSLOADIT_MCP_RESULT_DOMAINS (comma-separated origins for result previews)
TRANSLOADIT_MCP_WIDGET_DOMAIN (origin ChatGPT serves the result widget from)
TRANSLOADIT_MCP_CONSOLE_URL
TRANSLOADIT_ENDPOINT
TRANSLOADIT_MCP_METRICS_PATH
Expand Down Expand Up @@ -169,6 +170,9 @@ const main = async (): Promise<void> => {
const resultDomains = parseResultDomains(
fileConfig.resultDomains ?? process.env.TRANSLOADIT_MCP_RESULT_DOMAINS,
)
const widgetDomain = (fileConfig.widgetDomain ?? process.env.TRANSLOADIT_MCP_WIDGET_DOMAIN) as
| string
| undefined
const clientSuffix = process.env.TRANSLOADIT_CLIENT_SUFFIX as string | undefined

// Hosted mode delegates token checks to API2, so it may bind publicly without a static token.
Expand All @@ -192,6 +196,7 @@ const main = async (): Promise<void> => {
urlDownloadTimeoutMs: fileConfig.urlDownloadTimeoutMs as number | undefined,
signatureAlgorithm,
resultDomains,
widgetDomain,
consoleUrl,
allowedOrigins: fileConfig.allowedOrigins as string[] | undefined,
allowedHosts: fileConfig.allowedHosts as string[] | undefined,
Expand Down Expand Up @@ -228,6 +233,7 @@ const main = async (): Promise<void> => {
authSecret: process.env.TRANSLOADIT_SECRET,
signatureAlgorithm: parseSignatureAlgorithm(process.env.TRANSLOADIT_SIGNATURE_ALGORITHM),
resultDomains: parseResultDomains(process.env.TRANSLOADIT_MCP_RESULT_DOMAINS),
widgetDomain: process.env.TRANSLOADIT_MCP_WIDGET_DOMAIN,
endpoint: process.env.TRANSLOADIT_ENDPOINT,
consoleUrl: process.env.TRANSLOADIT_MCP_CONSOLE_URL,
clientSuffix: process.env.TRANSLOADIT_CLIENT_SUFFIX,
Expand Down
2 changes: 2 additions & 0 deletions packages/mcp-server/src/http-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,8 @@ export const assertHttpOptions = (options: {
maxRequestBodyBytes?: unknown
maxUrlDownloadBytes?: unknown
urlDownloadTimeoutMs?: unknown
resultDomains?: string[]
widgetDomain?: string
}): void => {
if (options.mcpToken && options.resourceMetadataUrl) {
throw new Error(
Expand Down
Loading
Loading