🎃 Add an opt-in Prometheus /metrics endpoint for tool calls
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Aptitud para principiantes
- 56/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- grafana, nodejs, prometheus, typescript
- Área
- backend, observability
Línea de trabajo
Start with logToolCall() in packages/backend/src/mcp-server/dynamic-mcp-tools.ts, where the metrics recording belongs, and with tracing.ts as the env-gated no-op pattern to copy. Then read processGauges.snapshot() in common/process-vitals.ts, app.listen in main.ts and isCloud() in common/deployment.service.ts. Done means the new src/common/metrics.spec.ts passes via npx jest src/common/metrics, /metrics returns the counters after a tool call, and the Cloud and token rules from the acceptance list hold.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Part of the October Challenge #997.
Why
Operators who self-host AnythingMCP want tool-call rates, error rates and latency in Grafana, next to the rest of their stack. Today they only have the Pino tool_call log lines, which they have to parse themselves, and the database (ToolInvocation). Our ROADMAP lists "per-tool latency histograms, error-rate dashboards". Most self-hosted gateways (Kong, Traefik, n8n) ship a Prometheus endpoint.
Self-hosted vs Cloud
- Self-hosted: off by default. When
METRICS_ENABLED=true, the backend starts a second, separate HTTP listener for/metrics(it does not use the main app port 4000). Available in Community; no licence gate. - Cloud (
DEPLOYMENT_MODE=cloud): the operator (us) uses the same code. Two extra rules: the listener refuses to start withoutMETRICS_TOKEN(it logs an error and metrics stay off), and per-tool/per-connector labels are always off. No series may carry an organization id, connector name, tool name or user. This prevents cross-tenant leaks and keeps cardinality bounded with thousands of workspaces. Per-org usage already exists in the database (AuditService.getBreakdowns). - Who can use it: whoever operates the instance (env vars). There are no app roles, no dashboard UI and no org scoping, because metrics are instance-wide by design. That is why they must never be reachable through the public port.
What to build
- Library: use
prom-client. Recommendation and reasons:@opentelemetry/exporter-prometheuswould hook into the existingNodeSDK(tracing.ts). But that SDK only starts whenOTEL_EXPORTER_OTLP_ENDPOINTis set, its 0.x packages must move in lockstep with@opentelemetry/sdk-node(^0.222.0), and Node runtime metrics need extra packages.prom-clientgivescollectDefaultMetrics()(event loop lag, heap, GC) for free and is trivial to unit-test (await register.metrics()returns a string). Wrap it in a small facade (src/common/metrics.ts:recordToolCall(...)), so a later switch to OTel metrics touches one file. - Env vars:
METRICS_ENABLED(defaultfalse),METRICS_PORT(default9464),METRICS_HOST(default0.0.0.0, because in Docker the Prometheus container must reach it over the compose network; the port is not published indocker-compose.yml),METRICS_TOKEN(optional on self-hosted, required on Cloud, compared withtimingSafeEqual),METRICS_TOOL_LABELS(defaultfalse, ignored on Cloud with a warning). - Listener: a plain
node:httpserver started frommain.tsafterapp.listen(), closed on shutdown. It serves onlyGET /metrics. Any other path returns 404, and a wrong or missing token returns 401. - Metrics (prefix
anythingmcp_):tool_calls_total{connector_type,status}counter (status =success|error)tool_call_duration_seconds{connector_type,status}histogram (buckets roughly 0.05 to 60 s; tool calls can take 20 s or more)tool_call_upstream_errors_total{connector_type,upstream_status_class}(4xx|5xx|none)- with
METRICS_TOOL_LABELS=true(self-hosted only), addconnector_idandtoollabels. Use the connector id (cuid), not the name. - gauges mirrored from the existing
processGauges(toolCallsInFlight,mcpRequestsInFlight,registeredTools…), using acollect()callback collectDefaultMetrics()
Where to look
packages/backend/src/mcp-server/dynamic-mcp-tools.ts:130:logToolCall()is called on both the success and the error path and already hasdurationMs,status,upstreamStatusandconnectorType. Record the metrics here.packages/backend/src/common/process-vitals.ts:246:ProcessGauges/processGauges.snapshot(), existing in-process gauges to expose.packages/backend/src/tracing.ts:26: the existing opt-in OTel setup (pattern for an env-gated, no-op-by-default module).packages/backend/src/main.ts:160:app.listen(port). Start the metrics listener after it.packages/backend/src/health/sentry-verify.controller.ts:27:sameSecret(), a constant-time token comparison to reuse.packages/backend/src/common/deployment.service.ts:10:isCloud().deploy/cloud/Caddyfile:91anddocs/deployment.md:221:/health*is proxied publicly on Cloud and self-hosted. That is why metrics must not live under/healthor on port 4000.
Acceptance criteria
- With
METRICS_ENABLEDunset, no listener starts andprom-clientdefault metrics are not collected. -
GET :9464/metricsreturns Prometheus text format, and the counters and histogram move after a tool call. - With
METRICS_TOKENset, a missing or wrongAuthorization: Bearerreturns 401. - With
DEPLOYMENT_MODE=cloudand no token, the listener does not start. WithMETRICS_TOOL_LABELS=trueon Cloud, notool/connector_idlabel appears. - Unit tests in
src/common/metrics.spec.ts(labels, Cloud rules, token check). Run withcd packages/backend && npx jest src/common/metrics. - Docs: new section "Prometheus metrics (opt-in)" in
docs/operations/observability.md, with a sample scrape config, plus the env vars in the table indocs/deployment.md(around line 338).
Out of scope
- Grafana dashboards or alert rules (a follow-up issue).
- Pushing metrics via OTLP.
- Per-organization metrics or any UI.
- Changing
docker-compose.cloud.ymlor the Cloud Caddyfile (maintainers wire scraping on Cloud).
Size
M (1–2 days)
How to claim
Comment "I'd like to work on this" and we'll assign you. Rules in #997.
- Lenguaje dominante
- TypeScript
- Estrellas
- 856
- Forks
- 82
- Merge medio
- 6 h 49 min
- PR fusionados (30 d)
- 152
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de HelpCode-ai/anythingmcp
-
Docs: document all SMTP_* and other undocumented env vars for self-hostingPosiblemente ocupada @notlakshitha la tomó hoy. Abiertoenhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
HelpCode-ai/anythingmcp#1049 · 3 comentarios ·
Los mantenedores suelen responder en 1 día
-
good first issue hacktoberfest
Dificultad 2/5 Medio día Aptitud para principiantes 70/100
HelpCode-ai/anythingmcp#996 ·
Los mantenedores suelen responder en 1 día
-
good first issue hacktoberfest
Dificultad 2/5 Medio día Aptitud para principiantes 72/100
HelpCode-ai/anythingmcp#995 ·
Los mantenedores suelen responder en 1 día
-
enhancement good first issue hacktoberfest help wanted
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
HelpCode-ai/anythingmcp#982 ·
Los mantenedores suelen responder en 1 día
-
Upload the new social previewPosiblemente ocupada @helpcodeai la tomó hoy. Abierto
HelpCode-ai/anythingmcp#1087 · 2 comentarios · 1 asignado ·
Los mantenedores suelen responder en 1 día
Todos los issues de HelpCode-ai/anythingmcp
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
one-zero-eight/apply-bot#39 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
bigbluebutton/bbb-ui-components-react#108 ·
Los mantenedores suelen responder en 2 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
Los mantenedores suelen responder en 1 día
-
high priority
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
CI-CMG/deep-sea-corals-exb#84 · 1 comentario ·