fix(mcp-server): add /api prefix to all product backend clients (critical — all routes 404 without it)

This commit is contained in:
saravanakumardb1 2026-03-05 13:10:08 -08:00
parent 9bf8ebd1fe
commit c9022665d6
8 changed files with 10 additions and 33 deletions

View File

@ -21,7 +21,7 @@ async function chronomindFetch<T>(
...(opts.token ? { Authorization: `Bearer ${opts.token}` } : {}),
...(opts.requestId ? { 'x-request-id': opts.requestId } : {}),
};
const res = await fetch(`${config.CHRONOMIND_BACKEND_URL}${path}`, {
const res = await fetch(`${config.CHRONOMIND_BACKEND_URL}/api${path}`, {
...init,
headers: { ...((init.headers as Record<string, string>) ?? {}), ...headers },
signal: AbortSignal.timeout(15_000),

View File

@ -23,7 +23,7 @@ async function jarvisFetch<T>(
...(opts.token ? { Authorization: `Bearer ${opts.token}` } : {}),
...(opts.requestId ? { 'x-request-id': opts.requestId } : {}),
};
const res = await fetch(`${config.JARVISJR_BACKEND_URL}${path}`, {
const res = await fetch(`${config.JARVISJR_BACKEND_URL}/api${path}`, {
...init,
headers: { ...((init.headers as Record<string, string>) ?? {}), ...headers },
signal: AbortSignal.timeout(15_000),

View File

@ -23,7 +23,7 @@ async function lysnraiFetch<T>(
...(opts.token ? { Authorization: `Bearer ${opts.token}` } : {}),
...(opts.requestId ? { 'x-request-id': opts.requestId } : {}),
};
const res = await fetch(`${config.LYSNRAI_BACKEND_URL}${path}`, {
const res = await fetch(`${config.LYSNRAI_BACKEND_URL}/api${path}`, {
...init,
headers: { ...((init.headers as Record<string, string>) ?? {}), ...headers },
signal: AbortSignal.timeout(15_000),
@ -129,12 +129,12 @@ export interface OrgDoc {
export function lysnraiOrgsList(
params: { limit?: number; offset?: number },
opts: LysnraiClientOptions
): Promise<{ organizations: OrgDoc[]; total: number }> {
): Promise<{ organizations: OrgDoc[] }> {
const qs = new URLSearchParams();
if (params.limit !== undefined) qs.set('limit', String(params.limit));
if (params.offset !== undefined) qs.set('offset', String(params.offset));
const q = qs.toString();
return lysnraiFetch(`/organizations${q ? `?${q}` : ''}`, { method: 'GET' }, opts);
return lysnraiFetch(`/orgs${q ? `?${q}` : ''}`, { method: 'GET' }, opts);
}
// ── API tokens ─────────────────────────────────────────────────────────────
@ -151,17 +151,10 @@ export interface ApiTokenDoc {
export function lysnraiApiTokensList(
params: { limit?: number; offset?: number },
opts: LysnraiClientOptions
): Promise<{ tokens: ApiTokenDoc[]; total: number }> {
): Promise<{ tokens: ApiTokenDoc[] }> {
const qs = new URLSearchParams();
if (params.limit !== undefined) qs.set('limit', String(params.limit));
if (params.offset !== undefined) qs.set('offset', String(params.offset));
const q = qs.toString();
return lysnraiFetch(`/api-tokens${q ? `?${q}` : ''}`, { method: 'GET' }, opts);
}
export function lysnraiApiTokenRotate(
tokenId: string,
opts: LysnraiClientOptions
): Promise<{ token: string; id: string }> {
return lysnraiFetch(`/api-tokens/${tokenId}/rotate`, { method: 'POST' }, opts);
}

View File

@ -27,7 +27,7 @@ async function mindlystFetch<T>(
...(opts.requestId ? { 'x-request-id': opts.requestId } : {}),
...(opts.adminUserId ? { 'x-admin-user-id': opts.adminUserId } : {}),
};
const res = await fetch(`${config.MINDLYST_BACKEND_URL}${path}`, {
const res = await fetch(`${config.MINDLYST_BACKEND_URL}/api${path}`, {
...init,
headers: { ...((init.headers as Record<string, string>) ?? {}), ...headers },
signal: AbortSignal.timeout(15_000),

View File

@ -23,7 +23,7 @@ async function nomgapFetch<T>(
...(opts.requestId ? { 'x-request-id': opts.requestId } : {}),
...(opts.productId ? { 'x-product-id': opts.productId } : { 'x-product-id': 'nomgap' }),
};
const res = await fetch(`${config.NOMGAP_BACKEND_URL}${path}`, {
const res = await fetch(`${config.NOMGAP_BACKEND_URL}/api${path}`, {
...init,
headers: { ...((init.headers as Record<string, string>) ?? {}), ...headers },
signal: AbortSignal.timeout(15_000),

View File

@ -23,7 +23,7 @@ async function peakpulseFetch<T>(
...(opts.requestId ? { 'x-request-id': opts.requestId } : {}),
...(opts.productId ? { 'x-product-id': opts.productId } : { 'x-product-id': 'peakpulse' }),
};
const res = await fetch(`${config.PEAKPULSE_BACKEND_URL}${path}`, {
const res = await fetch(`${config.PEAKPULSE_BACKEND_URL}/api${path}`, {
...init,
headers: { ...((init.headers as Record<string, string>) ?? {}), ...headers },
signal: AbortSignal.timeout(15_000),

View File

@ -16,7 +16,6 @@ import {
lysnraiSessionsList,
lysnraiOrgsList,
lysnraiApiTokensList,
lysnraiApiTokenRotate,
} from '../../lib/lysnrai-client.js';
import type { McpToolRequest } from '../tools/types.js';
@ -116,18 +115,3 @@ registerTool({
return lysnraiApiTokensList(args, { token: tokenOf(req), requestId: req.id });
},
});
// ── lysnrai.apiTokens.rotate ──────────────────────────────────────────────
registerTool({
name: 'lysnrai.apiTokens.rotate',
description:
'Rotate an API token — invalidates the current secret and issues a new one. Returns the new plaintext token (only visible once). Requires admin role.',
requiredRole: 'admin',
inputSchema: z.object({
tokenId: z.string().min(1).describe('API token ID to rotate'),
}),
async execute(args, req) {
return lysnraiApiTokenRotate(args.tokenId, { token: tokenOf(req), requestId: req.id });
},
});

View File

@ -40,7 +40,7 @@ const app = await createServiceApp({
name: 'mcp-server',
version: '0.1.0',
description:
'ByteLyst MCP Server — platform.*, extraction.*, support.*, mindlyst.*, lysnrai.*, jarvis.*',
'ByteLyst MCP Server — platform.*, extraction.*, support.*, mindlyst.*, lysnrai.*, jarvis.*, chronomind.*, nomgap.*, peakpulse.*',
corsOrigin: config.CORS_ORIGIN,
logLevel: config.LOG_LEVEL,
});