MYEQ MCP overview
MCP exposes semantic production tools over the same MYEQ server authority used by Studio and the HTTP API.
The public documentation is shareable, but API and MCP capability availability is governed by the live product manifest and account access. Foundation or experimental operations are not stability promises.
MCP is a transport, not a second product
The MCP client never becomes the source of truth. MYEQ validates project access, plans, costs, confirmation, idempotency, execution and receipts on the server.
Host-independent by design
The stdio server can be used from Claude-family clients, OpenAI-compatible MCP hosts and custom enterprise clients. The host may reason differently; MYEQ production authority does not.
Eight user languages, English technical schema
Tool names, fields and schemas remain English for interoperability. sourceLanguage, responseLanguage, dialogueLanguage, subtitleLanguage and visualPromptLanguage are independent production choices.
Do not embed large media in MCP JSON
Upload or register authorized assets through MYEQ, then pass durable asset identifiers. This keeps messages bounded and preserves storage, ownership and provenance rules.
24, 30 and 60 FPS in Studio, API and MCP
Use the same committed scene snapshot and exact admission across all three interfaces. Requested FPS is preserved; there is no automatic fallback to 24 FPS. Availability depends on the approved worker and the exact scene.
START/END canvases: 704×1280, 1280×704 or 960×960. I2V accepts generated audio or no audio; A2V requires authorized source audio and preserves its selected offset. Ingredients and V2V do not gain high FPS support from this table. Seeds are integers from 0 to 2147483647. I2V and A2V support END without START at 24, 30 and 60 FPS only when the deployed service explicitly admits it. END guides the final frame; the beginning is generated from the prompt. Leave start empty and keep the image in end. This does not promise identical pixels or reverse the video. A2V always needs authorized source audio and at least one START or END image; audio alone is not admitted.
| FPS | Admitted class | Physical limits |
|---|---|---|
| 24 | Default; selected modality must pass its own admission | Duration, audio and references depend on the selected native class |
| 30 | Approved I2V / A2V only | 720p · 2–10 whole seconds · 9:16 / 16:9 / 1:1 · I2V/A2V: START and/or END; A2V also requires source audio |
| 60 | Approved I2V / A2V only | 720p · 2–10 whole seconds · 9:16 / 16:9 / 1:1 · I2V/A2V: START and/or END; A2V also requires source audio |
Save, preflight the quote, then confirm one scene
Create or read the authorized project, commit the scene with PATCH expectedVersion, then send the same snapshot and targetSceneId to /api/v1/production/snapshots/preflight-scene. Inspect data.ready, issues and estimatedCredits; this creates no job or credit reservation. Generate through /api/v1/production/snapshots/generate-scene with confirm=true and a stable Idempotency-Key. Poll the returned jobId. MCP uses myeq.video.preflight_scene and myeq.video.generate_scene with the same snapshot; paid submission never retries automatically. Scene settings override project defaults; preserve matching frozen sceneContracts.
Legacy /video/start, /video/create, /video/create-job and /video/preflight are retired: default/24 returns 410; 30/60 requires snapshot migration with 422. 25/48/50 are unsupported. Preflight failure never changes cadence or charges credits. A successful check does not reserve availability or wallet balance.
const base = process.env.MYEQ_BASE_URL || 'https://myeq.pro';
const headers = { Authorization: 'Bearer ' + process.env.MYEQ_API_KEY, 'Content-Type': 'application/json' };
async function api(path, method, body, extra = {}) {
const response = await fetch(base + path, { method, headers: { ...headers, ...extra },
...(body === undefined ? {} : { body: JSON.stringify(body) }) });
const value = await response.json();
if (!response.ok) throw new Error(JSON.stringify(value));
return value;
}
const project = await api('/api/v1/projects', 'POST', { title: '60 FPS', aspectRatio: '9:16', duration: 4 });
const sourceAudioUrl = process.env.SOURCE_AUDIO_URL;
const generationInputs = { videoProvider: 'myeq_v2', videoModelSelection: 'myeq_v2',
inputModality: sourceAudioUrl ? 'audio_to_video' : 'image_to_video', durationSeconds: 4,
fps: 60, outputResolution: '720p', includeAudio: Boolean(sourceAudioUrl), seed: 12345,
...(sourceAudioUrl ? { sourceAudioUrl, sourceAudioStartTime: 0 } : {}) };
const scene = { id: 'scene-1', prompt: 'A slow camera move. Preserve the subject.',
settings: { fps: 60, durationSeconds: 4 },
start: process.env.START_URL ? [{ name: 'START', url: process.env.START_URL }] : [],
end: process.env.END_URL ? [{ name: 'END', url: process.env.END_URL }] : [], context: [], avatar: [] };
const snapshot = { id: crypto.randomUUID(), version: 1, projectId: project.id,
ownerId: project.ownerUserId, sourceEditorStateVersion: project.version + 1,
createdAt: new Date().toISOString(), projectTitle: project.title,
aspectRatio: '9:16', resolution: '720p', durationSeconds: 4, fps: 60,
generationInputs, scenes: [scene], avatars: [], assetsSummary: [],
sourceAudio: sourceAudioUrl ? { url: sourceAudioUrl, durationSeconds: null } : null, provenance: { source: 'ui' } };
await api('/api/v1/projects/' + project.id, 'PATCH', { expectedVersion: project.version,
editorState: { ...project.editorState, generationInputs,
sceneStoryboard: { scenes: [scene] }, productionSnapshot: snapshot } });
const input = { snapshot, targetSceneId: scene.id };
const quote = await api('/api/v1/production/snapshots/preflight-scene', 'POST', input);
console.log(quote);
if (quote.data?.ready && process.env.CONFIRM_PAID === 'true') {
const idempotencyKey = process.env.SAVED_IDEMPOTENCY_KEY;
if (!idempotencyKey) throw new Error('Persist one stable key before submitting');
const result = await api('/api/v1/production/snapshots/generate-scene', 'POST',
{ ...input, confirm: true }, { 'Idempotency-Key': idempotencyKey });
console.log(result);
const jobId = result.data?.pendingTake?.orchestrationJobId || result.data?.asset?.metadata?.jobId;
if (jobId) console.log(await api('/api/v1/production/jobs/' + encodeURIComponent(jobId), 'GET'));
}MCP · 24 / 30 / 60 FPS
// Reuse the full saved snapshot from the API example.
{ name: 'myeq.video.preflight_scene', arguments: { snapshot, targetSceneId: 'scene-1' } }
// Review data.ready, issues and estimatedCredits before confirming.
{ name: 'myeq.video.generate_scene', arguments: {
snapshot, targetSceneId: 'scene-1', confirm: true,
idempotencyKey: 'persisted-scene-request-0001'
} }
{ name: 'myeq.job.status', arguments: { jobId: 'returned-orchestration-job-id' } }