Health Check
pingVerify Claude CLI installation and authentication. Reports version, capabilities, and configuration details for local health check without cost.
Instructions
Health check: verifies Claude CLI is installed and authenticated, reports versions, capabilities, and configuration. No cost (local check only).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/tools/ping.ts:61-142 (handler)The core handler function that executes the ping tool logic: finds the Claude binary, runs '--version', detects authentication method, and returns a PingResult with version, auth, models, and capabilities.
export async function executePing(): Promise<PingResult> { const binary = findClaudeBinary(); const maxConcurrent = getMaxConcurrent(); const activeCount = getActiveCount(); const queueDepth = getQueueDepth(); let cliFound = false; let version: string | null = null; try { version = execFileSync(binary, ["--version"], { encoding: "utf8", timeout: 10_000, }).trim(); cliFound = true; } catch (e) { const err = e as NodeJS.ErrnoException; if (err.code === "ENOENT") { return { cliFound: false, version: null, authMethod: "none", subscriptionType: null, defaultModel: getDefaultModel("query"), fallbackModel: getFallbackModel() ?? null, serverVersion: PKG_VERSION, nodeVersion: process.version, maxConcurrent, activeCount, queueDepth, capabilities: { bareMode: false, jsonOutput: false, jsonSchema: false, sessionResume: false, }, }; } // Non-ENOENT errors (EACCES, timeout, broken binary) mean the CLI exists // but is not usable. Report cliFound: false with a diagnostic message. return { cliFound: false, version: `error: ${err.message ?? String(e)}`, authMethod: "none", subscriptionType: null, defaultModel: getDefaultModel("query"), fallbackModel: getFallbackModel() ?? null, serverVersion: PKG_VERSION, nodeVersion: process.version, maxConcurrent, activeCount, queueDepth, capabilities: { bareMode: false, jsonOutput: false, jsonSchema: false, sessionResume: false, }, }; } const auth = detectAuth(); return { cliFound, version, authMethod: auth.method, subscriptionType: auth.subscriptionType, defaultModel: getDefaultModel("query"), fallbackModel: getFallbackModel() ?? null, serverVersion: PKG_VERSION, nodeVersion: process.version, maxConcurrent, activeCount, queueDepth, capabilities: { bareMode: true, jsonOutput: true, jsonSchema: true, sessionResume: true, }, }; } - src/index.ts:324-355 (handler)The inline async handler passed to registerTool that calls executePing(), formats the result into text output, and handles errors.
async () => { const start = Date.now(); try { const result = await executePing(); const lines = [ `cliFound: ${result.cliFound}`, `version: ${result.version ?? "unknown"}`, `authMethod: ${result.authMethod}`, ...(result.subscriptionType ? [`subscriptionType: ${result.subscriptionType}`] : []), `defaultModel: ${result.defaultModel ?? "none"}`, `fallbackModel: ${result.fallbackModel ?? "none"}`, `serverVersion: ${result.serverVersion}`, `nodeVersion: ${result.nodeVersion}`, `maxConcurrent: ${result.maxConcurrent}`, `activeCount: ${result.activeCount}`, `queueDepth: ${result.queueDepth}`, `capabilities: bareMode=${result.capabilities.bareMode}, jsonOutput=${result.capabilities.jsonOutput}, jsonSchema=${result.capabilities.jsonSchema}, sessionResume=${result.capabilities.sessionResume}`, ]; return { content: [{ type: "text" as const, text: lines.join("\n") }], _meta: buildMeta({ durationMs: Date.now() - start }), }; } catch (e) { console.error("[ping]", e); return { content: [{ type: "text" as const, text: `Error: ${getErrorMessage(e)}` }], isError: true, _meta: buildMeta({ durationMs: Date.now() - start }), }; } }, - src/tools/ping.ts:12-30 (schema)PingResult interface defining the shape of the tool's output including cliFound, version, authMethod, models, server version, queue stats, and capabilities.
export interface PingResult { cliFound: boolean; version: string | null; authMethod: "api-key" | "subscription" | "none"; subscriptionType: string | null; defaultModel: string | null; fallbackModel: string | null; serverVersion: string; nodeVersion: string; maxConcurrent: number; activeCount: number; queueDepth: number; capabilities: { bareMode: boolean; jsonOutput: boolean; jsonSchema: boolean; sessionResume: boolean; }; } - src/index.ts:316-323 (registration)Registration of the 'ping' tool with server.registerTool(), including title, description (from descriptions.ts), inputSchema (empty object), and annotations (from annotations.ts).
server.registerTool( "ping", { title: "Health Check", description: pingDescription, inputSchema: {}, annotations: pingAnnotations, }, - src/tools/ping.ts:39-59 (helper)Helper function detectAuth() that checks for ANTHROPIC_API_KEY env var or reads ~/.claude/.credentials.json to determine the authentication method.
function detectAuth(): { method: PingResult["authMethod"]; subscriptionType: string | null } { const env = buildSubprocessEnv(); if (env["ANTHROPIC_API_KEY"]) { return { method: "api-key", subscriptionType: null }; } const configDir = process.env["CLAUDE_CONFIG_DIR"] ?? join(process.env["HOME"] ?? "", ".claude"); try { const raw = readFileSync(join(configDir, ".credentials.json"), "utf8"); const creds = JSON.parse(raw) as CredentialsFile; const oauth = creds.claudeAiOauth; if (oauth?.expiresAt && oauth.expiresAt > Date.now()) { return { method: "subscription", subscriptionType: oauth.subscriptionType ?? null }; } } catch { // No credentials file or unreadable } return { method: "none", subscriptionType: null }; }