Skip to content

Claude Code Skill

Autotel includes a Claude Code skill that gives AI coding agents deep knowledge of the instrumentation API. When the skill is active, Claude Code can:

  • Wrap functions with trace() and set semantic attributes
  • Convert console.log calls to getRequestLogger() wide events
  • Add createStructuredError() with why, fix, and link fields
  • Set up init() with the correct configuration
  • Review code for observability anti-patterns

The skill lives at .claude/skills/autotel/ in the repository root. Claude Code discovers it automatically when you work inside the repo. No extra configuration needed.

For other projects that use Autotel, copy the .claude/skills/autotel/ directory into your repo’s .claude/skills/ folder.

.claude/skills/autotel/
├── SKILL.md # Main skill entry point
└── references/
├── wide-events.md # Canonical log lines guide
├── structured-errors.md # Error handling patterns
├── request-logger.md # Request-scoped logging
└── code-review.md # Anti-pattern detection checklist

File: .claude/skills/autotel/references/wide-events.md

A wide event is a single structured record per request containing all context accumulated during processing. Instead of 10 scattered log lines, you get one queryable event with 25+ fields.

Covers:

  • Anatomy of a canonical log line (core fields, trace identifiers, duration)
  • Context grouping with dot-prefixed keys
  • Configuration options (keep, shouldEmit, pretty, drain, attributeRedactor)
  • Drain pipeline for production fan-out with batching and retry
  • SQL query examples for analyzing wide events
init({
service: 'my-app',
canonicalLogLines: {
enabled: true,
rootSpansOnly: true,
keep: [{ status: 500 }, { durationMs: 1000 }],
pretty: true,
drain: (event) => sendToAnalytics(event),
},
});

File: .claude/skills/autotel/references/structured-errors.md

Covers three APIs:

API Purpose
createStructuredError() Create errors with message, why, fix, link, code, status, details
recordStructuredError() Record a structured error onto a trace context (sets status + exception + attributes)
parseError() Normalize any thrown value to a consistent shape for API responses

Common patterns:

  • API endpoint error responses
  • Wrapping third-party errors (Stripe, etc.)
  • Domain validation errors
  • Span attribute mapping (error.type, error.why, error.fix, etc.)
throw createStructuredError({
message: 'Payment declined',
why: 'Card has insufficient funds for the requested amount',
fix: 'Prompt the user to update their payment method',
code: 'CARD_DECLINED',
status: 402,
link: 'https://docs.stripe.com/declines/codes#insufficient-funds',
});

File: .claude/skills/autotel/references/request-logger.md

Covers the getRequestLogger() API and framework adapters:

  • log.set(fields): merge fields onto the span (nested objects flatten automatically)
  • log.info(message, fields?): span event at info level
  • log.warn(message, fields?): span event at warn level, promotes canonical log line
  • log.error(error, fields?): record structured error on span
  • log.getContext(): snapshot of all accumulated fields
  • log.emitNow(overrides?): emit snapshot immediately with onEmit fan-out

Framework adapters:

  • useLogger() with withAutotel() (Next.js, Nitro, Cloudflare Workers)
  • useLogger() alone when middleware already creates the span (Hono)
  • Custom adapters via createUseLogger()
const log = getRequestLogger(ctx);
log.set({ feature: 'checkout', tier: req.user.tier });
const cart = await loadCart(req.cartId);
log.set({ cart_items: cart.items.length, cart_total: cart.total });

File: .claude/skills/autotel/references/code-review.md

Anti-pattern detection table with severity levels and fixes:

Anti-Pattern Severity Fix
console.log for request context High getRequestLogger(ctx) with log.set()
console.error in catch blocks High log.error(err) or recordStructuredError()
throw new Error('...') without context Medium createStructuredError({ message, why, fix })
catch (e) { throw e } without recording Medium Add log.error(e) before rethrowing
JSON.stringify for log output High log.set(): attributes flatten automatically
Manual request ID generation Low ctx.correlationId from trace context

Also includes a 4-step migration path from console.log to fully instrumented Autotel code.

