feat(mcp-server): add 5 missing tools for existing backend routes

New tools backed by routes that existed but had no MCP surface:
- maintenance.getSchedule: GET /settings/maintenance/schedule (list upcoming windows)
- maintenance.deleteWindow: DELETE /settings/maintenance/schedule/:id (cancel window)
- lysnrai.apiTokens.revoke: DELETE /api-tokens/:id (revoke token by ID)

New client functions:
- maintenanceGetSchedule, maintenanceDeleteWindow (platform-client.ts)
- lysnraiApiTokenRevoke (lysnrai-client.ts)
This commit is contained in:
saravanakumardb1 2026-03-05 14:09:00 -08:00
parent 5a3987bd9f
commit 26a9868380
4 changed files with 70 additions and 2 deletions

View File

@ -176,3 +176,10 @@ export function lysnraiApiTokensList(
const q = qs.toString();
return lysnraiFetch(`/api-tokens${q ? `?${q}` : ''}`, { method: 'GET' }, opts);
}
export function lysnraiApiTokenRevoke(
tokenId: string,
opts: LysnraiClientOptions
): Promise<{ success: boolean }> {
return lysnraiFetch(`/api-tokens/${tokenId}`, { method: 'DELETE' }, opts);
}

View File

@ -679,7 +679,22 @@ export function maintenanceScheduleWindow(
);
}
// ── Settings ──────────────────────────────────────────────────────────────────
export function maintenanceGetSchedule(opts: PlatformClientOptions): Promise<unknown[]> {
return platformFetch<unknown[]>('/api/settings/maintenance/schedule', { method: 'GET' }, opts);
}
export function maintenanceDeleteWindow(
windowId: string,
opts: PlatformClientOptions
): Promise<{ success: boolean }> {
return platformFetch<{ success: boolean }>(
`/api/settings/maintenance/schedule/${encodeURIComponent(windowId)}`,
{ method: 'DELETE' },
opts
);
}
// ── Settings ──────────────────────────────────────────────────────────────────────────────────
export function settingsGet(opts: PlatformClientOptions): Promise<unknown> {
return platformFetch<unknown>('/api/settings', { method: 'GET' }, opts);

View File

@ -19,6 +19,7 @@ import {
lysnraiOrgsList,
lysnraiOrgGet,
lysnraiApiTokensList,
lysnraiApiTokenRevoke,
} from '../../lib/lysnrai-client.js';
import type { McpToolRequest } from '../tools/types.js';
@ -149,7 +150,22 @@ registerTool({
},
});
// ── lysnrai.apiTokens.list ────────────────────────────────────────────────
// ── lysnrai.apiTokens.revoke ───────────────────────────────────────────────
registerTool({
name: 'lysnrai.apiTokens.revoke',
description:
'Revoke (soft-delete) an API token by ID — sets status to "revoked" so it can no longer authenticate. Irreversible. Requires admin role.',
requiredRole: 'admin',
inputSchema: z.object({
tokenId: z.string().min(1).describe('API token ID (tok_… prefix)'),
}),
async execute(args, req) {
return lysnraiApiTokenRevoke(args.tokenId, { token: tokenOf(req), requestId: req.id });
},
});
// ── lysnrai.apiTokens.list ─────────────────────────────────────────────────
registerTool({
name: 'lysnrai.apiTokens.list',

View File

@ -20,6 +20,8 @@ import {
maintenanceGetCurrent,
maintenanceSet,
maintenanceScheduleWindow,
maintenanceGetSchedule,
maintenanceDeleteWindow,
settingsGet,
settingsUpdate,
settingsCheckKillSwitch,
@ -260,6 +262,34 @@ registerTool({
},
});
// ── maintenance.getSchedule ──────────────────────────────────────────────────
registerTool({
name: 'maintenance.getSchedule',
description:
'List all upcoming scheduled maintenance windows (title, message, start, end, affectedServices). Requires admin role.',
requiredRole: 'admin',
inputSchema: z.object({}),
async execute(_args, req) {
return maintenanceGetSchedule({ token: tokenOf(req), requestId: req.id });
},
});
// ── maintenance.deleteWindow ──────────────────────────────────────────────
registerTool({
name: 'maintenance.deleteWindow',
description:
'Cancel (delete) a scheduled maintenance window by its ID. Returns { success: true } on removal. Requires admin role.',
requiredRole: 'admin',
inputSchema: z.object({
windowId: z.string().min(1).describe('Maintenance window ID (mw_… prefix)'),
}),
async execute(args, req) {
return maintenanceDeleteWindow(args.windowId, { token: tokenOf(req), requestId: req.id });
},
});
// ── settings.get ──────────────────────────────────────────────────────────────
registerTool({