---
canonical_url: "https://docs.composio.dev/toolkits/better_stack_mcp"
markdown_url: "https://docs.composio.dev/toolkits/better_stack_mcp.md"
product: "platform"
version: null
last_updated: null
---

# Better Stack MCP

Investigate Better Stack observability data, monitors, incidents, and logs.

- **Category:** server monitoring
- **Auth:** DCR_OAUTH
- **Composio-managed OAuth available?** No
- **Tools:** 116
- **Triggers:** 0
- **Slug:** `BETTER_STACK_MCP`
- **Version:** 20260910_00

## Tools

### Acknowledge incident

**Slug:** `BETTER_STACK_MCP_ACKNOWLEDGE_INCIDENT`

Acknowledge an ongoing incident

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the incident to acknowledge |
| `acknowledged_by` | string | No | User email or identifier of who acknowledged the incident. Optional - when omitted, the action is attributed to the authenticated OAuth user (or "API" for team/organisation API tokens). Only pass this if the user has explicitly told you who acknowledged the incident on their behalf. |

### Add chart to dashboard

**Slug:** `BETTER_STACK_MCP_ADD_CHART_TO_DASHBOARD`

Add a new chart to a dashboard. Use the `section` parameter to organize charts into named sections — sections are auto-created if they don't exist, and charts are auto-positioned within them.

**REQUIRED**: the `query`'s FROM must reference a source, either `{{source}}` or a source-type variable defined via `set_dashboard_variable` (e.g. `{{redis_source}}`). A query with no source is rejected with guidance to define it first.

Dashboard chart queries run against the metrics collection: use `sum(logs_count)` (or the matching `sum(<row_type>_count)` for the source), `avgMerge(value_avg)`, `label('tag')`. Do NOT use `JSONExtract(raw, …)` — that is for live-tail charts and `query` only; dashboards have no `raw` column. Call `metrics_query_help` with the source ID **and `context: 'chart_query'`** for available metrics/labels and chart-query-style examples.

**Workflow:**
1. Call `chart_building_help` for chart types, units, and settings.
2. Call `metrics_query_help` with `context: 'chart_query'` to see the source's metrics schema and chart-query examples.
3. Verify the query with `render_chart` (runs it and surfaces errors automatically) or with `query`.

Use `{{source}}`, `{{start_time}}`, `{{end_time}}`, `{{time}}` variables for integration with dashboard filters. Queries can also reference custom dashboard variables — `{{var}}` (required) or `[[ AND col = {{var}} ]]` (optional clause, dropped while the variable is empty); define them with `set_dashboard_variable`.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | Yes | Name/title for the chart |
| `query` | string | Yes | SQL query. Its FROM must reference a source: {{source}}, or a source-type variable defined via set_dashboard_variable (e.g. {{redis_source}}); hardcoded collection names are rejected. Use {{start_time}}/{{end_time}} in the time filter and {{time}} for bucketing. Dashboard charts query the metrics collection (use sum(logs_count) / sum(spans_count) / sum(exceptions_count) / sum(replays_count) / sum(web_events_count) / sum(metrics_count) for type-specific counts, avgMerge(value_avg), label('tag')); JSONExtract(raw, …) only works in live-tail charts. |
| `width` | integer | No | Chart width in grid units (1-12, default: 6) |
| `height` | integer | No | Chart height in grid units (default: 8) |
| `section` | string | No | Section name — chart is auto-placed within it. Section auto-created if it doesn't exist. |
| `settings` | object | No | Chart display settings. Which keys apply depends on chart_type: call `chart_building_help` for the per-type reference, possible values, and gotchas. |
| `chart_type` | string ("line_chart" | "bar_chart" | "number_chart" | "table_chart" | "pie_chart" | "heatmap_chart" | "scatter_chart" | "gauge_chart" | "map_chart" | "hierarchy_chart" | "static_text_chart") | Yes | Type of chart to create |
| `explanation` | string | No | Short description of the chart. |
| `dashboard_id` | integer | Yes | The ID of the dashboard to add the chart to |

### Add dashboard section

**Slug:** `BETTER_STACK_MCP_ADD_DASHBOARD_SECTION`

Add a section divider to a dashboard. Sections span the full width and help organize charts into groups. Charts and sections at or below the insertion point are shifted down to make room

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `y` | integer | Yes | Y position (row) where section should appear |
| `name` | string | Yes | Section title (e.g., 'Memory Metrics', 'Network') |
| `explanation` | string | No | Short description of the section, shown as a tooltip next to section name in the UI. Use rarely, when wanting to show more context for non-obvious sections. |
| `dashboard_id` | integer | Yes | The ID of the dashboard |

### Application

**Slug:** `BETTER_STACK_MCP_APPLICATION`

Get comprehensive details of a specific application including its configuration, retention settings, ingestion details, custom bucket settings (if configured)

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the application |

### Applications

**Slug:** `BETTER_STACK_MCP_APPLICATIONS`

List all available applications in a paginated table format. Returns application ID, name, platform type, team, status (active/paused), data region, and creation date

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | No | Filter applications by name (case-insensitive partial match) |
| `page` | integer | No | Page number for pagination (starts at 1) |
| `team_id` | integer | No | Filter applications by team ID (use teams to get team IDs) |
| `per_page` | integer | No | Number of results per page (default: 50, max: 250) |

### Available incident escalation policies

**Slug:** `BETTER_STACK_MCP_AVAILABLE_INCIDENT_ESCALATION_POLICIES`

Get available escalation policies for an incident

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the incident |
| `type` | string | No | Filter by escalation type. Possible values: user, team, policy, schedule, organisation |
| `search` | string | No | Filter options by text (searches in names, emails, and other text fields) |

### Change team member role

**Slug:** `BETTER_STACK_MCP_CHANGE_TEAM_MEMBER_ROLE`

Change a team member's role. Identify the member by `email` or `user_id`
(from team_members) and pass the target `role_id` (from team_roles). The
admin role cannot be assigned, and an existing admin's role cannot be changed,
via the API. Pending invitations can't have their role changed — cancel and
re-invite instead. If the token can reach more than one team, pass `team_id`
(or `team_name`).


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `email` | string | No | E-mail of the member whose role to change (alternative to user_id). |
| `role_id` | integer | Yes | ID of the role to assign (use team_roles to look up ids). |
| `team_id` | integer | No | ID of the team the member belongs to. Required when the token can access more than one team. |
| `user_id` | integer | No | ID of the member whose role to change (alternative to email). |
| `team_name` | string | No | Name of the team (alternative to team_id). |

### Chart

**Slug:** `BETTER_STACK_MCP_CHART`

Get detailed information about a specific chart including its SQL queries, configuration, and settings. Use dashboard first to find the chart ID

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the chart to retrieve |

### Chart alert

**Slug:** `BETTER_STACK_MCP_CHART_ALERT`

Get detailed information about a specific chart alert including its configuration, SQL queries, status, and current incident info. Use chart_alerts first to find the alert ID

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the chart alert to retrieve |

### Chart alert help

**Slug:** `BETTER_STACK_MCP_CHART_ALERT_HELP`

Get instructions for creating and configuring chart alerts, including alert types, operators, configuration fields, supported chart types, and common mistakes. Call this before creating or editing chart alerts

### Chart alerts

**Slug:** `BETTER_STACK_MCP_CHART_ALERTS`

List chart alerts with optional filtering by team, chart, or dashboard. Returns alert ID, name, type, chart, dashboard, and status

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number for pagination (default: 1, 25 per page) |
| `team_id` | integer | No | Filter alerts by team ID (use teams to get team IDs) |
| `chart_id` | integer | No | Filter to alerts on a specific chart |
| `dashboard_id` | integer | No | Filter to alerts on charts in a specific dashboard |

### Chart building help

**Slug:** `BETTER_STACK_MCP_CHART_BUILDING_HELP`

Get comprehensive instructions for building charts and dashboards, including chart types, units, axis settings, column mapping, legend placement, layout tips, and common mistakes. Call this before creating or editing charts

### Clusters

**Slug:** `BETTER_STACK_MCP_CLUSTERS`

List all available storage clusters for a specific team. Returns a table with cluster IDs, names, and regions. Used primarily for creating cloud connections to query logs and metrics data directly via ClickHouse

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `team_id` | integer | Yes | The ID of the team (use teams to get team IDs) |

### Create application

**Slug:** `BETTER_STACK_MCP_CREATE_APPLICATION`

Create a new application in Better Stack. Returns the created application details including ID, ingestion token, ingesting host URL, retention settings, and platform-specific integration documentation links with next steps for configuration

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | Yes | The name of the application |
| `team_id` | integer | Yes | The ID of the team to create the application in (use teams to get team IDs) |
| `platform` | string ("dot_net_errors" | "dot_net_maui_errors" | "dot_net_http_errors" | "aiohttp_errors" | "asgi_errors" | "asp_dot_net_errors" | "asp_dot_net_core_errors" | "aws_lambda_dot_net_errors" | "aws_lambda_node_errors" | "aws_lambda_python_errors" | "android_errors" | "angular_errors" | "astro_errors" | "azure_functions_node_errors" | "bottle_errors" | "javascript_errors" | "bun_errors" | "cli_errors" | "celery_errors" | "chalice_errors" | "cloudflare_pages_errors" | "connect_errors" | "dart_errors" | "deno_errors" | "django_errors" | "echo_errors" | "electron_errors" | "elixir_errors" | "ember_errors" | "express_errors" | "fasthttp_errors" | "falcon_errors" | "fastapi_errors" | "fastify_errors" | "fiber_errors" | "flask_errors" | "flutter_errors" | "go_errors" | "gatsby_errors" | "gin_errors" | "godot_errors" | "google_cloud_function_dot_net_errors" | "google_cloud_function_node_errors" | "google_cloud_function_python_errors" | "hapi_errors" | "iris_errors" | "java_errors" | "koa_errors" | "kotlin_errors" | "laravel_errors" | "log4j_errors" | "logback_errors" | "minidump_errors" | "native_errors" | "negroni_errors" | "nest_js_errors" | "next_js_errors" | "node_errors" | "nuxt_errors" | "php_errors" | "powershell_errors" | "pyramid_errors" | "python_errors" | "qt_errors" | "quart_errors" | "rq_errors" | "rack_middleware_errors" | "rails_errors" | "react_errors" | "react_native_errors" | "react_router_framework_errors" | "remix_errors" | "ruby_errors" | "rust_errors" | "sanic_errors" | "serverless_python_errors" | "solid_errors" | "solidstart_errors" | "spring_errors" | "spring_boot_errors" | "starlette_errors" | "svelte_errors" | "sveltekit_errors" | "symfony_errors" | "tanstack_start_react_errors" | "tornado_errors" | "tryton_errors" | "unity_errors" | "unreal_engine_errors" | "vue_errors" | "wpf_errors" | "wsgi_errors" | "windows_forms_errors" | "ios_errors" | "macos_errors") | Yes | The platform of the application |
| `data_region` | string | No | The data region for the application. Use 'data_regions' tool to see available options for your organization. Common values for most plans: us_east, germany, singapore. Ask the user if unsure. |
| `ingesting_paused` | boolean | No | Whether to start with ingesting paused (default: false) |

