Observability¶
Logs¶
kartoza-mcp writes structured logs to stderr at INFO level by
default. stdout is sacred — it carries the MCP frames.
2026-06-15T10:14:22Z INFO cluster_points request received n=412 eps=2000 minPts=4
2026-06-15T10:14:22Z INFO cluster_points completed clusters=7 duration_ms=18
Wire stderr into your logging stack:
- systemd →
journalctl -u kartoza-mcp-bridge. - Docker →
docker logs -f kartoza-mcp(or yourjson-filedriver). - Kubernetes → standard pod log collection (Loki / Cloudwatch / etc.).
What to measure¶
| Metric | Why it matters |
|---|---|
| Requests per minute | Capacity planning. |
cluster_points duration |
Watch tail latency; spikes often mean huge inputs. |
| Input point count | Outlier requests skew everything. |
| Error rate by tool | Schema breakage / malformed clients. |
Future versions will emit Prometheus metrics on an opt-in --metrics
flag. Tracking issue: #11.
Tracing¶
When MCP_TRACE=1, each request gets a UUID logged at start and end —
enough to follow a single call through the logs.
2026-06-15T10:14:22Z INFO trace_id=4f1c… cluster_points start
2026-06-15T10:14:22Z INFO trace_id=4f1c… cluster_points end clusters=7
OpenTelemetry support is planned but not yet shipped.
Health checks¶
There isn't really such a thing as "the process is healthy" for a
stdio MCP server — if it's alive, it's healthy. For Kubernetes, prefer
a livenessProbe: exec that runs a no-op JSON-RPC initialize and
asserts a response within 1 second.