# AITrans.Video MCP integration Remote MCP endpoint: https://aitrans.video/api/ai Use OAuth code with S256 PKCE, short-lived access tokens and rotating refresh tokens. Operator registration is required; dynamic client registration is not available. Contact support with the exact client/version/callback. Website cookies and API keys are not MCP credentials. Compatibility depends on enabled deployment, registration and current grant. Read authorization and protected-resource metadata at the links below when OAuth is enabled. Use the metadata's endpoints and exact resource identifier, preserve state and verify issuer. Remote callbacks require exact registered HTTPS URLs. Native IP loopback callbacks must be explicitly registered; only their port may vary. localhost hostnames and custom URI schemes are not accepted. Request only the client's allowed scopes: translations:create permits creation, while translations:read or translations:read_existing permits eligible task reads; one client's grant never authorizes another client's tasks. On 401 invalid_token, use the client's normal refresh flow; if refused, ask for browser authorization again. Never log or paste tokens into a conversation. Preparation uses verified_media, source_language_mode=auto, an available canonical target (en, zh-CN, pt, ja, th, id, vi), service_mode=express and requested_outputs=[editor]. Other website settings are not automatically available through MCP. ## Seven tools (examples use fictional IDs) ### get_translation_options Read currently available target_languages and official presets for selected_target_language. Optional target_language defaults to en; search voice_query literally and follow voice_cursor with the same target. Arguments: {} ### request_translation_upload Get a website upload link. The user selects and shares the video on the website. Arguments: {"request_key":"example-upload-001"} ### get_translation_upload Observe the original upload request until a verified media version is ready. Arguments: {"request_id":"11111111-1111-4111-8111-111111111111"} ### prepare_translation Freeze a server quote and obtain its website confirmation URL; this does not approve spending or create a task. Arguments: {"request_key":"example-prepare-001","request":{"source":{"type":"verified_media","value":"22222222-2222-4222-8222-222222222222"},"source_language_mode":"auto","target_language":"en","service_mode":"express","preset_voice_id":"example-use-returned-voice-id","translation_preferences":null,"requested_outputs":["editor"]}} ### create_translation Submit only the original website-confirmed intent; preserve its identity across response loss. Arguments: {"intent_id":"33333333-3333-4333-8333-333333333333"} ### get_translation Read the original intent, request key OR task; supply exactly one selector. Arguments: {"translation_id":"job_example_001"} ### get_translation_result Read the original task's project/download links, declared output format/role, nullable actual language, job edit version and persisted draft facts. Arguments: {"translation_id":"job_example_001","language":"en"} ## Choosing a target and official preset Search example: {"voice_query":"narrator","voice_page_size":16} Options returns currently qualified target_languages from user rollout, the current runner and compatible official voices. Omitted/null target_language selects en and its original first 32 voices. To choose another target, call options with target_language (for example zh-CN), then use an ID returned for selected_target_language. UI language and detected source language never select the target. Availability is not spending permission or proof of every voice's quality. A selected unavailable target returns 403 target_language_unavailable with current target_languages and choose_available_target_language; unproven runner facts return 503 target_languages_unavailable. Set voice_query (empty for all) for case-insensitive literal ID/name search and optionally voice_page_size=1..32. voice_page contains query, snapshot, offset and next_cursor. Repeat the same target/query with voice_cursor until null. Pages may shrink to fit the actual 16384-byte MCP envelope. Each page checks current OAuth; the cursor grants no access. A catalogue change returns 409 voice_catalog_changed: restart the search. No match returns an empty list. Copy IDs exactly, including spaces or parentheses. voice_query is at most 80 characters without controls, voice_cursor at most 512 URL-safe characters, and page size a strict integer. Null selectors act as omitted; never combine non-null target/voice selectors with require_subtitle_access=true. Selector request IDs, including JSON escaping, must fit 256 bytes. Oversized responses return 413 voice_catalog_response_too_large with use_voice_search_or_smaller_page. 503 voice_catalog_unavailable (transport), result_unavailable (catalogue) or target_languages_unavailable means retry only the read with bounded backoff. No UNKNOWN or paid operation follows. Selection requires a server quote and browser confirmation. ## Confirmation, recovery and delivery The user must open and approve the original server quote on the website before create_translation. Prices, eligibility and entitlements come from Gateway; connecting or uploading does not approve spending. Configuration changes require a new quote and confirmation. Keep the original request_key, request_id, intent_id and job_id. UNKNOWN or a lost response is not permission to create another task or automatically pay and resubmit. Read the original identity; follow poll_after_seconds (normally 30 while waiting) and use bounded backoff for transient failures. Stop on access denial or revocation, rather than retrying creation or substituting another grant. Task creation success is separate from completed media. get_translation_result returns project_url and downloads when reported available. Browser login and the website's current ownership, refund, entitlement and output-generation checks remain final; a link does not promise download success. result_generation is null unless the result passed current authorization, funding and stable App/job-version checks; then it is the nonnegative job edit version. It is not a content hash, same-version regeneration proof or download capability. Already eligible downloads also declare format (mp4/wav/srt/zip), role and nullable actual language. Formats are product declarations, not inspected bytes. Legacy subtitles means target subtitles and subtitles_en means source subtitles regardless of language direction. Missing, unknown or conflicting language stays null; bilingual subtitles and draft containers have null language. Default calls return no subtitle text or audio; existing grants and website download checks are unchanged. Example result metadata: {"result_generation":0,"download":{"key":"publish.dubbed_video","format":"mp4","role":"dubbed_video","language":"en"}} draft_outputs is an additive array of at most two persisted draft facts (disabled CapCut is omitted). It is [] for non-success, refunded, changed or unverified result reads. Each row contains only draft_format, status, warning, freshness and next_action; freshness is always unverified. These facts do not prove file existence or download permission. Example draft_outputs row: {"draft_format":"jianying","status":"needs_review","warning":"compatibility_needs_review","freshness":"unverified","next_action":"review_on_website"} Draft statuses: idle, running, succeeded, needs_review, failed, unknown. Draft next_action values: generate_on_website, wait, review_on_website, open_on_website, open_project_for_details, check_later. An unlocked idle draft points to website generation; a running draft waits; needs_review points to website review; succeeded points to the website only when the original strict draft link is available. Locked, failed or missing deliverables point to project details; unknown facts require checking later. Only needs_review has warning=compatibility_needs_review; other warnings are null. Draft generation, unlocking, editing, copying and final file download remain explicit website actions. No tool automatically buys or generates a draft. Legacy adapter validation failures can return unknown; retain the original IDs. No Agent file-transfer credential is offered here. ## Optional published target subtitle text get_translation_result accepts include_subtitles=true only with explicit translations:subtitles:read in the current client, grant and access token, plus original task-read permission and namespace. The registered ChatGPT client permits this optional scope; other clients must verify their registration. Old grants and refreshes gain no access. New browser consent creates a namespace for future tasks and inherits no old-grant tasks or website copies. On 2026-10-16, normal ChatGPT Settings reconnect, default-off subtitle consent and readiness passed. Three subtitle pages from one owned 12.834-second English Express task exactly matched the native API. This is bounded evidence, not all-language quality acceptance. The earlier inline reconnect-card setup-URL failure is not claimed fixed; use normal Settings reconnect. Optional arguments: {"translation_id":"job_example_001","include_subtitles":true,"page_size":1} include_subtitles defaults to false and must be a real JSON boolean. cursor defaults to null; page_size defaults to 50 when enabled and must be an integer from 1 to 50. cursor/page_size without opt-in are rejected. The opt-in JSON-RPC id, including JSON escaping, must encode to at most 256 bytes; an oversized id receives HTTP 400 without an echoed id before subtitle reading. Other tool/default transport semantics are unchanged. Example subtitles field: {"key":"editor.subtitles_target","role":"target_subtitles","language":"en","result_generation":0,"byte_sha256":"1a505e67aead4a658b451633f3634b9b687ddacd24a3e3c58ba132b5690a8eb2","cues":[{"index":0,"start_ms":0,"end_ms":1500,"text":"Example subtitle"}],"next_cursor":null} Only the currently readable published target SRT is returned, using the absent-only legacy target alias when needed. Cue index is a zero-based file ordinal, not an editing segment ID. File order, overlap, text and millisecond timestamps are preserved. No source/bilingual track, subtitle rebuilding, alignment, restore or remote-storage fetch is performed. Missing, archived, expired, refunded or unavailable local results require the website; no paid operation occurs. Pages contain whole cues only, at most 50 cues and 4096 UTF-8 JSON bytes; source files are limited to 262144 bytes and total upstream reading to 5 seconds. Each opt-in SDK HTTP response, including its text/structured copies and protocol envelope, is limited to 16384 bytes. Pages may shrink to fit. next_cursor advances or is null. The unsigned locator binds task, track, edit generation and exact published byte SHA; it grants no access. Re-read each page under current authorization. A same-generation file replacement also invalidates the cursor. New body reads never return UNKNOWN: 400 invalid request/cursor, 403 missing permission or eligibility, 409 subtitle_snapshot_changed with restart_from_first_page, 413 subtitle_source_too_large/subtitle_cue_too_large/subtitle_response_too_large with open_project_for_details, 422 subtitle_invalid, and 503 subtitle_source_unavailable. A single oversized cue cannot be fixed by reducing page_size; open the project. 401 uses normal refresh or reauthorization. Keep the same task ID; none of these errors authorizes generation or a paid resubmission. ## Public setup references Registration and client-specific setup support: https://aitrans.video/en/contact OAuth authorization metadata (when enabled): https://aitrans.video/.well-known/oauth-authorization-server MCP protected-resource metadata (when enabled): https://aitrans.video/.well-known/oauth-protected-resource/api/ai