Configuración, tools y seguridad MCP
Configura stdio una vez, descubre capacidades, planifica gratis y confirma explícitamente la ejecución pagada.
La documentación pública se puede compartir, pero la disponibilidad de capacidades API y MCP la gobiernan el manifiesto vivo y el acceso de la cuenta. Foundation o experimental no implican estabilidad.
| Tool | Autoridad | Propósito | Reintento automático |
|---|---|---|---|
| myeq.capabilities.search | read | Descubrir capacidades de producción | 429 / 502 / 503 |
| myeq.production.plan | plan | Compilar un plan gratuito e inspeccionable | nunca |
| myeq.production.preflight | read | Validar preparación y coste estimado | 429 / 502 / 503 |
| myeq.storyboard.apply | mutate | Aplicar un Storyboard aprobado | nunca |
| myeq.production.execute_step | spend | Ejecutar un paso confirmado del plan | nunca |
| myeq.production.execute | spend | Iniciar producción durable confirmada | nunca |
| myeq.job.status | read | Consultar el progreso durable del job | 429 / 502 / 503 |
| myeq.production.ledger | read | Consultar el ledger de ejecución del propietario | 429 / 502 / 503 |
| myeq.production.verticals | read | Listar recetas de producción | 429 / 502 / 503 |
| myeq.v2v.edit | spend | Editar un vídeo fuente con los gates V2V del Studio | nunca |
| myeq.video.preflight_scene | read | Comprobar FPS y coste exactos de una escena sin gastar | 429 / 502 / 503 |
| myeq.video.generate_scene | spend | Generar una escena confirmada con sus FPS admitidos | nunca |
Configuración stdio genérica
Compila el paquete MCP, aporta MYEQ_API_KEY y MYEQ_BASE_URL y apunta el host al entrypoint estable. La interfaz de instalación cambia según cliente.
{
"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"
}
}
}
}Empieza por discovery y plan
Busca capacidades antes de asumir funciones. Crea un plan inspeccionable, haz preflight y ejecuta sólo cuando el usuario haya autorizado mutación o gasto.
{
"projectId": "project-123",
"instruction": "Create a 60-second vertical trailer",
"vertical": "ai_film",
"sourceLanguage": "en",
"responseLanguage": "es",
"dialogueLanguage": "es",
"visualPromptLanguage": "en"
}Nunca reintentes a ciegas una tool pagada
Las tools pagadas requieren confirm=true e idempotency key. Un job durable aceptado sigue siendo propiedad de MYEQ aunque se desconecte el cliente MCP.
Reanuda por identidad de job
La ejecución larga devuelve un jobId durable. Reconecta y consulta estado: no dependas de que sigan vivos chat, editor o terminal.
24, 30 y 60 FPS en Studio, API y MCP
Las tres interfaces usan la misma instantánea confirmada de la escena y la misma admisión. Se conservan los FPS solicitados; no hay cambio automático a 24. La disponibilidad depende del worker aprobado y de la escena exacta.
Lienzos START/END: 704×1280, 1280×704 o 960×960. I2V admite audio generado o sin audio; A2V exige audio de origen autorizado y conserva el desplazamiento seleccionado. Esta tabla no habilita FPS altos para ingredientes ni V2V. La semilla es un entero entre 0 y 2147483647. I2V y A2V admiten END sin START a 24, 30 y 60 FPS solo si el servicio desplegado lo autoriza expresamente. END guía el último fotograma; el inicio se genera desde el prompt. Deja start vacío y conserva la imagen en end. Esto no garantiza píxeles idénticos ni invierte el vídeo. A2V siempre necesita audio de origen autorizado y al menos una imagen START o END; el audio solo no está admitido.
| FPS | Clase admitida | Límites físicos |
|---|---|---|
| 24 | Por defecto; cada modalidad debe superar su admisión | Duración, audio y referencias dependen de la clase nativa elegida |
| 30 | Solo I2V / A2V aprobados | 720p · 2–10 segundos enteros · 9:16 / 16:9 / 1:1 · I2V/A2V: START y/o END; A2V también exige audio de origen |
| 60 | Solo I2V / A2V aprobados | 720p · 2–10 segundos enteros · 9:16 / 16:9 / 1:1 · I2V/A2V: START y/o END; A2V también exige audio de origen |
Guardar, revisar el precio y confirmar una escena
Crea o lee el proyecto autorizado y guarda la escena con PATCH expectedVersion. Envía la misma snapshot y targetSceneId a /api/v1/production/snapshots/preflight-scene. Revisa data.ready, issues y estimatedCredits; no crea trabajos ni reserva créditos. Genera mediante /api/v1/production/snapshots/generate-scene con confirm=true e Idempotency-Key estable. Consulta el jobId devuelto. MCP usa myeq.video.preflight_scene y myeq.video.generate_scene con la misma snapshot; el envío pagado no se reintenta automáticamente. Los ajustes de escena prevalecen sobre los globales; conserva los sceneContracts confirmados que correspondan.
Las rutas antiguas /video/start, /video/create, /video/create-job y /video/preflight están retiradas: por defecto/24 devuelve 410; 30/60 exige migrar a snapshot con 422. 25/48/50 no están admitidos. Un fallo de preflight no cambia los FPS ni cobra créditos. Una comprobación correcta no reserva disponibilidad ni saldo.
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' } }