Monitor MCP Servers with Prometheus
Export MCP server metrics in Prometheus format and write PromQL queries for tool latency, error rate, and throughput.
Quick Answer / TL;DR
Prometheus monitors MCP servers by scraping a /metrics endpoint that exposes counters and histograms for tool calls, then lets you query and alert on them with PromQL.
Key Takeaways
- Expose a /metrics endpoint with the prom-client library rather than pushing metrics manually.
- Use a histogram for tool-call duration so you can derive p50/p95/p99, not just an average.
- Label by server and tool name, never by user ID, email, or request payload content.
Instrumenting an MCP server
The prom-client package is the standard way to expose Prometheus-format metrics from a Node.js process. Wrap each tool handler so every call increments a counter and records its duration in a histogram, then serve the aggregated result on a /metrics HTTP endpoint for Prometheus to scrape on an interval.
import { Counter, Histogram, register } from "prom-client";
import express from "express";
const toolCalls = new Counter({
name: "mcp_tool_calls_total",
help: "Total tool calls handled",
labelNames: ["server", "tool", "status"],
});
const toolDuration = new Histogram({
name: "mcp_tool_duration_seconds",
help: "Tool call duration in seconds",
labelNames: ["server", "tool"],
buckets: [0.05, 0.1, 0.25, 0.5, 1, 2, 5],
});
async function callTool(server: string, tool: string, handler: () => Promise<unknown>) {
const end = toolDuration.startTimer({ server, tool });
try {
const result = await handler();
toolCalls.inc({ server, tool, status: "success" });
return result;
} catch (err) {
toolCalls.inc({ server, tool, status: "error" });
throw err;
} finally {
end();
}
}
const app = express();
app.get("/metrics", async (_req, res) => {
res.set("Content-Type", register.contentType);
res.end(await register.metrics());
});
app.listen(9464);Useful PromQL queries
Once Prometheus is scraping the endpoint, these queries cover the metrics that matter most for an MCP server: error rate, p95 latency, and per-tool call volume.
| Question | PromQL |
|---|---|
| Error rate over 5 minutes | sum(rate(mcp_tool_calls_total{status="error"}[5m])) / sum(rate(mcp_tool_calls_total[5m])) |
| p95 tool latency | histogram_quantile(0.95, sum(rate(mcp_tool_duration_seconds_bucket[5m])) by (le, tool)) |
| Calls per tool per minute | sum(rate(mcp_tool_calls_total[1m])) by (tool) |
Monitor MCP Servers with Prometheus FAQs
Direct answers for developers, operators, and Indian teams evaluating MCP.