Files
agenticSystem/mcp-server/tools/records/listPageModules.js
2026-04-01 23:16:45 +01:00

119 lines
4.6 KiB
JavaScript

import { z } from "zod";
import { withAuth, getSessionCredentials } from "../../auth/index.js";
import { handleToolError, validateRequired } from "../helpers/errorHandler.js";
import { AcaiHttpClient } from "../helpers/acaiHttpClient.js";
import { withAuthParams } from "../helpers/authSchema.js";
export function registerListPageModulesTool(server) {
server.tool(
"list_page_modules",
`List all builder modules placed on a page/record. Returns module IDs, section_ids, positions, visibility, and config-vars.
Use this to understand the current layout of a page before adding, removing, or reordering modules.
Table names WITHOUT 'cms_' prefix. The recordNum is the 'num' primary key.
Common table for pages: 'apartados'.`,
withAuthParams({
tableName: z.string().describe("Table name without cms_ prefix (e.g. 'apartados')"),
recordNum: z.union([z.string(), z.number()]).describe("Record num (primary key)"),
}),
{ readOnlyHint: true, destructiveHint: false },
withAuth(async ({ tableName, recordNum }, extra) => {
try {
const validationError = validateRequired(
{ tableName, recordNum },
['tableName', 'recordNum'],
'list_page_modules'
);
if (validationError) return validationError;
const credentials = await getSessionCredentials(extra.sessionId);
const response = await AcaiHttpClient.postCmsApi(
credentials,
"get",
{
tableName,
where: `num=${recordNum}`,
limit: 1,
options: { uploads: false, relations: false },
},
credentials.token,
credentials.tokenHash
);
const records = response.data?.data || [];
if (records.length === 0) {
return {
content: [{
type: "text",
text: JSON.stringify({
success: false,
error: `Record num=${recordNum} not found in table '${tableName}'`,
}, null, 2)
}],
};
}
const record = records[0];
const builderRaw = record.builder || "[]";
let builderData;
try {
builderData = JSON.parse(builderRaw);
} catch {
return {
content: [{
type: "text",
text: JSON.stringify({
success: false,
error: "Could not parse builder JSON",
raw: builderRaw.substring(0, 500),
}, null, 2)
}],
isError: true,
};
}
if (!Array.isArray(builderData)) {
return {
content: [{
type: "text",
text: JSON.stringify({
success: false,
error: "Builder field is not an array",
}, null, 2)
}],
isError: true,
};
}
const modules = builderData.map((mod, index) => ({
position: index,
moduleId: mod.modulo || null,
sectionId: mod.section_id || null,
hidden: !!mod.oculto,
configVars: mod["config-vars"] || {},
}));
return {
content: [{
type: "text",
text: JSON.stringify({
success: true,
tableName,
recordNum,
recordTitle: record.titulo || record.name || record.nombre || null,
recordEnlace: record.enlace || null,
modulesCount: modules.length,
modules,
}, null, 2)
}],
};
} catch (error) {
return handleToolError(error, 'list_page_modules', { tableName, recordNum });
}
})
);
}