Tools reference
All times use RFC 3339, for example 2026-09-08T09:00:00Z.
Every tool that reads data takes two optional arguments. Omitted, they mean the workspace and the environment the app
shows. Call list_environments for the names.
| Parameter | Type | Required | Meaning |
|---|---|---|---|
workspace |
string | no | The workspace to read, by name or slug. |
environment |
string | no | The environment to read, by name, slug, or deployment.environment.name tag. |
query_logs
Section titled “query_logs”Search and filter log records.
| Parameter | Type | Required | Meaning |
|---|---|---|---|
query |
string | no | Text to find in the log message. |
severity |
string | no | One of TRACE, DEBUG, INFO, WARN, ERROR, FATAL. |
start_time |
string | no | Start of the time range. |
end_time |
string | no | End of the time range. |
limit |
number | no | Records to return. Default 100, maximum 1000. |
Each log record carries a resourceId. The resources map of the result holds, by that id, the resource attributes
the record came with: service.name, service.instance.id, telemetry.sdk.name, host.name, and so on. One entry
per process, however many records came from it. get_trace returns the same map for its spans.
query_metrics
Section titled “query_metrics”Read time-series metrics.
| Parameter | Type | Required | Meaning |
|---|---|---|---|
name |
string | no | Metric name pattern. |
start_time |
string | yes | Start of the time range. |
end_time |
string | yes | End of the time range. |
percentiles |
number[] | no | Quantiles between 0 and 1, for example [0.5, 0.95, 0.99]. |
Loggerhead keeps a histogram as one series for each statistic, with the type histogram: <name>.count,
<name>.sum, and <name>.min and <name>.max when the SDK records them. Thus a name pattern such as
http.server.request.duration returns all the series of that histogram. Loggerhead also keeps the buckets of each
histogram point. Pass percentiles to get one more series per quantile and label set, named <name>.p50,
<name>.p95, <name>.p99.9, and so on, computed from the buckets. A summary comes back as a gauge per quantile
under its name with the label quantile, plus <name>.count and <name>.sum.
A series of a sum or a histogram carries its temporality: cumulative when each point is the total since the
start, or delta when each point is the change since the previous point. A gauge has no temporality. A delta
counter goes down by design, so do not read a fall in a delta series as a reset.
A series carries the description that the instrument declared, such as “Duration of HTTP server requests”,
when the exporter sent one.
query_traces
Section titled “query_traces”Search traces.
| Parameter | Type | Required | Meaning |
|---|---|---|---|
service_name |
string | no | Filter by service. |
operation_name |
string | no | Filter by span name. |
start_time |
string | no | Start of the time range. |
end_time |
string | no | End of the time range. |
min_duration_ms |
number | no | Only traces at least this long. |
limit |
number | no | Traces to return. Default 100. |
get_trace
Section titled “get_trace”Read one trace. The result holds every span of the trace with its timing, its status, and its attributes. Each span also carries its events and its links. An event is a point inside the span with a name, a timestamp, and attributes; an SDK records an exception as an event named exception with exception.type, exception.message, and exception.stacktrace. A link points at a span in this trace or in another trace, for example the producer of the message that a consumer span handles.
The reason of a failed span is also in its attributes. otel.status_description holds the status message, and exception.type, exception.message, and exception.stacktrace hold the last exception that the span recorded.
| Parameter | Type | Required | Meaning |
|---|---|---|---|
trace_id |
string | yes | The trace ID. |
The result also holds exemplars: the metric samples an SDK took inside this trace, each with the metric name,
the point labels, the sampled value, and the span.
list_environments
Section titled “list_environments”List every workspace on this Mac with its environments. The tool has no parameters. It returns this JSON object.
| Field | Type | Meaning |
|---|---|---|
workspaces |
array | One entry per workspace with id, name, slug, grpcPort, httpPort, effectiveGrpcPort, effectiveHttpPort, current, and environments. Each environment has id, name, slug, kind, tag, and current. |
currentWorkspace |
string | The name of the workspace the app reads. |
currentEnvironment |
string | The name of the environment the app reads. |
The list is the same as the Workspaces page in the app.
get_receiver_info
Section titled “get_receiver_info”Report the effective OTLP endpoints of the receivers. The tool has no parameters. The top-level fields describe the workspace the app reads, and workspaces repeats them per workspace.
| Field | Type | Meaning |
|---|---|---|
otlpGrpcPort |
number | The effective gRPC port. Send gRPC telemetry to this port. |
otlpHttpPort |
number | The effective HTTP port. Send HTTP telemetry to this port. |
otlpGrpcConfiguredPort |
number | The gRPC port that the root asked for. |
otlpHttpConfiguredPort |
number | The HTTP port that the root asked for. |
otlpGrpcPortConflict |
boolean | true when the gRPC port was busy and the root moved to another port. |
otlpHttpPortConflict |
boolean | true when the HTTP port was busy and the root moved to another port. |
grpcEndpoint |
string | The gRPC address, for example http://127.0.0.1:4317. |
httpEndpoint |
string | The HTTP address, for example http://127.0.0.1:4318. |
workspaces |
array | One entry per workspace with workspace (the name) and the same port fields. Each workspace has its own port pair. |
Call this tool before you configure an OTLP exporter. Do not assume the default ports. See Ports and the effective port.
query_improvements
Section titled “query_improvements”List the telemetry-quality findings that the Linting page shows. Every parameter is optional. With no parameters the tool returns every finding.
| Parameter | Type | Required | Meaning |
|---|---|---|---|
impact |
string | no | One of high, med, low. |
source |
string | no | One of logs, metrics, traces. |
kind |
string | no | The detector name, for example noisy_logs, stale_metric, or suggested_alert. |
include_metric_health |
boolean | no | Also return the per-metric health table. Default false. |
The result has these fields.
| Field | Type | Meaning |
|---|---|---|
generatedAt |
string | When the engine built the report. |
windowSecs |
number | The lookback window the engine scanned, in seconds. |
findings |
array | The findings that match the filters. Each finding has id, kind, impact, source, title, description, meta, recommendation, action, ai, and count. A folded group (several findings with the same rule and shape) also has members, one finding per subject. |
counts |
object | total, high, med, and low for the findings in the result. |
resolved |
array | The findings that stopped firing in the last 24 hours, the latest first. Each has id, kind, title, source, reason, resolvedAt, and lastSeen. The source and kind filters apply to this list. The impact filter does not, because a resolved finding has no impact. |
metricHealth |
array | One row per metric with metric, state (ok, stale, broken), points, and lastSeen. Present only when include_metric_health is true. |
The list has only the open lint findings. It leaves out the findings that are marked as fixed or ignored, the findings that an exception of the workspace matches, and the findings of the AI analysis. Call query_ai_findings for the AI findings.
The engine scans the last hour again every 30 seconds. After you fix the cause and the new code runs, call mark_finding_fixed. Without that call, the old telemetry keeps the finding open until it ages out of the one-hour window. A finding moves to resolved with one of these reasons:
fixed: new telemetry of that signal arrived, and the rule does not fire on it. The fix worked.aged: the window has no telemetry of that signal. The fix is not proven. Send new telemetry, for example run the code path again, then call the tool again. If the problem is still there, the finding is infindingsagain.
mark_finding_fixed
Section titled “mark_finding_fixed”Mark one finding fixed after you changed the code and the new code runs. The old records keep the last hour tripping the rule, so Loggerhead then judges the finding by the telemetry after the fix only. At each scan, every 30 seconds:
- New telemetry trips the rule: the finding is open again.
- New telemetry of its signal arrives and does not trip the rule: the finding moves to
resolvedwith the reasonfixed. - No new telemetry arrives: the finding stays hidden.
| Parameter | Type | Required | Meaning |
|---|---|---|---|
finding_id |
string | yes | The id of one finding from query_improvements. A group id (group:…) is refused; mark each member. |
workspace |
string | no | The workspace of the finding. |
environment |
string | no | The environment of the finding. The state of a finding belongs to its environment. |
The result has findingId, fixedAt, and next, which says what the scans do. Run the code path, wait 30 seconds, then call query_improvements. Mark as fixed in the finding menu of the Linting page does the same.
When a finding is a false positive for this project, use add_lint_exception or ignore_finding with a reason.
list_lint_rules
Section titled “list_lint_rules”List the lint rules behind the Linting page, with the state, the thresholds, and the exceptions the app shows on the Rules tab of the Linting page. The rule settings belong to the workspace, so every environment of the workspace uses the same rules. Call it to explain why a finding fired or did not fire, and before you change a rule. Every parameter is optional.
| Parameter | Type | Required | Meaning |
|---|---|---|---|
kind |
string | no | Return one rule only, by its id, for example noisy_logs. |
The result has these fields.
| Field | Type | Meaning |
|---|---|---|
workspace |
string | The name of the workspace the list is for. |
environment |
string | The name of the environment the list is for. |
counts |
object | total, on, off, and edited for the rules in the result. |
rules |
array | One entry per rule with kind, name, signal (logs, metrics, traces, all_signals), description, enabled, edited, ignoredFindings, thresholds, and exceptions. Each threshold has field, label, unit (ratio, count, bytes, seconds, per_minute, list), value, default, edited, and sharedWith, the other rules that read the same field. A ratio is a share between 0 and 1. Each exception has id, the fields it matches, reason, source, and createdAt. |
ignoredFindings |
array | The ignored findings with findingId, rule, title, reason, source (mcp or ui), scope (workspace or environment), and until. |
recentChanges |
array | The newest changes to the settings with id, at, source, action, rule, summary, reason, and undone. |
note |
string | How to change a rule, on every result. |
Change the lint rules
Section titled “Change the lint rules”Seven tools change the lint rules of a workspace. Every environment of the workspace (Local, Staging, Production) uses the change. Each tool needs a reason, and takes an optional workspace. The Rules tab of the Linting page shows each change with its source, its time, and its reason, and the user can undo it there. The engine applies the change on its next scan, within 30 seconds.
Fix the telemetry at the source first. Change a rule only when a finding is a false positive for this project.
| Tool | Parameters | What it does |
|---|---|---|
set_lint_rule_enabled |
kind, enabled |
Switches a rule on or off. The rule keeps its thresholds. |
set_lint_threshold |
kind, field, value |
Sets one threshold. value is a number, or an array of names for a list threshold. The value must be in the range of the threshold. |
reset_lint_threshold |
kind, field |
Puts one threshold back to its default. |
add_lint_exception |
kind, and one or more of service_name, metric_name, attribute_key, operation, body_pattern |
Adds an exception: the findings of the rule that match every field you give do not show. * matches any run of characters, and the match ignores case. body_pattern matches any part of the log message and needs 3 characters or more. The result gives the exceptionId. |
remove_lint_exception |
exception_id |
Removes one exception. |
ignore_finding |
finding_id, optional until (RFC 3339) |
Ignores one finding by its id from query_improvements. A group id (group:…) is refused; ignore each member. |
unignore_finding |
finding_id |
Stops the ignore of one finding. |
A value that is not valid gives a tool error that names the argument, for example noisy_logs.noisyLogRatio must be between 0 and 1. See Tune the rules.
query_ai_findings
Section titled “query_ai_findings”List the findings of the last AI analysis run: the findings on the AI analysis page. The AI analysis reads the lint report and a sample of the raw logs and spans, and finds problems that one lint rule cannot find. Every parameter is optional.
| Parameter | Type | Required | Meaning |
|---|---|---|---|
impact |
string | no | One of high, med, low. |
source |
string | no | One of logs, metrics, traces. |
The result has these fields.
| Field | Type | Meaning |
|---|---|---|
status |
string | ok when the run gave findings. unavailable when the model did not answer. disabled when no AI provider is set. not_run when no run happened on this environment since Loggerhead started. |
ranAt |
string | When the run finished. Absent for not_run. |
window |
string | The window of the run: 1h or 24h. |
model |
string | The model that made the findings. |
message |
string | The reason for unavailable or disabled, or what to do for not_run. |
findings |
array | The findings that match the filters, the highest impact first. Each finding has the same fields as a query_improvements finding, with ai set to true. |
counts |
object | total, high, med, and low for the findings in the result. |
The tool does not start a run. A run can send a sample of the telemetry to a cloud model, and a cloud model can cost the user money. The user starts a run with Run AI analysis on the AI analysis page. The app keeps only the last run of each environment, and only until it quits. An AI finding does not clear on its own: after a fix, ask the user to run the analysis again, then call the tool again.
Example prompts
Section titled “Example prompts”- “Query the logs for ERROR entries in the last hour and explain what happened.”
- “Find the slowest traces from the last 24 hours and name the bottleneck span.”
- “Get the trace
abc123and explain the span hierarchy.” - “Read
loggerhead://statsand summarise what has been collected.” - “Call
get_receiver_infoand set OTEL_EXPORTER_OTLP_ENDPOINT to the gRPC address.” - “Call
query_improvementswith impact high, fix the first finding in this project, then call it again to confirm the finding is gone.” - “Call
list_environments, then query the staging logs for ERROR entries in the last hour.” - “Call
list_lint_ruleswith kind noisy_logs and explain why this finding fired against the threshold.” - “The broken_metric finding for
pool.wait_countis 0 because no request waits. Add an exception for that metric with a reason.” - “Call
query_ai_findings, check each finding against the logs and traces, and fix the real ones.”