A

Axiom

verifiedfeatured

by Axiom · HTTP

Axiom by Axiom — connect via http to access its tools through your RouterMCP gateway.

Documentation
TOOLS
17
available on this server
TRANSPORT
HTTP
SSE fallback
AUTH
Varies
depends on server or gateway configuration
REGION
Global
multi-region ready
STATUS
Active
accepting connections

Overview

ATTACHREADY
routermcp.jsonjson
{
"mcpServers": {
"axiom": {
"url": "https://mcp.axiom.co/mcp",
"type": "http"
}
},
"requiresAuth": true,
"requiresOAuth": true
}

Tools (17)

listDatasets

List all available datasets. The "kind" column determines which tools to use next: - events / otel.traces / other: use queryDataset() (APL) and getDatasetFields() - otel-metrics-v1: use listMetrics(), queryMetrics(), searchMetrics(), listMetricTags(), getMetricTagValues() — do NOT use queryDataset() or getDatasetFields() for these

schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
}

getDatasetFields

List all fields in an events or traces dataset (kind `events`, `otel.traces`, etc.). For metrics datasets (kind `otel-metrics-v1`), use `listMetrics()` and `listMetricTags()` instead — field schemas are not meaningful for that dataset type.

schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"datasetName"
],
"properties": {
"datasetName": {
"type": "string",
"minLength": 1,
"description": "The dataset name. You can find an list of datasets using the `listDatasets()` tool."
}
},
"additionalProperties": false
}

queryDataset

