metrics-snapshot
Read in-memory golden-signals metrics for this MCP server: counters and latency p50, p95, p99 per tool.
Instructions
Read in-memory golden-signals metrics for this MCP server (counters + latency p50/p95/p99 per tool).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/mcp-server/index.js:564-579 (handler)The handler function for the 'metrics-snapshot' tool. Calls metricsSnapshot() to get in-memory golden signals, then conditionally persists to disk (throttled to 1s via AUTO_PERSIST_THROTTLE_MS). Returns the snapshot payload.
async function handleMetricsSnapshot() { const payload = metricsSnapshot(); const now = Date.now(); if (now - _lastAutoPersistTs >= AUTO_PERSIST_THROTTLE_MS) { try { await persistSnapshot(); _lastAutoPersistTs = now; } catch (err) { // OBS-20-01: graceful — log to stderr, do NOT fail the handler. // In-memory snapshot still returned normally so the client tool call // contract is preserved even when fs is read-only or quota-exhausted. process.stderr.write(`[kit-mcp] auto-snapshot persist failed: ${err.message}\n`); } } return payload; } - src/mcp-server/index.js:581-591 (registration)Tool registration map: maps the string 'metrics-snapshot' to handleMetricsSnapshot.
const HANDLERS = { kit: handleKit, sync: handleSync, 'reverse-sync': handleReverseSync, gates: handleGates, forensics: handleForensics, install: handleInstall, 'metrics-snapshot': handleMetricsSnapshot, 'auto-install': handleAutoInstall, 'ack-restart': handleAckRestart, }; - src/mcp-server/index.js:146-155 (schema)Schema definition for 'metrics-snapshot' tool: parameterless (empty input schema), returns counters and latency p50/p95/p99 per tool.
// OBS-18 (Phase 94.01): expose four-golden-signals data for the MCP server itself. // Read-only (no auth needed beyond the underlying transport): returns counters // keyed `${tool}:${status}` and per-tool latency p50/p95/p99/count. name: 'metrics-snapshot', description: 'Read in-memory golden-signals metrics for this MCP server (counters + latency p50/p95/p99 per tool).', inputSchema: { type: 'object', properties: {}, }, }, - src/core/metrics.js:124-138 (helper)The snapshot() function that builds the read-only metrics payload: counters (keyed tool:status) and per-tool latency p50/p95/p99/count from in-memory histograms.
export function snapshot() { const out = { counters: {}, latency: {} }; for (const [key, val] of counters) out.counters[key] = val; for (const [tool, samples] of histograms) { if (samples.length === 0) continue; const sorted = [...samples].sort((a, b) => a - b); out.latency[tool] = { p50: percentile(sorted, 0.50), p95: percentile(sorted, 0.95), p99: percentile(sorted, 0.99), count: samples.length, }; } return out; } - src/core/metrics.js:170-183 (helper)Persists the current snapshot to disk under .planning/metrics/snapshots/ with rolling 30-day cleanup. Called via throttle from handleMetricsSnapshot.
export async function persistSnapshot(rootDir = process.cwd(), opts = {}) { const retentionMs = Number.isFinite(opts.retentionMs) ? opts.retentionMs : DEFAULT_RETENTION_MS; const dir = path.join(rootDir, SNAPSHOT_DIR_REL); await fs.mkdir(dir, { recursive: true }); const ts = Date.now(); const snap = { ts, ...snapshot() }; // Filesystem-safe ISO encoding — Windows forbids `:` in paths and `.` is // ambiguous with extension separators on shells with brace expansion. const isoSafe = new Date(ts).toISOString().replace(/[:.]/g, '-'); const file = path.join(dir, `${isoSafe}.json`); await fs.writeFile(file, JSON.stringify(snap, null, 2)); await cleanupOldSnapshots(dir, retentionMs); return { file, snap }; }