For agents
Your OpenTelemetry fleet, from your Claude console
Every backend lets an agent read telemetry. Telflo lets it build, test, and deploy what the fleet collects.
Over the MCP server or the CLI. From Claude Code, Cursor, Codex, or CI.
> Checkout spans have no service.version or http.route, so the latency dashboard lumps every checkout request together. Can you fix it at the collector?
Checkout spans pass through the prod-us-east node agents, which set the k8s attributes, so k8s-node-agent is the config to change.
$ telflo fleet deployments e9c47d12 --json: 4 deployments · k8s-node-agent 5d1b0c3a · config a41d7e2b · v10 · 42 nodes
$ telflo config pull a41d7e2b -o node-agent.yaml: wrote v10 to node-agent.yaml · pinned to otelcol-contrib 0.147.0
Read node-agent.yaml: traces pipeline is otlp → k8sattributes → batch → loadbalancing/gateway
kubectl get pods -n shop -l app=checkout --show-labels: 2 pods, both labelled app.kubernetes.io/version=2.14.3
k8sattributes extracts three k8s.* fields and no service.version, a one-line metadata field it derives from app.kubernetes.io/version.
Read 240 checkout server spans from the last 15 min via Grafana MCP: 0 of 240 carry http.route, names like POST /api/checkout/8841
The route is only in the span name. No transform in the traces pipeline copies it, so the dashboard groups on an empty http.route.
Two edits to node-agent.yaml: service.version under k8sattributes metadata, and http.route from the span name where it is missing.
node-agent.yaml · k8sattributes: processors: k8sattributes: extract: metadata: - k8s.namespace.name - k8s.pod.name - k8s.deployment.name +- service.version
node-agent.yaml · transform/route: +transform/route: +trace_statements: +- context: span +statements: +- set(attributes["http.route"], name) where attributes["http.route"] == nil and kind == SPAN_KIND_SERVER +- replace_pattern(attributes["http.route"], "^[A-Z]+ ", "") where kind == SPAN_KIND_SERVER and IsMatch(attributes["http.route"], "^[A-Z]+ ") +- replace_pattern(attributes["http.route"], "/\d+", "/{id}") where kind == SPAN_KIND_SERVER service: pipelines: traces: -processors: [k8sattributes, batch] +processors: [k8sattributes, transform/route, batch]
$ telflo ottl lint node-agent.yaml: invalid · processors.transform/route.trace_statements[0].statements[2] · 2 of 3 expressions parse · exit 4
Statement 3: OTTL rejects \d as an escape inside a string literal. Changed the pattern to /[0-9]+.
$ telflo ottl lint node-agent.yaml: 3 of 3 expressions parse · 420 ms
$ telflo validate node-agent.yaml --config a41d7e2b: valid · otelcol-contrib 0.147.0 · 2.1 s
Wrote route.test.yaml: 12 server spans, 8 checkout with no http.route, 4 cart that already carry /api/cart as the untouched control.
$ telflo test --spec route.test.yaml -f node-agent.yaml --config a41d7e2b: Success · run c6d2f8a1 · 4 of 4 rules passed · 12.6 s
pass: total count, 12 of 12 spans survived. pass: http.route on every span, all · attributes["http.route"] != nil · 12 of 12. pass: ids collapsed to {id}, 8 of 8 read /api/checkout/{id}. pass: untouched control, cart /api/cart, 4 of 4 unchanged
$ telflo config push a41d7e2b -f node-agent.yaml --publish --description "service.version from pod label, http.route from span name": appended v11 · published
$ telflo deploy --fleet e9c47d12 --config a41d7e2b: updated · deployment 5d1b0c3a now serves v11
prod-us-east · k8s-node-agent · v11: 42 of 42. 42 node agents pick up v11 · 38 s
Checkout spans from prod-us-east now carry service.version from the pod label and http.route with ids collapsed to {id}.
v10 is still published. telflo deploy --fleet e9c47d12 --config a41d7e2b --version 10 puts the fleet back on it.
> What do the attributes on a checkout span look like now?
Read 20 checkout server spans via Grafana MCP, 10 from 11:38 and 10 from 11:44. Showing one from 11:44.
Span attributes · checkout · POST /api/checkout/8841 · 212 ms
resource ├─ service.name checkout ├─ service.version new 2.14.3 ├─ k8s.namespace.name shop ├─ k8s.deployment.name checkout └─ k8s.pod.name checkout-6b9d8f7c4-k4xw2 span POST /api/checkout/8841 212 ms SERVER ├─ http.request.method POST ├─ http.route new /api/checkout/{id} ├─ http.response.status_code 200 └─ url.path /api/checkout/8841
10 of 10 spans from 11:44 carry service.version and http.route. 0 of 10 from 11:38, before the rollout, had either.
The latency dashboard can group checkout by http.route now, and p99 can split by service.version from the next release.
The old way
All Done Manually
Nothing runs it first.
Straight to prod, all 42 at once.
Scan panels to see what broke.
Each round is another prod rollout.
The new way
Fully Agentic
On demand
Full fidelity for one incident
Some data is only worth collecting while something is wrong. The agent turns it on and turns it back off.
Checkout p99 alerts.
Four of five slow traces were sampled away.
The agent turns collection up on checkout. Telflo tests the change and deploys it.
Root cause found.
The agent deploys the previous version. Sampling is back at baseline.
Checkout p99 alerts.
Four of five slow traces were sampled away.
The agent turns collection up on checkout. Telflo tests the change and deploys it.
Root cause found.
The agent deploys the previous version. Sampling is back at baseline.
Interfaces
MCP server
From Claude Code, Cursor, or any MCP client, under the same scoped tokens as the CLI.
MCP server docsGet started
Try it with your own agent
Connect the MCP server or install the CLI, and create a token in Settings.