From 9809e85e422f6251bf6c5b315322ab131858136a Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Fri, 22 May 2026 06:15:12 -0500 Subject: [PATCH] feat: add health_check, heartbeat_status, extensions_list, system_info (#9, #10, #12, #13) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New tools: - joomla_health_check — call /?mokowaas=health on any site - joomla_heartbeat_status — check Grafana registration - joomla_extensions_list — list installed extensions - joomla_system_info — get Joomla config Co-Authored-By: Claude Opus 4.6 (1M context) --- src/index.ts | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/src/index.ts b/src/index.ts index 0f274cb..19ff5be 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1201,6 +1201,88 @@ server.tool( }, ); +// ── Health & Monitoring ───────────────────────────────────────────────── + +server.tool( + 'joomla_health_check', + 'Call the MokoWaaS health endpoint (/?mokowaas=health) on a connected site', + { + token: z.string().describe('Health API bearer token'), + ...ConnectionParam, + }, + async ({ token, connection }) => { + const conn = getConnection(config, connection); + const url = conn.baseUrl.replace(/\/+$/, '') + '/?mokowaas=health'; + try { + const res = await fetch(url, { + headers: { 'Authorization': `Bearer ${token}` }, + signal: AbortSignal.timeout(15000), + }); + const data = await res.json(); + return { + content: [{ type: 'text' as const, text: JSON.stringify(data, null, 2) }], + }; + } catch (e) { + return { + content: [{ type: 'text' as const, text: `Health check failed: ${e}` }], + }; + } + }, +); + +server.tool( + 'joomla_heartbeat_status', + 'Check if a site is registered with the MokoWaaS heartbeat receiver', + { + site_url: z.string().describe('Site URL to check'), + ...ConnectionParam, + }, + async ({ site_url }) => { + const receiverUrl = 'https://bench.mokoconsulting.tech/api/waas-heartbeat/heartbeat'; + try { + const res = await fetch(receiverUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-MokoWaaS-Key': 'moko-waas-hb-2026-x9k4m', + }, + body: JSON.stringify({ site_url }), + signal: AbortSignal.timeout(10000), + }); + const data = await res.json(); + return { + content: [{ type: 'text' as const, text: JSON.stringify(data, null, 2) }], + }; + } catch (e) { + return { + content: [{ type: 'text' as const, text: `Heartbeat check failed: ${e}` }], + }; + } + }, +); + +server.tool( + 'joomla_extensions_list', + 'List installed extensions with version and status', + { + search: z.string().optional().describe('Filter by name'), + ...ConnectionParam, + }, + async ({ search, connection }) => { + const params: Record = {}; + if (search) params['filter[search]'] = search; + return formatResponse(await clientFor(connection).get('/extensions', params)); + }, +); + +server.tool( + 'joomla_system_info', + 'Get Joomla system configuration (application config)', + { ...ConnectionParam }, + async ({ connection }) => + formatResponse(await clientFor(connection).get('/config/application')), +); + // ── Connections Management ────────────────────────────────────────────── server.tool( -- 2.52.0