boscli_health_check
Run a comprehensive health check on your BOS ERP system, verifying modules, database, cache, and routes to ensure all components are operational.
Instructions
Full BOS system health check - modules, database, cache, routes
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/tools/health.ts:9-9 (handler)The handler for boscli_health_check - makes a GET request to '/boscli/health' using the BosApiClient.
handler: async (_, client) => client.get('/boscli/health'), - src/tools/health.ts:8-8 (schema)Empty schema for boscli_health_check - no input parameters required.
schema: {}, - src/tools/health.ts:4-35 (registration)Tool definition as part of the healthTools array. Exported and spread into allTools in src/index.ts, src/stdio.ts, and src/http.ts.
export const healthTools: McpTool[] = [ { name: 'boscli_health_check', description: 'Full BOS system health check - modules, database, cache, routes', schema: {}, handler: async (_, client) => client.get('/boscli/health'), }, { name: 'boscli_health_modules', description: 'Check health of all BOS modules', schema: {}, handler: async (_, client) => client.get('/boscli/health/modules'), }, { name: 'boscli_health_database', description: 'Check BOS database connectivity', schema: {}, handler: async (_, client) => client.get('/boscli/health/database'), }, { name: 'boscli_health_cache', description: 'Check BOS cache systems', schema: {}, handler: async (_, client) => client.get('/boscli/health/cache'), }, { name: 'boscli_health_schema', description: 'Check BOS database schema integrity', schema: {}, handler: async (_, client) => client.get('/boscli/health/schema'), }, ]; - src/index.ts:55-76 (registration)Registration loop in the main server - iterates allTools (including healthTools) and registers each with the McpServer via server.tool().
for (const tool of allTools) { const zodSchema = toZodSchema(tool.schema); server.tool( tool.name, tool.description, zodSchema.shape, async (args: any) => { try { const result = await tool.handler(args, client); return { content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }], }; } catch (error: any) { return { content: [{ type: 'text' as const, text: JSON.stringify({ error: error.message || 'Unknown error' }) }], isError: true, }; } } ); } - src/client/index.ts:38-105 (helper)BosApiClient class - the helper that executes the actual HTTP GET request to '/boscli/health'. Uses axios with retry logic and rate limiting.
export class BosApiClient { private client: AxiosInstance; constructor(config?: Partial<BosMcpConfig>) { const cfg = mergeConfig(config); this.client = axios.create({ baseURL: cfg.bosApiUrl, timeout: cfg.timeout, headers: { 'Content-Type': 'application/json', // BUG 5 FIX: Send x-mcp-api-key header that Laravel McpAuth middleware expects ...(cfg.mcpApiKey && { 'x-mcp-api-key': cfg.mcpApiKey }), ...(cfg.bosApiToken && { 'Authorization': `Bearer ${cfg.bosApiToken}` }), }, }); } async request<T>(method: string, path: string, data?: any, params?: Record<string, any>): Promise<T> { while (!(await rateLimiter.acquire())) { await new Promise(resolve => setTimeout(resolve, 1000)); } let lastError: Error | null = null; for (let attempt = 0; attempt < MAX_RETRIES; attempt++) { try { const response = await this.client.request<T>({ method, url: path, ...(data && { data }), // BUG 2 FIX: Support query params for GET requests ...(params && { params }), }); return response.data; } catch (error) { if (error instanceof AxiosError) { const status = error.response?.status; if (status && status >= 400 && status < 500 && status !== 429) { throw error; } lastError = error; if (attempt < MAX_RETRIES - 1) { await new Promise(resolve => setTimeout(resolve, RETRY_DELAY * (attempt + 1))); } } else { throw error; } } } throw lastError || new Error('Request failed after retries'); } // BUG 2+3 FIX: GET now accepts optional query params async get<T>(path: string, params?: Record<string, any>): Promise<T> { return this.request<T>('GET', path, undefined, params); } async post<T>(path: string, data?: any): Promise<T> { return this.request<T>('POST', path, data); } async put<T>(path: string, data?: any): Promise<T> { return this.request<T>('PUT', path, data); } async delete<T>(path: string): Promise<T> { return this.request<T>('DELETE', path); } }