### Create chart alert

**Slug:** `BETTER_STACK_MCP_CREATE_CHART_ALERT`

Create a new chart alert on an existing chart. The chart must support alerts (line_chart, bar_chart, number_chart, or tail_chart with time variables). Call chart_alert_help for configuration reference. Use chart or dashboard first to find the chart ID

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sms` | boolean | No | SMS notifications (default: false) |
| `call` | boolean | No | Phone notifications (default: false) |
| `name` | string | Yes | Name of the alert |
| `push` | boolean | No | Push notifications (default: false) |
| `email` | boolean | No | Email notifications (default: true) |
| `value` | number | No | Threshold value (required for threshold/relative types). For relative type, this is a percentage (e.g., 50 means 50%) |
| `chart_id` | integer | Yes | The ID of the chart to add the alert to |
| `operator` | string ("equal" | "higher_than" | "higher_than_or_equal" | "lower_than" | "lower_than_or_equal" | "increases_by" | "decreases_by" | "changes_by") | Yes | Comparison operator. For relative type also: increases_by, decreases_by, changes_by |
| `alert_type` | string ("threshold" | "relative" | "anomaly_rrcf") | Yes | Alert type: 'threshold' (fixed value), 'relative' (percentage change), 'anomaly_rrcf' (ML-based anomaly detection) |
| `check_period` | integer ("30" | "60" | "120" | "300" | "600" | "1800" | "3600" | "7200" | "10800" | "21600" | "43200" | "86400") | No | How often to run the alert check (seconds). Max 3600 for query-period-based alerts |
| `query_period` | integer ("30" | "60" | "120" | "300" | "600" | "1800" | "3600") | No | Seconds to look back for relative alerts and tail/table charts |
| `series_names` | array | No | Specific series to monitor. Empty = all series. Mutually exclusive with series_names_except |
| `shown_interval` | integer ("30" | "60" | "120" | "300" | "600" | "1800" | "3600" | "7200" | "10800" | "21600" | "43200" | "86400") | No | Anomaly chart aggregation interval (seconds). Only for anomaly_rrcf alerts |
| `anomaly_trigger` | string ("any" | "higher" | "lower") | No | Anomaly trigger direction: 'any' (default), 'higher', 'lower'. Only for anomaly_rrcf alerts |
| `recovery_period` | string ("0" | "30" | "60" | "120" | "300" | "600" | "1800" | "3600" | "7200" | "14400") | No | How long the condition must be resolved before auto-resolving (seconds, default: 60). null means never auto-resolve; the incident stays open until resolved manually |
| `escalation_target` | string | No | 'current_team' (default) or a GID like gid://uptime/Policy/123 or gid://uptime/Team/456 |
| `anomaly_sensitivity` | integer | No | Anomaly significance threshold (1-10, default 5), shown as 'Significance' in the UI. Higher = larger deviation required to fire, so FEWER alerts; lower = more sensitive, more alerts. Only for anomaly_rrcf alerts |
| `confirmation_period` | integer ("0" | "30" | "60" | "120" | "300" | "600" | "1800" | "3600" | "7200" | "14400") | No | How long the condition must persist before creating an incident (seconds, default: 60) |
| `series_names_except` | array | No | Series to exclude; alert fires on every other series. Mutually exclusive with series_names |
| `aggregation_interval` | integer ("30" | "60" | "120" | "300" | "600" | "1800" | "3600" | "7200" | "10800" | "21600" | "43200" | "86400") | No | Data range for threshold alerts on line/bar/number charts ('on data from' in UI, default: 60s) |
| `anomaly_training_range_days` | integer | No | How many days of data the anomaly model is first trained on (1-30, default 7), shown as 'Initial training data range' in the UI. A full week (7) captures daily and weekly pattern shifts. Only for anomaly_rrcf alerts |

### Create cloud connection

**Slug:** `BETTER_STACK_MCP_CREATE_CLOUD_CONNECTION`

Create a secure cloud connection for direct ClickHouse query access to logs, spans, and metrics data. Returns connection credentials (host, port, username, password), sample queries for each data type, and cURL command examples. Connections expire after 1 hour by default

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `note` | string | No | Optional note for the connection |
| `team_id` | integer | Yes | The ID of the team (use teams to get team IDs) |
| `source_id` | integer | No | The ID of the source (required, when cluster_id is empty) |
| `cluster_id` | integer | No | The ID of the cluster to use (required, when source_id is empty) |

### Create dashboard

**Slug:** `BETTER_STACK_MCP_CREATE_DASHBOARD`

Create a new dashboard. Optionally use a template to start with pre-configured charts. Call chart_building_help for guidance on dashboard structure and layout. Optionally specify a source_id to preconfigure the dashboard with that source. Returns the new dashboard ID which can be used with add_chart_to_dashboard to add charts

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | Yes | Name for the new dashboard |
| `team_id` | integer | Yes | The ID of the team to create the dashboard in (use teams to get team IDs) |
| `source_id` | integer | No | Optional source ID to preconfigure dashboard with that source's metrics |
| `template_id` | integer | No | Optional template ID to create dashboard from (use dashboard_templates to see available templates) |
| `resource_group_name` | string | No | Optional resource group name to place the dashboard in. If a group with this name already exists for the team it will be reused; otherwise a new group is created. |

### Create error issue

**Slug:** `BETTER_STACK_MCP_CREATE_ERROR_ISSUE`

Create an issue for an error in Linear, or a work item in Jira, through the team's integration and link the two. The issue gets Better Stack's standard body (error type, message, call site, stack trace, occurrence counts and a link back) and the integration's configured defaults for team or space, work type, assignee, labels and priority. Better Stack then posts every change to the error state as a comment on the issue. An error that already has an issue through the integration is reported, not duplicated; use link_error_issue to attach an issue that already exists.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `notes` | string | No | Extra context for whoever picks the issue up, placed above the standard error details in the issue body |
| `title` | string | No | Issue title. Defaults to Better Stack's standard one: [application] error type: message |
| `pattern` | string | Yes | The error pattern identifier |
| `application_id` | integer | Yes | The ID of the application |
| `integration_id` | integer | No | The Better Stack integration to create the issue through. Only needed when the team has more than one Linear or Jira integration, in which case this tool answers with the IDs to choose from. |

### Create heartbeat

**Slug:** `BETTER_STACK_MCP_CREATE_HEARTBEAT`

Create a new heartbeat that expects a periodic request from a cron job, worker, or
other background task, and alerts when that request stops arriving.

Provide a `name` for the heartbeat. The heartbeat reports down once no request is
received within `period` seconds plus the `grace` window. Use the returned heartbeat
URL as the endpoint your job pings on every successful run.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sms` | boolean | No | Send SMS alerts when the heartbeat goes down. |
| `call` | boolean | No | Call the on-call person when the heartbeat goes down. |
| `name` | string | Yes | Human-friendly name for the heartbeat. |
| `push` | boolean | No | Send push notification alerts when the heartbeat goes down. |
| `email` | boolean | No | Send e-mail alerts when the heartbeat goes down. |
| `grace` | integer | No | Extra seconds to wait after the period elapses before reporting the heartbeat as down. Defaults to 300. |
| `paused` | boolean | No | Create the heartbeat in a paused state, so it expects no requests and raises no incidents until resumed. |
| `period` | integer | No | How often you expect a request, in seconds. The heartbeat reports down if no request arrives within this window plus the grace period. Defaults to 86400 (one day). |
| `team_id` | integer | No | The ID of the team to create the heartbeat in (use list_heartbeats to see team IDs). Required only when the API token has access to multiple teams. |
| `policy_id` | integer | No | ID of the escalation policy to use for alerting. |
| `team_wait` | integer | No | Seconds to wait before escalating to the whole team. |
| `sort_index` | integer | No | Position of the heartbeat in the list, set to NULL to sort by creation date. |
| `critical_alert` | boolean | No | Send critical push notifications that ignore the device mute switch and Do Not Disturb. |
| `maintenance_to` | string | No | End of the daily maintenance window (e.g. "03:00:00"). |
| `maintenance_days` | array | No | Days the maintenance window applies to (e.g. ["mon", "tue", "wed"]). |
| `maintenance_from` | string | No | Start of a daily maintenance window during which alerts are paused (e.g. "01:00:00"). |
| `heartbeat_group_id` | integer | No | ID of the heartbeat group to add this heartbeat to. |
| `maintenance_timezone` | string | No | Timezone for the maintenance window (e.g. "UTC", "Europe/Berlin"). Defaults to UTC. |

### Create incident

**Slug:** `BETTER_STACK_MCP_CREATE_INCIDENT`

