Qencode MCP
Qencode lets AI assistants transcode, analyze, edit, optimize, and deliver video using natural language, powered by a cloud video processing platform.
Documentation
qencode-mcp
Model Context Protocol (MCP) server for the Qencode Transcoding API.
Connect any MCP-compatible AI client — Claude, Cursor, ChatGPT, Grok, Gemini — to your Qencode account and let it submit, monitor, and reason about transcoding jobs on your behalf.
Quick example
Once your client is connected (see Connect a client), ask your agent in plain English:
Transcode
https://example.com/input.mp4as an HLS ladder at 1080/720/540/360. Put it in my R2 bucketvideos/demo/.
The agent picks the hls_abr recipe, fills in the per-rendition encoding params, submits via start_encode2_raw, and polls until the job is done.
Prerequisites
- A Qencode portal account with at least one project — sign in at the portal for your environment: https://portal.qencode.com (production) or https://portal-qa.qencode.com (QA). You select the project during the OAuth consent step.
- An MCP-compatible client (Claude, Cursor, ChatGPT, Grok, Gemini, or any custom client).
There are no API keys to copy into client config — authentication is browser-based OAuth.
How it works
The connector uses standard OAuth 2.1 — no API keys in client config. On first use, your client opens a browser, you sign in to your Qencode portal account, pick a project, and approve the requested scopes. The client stores the token; subsequent calls are silent until the token expires.
Scopes the client should request at authorize time (published via Protected Resource Metadata):
| Scope | Purpose |
|---|---|
openid | OIDC identity |
profile | Display name |
email | Account email |
offline_access | Refresh token |
transcoding:read | get_job_status, wait_for_job, docs tools |
transcoding:write | transcode_video, start_encode2_raw |
The RS enforces transcoding:read and transcoding:write on access tokens at the transport layer.
Your Qencode API keys never leave the portal. The MCP server derives a short-lived session token per request via an internal portal endpoint.
Environments
The same connector is deployed in two environments. Each has its own domains, accounts, projects, and credentials — sign in to the portal that matches the endpoint you connect to.
| Role | Production | QA (testing) |
|---|---|---|
| MCP endpoint (connect here) | https://mcp.qencode.com/mcp | https://mcp-qa.qencode.com/mcp |
| Portal (sign in / projects) | https://portal.qencode.com | https://portal-qa.qencode.com |
| Authorization server | https://auth.qencode.com | https://auth-qa.qencode.com |
| Qencode API | https://api.qencode.com | https://api-qa.qencode.com |
The instructions below use the production endpoint. To test against QA, swap in the QA URL and sign in at the QA portal.
Connect a client
Endpoint: https://mcp.qencode.com/mcp — same for every client below. Sign in to your Qencode account when the browser opens and approve access.
QA (internal testing): use
https://mcp-qa.qencode.com/mcpand sign in at the QA portal instead.
| Client | Where to add it | MCP URL / config |
|---|---|---|
| Claude (chat) | Message box → + → Connectors → Add connector | https://mcp.qencode.com/mcp |
| Claude Code | Terminal | claude mcp add --transport http qencode https://mcp.qencode.com/mcp |
| ChatGPT | Apps → search Qencode → Connect; or Developer Mode → Build app | Connector URL: https://mcp.qencode.com/mcp |
| Gemini | ~/.gemini/settings.json → mcpServers | "httpUrl": "https://mcp.qencode.com/mcp" — then /mcp auth qencode in the CLI |
| Cursor | Settings → Tools & MCP → New MCP Server (or ~/.cursor/mcp.json) | "url": "https://mcp.qencode.com/mcp" — restart Cursor after saving |
Cursor (mcp.json):
{
"mcpServers": {
"qencode": { "url": "https://mcp.qencode.com/mcp" }
}
}
Gemini (settings.json):
{
"mcpServers": {
"qencode": {
"httpUrl": "https://mcp.qencode.com/mcp",
"timeout": 30000,
"trust": false
}
}
}
Tip: sign in to portal.qencode.com in your browser before connecting — OAuth goes smoother.
What the connector exposes
Tools
Transcoding & jobs
| Tool | Description |
|---|---|
transcode_video | Submit a job from a source URL to one or more outputs. Convenience wrapper — auto-injects encoder_version: 2 (or 1 for VMAF) when omitted. |
start_encode2_raw | Escape hatch — submit a job with the full query JSON exactly as the Qencode API expects. |
get_job_status | One-shot status snapshot by task_token. |
get_job_status_detailed | Full, authoritative job status, including per-rendition progress and output details. |
wait_for_job | Poll until terminal state, timeout, or internal poll cap. Do not call in parallel with other tools in the same client batch. |
search_qencode_docs | Search the built-in knowledge base of recipes and reference docs. |
fetch_qencode_doc | Fetch the full content of a knowledge-base resource by qencode:// URI (tool-based counterpart to resources/read). |
Media Storage
Bucket management and ingest for Qencode Media Storage. These ride the same OAuth grant as the transcoding tools — no extra scope and no re-consent.
| Tool | Description |
|---|---|
list_buckets | List the Media Storage buckets available to the account. |
create_bucket | Create a new bucket. Called only on an explicit request — not to satisfy a missing destination. |
list_objects | Browse the contents of a bucket. |
get_download_url | Return a time-limited download URL for an existing object. |
download_url_to_bucket | Server-side copy of a public URL into a bucket (ingest, no transcoding). |
Resources
The server ships a knowledge base of recipes and reference docs, exposed as MCP resources so the agent can fetch only what it needs. Notable URIs:
qencode://docs/best-practices— composition defaults the agent applies automaticallyqencode://docs/storage— destination compatibility matrix (Qencode S3, R2, AWS S3, Azure, B2, FTP/SFTP)qencode://docs/error-codes— error code → cause → fixqencode://docs/gotchas— non-obvious API quirksqencode://schema/digest— full attribute reference forstart_encode2qencode://recipe/<slug>— one per feature flow:hls_abr,mp4_ladder,audio_outputs,thumbnails,speech_to_text,subtitles,stitching,drm_widevine_ezdrm,drm_fairplay_ezdrm,drm_playready_ezdrm,drm_aes128,drm_buydrm,drm_expressplay,codec_av1,per_title_encoding,incremental_abr,refresh_abr_playlist,callbacks,reliability,video_metadata
Use search_qencode_docs to discover the right recipe URI for a goal.
Prompts (slash commands)
In clients that surface MCP prompts, 21 one-shot templates are available. Each tells the agent to read the matching qencode://recipe/... resource and submit via start_encode2_raw.
ABR / packaging: encode_hls_abr, encode_dash_abr, encode_mp4_ladder, encode_incremental_rung, encode_refreshing_playlist
Codecs / quality: encode_av1, tune_per_title
Audio / images / text: extract_audio, generate_thumbnails, transcribe, add_subtitles
Probe / stitch: get_video_metadata, stitch_videos
Production hooks: enable_callbacks, enable_reliability
DRM: encode_aes128_hls, encode_widevine_ezdrm, encode_playready_ezdrm, encode_fairplay_ezdrm, encode_drm_buydrm, encode_drm_expressplay
Source URL rules
transcode_video and start_encode2_raw accept source values with schemes https://, http://, s3://, or tus:. FTP/SFTP and private/metadata URLs are rejected at the tool boundary (SSRF defence). See docs/security/THREAT_MODEL.md for limitations.
Security
Authentication is OAuth 2.1 only — there is no static-API-key mode. Your Qencode API keys never leave the portal; the server derives a fresh, short-lived session token per request via an internal portal endpoint. Source URLs are validated at the tool boundary (SSRF defence — see Source URL rules).
Full threat model and adversarial test coverage: docs/security/THREAT_MODEL.md.
Development
uv venv && uv pip install -e ".[dev]"
NO_NETWORK=1 pytest -q # offline L1 + L2 + L5 (~540 tests)
pytest -m protocol # MCP wire conformance only
pytest -m unit # per-tool logic (FakeQencode)
pytest -m security # OWASP MCP Top 10 adversarial suite
Protocol tests run fully offline (mocked Authorization Server, portal, and Qencode API). CI is the Jenkins job mcp_automated_tests (Jenkinsfile.manual): manual checkboxes for any layer, nightly L3 cron, weekly L4 cron.
Supported MCP protocol versions
Clients negotiate a version at initialize. This server targets MCP 2025-11-25 as the primary version. CI also runs conformance tests against 2025-06-18 because JSON-RPC batching behavior differs between earlier revisions. We do not claim support for 2025-03-26 or older wire semantics beyond what the underlying SDK negotiates.
| Version | Support | Notes |
|---|---|---|
| 2025-11-25 | Primary | Streamable HTTP, resumable SSE where used |
| 2025-06-18 | CI matrix | Regression guard for mid-2025 clients |
| 2025-03-26 | Not targeted | Batching semantics differ from 2025-06-18 |
More docs
- Local server / env vars:
docs/local-development.md - Test layers (L1–L5):
docs/testing.mdandtests/README.md - L3 against live QA / PROD:
tests/integration/README.md - L4 agent evals:
evals/README.md - Pre-release gate:
docs/release-checklist.md
Versioning policy
The connector follows SemVer applied to the MCP surface — tools, prompts, resources, OAuth scopes, and supported protocol versions. Qencode HTTP API changes are out of scope (they are the API's own concern, not the connector's).
- MAJOR — a breaking surface change: a tool/prompt/resource is removed or renamed, a previously optional argument becomes required, an OAuth scope is added or tightened in a way that forces re-consent, or a supported MCP protocol version is dropped.
- MINOR — a backward-compatible addition: a new tool/prompt/resource, a new optional argument, or a newly supported protocol version.
- PATCH — no change to the surface shape: tool/prompt description rewordings, knowledge-base/doc updates, and bug fixes.
Surface changes are guarded by snapshot tests under tests/protocol/. When you change the surface, regenerate the snapshots (python scripts/regen_tools_snapshot.py) and bump the version in the same PR: pyproject.toml, src/qencode_mcp/__init__.py, server.json, and a new CHANGELOG.md entry must all agree.
Links
- Changelog:
CHANGELOG.md - OAuth 2.1 authorization-server spec:
docs/oauth-spec.md - Qencode portal: https://portal.qencode.com (production) · https://portal-qa.qencode.com (QA)
- Qencode API reference: https://docs.qencode.com/api-reference/transcoding