When you ask Claude Code to instrument code, review for observability, or work with errors/logging, the skill activates and loads the relevant reference guides. Claude Code then applies the patterns directly. Wrapping functions with trace(), replacing console.log with request loggers, and adding structured error context.

  • “Add tracing to this handler”
  • “Convert the console.logs in this file to use request logger”
  • “Add structured errors to the catch blocks”
  • “Review this file for observability anti-patterns”
  • “Set up canonical log lines for this service”

The skill described above teaches Claude Code how to write instrumented code. Two integrations serve a second class of agent task, investigating telemetry: querying traces, diagnosing errors, and ranking expensive LLM calls. They are two interchangeable mechanisms:

  1. autotel-mcp: an MCP server the user wires into .mcp.json.
  2. The autotel CLI itself: the same investigation surface as one-shot subcommands that emit JSON on stdout.

Both share the same backends (packages/autotel-mcp/src/backends/) and the same query helpers, so the answers are identical. The CLI route is useful when you’d rather not configure an MCP server, or when you’re driving an agent harness that doesn’t speak MCP.

MCP tool group CLI equivalent
health.backend_health autotel health
health.backend_capabilities autotel capabilities
discovery.discover_services autotel discover services
discovery.discover_trace_fields autotel discover trace-fields
discovery.discover_log_fields autotel discover log-fields
investigation.search_traces autotel query traces
investigation.search_spans autotel query spans
investigation.get_trace autotel trace get <id>
investigation.summarize_trace autotel trace summary <id>
signals.list_metrics autotel query metrics
signals.search_logs autotel query logs
topology.list_services autotel topology services
topology.list_operations autotel topology operations <name>
topology.service_map autotel topology map
diagnosis.find_anomalies autotel diagnose anomalies
diagnosis.find_root_cause autotel diagnose root-cause <id>
diagnosis.find_errors autotel diagnose errors
diagnosis.check_slos autotel diagnose slos --service <name>
correlation.correlate autotel correlate trace <id>
correlation.explain_slowdown autotel correlate explain-slowdown --service <name>
llm-analytics.get_llm_usage autotel llm usage
llm-analytics.list_llm_models autotel llm models
llm-analytics.get_llm_model_stats autotel llm model-stats --model-name <name>
llm-analytics.get_llm_expensive_traces autotel llm expensive
llm-analytics.get_llm_slow_traces autotel llm slow
llm-analytics.list_llm_tools autotel llm tools
semantic-conventions.* autotel semconv list | get <ns> | refresh
instrumentation.score_span_instrumentation autotel score (JSON span on stdin)
instrumentation.explain_instrumentation_score autotel score explain
collector-config.* autotel collector validate | suggest | explain
collector-schema.* autotel collector versions | components | schema | readme | validate-component | refresh

Every backend-touching command accepts the same flags as the MCP server’s env vars, with flags winning over env when both are set:

Terminal window
autotel query traces \
--backend tempo \
--tempo-base-url http://localhost:3200 \
--service-name checkout \
--error-only \
--limit 20

Available backends: collector (built-in OTLP receiver, in-memory or libsql-persisted) · jaeger · tempo · prometheus · loki · stack (composite) · auto (probe localhost) · fixture (JSON file).

Every investigate command emits one JSON document on stdout. Success:

{ "ok": true, "command": "query traces", "data": {/* … */} }

Failure:

{
"ok": false,
"error": {
"type": "validation" | "runtime",
"code": "AUTOTEL_E_INVALID_INPUT" | "AUTOTEL_E_UNKNOWN",
"message": "",
"retryable": false
}
}

Exit code is 0 on success, 2 on validation, 1 on runtime. Agents check result.ok and read data (or error).

MCP server CLI subcommands
Install step Edit .mcp.json, restart client npm i -g autotel
Transport stdio / HTTP per client Shell exec
Streaming results Yes One-shot per command
Cross-tool state Server holds backend connection Each call re-opens
Works in non-MCP agents No Yes
Discoverability MCP tool list autotel <group> --help

For an agent driving a single investigation prompt the CLI is usually faster. No MCP handshake, no per-tool round-trip. For an interactive incident review with many follow-up queries against a heavy backend, the MCP server’s persistent backend connection wins.

A ready-made skill that maps prompts → CLI commands ships at .claude/skills/autotel-investigate/SKILL.md. Claude Code discovers it automatically when you work inside the repo; copy the directory into another project’s .claude/skills/ to use it elsewhere.