OPA health check
opa_healthCheck the health of an Open Policy Agent instance. Optionally require bundle or plugin subsystems to be healthy by setting query flags.
Instructions
Hit the OPA /health endpoint. Returns { healthy: true } on 200. Supports bundles and plugins query flags to require those subsystems to also be healthy.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| bundles | No | Require bundle plugin to be healthy as well. | |
| plugins | No | Require all plugins to be healthy. |
Implementation Reference
- The main handler function for opa_health. Executes an HTTP GET to OPA's /health endpoint with optional 'bundles' and 'plugins' query parameters. Returns { healthy: true } on 200, or a structured error envelope otherwise.
async ({ bundles, plugins }) => { return withToolEnvelope<{ healthy: boolean }>(config, async () => { try { const query: Record<string, boolean> = {}; if (bundles) query['bundles'] = true; if (plugins) query['plugins'] = true; await opa.request({ method: 'GET', path: '/health', query, }); return ok({ healthy: true }); } catch (e) { if (e instanceof OpaUnreachableError) { return mapOpaClientError(e); } // Any non-2xx counts as unhealthy without raising. return err('OPA_UNREACHABLE', 'OPA reported unhealthy.', { details: { error: e instanceof Error ? e.message : String(e) }, }); } }); }, - Input schema for opa_health: optional 'bundles' and 'plugins' boolean flags to require those subsystems to be healthy.
inputSchema: { bundles: z.boolean().optional().describe('Require bundle plugin to be healthy as well.'), plugins: z.boolean().optional().describe('Require all plugins to be healthy.'), }, - src/tools/server-management/status.ts:17-51 (registration)Registration of the 'opa_health' tool via server.registerTool(), including its title, description, input schema, and handler.
server.registerTool( 'opa_health', { title: 'OPA health check', description: 'Hit the OPA `/health` endpoint. Returns `{ healthy: true }` on 200. Supports `bundles` and `plugins` query flags to require those subsystems to also be healthy.', inputSchema: { bundles: z.boolean().optional().describe('Require bundle plugin to be healthy as well.'), plugins: z.boolean().optional().describe('Require all plugins to be healthy.'), }, }, async ({ bundles, plugins }) => { return withToolEnvelope<{ healthy: boolean }>(config, async () => { try { const query: Record<string, boolean> = {}; if (bundles) query['bundles'] = true; if (plugins) query['plugins'] = true; await opa.request({ method: 'GET', path: '/health', query, }); return ok({ healthy: true }); } catch (e) { if (e instanceof OpaUnreachableError) { return mapOpaClientError(e); } // Any non-2xx counts as unhealthy without raising. return err('OPA_UNREACHABLE', 'OPA reported unhealthy.', { details: { error: e instanceof Error ? e.message : String(e) }, }); } }); }, ); - The registerStatusTools function that registers opa_health, opa_status, and opa_config on the MCP server.
export function registerStatusTools(server: McpServer, config: Config): void { - src/lib/opa-client.ts:62-123 (helper)The OpaClient.request() method used by the opa_health handler to make HTTP requests to the OPA server.
async request<T = unknown>(opts: RequestOptions): Promise<T> { const url = this.buildUrl(opts.path, opts.query); const headers: Record<string, string> = { Accept: 'application/json', ...(opts.headers ?? {}), }; if (this.config.opaToken) { headers['Authorization'] = `Bearer ${this.config.opaToken}`; } let bodyToSend: string | undefined; if (opts.rawBody !== undefined) { if (opts.body !== undefined) { throw new Error('OpaClient.request: pass either `body` or `rawBody`, not both.'); } bodyToSend = opts.rawBody; if (!headers['Content-Type']) { headers['Content-Type'] = opts.rawContentType ?? 'text/plain'; } } else if (opts.body !== undefined) { bodyToSend = JSON.stringify(opts.body); if (!headers['Content-Type']) { headers['Content-Type'] = 'application/json'; } } const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), this.config.httpTimeoutMs); const init: RequestInit = { method: opts.method, headers, signal: controller.signal, }; if (bodyToSend !== undefined) { init.body = bodyToSend; } let response: Response; try { response = await fetch(url, init); } catch (e) { throw new OpaUnreachableError(this.config.opaUrl, e); } finally { clearTimeout(timer); } if (response.status === 401) { throw new OpaAuthError(); } const contentType = response.headers.get('content-type') ?? ''; const isJson = contentType.includes('application/json'); const payload: unknown = isJson ? await response.json() : await response.text(); if (!response.ok) { throw new OpaHttpError(response.status, payload); } return payload as T; }