From f7e950694e00d28534bccbe03db12d7bf3d22b1a Mon Sep 17 00:00:00 2001 From: Jordan Diaz Date: Wed, 12 Aug 2026 11:32:17 +0000 Subject: [PATCH] feat: tools get_hook_entryparams / set_hook_entryparams Completan la feature del endpoint /api/creator/hook-entryparams, que ya estaba desplegado en el server (commit fe81765 del repo de Forge) pero sin tools que lo usaran desde el agente. Los entryParams son los parametros de entrada declarados de un hook global ({variable, value?, valueType?}), que se le pasan al invocarlo. --- mcp-server/tools/hooks/index.js | 120 +++++++++++++++++++++++++++++++- 1 file changed, 117 insertions(+), 3 deletions(-) diff --git a/mcp-server/tools/hooks/index.js b/mcp-server/tools/hooks/index.js index 25ceafd..cc36541 100644 --- a/mcp-server/tools/hooks/index.js +++ b/mcp-server/tools/hooks/index.js @@ -129,16 +129,130 @@ Examples: ); } +function registerGetHookEntryParamsTool(server) { + server.tool( + "get_hook_entryparams", + `Read the declared entry parameters (entryParams) of a global hook. entryParams are the input parameters a hook expects — each has a required 'variable' name plus optional 'value' and 'valueType'. They are passed to the hook when it is invoked. + +Use this when the user asks about a hook's inputs, or to inspect the current params before editing them. + +hookEndPoint format: starts and ends with '/', with '/' as separator. E.g. "/hooks/appListado/". + +Returns: +- entryParams: array of { variable, value?, valueType? }. + Example: [{ "variable": "action" }, { "variable": "data", "value": "", "valueType": "Integer" }].`, + withAuthParams({ + hookEndPoint: z.string().describe('Hook endpoint path, e.g. "/hooks/appListado/"'), + }), + { readOnlyHint: true, destructiveHint: false }, + withAuth(async ({ hookEndPoint }, extra) => { + try { + const { projectSlug } = getCurrentProjectInfo(); + const result = await pythonGet("/api/creator/hook-entryparams", { + project: projectSlug, + endPoint: hookEndPoint, + }); + if (!result?.success) { + return { + content: [{ + type: "text", + text: JSON.stringify({ + success: false, + error: result?.error || "No se pudieron leer los entryParams", + }), + }], + isError: true, + }; + } + return { + content: [{ + type: "text", + text: JSON.stringify({ + success: true, + exists: !!result.exists, + entryParams: result.entryParams || [], + hookEndPoint, + }, null, 2), + }], + }; + } catch (error) { + return handleToolError(error, "get_hook_entryparams", { hookEndPoint }); + } + }) + ); +} + +function registerSetHookEntryParamsTool(server) { + server.tool( + "set_hook_entryparams", + `Set the declared entry parameters (entryParams) of a global hook. entryParams describe the inputs a hook expects — each has a required 'variable' name plus optional 'value' and 'valueType'. + +IMPORTANT: this OVERWRITES the entire entryParams list of the hook (it does NOT merge). You must pass the COMPLETE set of params every time, because the whole array is replaced. + +Use this AFTER creating or editing the hook file (via acai-write) to declare which inputs it accepts. + +entryParams format: array of { variable, value?, valueType? }. +Example: [{ "variable": "action" }, { "variable": "data", "value": "", "valueType": "Integer" }].`, + withAuthParams({ + hookEndPoint: z.string().describe('Hook endpoint path, e.g. "/hooks/appListado/"'), + entryParams: z.array(z.object({ + variable: z.string(), + value: z.string().optional(), + valueType: z.string().optional(), + })).describe('Complete list of entry params. Each item: { variable (required), value? (string), valueType? (string) }. Replaces the whole array. E.g. [{"variable":"action"},{"variable":"data","value":"","valueType":"Integer"}]'), + }), + { readOnlyHint: false, destructiveHint: false }, + withAuth(async ({ hookEndPoint, entryParams }, extra) => { + try { + const { projectSlug } = getCurrentProjectInfo(); + const result = await pythonPost("/api/creator/hook-entryparams", { + project: projectSlug, + endPoint: hookEndPoint, + entryParams, + }); + if (!result?.success) { + return { + content: [{ + type: "text", + text: JSON.stringify({ + success: false, + error: result?.error || "No se pudo guardar", + }), + }], + isError: true, + }; + } + return { + content: [{ + type: "text", + text: JSON.stringify({ + success: true, + message: result.message || "entryParams actualizados", + entryParams: result.entryParams || [], + hookEndPoint, + }, null, 2), + }], + }; + } catch (error) { + return handleToolError(error, "set_hook_entryparams", { hookEndPoint, entryParams }); + } + }) + ); +} + /** * Registra las tools de configuracion de hooks globales. * - * `get_hook_middleware` es de solo lectura y se registra siempre. El set - * modifica el layout y solo se expone si el rol puede editar codigo — sigue - * el mismo criterio que otras tools de escritura (ver project/index.js). + * Las tools de solo lectura (`get_hook_middleware`, `get_hook_entryparams`) se + * registran siempre. Las de escritura modifican el layout y solo se exponen si + * el rol puede editar codigo — sigue el mismo criterio que otras tools de + * escritura (ver project/index.js). */ export function registerHookTools(server) { registerGetHookMiddlewareTool(server); + registerGetHookEntryParamsTool(server); if (canEditCode()) { registerSetHookMiddlewareTool(server); + registerSetHookEntryParamsTool(server); } }