MCP setup, tools and safety
Configure the stdio server once, discover capabilities, plan for free and confirm paid execution explicitly.
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.
| Tool | Authority | Purpose | Automatic retry |
|---|---|---|---|
| myeq.capabilities.search | read | Discover production capabilities | 429 / 502 / 503 |
| myeq.production.plan | plan | Compile a free, inspectable plan | never |
| myeq.production.preflight | read | Validate readiness and estimated cost | 429 / 502 / 503 |
| myeq.storyboard.apply | mutate | Apply an approved Storyboard | never |
| myeq.production.execute_step | spend | Execute one confirmed plan step | never |
| myeq.production.execute | spend | Start confirmed durable production | never |
| myeq.job.status | read | Read durable job progress | 429 / 502 / 503 |
| myeq.production.ledger | read | Read the owner-scoped execution ledger | 429 / 502 / 503 |
| myeq.production.verticals | read | List production recipes | 429 / 502 / 503 |
| myeq.v2v.edit | spend | Edit a source video with the Studio V2V gates | never |
| myeq.video.preflight_scene | read | Check exact scene FPS and cost without spending | 429 / 502 / 503 |
| myeq.video.generate_scene | spend | Generate one confirmed scene at its admitted FPS | never |
Generic stdio configuration
Build the MCP package, provide MYEQ_API_KEY and MYEQ_BASE_URL, then point your MCP host at the stable server entrypoint. Client-specific screens may differ.
{
"mcpServers": {
"myeq": {
"command": "node",
"args": ["/absolute/path/to/myeq-full/mcp/dist/server.js"],
"env": {
"MYEQ_API_KEY": "your-key",
"MYEQ_BASE_URL": "https://myeq.pro"
}
}
}
}Start with discovery and planning
Search capabilities before assuming a feature. Create an inspectable plan, preflight it, then apply Storyboard or execute only after the user has authorized the mutation or spend.
{
"projectId": "project-123",
"instruction": "Create a 60-second vertical trailer",
"vertical": "ai_film",
"sourceLanguage": "en",
"responseLanguage": "es",
"dialogueLanguage": "es",
"visualPromptLanguage": "en"
}Never blind-retry paid tools
Paid tools require confirm=true and an idempotency key. A successfully accepted durable job remains owned by MYEQ even if the MCP client disconnects.
Resume by job identity
Long-running execution returns a durable job identifier. Reconnect later and read job status; do not depend on the chat, editor or terminal process remaining alive.
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' } }