Create a new incident providing a summary of the issue, requester email, and other optional details


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sms` | boolean | No | Send SMS to on-call person |
| `call` | boolean | No | Call on-call person |
| `name` | string | No | Short incident name |
| `email` | boolean | No | Send email to on-call person |
| `summary` | string | Yes | Brief incident summary |
| `team_id` | integer | Yes | The ID of the team (use teams to get team IDs) |
| `metadata` | object | No | Additional incident key-value metadata |
| `policy_id` | string | No | Escalation policy ID |
| `team_wait` | integer | No | Seconds to wait before escalating to team |
| `description` | string | No | Full incident description |
| `critical_alert` | boolean | No | Send critical push notification |
| `requester_email` | string | No | Email of the incident requester. Optional when authenticated via OAuth - defaults to the OAuth user. Required when using a team or organisation API token. |

### Create incident comment

**Slug:** `BETTER_STACK_MCP_CREATE_INCIDENT_COMMENT`

Create a comment on an incident

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `content` | string | Yes | The content of the comment (Markdown is supported for formatting) |
| `incident_id` | integer | Yes | The ID of the incident to comment on |

### Create metric expression

**Slug:** `BETTER_STACK_MCP_CREATE_METRIC_EXPRESSION`

Create a new metric expression (extract-metrics-from-logs rule) on a source.

`sql_expression` runs against each log row; log fields live inside the `raw` JSON column — use `JSONExtract(raw, 'path', 'Nullable(Type)')`. The `Nullable(...)` wrapper is required. Nested paths use positional args: `JSONExtract(raw, 'request', 'headers', 'user-agent', 'Nullable(String)')`. Call `source_fields` to see what fields exist.

Pass `aggregations` (e.g. `["avg", "count"]`) for an aggregated metric, or omit / pass `[]` for a label (group-by column).

Prefer `build_type: new_data` (default). `historical_logs` re-runs the rule over every stored log — expensive; only when the user explicitly asks.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | Yes | Metric name. Letters, numbers, and underscores only |
| `type` | string ("string" | "string_low_cardinality" | "int64_delta" | "int64" | "uint64_delta" | "uint64" | "float64_delta" | "datetime64_delta" | "boolean") | Yes | ClickHouse storage type for the extracted value |
| `source_id` | integer | Yes | The ID of the source (use sources to get source IDs) |
| `build_type` | string ("new_data" | "historical_logs") | No | How to process existing data: 'new_data' (default, cheap) only applies to new logs; 'historical_logs' rebuilds metrics from existing logs |
| `aggregations` | array | No | Aggregations to compute for this metric (e.g. ['avg', 'count']). Omit or pass [] to store the value as a label (group-by column) instead of an aggregated metric |
| `sql_expression` | string | Yes | ClickHouse SQL expression evaluated against each log row (e.g. "JSONExtractInt(raw, 'status')") |

### Create monitor

**Slug:** `BETTER_STACK_MCP_CREATE_MONITOR`

Create a new monitor that tracks the availability of a website, host, or service.

Provide the `url` to monitor. For ping, TCP, UDP, SMTP, POP, IMAP, and DNS monitors
this is the host (e.g. `example.com`) rather than a full URL. The monitor starts
checking immediately unless `paused` is set to true.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sms` | boolean | No | Send SMS alerts when the monitor goes down. |
| `url` | string | Yes | URL to monitor (e.g. https://example.com). For ping, TCP, UDP, SMTP, POP, IMAP, and DNS monitors, provide the host instead (e.g. example.com). |
| `call` | boolean | No | Call the on-call person when the monitor goes down. |
| `port` | integer | No | Port to check. Used for tcp, udp, smtp, pop, and imap monitors. |
| `push` | boolean | No | Send push notification alerts when the monitor goes down. |
| `email` | boolean | No | Send e-mail alerts when the monitor goes down. |
| `paused` | boolean | No | Create the monitor in a paused state, so it performs no checks until resumed. |
| `regions` | array | No | Regions to check from (e.g. ["us", "eu", "as", "au"]). |
| `team_id` | integer | No | The ID of the team to create the monitor in (use monitors to see team IDs). Required only when the API token has access to multiple teams. |
| `policy_id` | integer | No | ID of the escalation policy to use for alerting. |
| `team_wait` | integer | No | Seconds to wait before escalating to the whole team. |
| `verify_ssl` | boolean | No | Verify the SSL certificate when checking HTTPS URLs. |
| `http_method` | string | No | HTTP method to use for the check (e.g. get, post, head). |
| `monitor_type` | string ("status" | "expected_status_code" | "keyword" | "keyword_absence" | "ping" | "tcp" | "udp" | "smtp" | "pop" | "imap" | "dns" | "playwright") | No | What kind of check to run. Defaults to "status" (HTTP up/down). Use "keyword"/"keyword_absence" to assert a response body keyword, "expected_status_code" to assert specific HTTP codes, and "ping"/"tcp"/"udp"/"smtp"/"pop"/"imap"/"dns" for the matching protocol. |
| `request_body` | string | No | Request body to send with the check. |
| `critical_alert` | boolean | No | Send critical push notifications that ignore the device mute switch and Do Not Disturb. |
| `check_frequency` | integer | No | How often to check the monitor, in seconds (e.g. 30, 180). |
| `recovery_period` | integer | No | Seconds the monitor must stay healthy before a related incident is resolved. |
| `request_headers` | array | No | Custom request headers to send with the check. |
| `request_timeout` | integer | No | How long to wait for a response before the check times out, in seconds. |
| `follow_redirects` | boolean | No | Follow HTTP redirects when checking the monitor. |
| `monitor_group_id` | integer | No | ID of the monitor group to add this monitor to. |
| `required_keyword` | string | No | Keyword to search for in the response body. Required for the keyword and keyword_absence monitor types. |
| `pronounceable_name` | string | No | Human-friendly name for the monitor. Defaults to the URL host. |
| `confirmation_period` | integer | No | Seconds to wait and re-check before confirming the monitor is down. |
| `expected_status_codes` | array | No | HTTP status codes considered healthy. Used with the expected_status_code monitor type. |

### Create release

**Slug:** `BETTER_STACK_MCP_CREATE_RELEASE`

Register a release for an errors application, so it appears the moment it deploys instead of when its first error arrives. Returns the release ID, usable with remove_release

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `version` | string | Yes | Release version or commit ref, e.g. 'v1.2.3' |
| `environments` | array | No | Environments this release was deployed to, e.g. ['production'] |
| `application_id` | integer | Yes | The ID of the errors application to register the release for |

### Create source

**Slug:** `BETTER_STACK_MCP_CREATE_SOURCE`

Create a new log source in Better Stack. Returns the created source details including ID, ingestion token, ingesting host URL, retention settings, and platform-specific integration documentation links with next steps for configuration

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | Yes | The name of the source |
| `team_id` | integer | Yes | The ID of the team to create the source in (use teams to get team IDs) |
| `platform` | string ("apache2" | "datadog_agent" | "docker" | "haproxy" | "kubernetes" | "nginx" | "open_telemetry" | "ubuntu" | "vector" | "vercel_integration" | "dokku" | "fly_io" | "heroku" | "dotnet" | "aws" | "aws_elb" | "aws_fargate" | "aws_cloudwatch" | "aws_ecs" | "azure" | "azure_logs" | "cloudflare_worker" | "cloudflare_logpush" | "erlang" | "fastly" | "filebeat" | "gcp" | "go" | "java" | "javascript" | "php" | "python" | "ruby" | "winlogbeat" | "elasticsearch" | "mongodb" | "mysql" | "postgresql" | "rabbitmq" | "redis" | "traefik" | "google_cloud_pubsub" | "http" | "digitalocean" | "fluentbit" | "fluentd" | "logstash" | "rsyslog" | "render" | "syslog-ng" | "cloudflare_prometheus_exporter" | "minio" | "prometheus" | "prometheus_scrape" | "flights" | "collector") | Yes | The platform for the source (e.g., nginx, docker, kubernetes, http, vector) |
| `data_region` | string | No | The data region for the source. Use 'data_regions' tool to see available options for your organization. Common values for most plans: us_east, germany, singapore. Ask the user if unsure. |
| `logs_retention` | integer | No | Log retention in days (default: 30) |
| `ingesting_paused` | boolean | No | Whether to start with ingesting paused (default: false) |

### Create status page report

**Slug:** `BETTER_STACK_MCP_CREATE_STATUS_PAGE_REPORT`

Create a new status page report

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `title` | string | Yes | The title of the status report |
| `ends_at` | string | No | End time for the report (ISO 8601 format, required for maintenance reports) |
| `message` | string | Yes | The initial status update message |
| `team_id` | integer | No | Optional team ID (use teams to get team IDs). Status pages belong to organizations, so this is only needed to narrow the lookup to one team's organization |
| `starts_at` | string | No | Start time for the report (ISO 8601 format) |
| `report_type` | string ("manual" | "maintenance") | No | Type of report - manual (incident) or maintenance (default: manual) |
| `published_at` | string | No | When the report should be published (ISO 8601 format, default: now) |
| `status_page_id` | integer | Yes | The ID of the status page |
| `affected_resources` | array | No | Array of affected resources with status_page_resource_id and status |
| `notify_subscribers` | boolean | No | Whether to notify subscribers via email (default: false) |

### Create status page report update

**Slug:** `BETTER_STACK_MCP_CREATE_STATUS_PAGE_REPORT_UPDATE`

Create a new status update for an existing status page report

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `message` | string | No | The status update message |
| `report_id` | integer | Yes | The ID of the status report |
| `published_at` | string | No | When the update should be published (ISO 8601 format, default: now) |
| `status_page_id` | integer | Yes | The ID of the status page |
| `affected_resources` | array | Yes | Array of affected resources with status_page_resource_id and status |
| `notify_subscribers` | boolean | No | Whether to notify subscribers via email (default: false) |

### Create status page resource

**Slug:** `BETTER_STACK_MCP_CREATE_STATUS_PAGE_RESOURCE`

Add a resource (monitor, heartbeat, or group) to a status page.

Provide the `resource_type` and `resource_id` of the thing to display, plus a
`public_name` shown to visitors (usually the resource's own name). Use
`status_page_sections` to find the section to place it in; when omitted the
resource is added to the status page's first section.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `team_id` | integer | No | The ID of the team that owns the status page. Required only when the API token has access to multiple teams. |
| `position` | integer | No | Zero-based position of the resource within its section |
| `explanation` | string | No | Optional description shown under the resource |
| `public_name` | string | Yes | Name shown to visitors, usually the resource name |
| `resource_id` | integer | Yes | The ID of the monitor, heartbeat, or group to add |
| `widget_type` | string ("plain" | "history" | "intraday_history" | "response_times" | "intraday_response_times" | "chart_only") | No | How the resource is displayed. "history" shows the daily uptime bar, "plain" hides it. |
| `resource_type` | string ("Monitor" | "Heartbeat" | "MonitorGroup" | "HeartbeatGroup") | Yes | What kind of resource to add |
| `status_page_id` | integer | Yes | The ID of the status page |
| `status_page_section_id` | integer | No | The ID of the section to add the resource to (use status_page_sections to list them). Defaults to the first section. |

### Create status page section

**Slug:** `BETTER_STACK_MCP_CREATE_STATUS_PAGE_SECTION`

Create a section (resource group) on a status page to group resources under a heading

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | Yes | The section heading shown to visitors |
| `team_id` | integer | No | The ID of the team that owns the status page. Required only when the API token has access to multiple teams. |
| `position` | integer | No | Zero-based position of the section on the status page |
| `status_page_id` | integer | Yes | The ID of the status page |

### Dashboard

**Slug:** `BETTER_STACK_MCP_DASHBOARD`

Get detailed information about a specific dashboard including its charts, sections, layout, template variables, and configuration. Use this to understand a dashboard structure before modifying it

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the dashboard to retrieve |

### Dashboard query help

**Slug:** `BETTER_STACK_MCP_DASHBOARD_QUERY_HELP`

Get instructions for writing a ClickHouse query to use inside a Better Stack **Dashboard** chart (or chart alert).

The query uses template variables (`{{source}}`, `{{time}}`, `{{start_time}}`, `{{end_time}}`) and runs against the source's metrics collection — it is meant to be saved as a dashboard chart via `add_chart_to_dashboard` / `edit_chart`, NOT run directly.

To instead write an ad-hoc query you will run directly via `query` or `render_chart`, use `metrics_query_help`.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The source ID |

### Dashboards

**Slug:** `BETTER_STACK_MCP_DASHBOARDS`

List all available dashboards in a paginated table format. Returns dashboard ID, name, creation date, and last updated date

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number for pagination (starts at 1) |
| `team_id` | integer | No | Filter dashboards by team ID (use teams to get team IDs) |
| `per_page` | integer | No | Number of results per page (default: 50, max: 250) |

### Dashboard templates

**Slug:** `BETTER_STACK_MCP_DASHBOARD_TEMPLATES`

List all available dashboard templates in a paginated table format. Returns template ID, name, description, and other metadata

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number for pagination (starts at 1) |
| `per_page` | integer | No | Number of results per page (default: 50, max: 250) |

### Data regions

**Slug:** `BETTER_STACK_MCP_DATA_REGIONS`

List all available data regions and clusters for application and source creation. Returns a table with region IDs (to use when creating applications or sources), display names, types (Region or Cluster), and geographical locations. Includes usage instructions for both standard regions and custom clusters

### Delete chart alert

**Slug:** `BETTER_STACK_MCP_DELETE_CHART_ALERT`

Delete a chart alert permanently. This will also clean up any associated incidents and anomaly models. This action cannot be undone. Use chart_alerts or chart_alert first to find the alert ID

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the chart alert to delete |

### Delete metric expression

**Slug:** `BETTER_STACK_MCP_DELETE_METRIC_EXPRESSION`

Delete a metric expression from a source. This action cannot be undone. Call `metric_expressions` first to get the ID.

`build_type: new_data` (default) stops the rule from applying to future logs but leaves already-extracted data. `build_type: historical_logs` also rebuilds the source's metrics without this rule — expensive.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | string | Yes | The metric expression ID returned by metric_expressions, e.g. "m-123" or "g-456" |
| `source_id` | integer | Yes | The ID of the source (use sources to get source IDs) |
| `build_type` | string ("new_data" | "historical_logs") | No | How to process existing data: 'new_data' (default) only stops new data; 'historical_logs' also rebuilds historical metrics without this rule |

### Documentation

**Slug:** `BETTER_STACK_MCP_DOCUMENTATION`

Search for relevant documentation articles and return their contents

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `url` | string | No | Direct URL to a specific documentation article |
| `query` | string | No | The search query to find relevant documentation articles |

### Edit application

**Slug:** `BETTER_STACK_MCP_EDIT_APPLICATION`

Edit an existing application in Better Stack - rename it, pause or resume ingesting, or set its VRL transformations, including the exception grouping program. Only provide the fields you want to change. Use applications or application first to find the application ID.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the application to edit |
| `name` | string | No | New name for the application |
| `ingesting_paused` | boolean | No | Set to true to temporarily pause data ingesting for this application, false to resume it |
| `vrl_transformation_logs` | string | No | VRL transformation applied to logs during ingestion. Set to an empty string to remove, omit to leave unchanged. |
| `vrl_transformation_spans` | string | No | VRL transformation applied to traces (spans) during ingestion. Set to an empty string to remove, omit to leave unchanged. |
| `vrl_transformation_replays` | string | No | VRL transformation applied to session replays during ingestion. Set to an empty string to remove, omit to leave unchanged. |
| `vrl_transformation_exceptions` | string | No | VRL transformation applied to exceptions during ingestion. This is what controls how exceptions are grouped into errors: it should set the `._pattern` grouping key. Set to an empty string to remove a custom program, omit to leave unchanged. |
| `vrl_transformation_web_events` | string | No | VRL transformation applied to web events (page views and web vitals) during ingestion. Set to an empty string to remove, omit to leave unchanged. |

### Edit chart

**Slug:** `BETTER_STACK_MCP_EDIT_CHART`

Edit an existing chart name, query, type, or settings. Only provide the fields you want to change.

**If changing the query:** the new query's FROM must reference a source, either `{{source}}` or a source-type variable defined via `set_dashboard_variable` (queries with no source are rejected).

Dashboard chart queries run against the metrics collection: use `sum(logs_count)` (or the matching `sum(<row_type>_count)` for the source), `avgMerge(value_avg)`, `label('tag')`. `JSONExtract(raw, …)` only works in live-tail charts — dashboards have no `raw` column.

Verify the new query with `render_chart` (runs it and surfaces errors automatically) or with `query` before saving.

Queries can also reference custom dashboard variables — `{{var}}` (required) or `[[ AND col = {{var}} ]]` (optional clause, dropped while the variable is empty); define them with `set_dashboard_variable`.

Call `chart_building_help` for chart/settings reference and `metrics_query_help` with `context: 'chart_query'` for the source's metrics schema and chart-query-style examples. Use `dashboard` first to find the chart ID.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the chart to edit |
| `name` | string | No | New name for the chart |
| `query` | string | No | New SQL query. Its FROM must reference a source: {{source}}, or a source-type variable defined via set_dashboard_variable (e.g. {{redis_source}}); hardcoded collection names are rejected. Use {{start_time}}/{{end_time}} in the time filter and {{time}} for bucketing. Dashboard charts query the metrics collection (use sum(logs_count) / sum(spans_count) / sum(exceptions_count) / sum(replays_count) / sum(web_events_count) / sum(metrics_count) for type-specific counts, avgMerge(value_avg), label('tag')); JSONExtract(raw, …) only works in live-tail charts. |
| `width` | integer | No | New width in grid units (1-12). Grid is 12 columns wide. |
| `height` | integer | No | New height in grid units (1-50). |
| `settings` | object | No | Chart display settings. Which keys apply depends on chart_type: call `chart_building_help` for the per-type reference, possible values, and gotchas. |
| `chart_type` | string ("line_chart" | "bar_chart" | "number_chart" | "table_chart" | "pie_chart" | "heatmap_chart" | "scatter_chart" | "gauge_chart" | "map_chart" | "hierarchy_chart" | "static_text_chart") | No | New chart type |
| `explanation` | string | No | Short description of the chart. Set to empty string to clear. |

### Edit chart alert

**Slug:** `BETTER_STACK_MCP_EDIT_CHART_ALERT`

Edit an existing chart alert configuration. Only provide the fields you want to change. Call chart_alert_help for configuration reference. Use chart_alerts or chart_alert first to find the alert ID

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the chart alert to edit |
| `sms` | boolean | No | SMS notifications |
| `call` | boolean | No | Phone notifications |
| `name` | string | No | New name for the alert |
| `push` | boolean | No | Push notifications |
| `email` | boolean | No | Email notifications |
| `value` | number | No | New threshold value |
| `operator` | string ("equal" | "higher_than" | "higher_than_or_equal" | "lower_than" | "lower_than_or_equal" | "increases_by" | "decreases_by" | "changes_by") | No | New comparison operator |
| `alert_type` | string ("threshold" | "relative" | "anomaly_rrcf") | No | New alert type |
| `check_period` | integer ("30" | "60" | "120" | "300" | "600" | "1800" | "3600" | "7200" | "10800" | "21600" | "43200" | "86400") | No | How often to run the alert check (seconds) |
| `query_period` | integer ("30" | "60" | "120" | "300" | "600" | "1800" | "3600") | No | Seconds to look back for relative alerts |
| `series_names` | array | No | Specific series to monitor. Mutually exclusive with series_names_except |
| `shown_interval` | integer ("30" | "60" | "120" | "300" | "600" | "1800" | "3600" | "7200" | "10800" | "21600" | "43200" | "86400") | No | Anomaly chart aggregation interval (seconds) |
| `anomaly_trigger` | string ("any" | "higher" | "lower") | No | Anomaly trigger: 'any', 'higher', 'lower' |
| `recovery_period` | string ("0" | "30" | "60" | "120" | "300" | "600" | "1800" | "3600" | "7200" | "14400") | No | How long the condition must be resolved before auto-resolving (seconds). null means never auto-resolve; the incident stays open until resolved manually |
| `escalation_target` | string | No | 'current_team' or a GID like gid://uptime/Policy/123 or gid://uptime/Team/456 |
| `anomaly_sensitivity` | integer | No | Anomaly significance threshold (1-10, default 5), shown as 'Significance' in the UI. Higher = larger deviation required to fire, so FEWER alerts; lower = more sensitive, more alerts |
| `confirmation_period` | integer ("0" | "30" | "60" | "120" | "300" | "600" | "1800" | "3600" | "7200" | "14400") | No | How long the condition must persist before creating an incident (seconds) |
| `incident_per_series` | boolean | No | When true, each alerting series opens its own incident instead of one shared incident |
| `series_names_except` | array | No | Series to exclude; alert fires on every other series. Mutually exclusive with series_names |
| `aggregation_interval` | integer ("30" | "60" | "120" | "300" | "600" | "1800" | "3600" | "7200" | "10800" | "21600" | "43200" | "86400") | No | Data range for threshold alerts ('on data from' in UI) |
| `anomaly_training_range_days` | integer | No | How many days of data the anomaly model is first trained on (1-30, default 7), shown as 'Initial training data range' in the UI |

### Edit dashboard

**Slug:** `BETTER_STACK_MCP_EDIT_DASHBOARD`

Edit an existing dashboard's name or source eligibility. Only provide the fields you want to change. Use dashboard first to find the dashboard ID.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the dashboard to edit |
| `name` | string | No | New name for the dashboard |
| `source_eligibility_sql` | string | No | Source eligibility SQL — the ClickHouse query that decides which sources (and services) the dashboard applies to. It runs against the source's metrics collection and must return a single truthy/falsy value (e.g. `SELECT count() > 0 FROM {{source}}`); the dashboard is offered for a source only when the query returns truthy. The selected source and time range are injected automatically (as the {{source}}, {{start_time}}, and {{end_time}} variables), so the query should not reference any other dashboard variables. Call `metrics_query_help` with `context: 'chart_query'` for the source's metrics schema and query syntax. Set to an empty string to clear eligibility and make the dashboard visible for all sources; omit to leave it unchanged. |

### Edit dashboard section

**Slug:** `BETTER_STACK_MCP_EDIT_DASHBOARD_SECTION`

Edit an existing dashboard section. Only provide the fields you want to change. Use dashboard first to find the section ID

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the section to edit |
| `name` | string | No | New section title |
| `collapsed` | boolean | No | Whether the section is collapsed (true = folded, false = expanded) |
| `explanation` | string | No | Short description shown as a tooltip next to the section name. Pass an empty string to clear it. |

### Error

**Slug:** `BETTER_STACK_MCP_ERROR`

Get comprehensive details of a specific error including its type, message, call site information, first occurrence, current state (unhandled, unresolved, ignored, resolved, or reoccurred), and linked Linear/Jira issues

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `pattern` | string | Yes | The error pattern identifier |
| `application_id` | integer | Yes | The ID of the application |

### Errors

**Slug:** `BETTER_STACK_MCP_ERRORS`

List error patterns for an application with occurrence counts, affected users, current state, and links. Defaults to unresolved errors and supports filtering by state. For specialized error analytics or custom SQL, use errors_query_help instead.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number for pagination (starts at 1) |
| `query` | string | No | Search by error type or message |
| `state` | string ("all" | "new" | "unresolved" | "ignored" | "resolved" | "reoccurred" | "unhandled") | No | Filter by error state. Defaults to 'unresolved'. 'unresolved' includes reoccurred errors and errors not yet triaged. |
| `release` | string | No | Filter by release version |
| `end_time` | string | No | End of time range (e.g. 'now'). Default: 'now' |
| `order_by` | string ("last_seen" | "first_seen" | "exceptions_count" | "users_count") | No | Sort order. Default: 'last_seen' |
| `start_time` | string | No | Start of time range (e.g. 'now-3d', '2024-01-01T00:00:00Z'). Default: 'now-3d' |
| `environment` | string | No | Filter by environment (for example, 'production' or 'staging') |
| `application_id` | integer | Yes | The ID of the application |

### Errors query help

**Slug:** `BETTER_STACK_MCP_ERRORS_QUERY_HELP`

Get comprehensive instructions for building SQL ClickHouse queries for error tracking, including both error patterns (metrics) and individual exceptions. Explains when to use each source and provides examples for common use cases

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `application_id` | integer | Yes | The application (source) ID |

### Escalate incident

**Slug:** `BETTER_STACK_MCP_ESCALATE_INCIDENT`

Escalate an ongoing incident to a user, team, schedule, or policy

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the incident to escalate |
| `sms` | boolean | No | Send SMS notification |
| `call` | boolean | No | Send phone call notification |
| `push` | boolean | No | Send push notification |
| `email` | boolean | No | Send email notification |
| `team_id` | integer | No | Define which team to escalate to. Either team_name or team_id required when escalating to Team. |
| `user_id` | integer | No | Define which team member to escalate to. Either user_email or user_id required when escalating to User. |
| `policy_id` | integer | No | Define which escalation policy to escalate to. Required when escalating to Policy. |
| `team_name` | string | No | Define which team to escalate to. Either team_name or team_id required when escalating to Team. |
| `user_email` | string | No | Define which team member to escalate to. Either user_email or user_id required when escalating to User. |
| `schedule_id` | integer | No | Define which on-call calendar to escalate to. Required when escalating to Schedule. |
| `critical_alert` | boolean | No | Send as critical alert |
| `escalation_type` | string | Yes | Type of escalation: User, Team, Schedule, Policy, or Organization |

### Escalation policies

**Slug:** `BETTER_STACK_MCP_ESCALATION_POLICIES`

List all escalation policies with their steps and configuration

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number for pagination (starts at 1) |
| `team_id` | integer | No | Filter by team ID (use teams to get team IDs) |
| `per_page` | integer | No | Number of results per page (default: 50, max: 250) |

### Escalation policy

**Slug:** `BETTER_STACK_MCP_ESCALATION_POLICY`

Get detailed information about a specific escalation policy

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the escalation policy |

### Exploration

**Slug:** `BETTER_STACK_MCP_EXPLORATION`

Get detailed information about a specific exploration (saved Explore query) including its sources, chart type, template variables, saved time range, and query. Use this to understand an exploration before modifying its source or variables

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the exploration to retrieve |

### Explorations

**Slug:** `BETTER_STACK_MCP_EXPLORATIONS`

List saved explorations (saved Explore queries) in a paginated table. Returns exploration ID, name, chart type, sources, group, and last updated date. Use this to discover explorations before viewing or modifying one

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number for pagination (starts at 1) |
| `query` | string | No | Optional search query to filter explorations by name |
| `team_id` | integer | No | Filter explorations by team ID (use teams to get team IDs) |
| `per_page` | integer | No | Number of results per page (default: 50, max: 250) |

### Explore logs query help

**Slug:** `BETTER_STACK_MCP_EXPLORE_LOGS_QUERY_HELP`

Get instructions for writing a ClickHouse query to use inside the Better Stack **Explore logs** page (and live-tail charts) for log and span data.

The query uses template variables (`{{source}}`, `{{time}}`, `{{start_time}}`, `{{end_time}}`) and reads fields from the `raw` JSON column — it is meant to be used in the Explore UI, NOT run directly.

To instead write an ad-hoc logs/spans query you will run directly via `query`, use `query_help`.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The source ID |
| `source_type` | string ("logs" | "spans") | No | Type of source data to query (default: logs) |

### Export dashboard

**Slug:** `BETTER_STACK_MCP_EXPORT_DASHBOARD`

Export a dashboard configuration as JSON. Returns the complete dashboard data structure including charts, sections, presets, and settings

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the dashboard or dashboard template to export |

### Heartbeat

**Slug:** `BETTER_STACK_MCP_HEARTBEAT`

Get details of a specific heartbeat

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the heartbeat |

### Heartbeat availability

**Slug:** `BETTER_STACK_MCP_HEARTBEAT_AVAILABILITY`

Get availability summary for a specific heartbeat

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the heartbeat |
| `to` | string | No | End date (YYYY-MM-DD format) |
| `from` | string | No | Start date (YYYY-MM-DD format) |

### Heartbeats

**Slug:** `BETTER_STACK_MCP_HEARTBEATS`

List all heartbeats with filtering and pagination options

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | No | Filter by heartbeat name |
| `page` | integer | No | Page number for pagination (starts at 1) |
| `status` | string | No | Filter by status (paused, pending, up, down) |
| `team_id` | integer | No | Filter by team ID (use teams to get team IDs) |
| `per_page` | integer | No | Number of results per page (default: 50, max: 250) |

### Import dashboard

**Slug:** `BETTER_STACK_MCP_IMPORT_DASHBOARD`

Import a dashboard from JSON configuration. Creates a new dashboard with the provided data structure

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `data` | string | Yes | The dashboard data as a JSON string (can be obtained from export_dashboard) |
| `name` | string | Yes | The name for the new dashboard |
| `team_id` | integer | Yes | The ID of the team to import the dashboard into (use teams to get team IDs) |

### Incident

**Slug:** `BETTER_STACK_MCP_INCIDENT`

Get detailed information about a specific incident

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the incident to retrieve |

### Incident comments

**Slug:** `BETTER_STACK_MCP_INCIDENT_COMMENTS`

Get comments for an incident

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `incident_id` | integer | Yes | The ID of the incident |

### Incidents

**Slug:** `BETTER_STACK_MCP_INCIDENTS`

List incidents with filtering and pagination options

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `to` | string | No | Return incidents until a specific date (ISO 8601 format) |
| `from` | string | No | Return incidents from a specific date (ISO 8601 format) |
| `page` | integer | No | Page number for pagination (starts at 1) |
| `cause` | string | No | Filter by a substring of the incident cause (case-insensitive). Whitespace and dashes match flexibly. |
| `status` | array | No | Filter by current lifecycle status. Statuses are mutually exclusive: an incident is either ongoing, currently acknowledged (not yet resolved), or resolved. Pass an array to match any of them. |
| `team_id` | integer | No | Filter by team ID (use teams to get team IDs) |
| `metadata` | object | No | Filter by metadata key/value. Pass an object like { "severity": "high" } or { "severity": ["high", "medium"] } for multi-value match. |
| `per_page` | integer | No | Number of results per page (default: 10, max: 50) |
| `resolved` | boolean | No | List only resolved incidents (true) or unresolved incidents (false). Independent of acknowledged_at — treats both states as separate timestamps. Use `status` for mutually-exclusive lifecycle filtering. |
| `monitor_id` | integer | No | Filter incidents for a specific monitor |
| `acknowledged` | boolean | No | List only acknowledged incidents (true) or unacknowledged incidents (false). Includes already-resolved incidents that were acknowledged at some point. Use `status` for mutually-exclusive lifecycle filtering. |
| `has_comments` | boolean | No | true → only incidents with comments; false → only incidents without comments. |
| `heartbeat_id` | integer | No | Filter incidents for a specific heartbeat |
| `has_jira_task` | boolean | No | true → only incidents linked to a Jira work item; false → only those without. |
| `has_postmortem` | boolean | No | true → only incidents with a post-mortem comment; false → only those without. |
| `has_linear_task` | boolean | No | true → only incidents linked to a Linear issue; false → only those without. |
| `incident_group_id` | integer | No | Filter to incidents within a specific incident group. Discover group IDs by reading `incident_group_id` off an existing incident. |
| `max_duration_minutes` | integer | No | Only incidents that lasted shorter than this many minutes. |
| `min_duration_minutes` | integer | No | Only incidents that lasted longer than this many minutes. |
| `escalation_policy_ids` | array | No | Filter to incidents associated with any of these escalation policies (via the incident itself or its escalation events). |

### Incident timeline

**Slug:** `BETTER_STACK_MCP_INCIDENT_TIMELINE`

Get the timeline of events for an incident

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the incident |

### Invite team member

**Slug:** `BETTER_STACK_MCP_INVITE_TEAM_MEMBER`

Invite someone to a Better Stack team by e-mail address. Optionally set their
role by system-role name (`role`: responder, member, team_lead, billing_admin)
or by `role_id` (use team_roles to look up ids). Defaults to responder. The
admin role cannot be assigned via the API. Someone who already belongs to
the organization is added to the team directly, with no invitation to
accept; the Admin role applies to every team, so an existing Admin keeps it.
If the token can reach more than one team, pass `team_id` (or `team_name`).


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `role` | string | No | System-role name: responder, member, team_lead, or billing_admin. Defaults to responder. 'admin' is not allowed. |
| `email` | string | Yes | E-mail address of the person to invite. |
| `role_id` | integer | No | ID of the role to assign (alternative to role; supports custom roles). Use team_roles to look up ids. |
| `team_id` | integer | No | ID of the team to invite into. Required when the token can access more than one team. |
| `team_name` | string | No | Name of the team to invite into (alternative to team_id). |

### Link error issue

**Slug:** `BETTER_STACK_MCP_LINK_ERROR_ISSUE`

Link an error to an issue or work item that already exists in Linear or Jira. Better Stack then posts every change to the error state as a comment on the issue. For Linear, resolving the issue also resolves the error when auto-resolve is turned on for that integration; Jira has no status sync back. Create the issue in Linear or Jira first, then pass its identifier, key, or URL here.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `issue` | string | Yes | The issue to link: a Linear issue identifier (ENG-123), a Jira work item key (PROJ-45), or the issue URL from either |
| `pattern` | string | Yes | The error pattern identifier |
| `application_id` | integer | Yes | The ID of the application |
| `integration_id` | integer | No | The Better Stack integration to link through. Only needed when more than one of the team's integrations could hold the issue, in which case this tool answers with the IDs to choose from. |

### Metric

**Slug:** `BETTER_STACK_MCP_METRIC`

Get comprehensive details about a specific metric. Returns metric overview (data points, active series, available aggregations), definition (SQL expression or JSON path), example queries for different aggregation functions, and Prometheus tags (for pure metrics). Essential for understanding how to query and use a metric

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `source_id` | integer | Yes | The ID of the source |
| `metric_name` | string | Yes | The name of the metric |

### Metric expressions

**Slug:** `BETTER_STACK_MCP_METRIC_EXPRESSIONS`

List the metric expressions (extract-metrics-from-logs rules) on a source. Returns the rule ID, name, kind (metric vs label), ClickHouse type, SQL expression, and aggregations. IDs use a short prefixed form that feeds straight into update_metric_expression / delete_metric_expression

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number for pagination (starts at 1) |
| `per_page` | integer | No | Number of results per page (default: 50, max: 250) |
| `source_id` | integer | Yes | The ID of the source (use sources to get source IDs) |

### Metrics query help

**Slug:** `BETTER_STACK_MCP_METRICS_QUERY_HELP`

Get instructions for building SQL ClickHouse queries for metrics (available metrics, aggregations, examples) to run directly via the query tools (`query` / `render_chart`), using concrete `remote(...)` / `s3Cluster(...)` collection names and explicit time filters.

To instead write a query for use inside a Dashboard chart, use `dashboard_query_help`.

Pass `context: 'chart_query'` when the query will be saved as a dashboard chart or chart alert — the prompt will emphasize `{{source}}` / `{{time}}` / `{{start_time}}` / `{{end_time}}` template variables and chart column aliases. (`context: 'direct_query'` is the default, for ad-hoc queries.)


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The source ID |
| `context` | string ("direct_query" | "chart_query") | No | Where the query will run. 'direct_query' (default) — running directly via query or render_chart; prompt uses concrete remote()/s3Cluster() collection names and explicit time filters. 'chart_query' — query will be saved as a dashboard chart or chart alert; prompt uses {{source}}/{{time}}/{{start_time}}/{{end_time}} template variables throughout. |

### Metrics schema

**Slug:** `BETTER_STACK_MCP_METRICS_SCHEMA`

Get metrics and cardinality for a source. Returns a paginated table of available metrics (user-defined and ingested) ordered by active series (highest cardinality first), with their names, types, storage layout, data points count, and active series count. Use `name_filter` to search by name: `rabbitmq*`, `*queue*`, `*_total`, or an exact name. When more than 250 metrics match and grouping them by name prefix would shrink the list at least 3x, a prefix summary is returned instead of the list; drill in with the `name_filter` it suggests. `page` applies to whichever table is shown

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the source |
| `page` | integer | No | Page number for pagination (starts at 1) |
| `per_page` | integer | No | Number of results per page (default: 50, max: 250) |
| `name_filter` | string | No | Filter metrics by name. Supports wildcards: 'rabbitmq*' (starts with), '*queue*' (contains), '*_total' (ends with), or an exact name. Case-insensitive |

### Monitor

**Slug:** `BETTER_STACK_MCP_MONITOR`

Get details of a specific monitor

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the monitor |

### Monitor availability

**Slug:** `BETTER_STACK_MCP_MONITOR_AVAILABILITY`

Get availability (SLA) summary for a specific monitor

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the monitor |
| `to` | string | No | End date (YYYY-MM-DD format) |
| `from` | string | No | Start date (YYYY-MM-DD format) |

### Monitor response times

**Slug:** `BETTER_STACK_MCP_MONITOR_RESPONSE_TIMES`

Get response time metrics for a specific monitor

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the monitor |

### Monitors

**Slug:** `BETTER_STACK_MCP_MONITORS`

List monitors with optional filtering and pagination

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `url` | string | No | Filter monitors by URL |
| `page` | integer | No | Page number for pagination (starts at 1) |
| `team_id` | integer | No | Filter by team ID (use teams to get team IDs) |
| `per_page` | integer | No | Number of results per page (default: 50, max: 250) |
| `pronounceable_name` | string | No | Filter monitors by name |

### Move charts

**Slug:** `BETTER_STACK_MCP_MOVE_CHARTS`

Move one or more charts to new positions on a dashboard. Validates the final layout for overlaps, allowing swaps and complex rearrangements. All moves are applied atomically - if any move is invalid, none are applied. Grid is 12 columns wide

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `moves` | array | Yes | Array of chart moves |
| `dashboard_id` | integer | Yes | The ID of the dashboard |

### On call

**Slug:** `BETTER_STACK_MCP_ON_CALL`

Get detailed information about a specific on-call calendar or the default calendar

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | string | No | The ID of the on-call calendar (use "default" for team's default calendar) |
| `date` | string | No | ISO-8601 formatted date/time to look up who is on-call at that time |

### On call event

**Slug:** `BETTER_STACK_MCP_ON_CALL_EVENT`

Get detailed information about a specific on-call event

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `event_id` | integer | Yes | The ID of the event to retrieve |
| `calendar_id` | string | Yes | The ID of the on-call calendar (use "default" for team's default calendar) |

### On call events

**Slug:** `BETTER_STACK_MCP_ON_CALL_EVENTS`

List all on-call schedule events for a specific calendar

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | string | Yes | The ID of the on-call calendar (use "default" for team's default calendar) |

### On call rotation

**Slug:** `BETTER_STACK_MCP_ON_CALL_ROTATION`

Get on-call rotation configuration for a specific calendar

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | string | Yes | The ID of the on-call calendar (use "default" for team's default calendar) |

### On calls

**Slug:** `BETTER_STACK_MCP_ON_CALLS`

List all on-call calendars for the team

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number for pagination (starts at 1) |
| `team_id` | integer | No | Filter by team ID (use teams to get team IDs) |
| `per_page` | integer | No | Number of results per page (default: 50, max: 250) |

### Query

**Slug:** `BETTER_STACK_MCP_QUERY`

Execute a ClickHouse SQL query to retrieve logs, traces/spans, errors, and metrics from telemetry data.

- **IMPORANT**: Use `query_help` to get instructions on how to create the correct query for logs and spans
- **IMPORANT**: Use `errors_query_help` to get instructions on how to create the correct query for errors
- **IMPORANT**: Use `metrics_query_help` to get instructions on how to create the correct query for metrics

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `host` | string | No |  |
| `query` | string | Yes | The SQL query to execute |
| `table` | string | Yes | Table name, ie. `t123.my_source` |
| `password` | string | No |  |
| `username` | string | No |  |
| `source_id` | number | Yes | Source ID |

### Query help

**Slug:** `BETTER_STACK_MCP_QUERY_HELP`

Get instructions for building SQL ClickHouse queries for logs and spans (fields, aggregations, examples) to run directly via the query tools (query / render_chart) against the ClickHouse proxy. To instead write a query for use inside the Explore logs UI, use explore_logs_query_help.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The source ID |
| `source_type` | string ("logs" | "spans") | Yes | The type of source (logs or spans) |

### Releases

**Slug:** `BETTER_STACK_MCP_RELEASES`

List all releases for a specific application in a paginated table format. Returns release ID (usable with remove_release), reference, environments, origin, first seen, and last seen timestamps

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number for pagination (starts at 1) |
| `order` | string ("asc" | "desc") | No | Sort order: 'asc' or 'desc' (default: 'desc') |
| `per_page` | integer | No | Number of results per page (default: 50, max: 250) |
| `application_id` | integer | Yes | The ID of the application to list releases for |

### Remove chart

**Slug:** `BETTER_STACK_MCP_REMOVE_CHART`

Remove a chart from its dashboard permanently. This action cannot be undone and will also remove any alerts associated with the chart. Use dashboard first to find the chart ID

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the chart to remove |

### Remove dashboard

**Slug:** `BETTER_STACK_MCP_REMOVE_DASHBOARD`

Remove a dashboard permanently. This action cannot be undone

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the dashboard to remove |

### Remove dashboard section

**Slug:** `BETTER_STACK_MCP_REMOVE_DASHBOARD_SECTION`

Remove a section divider from a dashboard permanently. This action cannot be undone. Charts are not affected - only the section header is removed. Use dashboard first to find the section ID

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the section to remove |

### Remove dashboard variable

**Slug:** `BETTER_STACK_MCP_REMOVE_DASHBOARD_VARIABLE`

Remove a dashboard template variable by name. Cannot remove the automatic variables source, start_time, end_time, or time. A chart still referencing a removed variable as a required {{name}} errors until it is redefined (the next chart save auto-creates it again, empty). Use dashboard first to see the defined variables.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | Yes | Name of the variable to remove |
| `dashboard_id` | integer | Yes | The ID of the dashboard |

### Remove exploration variable

**Slug:** `BETTER_STACK_MCP_REMOVE_EXPLORATION_VARIABLE`

Remove a variable from an exploration (saved Explore query) by name. Cannot remove the automatic variables source, start_time, end_time, or time. A query still referencing a removed variable as a required {{name}} errors until it is redefined. Use exploration first to see the defined variables.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | Yes | Name of the variable to remove |
| `exploration_id` | integer | Yes | The ID of the exploration |

### Remove release

**Slug:** `BETTER_STACK_MCP_REMOVE_RELEASE`

Remove a release permanently. A release still receiving error events is re-detected automatically when its next event arrives. Use the releases tool to find release IDs

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `release_id` | integer | Yes | The ID of the release to remove (listed by the releases tool) |

### Remove status page resource

**Slug:** `BETTER_STACK_MCP_REMOVE_STATUS_PAGE_RESOURCE`

Remove a resource from a status page

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `resource_id` | integer | Yes | The ID of the status page resource to remove (from status_page_resources) |
| `status_page_id` | integer | Yes | The ID of the status page |

### Remove status page section

**Slug:** `BETTER_STACK_MCP_REMOVE_STATUS_PAGE_SECTION`

Remove a section from a status page. Resources in the section are removed with it.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `section_id` | integer | Yes | The ID of the section to remove (from status_page_sections) |
| `status_page_id` | integer | Yes | The ID of the status page |

### Remove team member

**Slug:** `BETTER_STACK_MCP_REMOVE_TEAM_MEMBER`

Remove a member from a Better Stack team, or cancel a pending invitation.
Identify them by `email` or `user_id` (from team_members). Admins cannot be
removed via the API, and the organization's last member cannot be removed. If
the token can reach more than one team, pass `team_id` (or `team_name`). This
permanently removes the person's access to the team.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `email` | string | No | E-mail of the member to remove, or of a pending invitation to cancel (alternative to user_id). |
| `team_id` | integer | No | ID of the team to remove from. Required when the token can access more than one team. |
| `user_id` | integer | No | ID of the member to remove, or of a pending invitation to cancel — the id column from team_members (alternative to email). |
| `team_name` | string | No | Name of the team (alternative to team_id). |

### Render chart

**Slug:** `BETTER_STACK_MCP_RENDER_CHART`

Execute a ClickHouse SQL query and visualize the result as a chart.

Use `chart_type` to choose the visualization:
- `line` (default) — trends over time. Alias columns as `time`, `value`, and optional `series`.
- `bar` — magnitude over time or across buckets. Uses the same columns as `line`; set `stacked: true` to stack the series.
- `pie` — share of a total across categories. Alias a categorical column `AS series` (the slice label) and a numeric column `AS value` (the slice size), e.g. `SELECT service AS series, count() AS value FROM ... GROUP BY service`.

Alias result columns as (line/bar):
- `... AS time` — the time bucket (e.g., `toStartOfHour(dt) AS time`)
- `... AS value` — the numeric metric (e.g., `count() AS value`)
- `... AS series` — optional: a grouping column for multiple series (e.g., `service AS series`)

**IMPORTANT (line/bar): Always choose a time granularity that produces 50–500 data points** — too few points make the chart useless, too many make it unreadable. Use these rules based on the query's time range:
- Up to 1 hour → `toStartOfMinute(dt) AS time` → ~60 points
- 1–24 hours → `toStartOfInterval(dt, INTERVAL 5 MINUTE) AS time` → up to 288 points
- 1–7 days → `toStartOfHour(dt) AS time` → up to 168 points
- 7–30 days → `toStartOfInterval(dt, INTERVAL 4 HOUR) AS time` → up to 180 points
- 30–90 days → `toStartOfInterval(dt, INTERVAL 12 HOUR) AS time` → up to 180 points
- 90+ days → `toStartOfDay(dt) AS time`

Additional query instructions (data access patterns) are in:
- `query_help` — logs and spans
- `errors_query_help` — errors
- `metrics_query_help` — metrics

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `host` | string | No |  |
| `name` | string | No |  |
| `query` | string | Yes | The SQL query to execute |
| `table` | string | Yes | Table name, ie. `t123.my_source` |
| `stacked` | boolean | No | Stack the series on top of each other. Applies to `line` and `bar` charts. |
| `password` | string | No |  |
| `username` | string | No |  |
| `source_id` | number | Yes | Source ID |
| `chart_type` | string ("line" | "bar" | "pie") | No | How to visualize the result: `line` (trends over time, default), `bar` (magnitude over time or across buckets), or `pie` (share of a total across categories). |

### Reopen incident

**Slug:** `BETTER_STACK_MCP_REOPEN_INCIDENT`

Reopen a resolved incident (must be within 24 hours of resolution)

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the incident to reopen |
| `reopened_by` | string | No | User email or identifier of who reopened the incident. Optional - when omitted, the action is attributed to the authenticated OAuth user (or "API" for team/organisation API tokens). Only pass this if the user has explicitly told you who reopened the incident on their behalf. |

### Replays query help

**Slug:** `BETTER_STACK_MCP_REPLAYS_QUERY_HELP`

Get comprehensive instructions for building SQL ClickHouse queries for session replays. Explains data structure, provides examples for listing replays, finding replays linked to errors, and filtering by user/environment

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `application_id` | integer | Yes | The application (source) ID |

### Resolve incident

**Slug:** `BETTER_STACK_MCP_RESOLVE_INCIDENT`

Resolve an ongoing incident

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the incident to resolve |
| `resolved_by` | string | No | User email or identifier of who resolved the incident. Optional - when omitted, the action is attributed to the authenticated OAuth user (or "API" for team/organisation API tokens). Only pass this if the user has explicitly told you who resolved the incident on their behalf. |

### Set dashboard variable

**Slug:** `BETTER_STACK_MCP_SET_DASHBOARD_VARIABLE`

Create or update a dashboard template variable — a user-facing filter in the dashboard toolbar, referenced in chart SQL as `{{name}}` (required — the chart errors until it resolves to a value) or `[[ AND col = {{name}} ]]` (optional — the whole `[[ ... ]]` clause is dropped while the variable is empty).

Saving a chart auto-creates a plain text variable (or a source variable when the name contains 'source') for any undefined required `{{name}}`, but it starts empty — use this tool to give it a typed definition or a default value so the chart resolves without manual input.

Fields per type:
- `select_value` (shown as "Static list") → the options in `default_values` (first = default selection)
- `select_with_sql` (shown as "Dynamic list") → an option-yielding **expression** (NOT a full query) in `sql_definition`, e.g. `label('_host')`; see the `sql_definition` parameter for how it is interpolated
- Both list types accept `allow_multiple_values: true` to let users pick several options at once (interpolates as a regex used with `match()`). `multi_select_with_sql` is the legacy always-multiple Dynamic list; prefer `select_with_sql` with `allow_multiple_values: true`.
- `select_predefined_sql` (shown as "Query per value") → named SQL filters in `filters` (each a **full query**), default picked via `selected_label`
- `string` / `number` / `boolean` → `[default]` in `default_values`
- `sql_expression` → `[raw SQL]` in `default_values`, spliced into chart SQL unescaped
- `source` → the source IDs in `source_ids`. Name it `source` to set the dashboard's own source (which sources every chart queries by default), or use a custom name for an extra source variable that a chart references in its FROM (e.g. `FROM {{name}}`) to query a different set of sources than the dashboard default.
- `date` / `datetime` → an ISO date in `default_values`, e.g. `['2026-07-23']` or `['2026-07-23T14:30:00Z']`

SQL-backed types are validated at save time by running their SQL against the dashboard's source — the save is refused when it fails.

The names `start_time`, `end_time`, and `time` are reserved (they come from the time picker). `source` is the exception: set it as a source-type variable to change the dashboard's source. Use `dashboard` to list a dashboard's variables and `dashboard_query_help` for how each type is referenced in chart SQL.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | Yes | Variable name used as {{name}} in chart queries |
| `filters` | array | No | select_predefined_sql: named SQL filters. Unlike sql_definition, each sql is a FULL query returning one column, whose rows are injected into the chart as an IN-list. Filter time with `dt BETWEEN {{start_time}} AND {{end_time}}`, never {{time}} (that macro only buckets inside charts). Example: SELECT label('cmd') FROM {{source}} WHERE dt BETWEEN {{start_time}} AND {{end_time}} GROUP BY 1 ORDER BY count() DESC LIMIT 5. |
| `source_ids` | array | No | source: the source IDs this variable resolves to (must be accessible to the dashboard's team). Ignored for other types. |
| `dashboard_id` | integer | Yes | The ID of the dashboard |
| `variable_type` | string ("string" | "number" | "boolean" | "sql_expression" | "date" | "datetime" | "source" | "select_value" | "select_with_sql" | "multi_select_with_sql" | "select_predefined_sql") | Yes | The variable type |
| `default_values` | array | No | select_value: the options (first = default). string/number/boolean: [default]. sql_expression: [raw SQL]. date/datetime: [ISO date], e.g. ['2026-07-23T14:30:00Z']. |
| `selected_label` | string | No | select_predefined_sql: the default filter label. |
| `sql_definition` | string | No | select_with_sql / multi_select_with_sql: an expression (NOT a full query) yielding the option values — the platform interpolates it as `SELECT DISTINCT <sql_definition> AS option FROM {{source}} WHERE dt BETWEEN {{start_time}} AND {{end_time}} LIMIT 50` to populate the dropdown. Example: label('_host'). |
| `allow_multiple_values` | boolean | No | select_value / select_with_sql: let users pick several options at once; the variable then interpolates as a quoted regex used with `match()`, or as a parenthesised list when written straight after `IN` / `NOT IN`. Never `IN ({{var}})`, which keeps the regex and matches nothing. Ignored for other types. |

### Set exploration variable

**Slug:** `BETTER_STACK_MCP_SET_EXPLORATION_VARIABLE`

Create or update a variable on an exploration (saved Explore query), referenced in its query as `{{name}}`.

The most common use is setting the exploration's source: name it `source`, type `source`, and pass the source IDs in `source_ids` — the query then runs against those sources.

Fields per type:
- `source` → the source IDs in `source_ids`. Name it `source` to set the exploration's own source, or use a custom name for an extra source variable the query references in its FROM (e.g. `FROM {{name}}`).
- `select_value` → the options in `default_values` (first = default selection)
- `select_with_sql` / `multi_select_with_sql` → an option-yielding expression (NOT a full query) in `sql_definition`, e.g. `label('_host')`
- `select_predefined_sql` → named SQL filters in `filters` (each a full query), default picked via `selected_label`
- `string` / `number` / `boolean` → `[default]` in `default_values`
- `sql_expression` → `[raw SQL]` in `default_values`, spliced into the query unescaped
- `date` / `datetime` → an ISO date in `default_values`, e.g. `['2026-07-23']` or `['2026-07-23T14:30:00Z']`

SQL-backed types are validated at save time by running their SQL against the exploration's source — the save is refused when it fails.

The names `start_time`, `end_time`, and `time` are reserved (they come from the time picker). `source` is the exception: set it as a source-type variable to change the exploration's source. Use `exploration` to list an exploration's variables.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | Yes | Variable name used as {{name}} in the query. Use 'source' to set the exploration's own source. |
| `filters` | array | No | select_predefined_sql: named SQL filters. Each sql is a FULL query returning one column, whose rows are injected as an IN-list. Filter time with `dt BETWEEN {{start_time}} AND {{end_time}}`. |
| `source_ids` | array | No | source: the source IDs this variable resolves to (must be accessible to the exploration's team). Ignored for other types. |
| `variable_type` | string ("string" | "number" | "boolean" | "sql_expression" | "date" | "datetime" | "source" | "select_value" | "select_with_sql" | "multi_select_with_sql" | "select_predefined_sql") | Yes | The variable type |
| `default_values` | array | No | select_value: the options (first = default). string/number/boolean: [default]. sql_expression: [raw SQL]. date/datetime: [ISO date], e.g. ['2026-07-23T14:30:00Z']. |
| `exploration_id` | integer | Yes | The ID of the exploration |
| `selected_label` | string | No | select_predefined_sql: the default filter label. |
| `sql_definition` | string | No | select_with_sql / multi_select_with_sql: an expression (NOT a full query) yielding the option values — the platform interpolates it as `SELECT DISTINCT <sql_definition> AS option FROM {{source}} WHERE dt BETWEEN {{start_time}} AND {{end_time}} LIMIT 50`. Example: label('_host'). |

### Severities

**Slug:** `BETTER_STACK_MCP_SEVERITIES`

List all severities (urgency levels) with their notification settings

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number for pagination (starts at 1) |
| `team_id` | integer | No | Filter by team ID (use teams to get team IDs) |
| `per_page` | integer | No | Number of results per page (default: 50, max: 250) |

### Severity

**Slug:** `BETTER_STACK_MCP_SEVERITY`

Get detailed information about a specific severity (urgency level)

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the severity |

### Source

**Slug:** `BETTER_STACK_MCP_SOURCE`

Get comprehensive details of a specific source including its configuration, retention settings, ingestion details, custom bucket settings (if configured)

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the source |

### Source fields

**Slug:** `BETTER_STACK_MCP_SOURCE_FIELDS`

Get complete field catalog for a logs or spans source. Returns a table of all queryable fields with their paths and data types. Essential for understanding what fields can be queried for building custom queries

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the source |
| `source_type` | string ("logs" | "spans") | No | Type of source data to query (default: logs) |

### Sources

**Slug:** `BETTER_STACK_MCP_SOURCES`

List all available sources in a paginated table format. Returns source ID, name, platform type, team, status (active/paused), data region, and creation date

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | No | Filter sources by name (case-insensitive partial match) |
| `page` | integer | No | Page number for pagination (starts at 1) |
| `team_id` | integer | No | Filter sources by team ID (use teams to get team IDs) |
| `per_page` | integer | No | Number of results per page (default: 50, max: 250) |

### Status page

**Slug:** `BETTER_STACK_MCP_STATUS_PAGE`

Get details of a specific status page

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the status page |

### Status page reports

**Slug:** `BETTER_STACK_MCP_STATUS_PAGE_REPORTS`

List status reports (incidents/maintenance) for a specific status page

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number for pagination (starts at 1) |
| `team_id` | integer | No | Filter by team ID (use teams to get team IDs) |
| `per_page` | integer | No | Number of results per page (default: 50, max: 250) |
| `status_page_id` | integer | Yes | The ID of the status page |

### Status page report update

**Slug:** `BETTER_STACK_MCP_STATUS_PAGE_REPORT_UPDATE`

Get details of a specific status page report update

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `report_id` | integer | Yes | The ID of the status report |
| `update_id` | integer | Yes | The ID of the status update |
| `status_page_id` | integer | Yes | The ID of the status page |

### Status page report updates

**Slug:** `BETTER_STACK_MCP_STATUS_PAGE_REPORT_UPDATES`

List status updates for a specific status report

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number for pagination (starts at 1) |
| `per_page` | integer | No | Number of results per page (default: 50, max: 250) |
| `report_id` | integer | Yes | The ID of the status report |
| `status_page_id` | integer | Yes | The ID of the status page |

### Status page resources

**Slug:** `BETTER_STACK_MCP_STATUS_PAGE_RESOURCES`

Get resources (monitors/heartbeats) for a specific status page

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number for pagination (starts at 1) |
| `per_page` | integer | No | Number of results per page (default: 50, max: 250) |
| `status_page_id` | integer | Yes | The ID of the status page |

### Status pages

**Slug:** `BETTER_STACK_MCP_STATUS_PAGES`

List all status pages with filtering and pagination options

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number for pagination (starts at 1) |
| `per_page` | integer | No | Number of results per page (default: 50, max: 250) |

### Status page sections

**Slug:** `BETTER_STACK_MCP_STATUS_PAGE_SECTIONS`

List the sections (resource groups) of a status page

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number for pagination (starts at 1) |
| `per_page` | integer | No | Number of results per page (default: 50, max: 250) |
| `status_page_id` | integer | Yes | The ID of the status page |

### Team members

**Slug:** `BETTER_STACK_MCP_TEAM_MEMBERS`

List the members of a Better Stack team, including pending invitations.
Returns each member's email, name, role and the mobile app platforms they
have signed in on. Supports the same email filter and pagination as the REST
team-members API. If the token can reach more than one team, pass `team_id`
(or `team_name`) to pick one; call it without a team first to see the list of
accessible teams. Useful for auditing who has access — e.g. offboarding.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number (1-based). Defaults to 1. |
| `email` | string | No | Return only the member or pending invitation with this exact email address. |
| `team_id` | integer | No | ID of the team to list members for. Required when the token can access more than one team. |
| `per_page` | integer | No | Results per page. Defaults to 50, maximum 250. |
| `team_name` | string | No | Name of the team to list members for (alternative to team_id). |

### Team roles

**Slug:** `BETTER_STACK_MCP_TEAM_ROLES`

List the roles defined in a Better Stack organization, including their
role_id and system-role identifier (admin, billing_admin, team_lead,
responder, member, or "custom"). Use this to discover valid role_id values
for interpreting team member roles. If the token can reach more than one
team/organization, pass `team_id` (or `team_name`) to choose one.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `team_id` | integer | No | ID of a team in the target organization. Required when the token can access more than one team. |
| `team_name` | string | No | Name of a team in the target organization (alternative to team_id). |

### Teams

**Slug:** `BETTER_STACK_MCP_TEAMS`

List all available teams in Better Stack Logs. Returns a table with team IDs and names, grouped by organization

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `search` | string | No | Filter teams by name (case-insensitive partial match) |

### Toggle chart alert pause

**Slug:** `BETTER_STACK_MCP_TOGGLE_CHART_ALERT_PAUSE`

Pause or unpause a chart alert. When paused, the alert will not trigger any incidents

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the chart alert |
| `paused` | boolean | Yes | Set to true to pause, false to unpause |

### Unlink error issue

**Slug:** `BETTER_STACK_MCP_UNLINK_ERROR_ISSUE`

Remove the link between an error and an issue in Linear, Jira, or GitLab. Better Stack stops syncing the two; the issue itself is left untouched.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `issue` | string | Yes | The linked issue to unlink, by the label the error tool prints for it (ENG-123, PROJ-45, #42) or by issue URL |
| `pattern` | string | Yes | The error pattern identifier |
| `application_id` | integer | Yes | The ID of the application |

### Update error state

**Slug:** `BETTER_STACK_MCP_UPDATE_ERROR_STATE`

Update the state of a specific error (mark as resolved, ignored, or unresolved)

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `state` | string ("ignored" | "resolved" | "unresolved") | Yes | The target state |
| `pattern` | string | Yes | The error pattern identifier |
| `application_id` | integer | Yes | The ID of the application |
| `ignore_next_count` | integer ("1" | "10" | "100" | "1000") | No | Number of next occurrences to ignore (only valid when state is 'ignored'). Must be 1, 10, 100, or 1000 |
| `resolve_in_release` | string ("current") | No | Pin the resolution to the application's latest release. The error will only re-open if it appears in a strictly newer release. Only valid when state is 'resolved'. |
| `notify_every_exception` | boolean | No | Whether to notify for every occurrence of this error |

### Update metric expression

**Slug:** `BETTER_STACK_MCP_UPDATE_METRIC_EXPRESSION`

Update an existing metric expression. Call `metric_expressions` first to get the ID.

At least one of `name`, `sql_expression`, `type`, `aggregations` must be provided — `build_type` alone is not a change and will be rejected. See `create_metric_expression` for `sql_expression` / `type` / `aggregations` guidance.

Prefer `build_type: new_data` (default). `historical_logs` re-runs the rule over every stored log — expensive; only when the user explicitly asks.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | string | Yes | The metric expression ID returned by metric_expressions, e.g. "m-123" or "g-456" |
| `name` | string | No | New metric name. Letters, numbers, and underscores only |
| `type` | string ("string" | "string_low_cardinality" | "int64_delta" | "int64" | "uint64_delta" | "uint64" | "float64_delta" | "datetime64_delta" | "boolean") | No | New ClickHouse storage type |
| `source_id` | integer | Yes | The ID of the source (use sources to get source IDs) |
| `build_type` | string ("new_data" | "historical_logs") | No | How to process existing data: 'new_data' (default) only applies to new logs; 'historical_logs' rebuilds metrics from existing logs |
| `aggregations` | array | No | New set of aggregations. Pass [] to convert to a label (group-by column) |
| `sql_expression` | string | No | New ClickHouse SQL expression |

### Update status page

**Slug:** `BETTER_STACK_MCP_UPDATE_STATUS_PAGE`

Update the settings of a status page (company name, contact URL, theme, layout, and more)

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | integer | Yes | The ID of the status page |
| `theme` | string ("light" | "dark" | "system") | No | Color theme |
| `layout` | string ("vertical" | "horizontal") | No | Resource layout |
| `timezone` | string | No | Timezone used to display times (e.g. "Europe/Prague") |
| `published` | boolean | No | Whether the status page is published (publicly visible) |
| `subdomain` | string | No | Subdomain the page is served on (e.g. "acme" for acme.betteruptime.com) |
| `company_url` | string | No | URL the company name links to |
| `contact_url` | string | No | URL or mailto link for the contact/support button |
| `announcement` | string | No | Announcement banner text shown at the top of the page |
| `company_name` | string | No | Company name shown as the status page title |
| `subscribable` | boolean | No | Whether visitors can subscribe to updates |
| `custom_domain` | string | No | Custom CNAME domain for the status page |
| `hide_from_search_engines` | boolean | No | Hide the status page from search engines |

### Update status page resource

**Slug:** `BETTER_STACK_MCP_UPDATE_STATUS_PAGE_RESOURCE`

Update a resource on a status page.

Change its public name, description, widget type (e.g. show or hide the uptime
history), or move it by setting `position` (zero-based) and/or
`status_page_section_id`. Use `status_page_resources` to find resource IDs.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `position` | integer | No | Zero-based position of the resource within its section |
| `explanation` | string | No | Description shown under the resource |
| `public_name` | string | No | Name shown to visitors |
| `resource_id` | integer | Yes | The ID of the status page resource to update (from status_page_resources) |
| `widget_type` | string ("plain" | "history" | "intraday_history" | "response_times" | "intraday_response_times" | "chart_only") | No | How the resource is displayed. "history" shows the daily uptime bar, "plain" hides it. |
| `status_page_id` | integer | Yes | The ID of the status page |
| `status_page_section_id` | integer | No | Move the resource to this section (use status_page_sections to list them) |

### Update status page section

**Slug:** `BETTER_STACK_MCP_UPDATE_STATUS_PAGE_SECTION`

Rename a status page section or move it by setting its position

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | No | The section heading shown to visitors |
| `position` | integer | No | Zero-based position of the section on the status page |
| `section_id` | integer | Yes | The ID of the section to update (from status_page_sections) |
| `status_page_id` | integer | Yes | The ID of the status page |
