Meicut Developer Documentation
Integrate Meicut video processing into your app via REST API or the MCP protocol — video editing, format conversion, compression, and more.
REST API
Standard HTTP endpoints accessible from any programming language
MCP Protocol
Model Context Protocol — the AI-native way to integrate
20+ Tools
Video editing, merging, compression, format conversion, audio processing, and more
How It Works
Create an App
Log in to the console and create an app under "Developer Center" to get an API Key — required for every call; REST and MCP share the same key.
Upload a File
Upload a video, audio, or image file to get a stored_name — REST calls POST /api/v1/upload, MCP calls the upload_file tool.
Call a Tool
Call the processing tool you need with the stored_name to get a job_id — REST posts to the corresponding endpoint, MCP calls the same-named tool (snake_case).
Get the Result
Jobs run asynchronously. Poll the status with the job_id — REST calls GET /api/v1/job//status, MCP calls get_job_status; once finished you get a download_url.
Authentication
REST requests carry the API Key in a request header. Create an app under "Developer Center" in the console to get one; each key is bound to a user account and all charges are deducted from that account's balance.
X-API-Key: mv_your_api_key_hereHow It Works
The base URL for all REST endpoints is https://meicut.com
All processing endpoints follow the same asynchronous job flow:
- Submit a job (upload a file, then call a tool endpoint) and get a
job_id - Poll
GET /api/v1/job/{job_id}/statusuntil it becomes completed or failed - Download the result from the returned
download_url(presigned, no auth needed)
Video, audio and conversion tools each share a single endpoint: pick the function via the tool field in the request body, and pass its arguments in params.
{
"stored_name": "a1b2c3....mp4", // file id from the upload endpoint
"tool": "cut-video", // tool name — see each tool section
"params": { ... } // arguments for that tool — see its section
}File Upload
/api/v1/uploadUpload media files (video/audio/image) and receive a stored_name for use in later tool calls.
Request
curl -X POST https://meicut.com/api/v1/upload \
-H "X-API-Key: mv_your_api_key" \
-F "file=@/path/to/video.mp4"Response
{
"file_id": "uuid",
"filename": "video.mp4",
"stored_name": "uuid.mp4",
"size": 10485760,
"media_info": { "duration": 30.5, "width": 1920, "height": 1080 }
}Job Status Query
/api/v1/job/{job_id}/status# Poll every 3s until "status" becomes "completed" or "failed"
curl https://meicut.com/api/v1/job/<job_id>/status \
-H "X-API-Key: mv_your_api_key"{
"job_id": "uuid",
"status": "completed",
"progress": 100,
"output_file": "exports/uuid.mp4",
"download_url": "https://meicut.com/minio-upload/meicut-files/exports/uuid.mp4?X-Amz-..."
}completed
Video Tools
Video processing exposes 2 endpoints: single-file operations go through the general endpoint, multi-video merging uses a dedicated one.
Endpoint 1: General Processing (13 tools)
/api/v1/video-toolGeneral-purpose endpoint. Set the tool field in the request body to one of the values below and pass arguments via params. Supports 13 tools (all except merge):
Example — Cut Video
curl -X POST https://meicut.com/api/v1/video-tool \
-H "X-API-Key: mv_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"stored_name": "a1b2c3....mp4",
"tool": "cut-video",
"params": { "start_time": 5, "duration": 10 }
}'Endpoint 2: Merge Videos (dedicated)
/api/v1/video-tool/mergeDedicated multi-video merge endpoint (no tool field in the body): pass at least 2 files in stored_names; optional params support resolution_mode / target_width / target_height — see the Merge Video section below.
{
"stored_names": ["uuid1.mp4", "uuid2.mp4"],
"params": { "resolution_mode": "auto" }
}Trim Video cut-video
/api/v1/video-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
start_time | number | No | 0 | ≥ 0 5 | Start time in seconds |
duration | number | No | — | > 0 10 | Duration in seconds |
segments | array | No | — | [{"start": 0, "end": 5}] | Multi-segment cut: [{start, end}, ...] (seconds). Overrides start_time/duration |
fade_in | boolean | No | false | true / false true | Apply fade-in effect |
fade_out | boolean | No | false | true / false true | Apply fade-out effect |
Merge Video merge-video
/api/v1/video-tool/merge| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_names | array | Yes | — | at least 2 items ["uuid1.mp4", "uuid2.mp4"] | stored_name list of videos to merge |
resolution_mode | string | No | auto | fit / crop / stretch / auto fit | How to unify different resolutions |
target_width | integer | No | — | positive integer 1920 | Target width for all segments (auto-detected if omitted) |
target_height | integer | No | — | positive integer 1080 | Target height for all segments (auto-detected if omitted) |
REST uses the dedicated endpoint POST /api/v1/video-tool/merge (no tool field needed).
Resize Video resize-video
/api/v1/video-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
width | integer | Yes | — | positive integer 1280 | Target width in pixels |
height | integer | Yes | — | positive integer 720 | Target height in pixels |
fit_mode | string | No | fit | fit / fill / stretch fill | fit = pad, fill = crop, stretch = stretch |
bg_color | string | No | #000000 | #RRGGBB #FFFFFF | Padding background color (fit mode) |
pan_x | number | No | 0 | 0 | Horizontal crop offset |
pan_y | number | No | 0 | 0 | Vertical crop offset |
Crop Video crop-video
/api/v1/video-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
crop_w | integer | Yes | — | positive integer 640 | Crop width in pixels |
crop_h | integer | Yes | — | positive integer 360 | Crop height in pixels |
crop_x | integer | No | 0 | ≥ 0 100 | Crop X offset |
crop_y | integer | No | 0 | ≥ 0 50 | Crop Y offset |
Rotate Video rotate-video
/api/v1/video-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
angle | integer | No | — | 90 / 180 / 270 180 | Rotation angle |
Flip Video flip-video
/api/v1/video-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
flip_h | boolean | No | — | true / false true | Flip horizontally |
flip_v | boolean | No | — | true / false false | Flip vertically |
Change Speed speed-video
/api/v1/video-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
speed | number | Yes | — | > 0 1.5 | Speed multiplier, e.g. 0.5 = half, 2.0 = double |
Reverse Video reverse-video
/api/v1/video-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
Loop Video loop-video
/api/v1/video-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
loops | integer | No | 2 | ≥ 1 3 | Number of loops |
Mute Video mute-video
/api/v1/video-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
Add Audio add-audio
/api/v1/video-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
audio_stored_name | string | No | — | b2c3d4....mp3 | stored_name of a single audio file (use this OR audios[]) |
audios | array | No | — | [{"audio_stored_name": "b2....mp3", "volume": 0.8}] | Multiple tracks: [{audio_stored_name, trim_start, trim_end, start_time, volume}] — trim in seconds, start_time = delay before the track plays, volume default 1.0 |
mix | boolean | No | false | true / false true | Mix with the original video audio (default: only added tracks) |
Add Subtitles add-subtitles
/api/v1/video-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
subtitle_stored_name | string | Yes | — | c3d4e5....srt | stored_name of the subtitle file (SRT / ASS) |
Add Text add-text
/api/v1/video-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
text | string | No | — | Hello | Text content for a single overlay (use this OR texts[]) |
texts | array | No | — | [{"text": "Hello", "x": 50, "y": 50}] | Multiple overlays: [{text, x, y, font_size, font_color, opacity, stroke_width, stroke_color, shadow_color, shadow_x, shadow_y, start_time, end_time}] |
x | integer | No | 50 | 100 | X position |
y | integer | No | 50 | 80 | Y position |
font_size | integer | No | 48 | positive integer 36 | Font size |
font_color | string | No | white | #FFDD00 | Font color |
font_file | string | No | — | fonts/NotoSansSC.ttf | Path to a TTF/OTF font file (default font if omitted) |
opacity | number | No | 1.0 | 0.0 – 1.0 0.8 | Text opacity |
stroke_width | integer | No | 0 | ≥ 0 2 | Text stroke width |
stroke_color | string | No | black | #000000 | Text stroke color |
start_time | number | No | — | ≥ 0 2 | Overlay start time in seconds (default: entire video) |
end_time | number | No | — | > start_time 8 | Overlay end time in seconds (default: entire video) |
Filter Video filter-video
/api/v1/video-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
filter | string | No | — | one of 12 presets (see description) sepia | Preset: grayscale / sepia / blur / sharpen / brightness_up / brightness_down / contrast_up / saturation_up / vintage / invert / warm / cool |
custom_vf | string | No | — | eq=brightness=0.2 | Custom FFmpeg video filter expression (overrides preset) |
Pixelate Video mosaic-video
/api/v1/video-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
mode | string | No | — | full / region region | full = whole frame pixelated, region = selected area (default full) |
shape | string | No | — | rect / ellipse ellipse | region mode only: area shape (default rect; ellipse with equal width/height = circle) |
intensity | integer | No | — | 1-10 5 | Block size (default 5, ~17px blocks) |
x / y / width / height | number | No | — | 0-100 (percent of frame) 25, 25, 50, 50 | region mode only: mosaic area as percent of frame (defaults 25/25/50/50) |
frequency | number | No | — | 0-3600 seconds 10 | Seconds between mosaic appearances; 0 = continuous (default 0) |
effect_duration | number | No | — | 2 | Seconds each appearance lasts (default 1, only when frequency > 0) |
Audio Tools
Audio processing exposes 2 endpoints: single-file operations go through the general endpoint, multi-audio merging uses a dedicated one.
Endpoint 1: General Processing (4 tools)
/api/v1/audio-toolGeneral-purpose endpoint. Set the tool field to cut-audio / speed-audio / volume-audio / audio-converter and pass arguments via params; per-tool parameters are documented in the sections below.
Endpoint 2: Merge Audio (dedicated)
/api/v1/audio-tool/mergeDedicated multi-audio merge endpoint (no tool field in the body): pass at least 2 files in stored_names — see the Merge Audio section below.
Cut Audio cut-audio
/api/v1/audio-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
start_time | number | No | 0 | ≥ 0 5 | Start time in seconds |
duration | number | No | — | > 0 10 | Duration in seconds |
segments | array | No | — | [{"start": 0, "end": 5}] | Multi-segment cut: [{start, end}, ...] (seconds). Overrides start_time/duration |
fade_in | boolean | No | false | true / false true | Apply fade-in effect |
fade_out | boolean | No | false | true / false true | Apply fade-out effect |
bitrate | string | No | 192k | 128k | Audio bitrate |
Merge Audio merge-audio
/api/v1/audio-tool/merge| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_names | array | Yes | — | at least 2 items ["a1....mp3", "b2....mp3"] | stored_name list of audio files to merge |
REST uses the dedicated endpoint POST /api/v1/audio-tool/merge (no tool field needed).
Audio Converter audio-converter
/api/v1/audio-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
format | string | No | mp3 | mp3 / wav / ogg / m4a / aac / flac wav | Target format (MCP name: output_format) |
Change Audio Speed speed-audio
/api/v1/audio-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
speed | number | Yes | — | > 0 1.5 | Speed multiplier, e.g. 0.5 = half, 2.0 = double |
bitrate | string | No | 192k | 128k | Audio bitrate |
Audio Volume volume-audio
/api/v1/audio-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
volume_db | number | No | — | -6 | Volume adjustment in dB (negative = quieter, positive = louder). Ignored when mute=true |
mute | boolean | No | false | true / false true | Mute completely |
bitrate | string | No | 192k | 128k | Audio bitrate |
Format Conversion
/api/v1/convert-toolConversion endpoint. Set the tool field to video-converter or image-converter and pass arguments via params; per-tool parameters are documented in the sections below.
Video Converter video-converter
/api/v1/convert-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
format | string | No | mp4 | mp4 / avi / mov / mkv / webm / gif webm | Target format (MCP name: output_format) |
Image Converter image-converter
/api/v1/convert-tool| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
format | string | No | png | jpg / png / webp / gif / bmp / svg webp | Target format (MCP name: output_format) |
svg_mode | string | No | — | truecolor / detailed / posterized1-3 / curvy / sharp / smoothed / grayscale detailed | SVG vectorization mode (svg output only) |
numberofcolors | integer | No | 64 | 2 – 256 128 | Number of colors for SVG output |
pathomit | integer | No | 0 | 0 – 20 8 | SVG path simplification (lower = more detail) |
ltres | number | No | 1.0 | 1.0 | SVG linear threshold |
qtres | number | No | 1.0 | 1.0 | SVG quad threshold |
Image Watermark image-watermark
/v1/image-watermark| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
content | string | Yes | — | © Meicut | Watermark text, multi-line supported via \n |
layout | string | No | single | single / tile tile | single = one watermark at position; tile = repeat across the whole image |
pos_x | number | No | bottom-right | 0 – 100 50 | Watermark block center X as percent of image width (single layout; default: bottom-right with 3% margin) |
font_family | string | No | Arial | Noto Sans SC | Font family (bundled OFL fonts + system fonts) |
font_size_pct | number | No | 5 | 1 – 50 8 | Font size as percent of image height (scales with each image in batch) |
font_color | string | No | #ffffff | #ffcc00 | Text color (hex) |
opacity | number | No | 0.6 | 0 – 1 0.4 | Watermark opacity |
rotation | number | No | 0 | -180 – 180 -30 | Rotation angle in degrees, clockwise positive |
font_weight | integer | No | 400 | 300 – 900 700 | Font weight |
pos_y | number | No | bottom-right | 0 – 100 50 | Watermark block center Y as percent of image height (single layout; default: bottom-right with 3% margin) |
tile_gap | number | No | 50 | 10 – 300 80 | Gap between tiles as percent of the text block size (tile layout) |
stroke_color | string | No | — | #000000 | Text outline color (hex) |
stroke_width | integer | No | 0 | 0 – 20 2 | Text outline width in px |
shadow | boolean | No | false | true / false true | Add a drop shadow behind the text |
output_format | string | No | original | original / png / jpg / webp webp | Output format; original keeps the input format |
Video Compression
/api/v1/compressParameters for this endpoint live at the top level of the request body (not nested in params):
| Parameter | Type | Required | Default | Range / Example | Description |
|---|---|---|---|---|---|
stored_name | string | Yes | — | a1b2c3....mp4 | File identifier returned by the upload endpoint |
quality | string | No | medium | low / medium / high high | Compression quality |
resolution | string | No | original | original / 1080p / 720p / 480p 720p | Target resolution |
remove_audio | boolean | No | false | true / false true | Remove the audio track |
{
"stored_name": "a1b2c3....mp4",
"quality": "medium",
"resolution": "720p",
"remove_audio": false
}Integration Example (REST)
A complete runnable REST script (upload → call → poll → download) — replace the API Key with yours and run:
# Meicut quickstart — Python 3.8+, standard library only.
# Set your key first: export MEICUT_API_KEY=mv_your_api_key
import json
import os
import time
import urllib.request
API_KEY = os.environ["MEICUT_API_KEY"]
API = "https://meicut.com/api"
def call(method, path, payload=None, raw=None, content_type="application/json"):
if raw is not None:
data = raw
elif payload is not None:
data = json.dumps(payload).encode()
else:
data = None
req = urllib.request.Request(API + path, data=data, method=method, headers={
"X-API-Key": API_KEY,
"Content-Type": content_type,
})
with urllib.request.urlopen(req, timeout=120) as r:
return json.loads(r.read())
# 1. Upload a file (multipart/form-data) -> stored_name
boundary = "----meicut"
content = open("video.mp4", "rb").read()
body = (
("--" + boundary + "\r\n"
'Content-Disposition: form-data; name="file"; filename="video.mp4"' + "\r\n"
"Content-Type: application/octet-stream\r\n\r\n").encode()
+ content
+ ("\r\n--" + boundary + "--\r\n").encode()
)
up = call("POST", "/v1/upload", raw=body,
content_type="multipart/form-data; boundary=" + boundary)
stored_name = up["stored_name"]
# 2. Submit a cut job -> job_id (all video/audio tools use this same pattern)
job = call("POST", "/v1/video-tool", {
"stored_name": stored_name,
"tool": "cut-video",
"params": {"start_time": 0, "duration": 10},
})
job_id = job["job_id"]
# 3. Poll every 3s until the job finishes
while True:
st = call("GET", "/v1/job/" + job_id + "/status")
if st["status"] in ("completed", "failed"):
break
time.sleep(3)
if st["status"] == "failed":
raise SystemExit("Job failed: " + str(st.get("error")))
# 4. Download — download_url is presigned, no auth header needed
urllib.request.urlretrieve(st["download_url"], "result.mp4")
print("Done -> result.mp4")Prefer runnable code? Tested Python/Node.js/MCP demos and the full open-source validation suite are on the API Examples page
Authentication
MCP uses the same API Key as REST (create an app under "Developer Center" in the console); send it according to the transport:
Streamable HTTP Endpoint (recommended)
POST https://meicut.com/mcp
Authorization: Bearer mv_your_api_keyModern single-endpoint transport: POST JSON-RPC messages and get JSON responses directly. Authenticate with the Authorization header (or the api_key query parameter). After initialize, the server returns a Mcp-Session-Id header — send it back on subsequent requests.
SSE Endpoint (legacy)
https://meicut.com/mcp/sse?api_key=mv_your_api_keyAbout the MCP Protocol
Meicut supports the Model Context Protocol (MCP), allowing AI assistants (such as Claude and Cursor) to call video processing capabilities directly.
MCP is a standardized protocol that lets AI models discover and invoke external tools. The Meicut MCP Server exposes 25 tools covering all video and audio processing features.
How Parameters Are Passed
Parameter names and value ranges are identical to REST (see the tool sections above) — only the envelope differs: REST nests arguments in a params object with the tool name in the tool field; MCP has no wrapper, every argument is passed flat as the tool call arguments and the tool name is the method name (name). Merge tools are dedicated endpoints in REST (e.g. /video-tool/merge) but plain tools in MCP (merge_video). The same cut operation in both styles:
POST /api/v1/video-tool
{
"stored_name": "a1b2c3....mp4",
"tool": "cut-video",
"params": { "start_time": 5, "duration": 10 }
}{
"method": "tools/call",
"params": {
"name": "cut_video",
"arguments": {
"stored_name": "a1b2c3....mp4",
"start_time": 5,
"duration": 10
}
}
}MCP Tool List
MCP tools map one-to-one to the REST endpoints: names use snake_case (e.g. cut_video = cut-video) and take the same parameters documented in the REST sections above (only the conversion tools name the target format output_format instead of format). upload_file / upload_from_url correspond to file upload, get_job_status to job status polling.
MCP Integration Example
Add the following to your MCP config file:
{
"mcpServers": {
"meicut": {
"url": "https://meicut.com/mcp",
"headers": {
"Authorization": "Bearer mv_your_api_key"
}
}
}
}Usage Flow
- The AI assistant automatically discovers the list of available tools
- Call
upload_fileto upload a file and get astored_name - Call a specific tool (e.g.,
cut_videoorcompress_video) to get ajob_id - Call
get_job_statusto check processing progress and results
Billing
API calls are deducted from the quota of the user account that owns the app. Each tool call consumes 1 quota. Quota amounts and billing rules depend on the developer plan the user subscribes to; query the current plan and remaining quota via GET /api/pricing/plans.
File uploads do not consume quota. Calls return a 402 error when quota is insufficient.