# Instructions 1. Query Axiom datasets using Axiom Processing Language (APL). The query must be a valid APL query string. **Only use this for `events`, `otel.traces`, and similar datasets. Do NOT use for `otel-metrics-v1` datasets — use `queryMetrics()` instead.** 2. ALWAYS understand schema before substantive queries—do not guess column names or types. Prefer `getDatasetFields()` or APL `| where _time > ago(5m) | getschema` on a narrow window (use dataset names from `listDatasets`); use `take 1` or project specific columns for sample values. Before you `where` or `summarize` by a field, estimate cardinality on recent data: `| where _time > ago(5m) | summarize count() by <field> | top 10 by count_`. Avoid `project *` or projecting all fields on very wide datasets unless deliberately mapping shape (see item 5). Skipping probes causes wrong field names, bad types, and expensive re-runs. 3. Keep in mind that there's a maximum row limit of 65000 rows per query. 4. Prefer aggregations over non aggregating queries when possible to reduce the amount of data returned. 5. Be selective in what you project in each query (unless otherwise needed, like for discovering the schema). It's expensive to project all fields. 6. ALWAYS restrict `startTime`/`endTime` to the narrowest window that answers the question—every query scans data and consumes resources. Prefer the smallest APL per step; widen time or complexity only after probing (item 2). 7. When filtering for a specific term or value, put it on the right field—use `has`/`has_cs`/`contains` there after item 2. See **Avoid `search`** under Query performance rules. 8. **`map[string]` columns (e.g. `attributes`, `attributes.custom`, `resource` in OTel-style data)** — `getDatasetFields` and in-query `getschema` show the type but **not** the keys inside the map. You must **sample** (`take`, `project` the map column, or `mv-expand` + `summarize` to list keys) to learn the structure, then use bracket access (e.g. `['attributes']['http.method']`, `['attributes.custom']['http.response.status_code']`). Do not assume key names across services or SDK versions. ### Query performance rules 1. **Narrow `startTime`/`endTime`** — These bound how much data is scanned. Do not rely on in-query `_time` filters alone; keep the API window as tight as your question allows. 2. **`_time` first in APL** — When you filter on `_time` in the query text, put `where _time between (...)` before other filters. This keeps extra in-query narrowing fast. 3. **Most selective `where` first** — Axiom does not reorder predicates; put the filter that removes the most rows earliest. 4. **`project` early and narrowly** — Avoid pulling all columns from very wide datasets (expensive payloads; risk of failures on huge rows). 5. **Prefer fast string ops** — Use `_cs` (case-sensitive) variants when possible; prefer `startswith`/`endswith` over `contains` when applicable; `matches regex` only as a last resort. 6. **Use `has`/`has_cs` for unique-looking strings** — IDs, UUIDs, trace IDs, error codes, session tokens. `has` leverages full-text indexes when available and is much faster than `contains` for high-entropy terms. Use `contains` only when you need true substring matching (e.g., partial paths). 7. **Duration literals** — e.g. `duration > 10s`, not manual conversion. 8. **Avoid search** — scans ALL fields. Use `has`/`has_cs`/`contains` on specific fields. 9. **Avoid heavy `parse_json()` in hot paths** — Filter/narrow first when possible. 10. **Avoid pack(*)** — creates dict of ALL fields per row. Use pack with named fields only. 11. Limit results—use take 10 or top 20 instead of default 1000 when exploring. 12. **Field quoting**—quote identifiers with dots/dashes/spaces: ['geo.country']. For map field keys, use index notation: ['attributes.custom']['http.protocol']. # Examples Basic: - Filter: ['logs'] | where ['severity'] == "error" or ['duration'] > 500ms - Time range: ['logs'] | where ['_time'] > ago(2h) and ['_time'] < now() - Project rename: ['logs'] | project-rename responseTime=['duration'], path=['url'] Aggregations: - Count by: ['logs'] | summarize count() by bin(['_time'], 5m), ['status'] - Multiple aggs: ['logs'] | summarize count(), avg(['duration']), max(['duration']), p95=percentile(['duration'], 95) by ['endpoint'] - Dimensional: ['logs'] | summarize dimensional_analysis(['isError'], pack_array(['endpoint'], ['status'])) - Histograms: ['logs'] | summarize histogram(['responseTime'], 100) by ['endpoint'] - Distinct: ['logs'] | summarize dcount(['userId']) by bin_auto(['_time']) Text matching & Parse: - Match on known fields (avoid full-row `search`): ['logs'] | where ['message'] has_cs "error" or ['message'] has_cs "exception" - Parse logs: ['logs'] | parse-kv ['message'] as (duration:long, error:string) with (pair_delimiter=",") - Regex extract: ['logs'] | extend errorCode = extract("error code ([0-9]+)", 1, ['message']) - Contains ops: ['logs'] | where ['message'] contains_cs "ERROR" or ['message'] startswith "FATAL" Data Shaping: - Extend & Calculate: ['logs'] | extend duration_s = ['duration']/1000, success = ['status'] < 400 - Dynamic: ['logs'] | extend props = parse_json(['properties']) | where ['props.level'] == "error" - Pack/Unpack: ['logs'] | extend fields = pack("status", ['status'], "duration", ['duration']) - Arrays: ['logs'] | where ['url'] in ("login", "logout", "home") | where array_length(['tags']) > 0 Advanced: - Union: union ['logs-app*'] | where ['severity'] == "error" - Case: ['logs'] | extend level = case(['status'] >= 500, "error", ['status'] >= 400, "warn", "info") Time Operations: - Bin & Range: ['logs'] | where ['_time'] between(datetime(2024-01-01)..now()) - Multiple time bins: ['logs'] | summarize count() by bin(['_time'], 1h), bin(['_time'], 1d) - Time shifts: ['logs'] | extend prev_hour = ['_time'] - 1h String Operations: - String funcs: ['logs'] | extend domain = tolower(extract("://([^/]+)", 1, ['url'])) - Concat: ['logs'] | extend full_msg = strcat(['level'], ": ", ['message']) - Replace: ['logs'] | extend clean_msg = replace_regex("(password=)[^&]*", "\1***", ['message']) Common Patterns: - Error analysis: ['logs'] | where ['severity'] == "error" | summarize error_count=count() by ['error_code'], ['service'] - Status codes: ['logs'] | summarize requests=count() by ['status'], bin_auto(['_time']) | where ['status'] >= 500 - Latency tracking: ['logs'] | summarize p50=percentile(['duration'], 50), p90=percentile(['duration'], 90) by ['endpoint'] - User activity: ['logs'] | summarize user_actions=count() by ['userId'], ['action'], bin(['_time'], 1h)

schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"apl"
],
"properties": {
"apl": {
"type": "string",
"description": "The APL query to execute"
},
"endTime": {
"type": "string",
"default": "now",
"description": "End time for the query range. A fixed (RFC3339) or relative (now, now-5m) time value. Defaults to \"now\"."
},
"startTime": {
"type": "string",
"default": "now-30m",
"description": "Start time for the query range. A fixed (RFC3339) or relative (now, now-5m) time value. Defaults to \"now-30m\"."
}
},
"additionalProperties": false
}

getSavedQueries

Retrieve saved/starred queries from Axiom - shows APL queries that users have bookmarked for reuse

schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
}

listDashboards

List all available dashboards. Shows user-created dashboards with their metadata.

schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
}

getDashboard

Get detailed information about a specific dashboard by UID.

schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"dashboardId"
],
"properties": {
"dashboardId": {
"type": "string",
"description": "The dashboard UID. You can find a list of dashboards using the `listDashboards()` tool."
}
},
"additionalProperties": false
}

exportDashboard

Export a dashboard as JSON by its UID. Returns the full dashboard document that can be used to create or update dashboards via the API.

schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"dashboardUid"
],
"properties": {
"dashboardUid": {
"type": "string",
"description": "The dashboard UID (stable external identifier). You can find UIDs using the `listDashboards()` tool."
}
},
"additionalProperties": false
}

createDashboard

Create a new dashboard from a JSON document. The dashboard JSON must include required fields: name, owner, charts, layout, refreshTime, schemaVersion (2), timeWindowStart, timeWindowEnd. Set owner to "X-AXIOM-EVERYONE" to make it visible to all org members.

schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"dashboardJson"
],
"properties": {
"uid": {
"type": "string",
"description": "Optional custom UID for the dashboard. If omitted, the server generates one."
},
"message": {
"type": "string",
"description": "Optional audit/change note for this operation."
},
"dashboardJson": {
"type": "string",
"minLength": 1,
"description": "The full dashboard document as a JSON string. Must include required fields: name, owner, charts (array), layout (array), refreshTime (15, 60, or 300), schemaVersion (2), timeWindowStart, timeWindowEnd."
}
},
"additionalProperties": false
}

updateDashboard

Update an existing dashboard by UID. Provide the full dashboard JSON document. Use overwrite=true to skip version conflict checks (last-write-wins), or provide the current version number for optimistic concurrency control.

schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"dashboardUid",
"dashboardJson"
],
"properties": {
"message": {
"type": "string",
"description": "Optional audit/change note for this operation."
},
"version": {
"type": "number",
"description": "The current dashboard version number. Required when overwrite is false. Get this from exportDashboard()."
},
"overwrite": {
"type": "boolean",
"default": true,
"description": "When true (default), bypasses version checks and applies last-write-wins. When false, the version parameter is required."
},
"dashboardUid": {
"type": "string",
"description": "The dashboard UID (stable external identifier). You can find UIDs using the `listDashboards()` tool."
},
"dashboardJson": {
"type": "string",
"minLength": 1,
"description": "The full dashboard document as a JSON string. Must include required fields: name, owner, charts (array), layout (array), refreshTime (15, 60, or 300), schemaVersion (2), timeWindowStart, timeWindowEnd."
}
},
"additionalProperties": false
}

deleteDashboard

Delete a dashboard by its UID. This action is irreversible.

schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"dashboardUid"
],
"properties": {
"dashboardUid": {
"type": "string",
"description": "The dashboard UID (stable external identifier). You can find UIDs using the `listDashboards()` tool."
}
},
"additionalProperties": false
}

getMonitorHistory

Get recent check history of monitor. Use the checkMonitors() tool to list all the monitors.

schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"monitorId"
],
"properties": {
"monitorId": {
"type": "string",
"description": "The monitor ID. You can find an list of monitors using the `checkMonitors()` tool."
}
},
"additionalProperties": false
}

checkMonitors

Check all monitors and their statuses.

schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
}

queryMetrics

