import { SDK } from '@meetkai/mka1';
import type * as components from '@meetkai/mka1/models/components';
const mka1 = new SDK({
bearerAuth: `Bearer ${YOUR_API_KEY}`,
});
// Paso 1: Crea una respuesta en background con aprobación requerida
let pendingResponse = await mka1.llm.responses.create(
{
model: 'gpt-5',
instructions:
'Eres un asistente de gestión de proyectos con acceso a Linear vía MCP. Usa las herramientas de Linear cuando el usuario pregunte sobre tareas, bugs o proyectos. Mantén la respuesta final concisa.',
input: 'Lista mi incidencia de Linear más reciente asignada a mí.',
background: true,
store: true,
stream: false,
tools: [
{
type: 'mcp',
serverLabel: 'Linear MCP',
serverDescription: 'Accede a incidencias de Linear a través de MCP.',
serverUrl: 'https://mcp.linear.app/mcp',
allowedTools: ['issues.list'],
headers: {
Authorization: `Bearer ${process.env.LINEAR_API_KEY}`,
},
requireApproval: 'always',
},
],
},
{ headers: { 'X-On-Behalf-Of': '<end-user-id>' } },
);
// Paso 2: Haz polling hasta que aparezca una solicitud de aprobación
let approvalRequest: components.MCPApprovalRequest | undefined;
while (
pendingResponse.status === 'queued' ||
pendingResponse.status === 'in_progress'
) {
approvalRequest = pendingResponse.output.find(
(item): item is components.MCPApprovalRequest =>
item.type === 'mcp_approval_request',
);
if (approvalRequest) break;
await new Promise(resolve => setTimeout(resolve, 1000));
pendingResponse = await mka1.llm.responses.get(
{ responseId: pendingResponse.id },
{ headers: { 'X-On-Behalf-Of': '<end-user-id>' } },
);
}
if (!approvalRequest) {
throw new Error(`No se encontró ninguna solicitud de aprobación. La respuesta terminó con ${pendingResponse.status}.`);
}
// Paso 3: Muestra al usuario lo que el modelo quiere hacer
console.log('Servidor:', approvalRequest.serverLabel);
console.log('Herramienta:', approvalRequest.name);
console.log('Argumentos:', approvalRequest.arguments);
// Paso 4: Envía la aprobación (o rechazo) para continuar
const approve = true; // Reemplaza con la decisión de tu UI
const continuedResponse = await mka1.llm.responses.create(
{
model: 'gpt-5',
previousResponseId: pendingResponse.id,
input: [
{
type: 'mcp_approval_response',
approvalRequestId: approvalRequest.id,
approve,
},
],
store: true,
stream: false,
},
{ headers: { 'X-On-Behalf-Of': '<end-user-id>' } },
);
const assistantText = continuedResponse.output
.filter(
(item): item is components.OutputMessage =>
item.type === 'message' && item.role === 'assistant',
)
.flatMap(item =>
item.content.flatMap(content =>
content.type === 'output_text' ? [content.text] : [],
),
)
.join('\n\n')
.trim();
console.log(assistantText);