# Instructions 1. Query OpenTelemetry metrics stored in Axiom using MPL (Metrics Processing Language). NOT APL. 2. The query targets a metrics dataset (kind "otel-metrics-v1"). 3. Use listMetrics() to discover available metric names in a dataset before querying. 4. Use listMetricTags() and getMetricTagValues() to discover filtering dimensions. 5. ALWAYS restrict the time range to the smallest possible range that meets your needs. 6. NEVER guess metric names or tag values. Always discover them first. # MPL Query Syntax A query has three parts: source, filtering, and transformation. Filters must appear before transformations. ## Source ``` <dataset>:<metric> ``` Backtick-escape identifiers containing special characters: ``my-dataset``:``http.server.duration`` ## Filtering (where) Chain filters with `|`. Use `where` (not `filter`, which is deprecated). ``` | where <tag> <op> <value> ``` Operators: ==, !=, >, <, >=, <= Values: "string", 42, 42.0, true, /regexp/ Combine with: and, or, not, parentheses ## Transformations ### Aggregation (align) — aggregate data over time windows ``` | align to <interval> using <function> ``` Functions: avg, sum, min, max, count, last Intervals: 5m, 1h, 1d, etc. ### Grouping (group) — group series by tags ``` | group by <tag1>, <tag2> using <function> ``` Functions: avg, sum, min, max, count Without `by`: combines all series: `| group using sum` ### Mapping (map) — transform values in place ``` | map rate // per-second rate of change | map increase // increase between datapoints | map + 5 // arithmetic: +, -, *, / | map abs // absolute value | map fill::prev // fill gaps with previous value | map fill::const(0) // fill gaps with constant | map filter::lt(0.4) // remove datapoints >= 0.4 | map filter::gt(100) // remove datapoints <= 100 | map is::gte(0.5) // set to 1.0 if >= 0.5, else 0.0 ``` ### Computation (compute) — combine two metrics ``` ( `dataset`:`errors_total` | group using sum, `dataset`:`requests_total` | group using sum; ) | compute error_rate using / ``` Functions: +, -, *, /, min, max, avg ### Bucketing (bucket) — for histograms ``` | bucket by method, path to 5m using histogram(count, 0.5, 0.9, 0.99) | bucket by method to 5m using interpolate_delta_histogram(0.90, 0.99) | bucket by method to 5m using interpolate_cumulative_histogram(rate, 0.90, 0.99) ``` ### Prometheus compatibility ``` | align to 5m using prom::rate // Prometheus-style rate ``` ## Identifiers Use backticks for names with special characters: ``my-dataset``, ``service.name``, ``http.request.duration`` # Examples Basic query: `my-metrics`:`http.server.duration` | align to 5m using avg Filtered: `my-metrics`:`http.server.duration` | where `service.name` == "frontend" | align to 5m using avg Grouped: `my-metrics`:`http.server.duration` | align to 5m using avg | group by endpoint using sum Rate: `my-metrics`:`http.requests.total` | align to 5m using prom::rate | group by method, path, code using sum Error rate (compute): ( `my-metrics`:`http.requests.total` | where code >= 400 | group by method, path using sum, `my-metrics`:`http.requests.total` | group by method, path using sum; ) | compute error_rate using / | align to 5m using avg SLI (error budget): ( `my-metrics`:`http.requests.total` | where code >= 500 | align to 1h using prom::rate | group using sum, `my-metrics`:`http.requests.total` | align to 1h using prom::rate | group using sum; ) | compute error_rate using / | map is::lt(0.2) | align to 7d using avg Histogram percentiles: `my-metrics`:`http.request.duration.seconds.bucket` | bucket by method, path to 5m using interpolate_delta_histogram(0.90, 0.99) Fill gaps: `my-metrics`:`cpu.usage` | map fill::prev | align to 1m using avg

schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"mpl",
"datasetName"
],
"properties": {
"mpl": {
"type": "string",
"minLength": 1,
"description": "The metrics query string. Format: <dataset>:<metric> | <operations>"
},
"endTime": {
"type": "string",
"default": "now",
"description": "End time for the query range. A fixed (RFC3339) or relative (now, now-5m) time value. Defaults to \"now\"."
},
"startTime": {
"type": "string",
"default": "now-30m",
"description": "Start time for the query range. A fixed (RFC3339) or relative (now, now-5m) time value. Defaults to \"now-30m\"."
},
"datasetName": {
"type": "string",
"minLength": 1,
"description": "The dataset name. You can find an list of datasets using the `listDatasets()` tool."
}
},
"additionalProperties": false
}

listMetrics

List all available metrics in a metrics dataset (kind "otel-metrics-v1"). Use this to discover metric names before querying.

schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"datasetName"
],
"properties": {
"endTime": {
"type": "string",
"default": "now",
"description": "End time for the query range. A fixed (RFC3339) or relative (now, now-5m) time value. Defaults to \"now\"."
},
"startTime": {
"type": "string",
"default": "now-30m",
"description": "Start time for the query range. A fixed (RFC3339) or relative (now, now-5m) time value. Defaults to \"now-30m\"."
},
"datasetName": {
"type": "string",
"minLength": 1,
"description": "The dataset name. You can find an list of datasets using the `listDatasets()` tool."
}
},
"additionalProperties": false
}

listMetricTags

List all available tags (dimensions) in a metrics dataset (kind `otel-metrics-v1`). Tags can be used to filter and group metrics queries.

schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"datasetName"
],
"properties": {
"endTime": {
"type": "string",
"default": "now",
"description": "End time for the query range. A fixed (RFC3339) or relative (now, now-5m) time value. Defaults to \"now\"."
},
"startTime": {
"type": "string",
"default": "now-30m",
"description": "Start time for the query range. A fixed (RFC3339) or relative (now, now-5m) time value. Defaults to \"now-30m\"."
},
"datasetName": {
"type": "string",
"minLength": 1,
"description": "The dataset name. You can find an list of datasets using the `listDatasets()` tool."
}
},
"additionalProperties": false
}

searchMetrics

Start here when the user mentions a specific service, host, or entity name and you need to work with metrics data. Searches tag values across all metrics in a dataset and returns the metric names that are associated with the given entity. This is the fastest way to go from a known entity name (e.g. "checkout-service", "api-gateway", "us-east-1") to a concrete list of metric names you can actually query. Returns a map of metric name → list of matched tag dimensions, e.g.: { "http.server.duration": ["service.name"], "http.requests.total": ["service.name", "host"] } **Time range:** Use a window of at least 3 hours. Recently-ingested data can take up to 2 hours to become searchable here, so narrow windows may return empty results even when data exists. For recent data, default to `now-3h` / `now`. For historical data, use whatever window covers the period you care about — e.g. `now-14d` / `now-7d` is valid. **Workflow:** 1. Call this tool with the entity name to get relevant metric names. 2. Use listMetricTags() / getMetricTagValues() to discover filter dimensions for those metrics. 3. Call queryMetrics() with an MPL query targeting the specific metric and filters. Use listMetrics() instead when you have no entity name to search by and need a full catalogue of what's in the dataset.

schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"datasetName",
"value"
],
"properties": {
"value": {
"type": "string",
"minLength": 1,
"description": "The entity name to search for across all tag values (e.g. a service name \"checkout-service\", a host \"prod-worker-1\", a region \"us-east-1\"). The search matches this exact string against tag values — use the canonical name as it appears in your infrastructure."
},
"endTime": {
"type": "string",
"default": "now",
"description": "End time for the query range. A fixed (RFC3339) or relative (now, now-5m) time value. Defaults to \"now\"."
},
"startTime": {
"type": "string",
"default": "now-30m",
"description": "Start time for the query range. A fixed (RFC3339) or relative (now, now-5m) time value. Defaults to \"now-30m\"."
},
"datasetName": {
"type": "string",
"minLength": 1,
"description": "The dataset name. You can find an list of datasets using the `listDatasets()` tool."
}
},
"additionalProperties": false
}

getMetricTagValues

List all values for a specific tag in a metrics dataset (kind `otel-metrics-v1`). Useful for discovering filter values before querying.

schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"datasetName",
"tag"
],
"properties": {
"tag": {
"type": "string",
"minLength": 1,
"description": "The tag name to list values for."
},
"endTime": {
"type": "string",
"default": "now",
"description": "End time for the query range. A fixed (RFC3339) or relative (now, now-5m) time value. Defaults to \"now\"."
},
"startTime": {
"type": "string",
"default": "now-30m",
"description": "Start time for the query range. A fixed (RFC3339) or relative (now, now-5m) time value. Defaults to \"now-30m\"."
},
"datasetName": {
"type": "string",
"minLength": 1,
"description": "The dataset name. You can find an list of datasets using the `listDatasets()` tool."
}
},
"additionalProperties": false
}