> **Building with AI coding agents?** Install the authstack plugin with one command. This equips your agent with accurate Scalekit implementation patterns.
>
> **Recommended** (the `-y` flags skip prompts, so the command runs without an interactive terminal):
> ```bash
> npx -y @scalekit-inc/cli setup -y
> ```
>
> Global:
> ```bash
> npm install -g @scalekit-inc/cli
> scalekit setup -y
> ```
>
> Supports Claude Code, Cursor, GitHub Copilot, Codex + skills for other Agent Skills-compatible agents in `~/.agents/skills`.
> Skills: integrate-agentkit, implement-saaskit, add-mcp-oauth, implement-sso, implement-scim.
> [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Connect AI agents to the Betterstack MCP server

The Betterstack MCP connector routes your AI agent's tool calls to Betterstack's own MCP server through Scalekit. Each user signs in to Betterstack once, and Scalekit stores and refreshes their tokens, so your agent never handles credentials. It comes with 107 tools.

**Authentication:** OAuth2.1/DCR
**Categories:** Monitoring, Developer Tools
**Tools:** 107: 49 read, 49 write, 9 destructive
**Users sign in with:** OAuth
**OAuth app:** Scalekit's or your own
**Built by:** Vendor MCP
**Try it:** [Playground in the Scalekit dashboard](https://app.scalekit.com/ws/signup?sk_intent=playground&provider=BETTERSTACKMCP)

## Setup

1. ### Install the SDK

   **Node.js**

   ```bash
   npm install @scalekit-sdk/node dotenv
   ```

   **Python**

   ```bash
   pip install scalekit-sdk-python python-dotenv
   ```

2. ### Set your credentials

   Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**.

   ```sh title=".env"
   SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
   SCALEKIT_CLIENT_ID=<your-client-id>
   SCALEKIT_CLIENT_SECRET=<your-client-secret>
   ```

3. ### Create the Betterstack MCP connection

   In **AgentKit > Connections**, create a Betterstack MCP connection. The name you give it is the `connection_name` your code passes. See [Configure connections](/agentkit/connections/).

   Scalekit credentials are available for Betterstack MCP server, so you don't need to register an OAuth app.

4. ### Authorize a user and make your first call

   **Node.js** (`quickstart.mts`)

   ```typescript
   import { ScalekitClient } from '@scalekit-sdk/node'
   import 'dotenv/config'
   import { createInterface } from 'node:readline/promises'

   const scalekit = new ScalekitClient(
     process.env.SCALEKIT_ENVIRONMENT_URL,
     process.env.SCALEKIT_CLIENT_ID,
     process.env.SCALEKIT_CLIENT_SECRET,
   )
   const actions = scalekit.actions

   const connector = 'betterstackmcp'
   const identifier = 'user_123'

   // Generate an authorization link for the user
   const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
   console.log('Authorize Betterstack MCP:', link)
   const rl = createInterface({ input: process.stdin, output: process.stdout })
   await rl.question('Press Enter after authorizing...')
   rl.close()

   // Make your first call
   const result = await actions.executeTool({
     connector,
     identifier,
     toolName: 'betterstackmcp_applications',
     toolInput: {},
   })
   console.log(result)
   ```

   ```bash
   npx tsx quickstart.mts
   ```

   **Python** (`quickstart.py`)

   ```python
   import os
   from scalekit import ScalekitClient
   from dotenv import load_dotenv
   load_dotenv()

   scalekit_client = ScalekitClient(
       env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"),
       client_id=os.getenv("SCALEKIT_CLIENT_ID"),
       client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
   )
   actions = scalekit_client.actions

   connection_name = "betterstackmcp"
   identifier = "user_123"

   # Generate an authorization link for the user
   link_response = actions.get_authorization_link(
       connection_name=connection_name,
       identifier=identifier,
   )
   print("Authorize Betterstack MCP:", link_response.link)
   input("Press Enter after authorizing...")

   # Make your first call
   result = actions.execute_tool(
       tool_input={},
       tool_name="betterstackmcp_applications",
       connection_name=connection_name,
       identifier=identifier,
   )
   print(result)
   ```

   ```bash
   python quickstart.py
   ```

   Each user signs in once. See [Authorize a user](/agentkit/tools/authorize/) for the full flow and statuses.

## Tools

Pass the exact name to `execute_tool`, with an input like each tool's example. To ask for a tool that's missing, use the [request form](https://scalekitsupport.portal.usepylon.com/forms/request-a-connector-tool).

**Node.js**

```typescript
const result = await actions.executeTool({
  toolName: 'betterstackmcp_applications',
  toolInput: {},
  connector: 'betterstackmcp',
  identifier: 'user_123',
})
```

**Python**

```python
result = actions.execute_tool(
    tool_name="betterstackmcp_applications",
    tool_input={},
    connection_name="betterstackmcp",
    identifier="user_123",
)
```

`result.data` is the app's response as JSON, and `result.execution_id` (`executionId` in Node.js) is the ID of the call.

### `betterstackmcp_applications`

Applications · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

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

Example input: `{}`

### `betterstackmcp_chart_alert_help`

Chart Alert Help · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): no.

Inputs: none.

Example input: `{}`

### `betterstackmcp_chart_alerts`

Chart Alerts · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

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

Example input: `{}`

### `betterstackmcp_chart_building_help`

Chart Building Help · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): no.

Inputs: none.

Example input: `{}`

### `betterstackmcp_clusters`

Clusters · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `team_id` (`integer`, required): The ID of the team (use teams to get team IDs)

Example input: `{"team_id":1}`

### `betterstackmcp_dashboard_query_help`

Dashboard Query Help · Read-only

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`.

Read only: yes. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The source ID

Example input: `{"id":1}`

### `betterstackmcp_dashboard_templates`

Dashboard Templates · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `page` (`integer`, optional): Page number for pagination (starts at 1)
- `per_page` (`integer`, optional): Number of results per page (default: 50, max: 250)

Example input: `{}`

### `betterstackmcp_dashboards`

Dashboards · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

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

Example input: `{}`

### `betterstackmcp_data_regions`

Data Regions · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs: none.

Example input: `{}`

### `betterstackmcp_documentation`

Documentation · Read-only

Search for relevant documentation articles and return their contents

Read only: yes. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `query` (`string`, optional): The search query to find relevant documentation articles
- `url` (`string`, optional): Direct URL to a specific documentation article

Example input: `{}`

### `betterstackmcp_error`

Error · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `application_id` (`integer`, required): The ID of the application
- `pattern` (`string`, required): The error pattern identifier

Example input: `{"application_id":1,"pattern":"<pattern>"}`

### `betterstackmcp_errors`

Errors · Read-only

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.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

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

Example input: `{"application_id":1}`

### `betterstackmcp_errors_query_help`

Errors Query Help · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `application_id` (`integer`, required): The application (source) ID

Example input: `{"application_id":1}`

### `betterstackmcp_escalation_policies`

Escalation Policies · Read-only

List all escalation policies with their steps and configuration

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

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

Example input: `{}`

### `betterstackmcp_explore_logs_query_help`

Explore Logs Query Help · Read-only

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 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.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `id` (`integer`, required): The source ID
- `source_type` (`string`, optional): Type of source data to query (default: logs). One of: `logs`, `spans`.

Example input: `{"id":1}`

### `betterstackmcp_heartbeat`

Heartbeat · Read-only

Get details of a specific heartbeat

Read only: yes. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the heartbeat

Example input: `{"id":1}`

### `betterstackmcp_heartbeat_availability`

Heartbeat Availability · Read-only

Get availability summary for a specific heartbeat

Read only: yes. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the heartbeat
- `from` (`string`, optional): Start date (YYYY-MM-DD format)
- `to` (`string`, optional): End date (YYYY-MM-DD format)

Example input: `{"id":1}`

### `betterstackmcp_heartbeats`

Heartbeats · Read-only

List all heartbeats with filtering and pagination options

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

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

Example input: `{}`

### `betterstackmcp_incidents`

Incidents · Read-only

List incidents with filtering and pagination options

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `acknowledged` (`boolean`, optional): List only acknowledged incidents (true) or unacknowledged incidents (false).
- `cause` (`string`, optional): Filter by a substring of the incident cause (case-insensitive).
- `escalation_policy_ids` (`array`, optional): Filter to incidents associated with any of these escalation policies.
- `from` (`string`, optional): Return incidents from a specific date (ISO 8601 format)
- `has_comments` (`boolean`, optional): true: only incidents with comments; false: only incidents without comments.
- `has_jira_task` (`boolean`, optional): true: only incidents linked to a Jira issue; false: only those without.
- `has_linear_task` (`boolean`, optional): true: only incidents linked to a Linear issue; false: only those without.
- `has_postmortem` (`boolean`, optional): true: only incidents with a post-mortem comment; false: only those without.
- `heartbeat_id` (`integer`, optional): Filter incidents for a specific heartbeat
- `incident_group_id` (`integer`, optional): Filter to incidents within a specific incident group.
- `max_duration_minutes` (`integer`, optional): Only incidents that lasted shorter than this many minutes.
- `metadata` (`object`, optional): Filter by metadata key/value.
- `min_duration_minutes` (`integer`, optional): Only incidents that lasted longer than this many minutes.
- `monitor_id` (`integer`, optional): Filter incidents for a specific monitor
- `page` (`integer`, optional): Page number for pagination (starts at 1)
- `per_page` (`integer`, optional): Number of results per page (default: 10, max: 50)
- `resolved` (`boolean`, optional): List only resolved incidents (true) or unresolved incidents (false).
- `status` (`array`, optional): Filter by current lifecycle status. Pass an array to match any of them.
- `team_id` (`integer`, optional): Filter by team ID (use teams to get team IDs)
- `to` (`string`, optional): Return incidents until a specific date (ISO 8601 format)

Example input: `{}`

### `betterstackmcp_metric`

Metric · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `metric_name` (`string`, required): The name of the metric
- `source_id` (`integer`, required): The ID of the source

Example input: `{"metric_name":"<metric_name>","source_id":1}`

### `betterstackmcp_metric_expressions`

Metric Expressions · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `source_id` (`integer`, required): The ID of the source (use sources to get source IDs)
- `page` (`integer`, optional): Page number for pagination (starts at 1)
- `per_page` (`integer`, optional): Number of results per page (default: 50, max: 250)

Example input: `{"source_id":1}`

### `betterstackmcp_metrics_query_help`

Metrics Query Help · Read-only

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.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `id` (`integer`, required): The source ID
- `context` (`string`, optional): 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. One of: `direct_query`, `chart_query`.

Example input: `{"id":1}`

### `betterstackmcp_metrics_schema`

Metrics Schema · Read-only

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. Sources with many metrics are paginated — use the page argument to read the rest

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `id` (`integer`, required): The ID of the source
- `page` (`integer`, optional): Page number for pagination (starts at 1)
- `per_page` (`integer`, optional): Number of results per page (default: 50, max: 250)

Example input: `{"id":1}`

### `betterstackmcp_monitor_availability`

Monitor Availability · Read-only

Get availability (SLA) summary for a specific monitor

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `id` (`integer`, required): The ID of the monitor
- `from` (`string`, optional): Start date (YYYY-MM-DD format)
- `to` (`string`, optional): End date (YYYY-MM-DD format)

Example input: `{"id":1}`

### `betterstackmcp_monitor_response_times`

Monitor Response Times · Read-only

Get response time metrics for a specific monitor

Read only: yes. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the monitor

Example input: `{"id":1}`

### `betterstackmcp_monitors`

Monitors · Read-only

List monitors with optional filtering and pagination

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

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

Example input: `{}`

### `betterstackmcp_on_call`

On Call · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `date` (`string`, optional): ISO-8601 formatted date/time to look up who is on-call at that time
- `id` (`string`, optional): The ID of the on-call calendar (use "default" for team's default calendar)

Example input: `{}`

### `betterstackmcp_on_call_event`

On Call Event · Read-only

Get detailed information about a specific on-call event

Read only: yes. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `calendar_id` (`string`, required): The ID of the on-call calendar (use "default" for team's default calendar)
- `event_id` (`integer`, required): The ID of the event to retrieve

Example input: `{"calendar_id":"<calendar_id>","event_id":1}`

### `betterstackmcp_on_call_events`

On Call Events · Read-only

List all on-call schedule events for a specific calendar

Read only: yes. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`string`, required): The ID of the on-call calendar (use "default" for team's default calendar)

Example input: `{"id":"m-123"}`

### `betterstackmcp_on_call_rotation`

On Call Rotation · Read-only

Get on-call rotation configuration for a specific calendar

Read only: yes. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`string`, required): The ID of the on-call calendar (use "default" for team's default calendar)

Example input: `{"id":"m-123"}`

### `betterstackmcp_on_calls`

On Calls · Read-only

List all on-call calendars for the team

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

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

Example input: `{}`

### `betterstackmcp_query`

Query · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `query` (`string`, required): The SQL query to execute
- `source_id` (`number`, required): Source ID
- `table` (`string`, required): Table name, ie. `t123.my_source`
- `host` (`string`, optional): ClickHouse host URL.
- `password` (`string`, optional): Password for ClickHouse authentication.
- `username` (`string`, optional): Username for ClickHouse authentication.

Example input: `{"query":"<query>","source_id":1,"table":"<table>"}`

### `betterstackmcp_query_help`

Query Help · Read-only

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.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `id` (`integer`, required): The source ID
- `source_type` (`string`, required): The type of source (logs or spans). One of: `logs`, `spans`.

Example input: `{"id":1,"source_type":"logs"}`

### `betterstackmcp_releases`

Releases · Read-only

List all releases for a specific application in a paginated table format. Returns release reference, environments, first seen, and last seen timestamps

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `application_id` (`integer`, required): The ID of the application to list releases for
- `order` (`string`, optional): Sort order: 'asc' or 'desc' (default: 'desc'). One of: `asc`, `desc`.
- `page` (`integer`, optional): Page number for pagination (starts at 1)
- `per_page` (`integer`, optional): Number of results per page (default: 50, max: 250)

Example input: `{"application_id":1}`

### `betterstackmcp_replays_query_help`

Replays Query Help · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `application_id` (`integer`, required): The application (source) ID

Example input: `{"application_id":1}`

### `betterstackmcp_severities`

Severities · Read-only

List all severities (urgency levels) with their notification settings

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

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

Example input: `{}`

### `betterstackmcp_source`

Source · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `id` (`integer`, required): The ID of the source

Example input: `{"id":1}`

### `betterstackmcp_source_fields`

Source Fields · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `id` (`integer`, required): The ID of the source
- `source_type` (`string`, optional): Type of source data to query (default: logs). One of: `logs`, `spans`.

Example input: `{"id":1}`

### `betterstackmcp_sources`

Sources · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

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

Example input: `{}`

### `betterstackmcp_status_page`

Status Page · Read-only

Get details of a specific status page

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `id` (`integer`, required): The ID of the status page

Example input: `{"id":1}`

### `betterstackmcp_status_page_report_update`

Status Page Report Update · Read-only

Get details of a specific status page report update

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `report_id` (`integer`, required): The ID of the status report
- `status_page_id` (`integer`, required): The ID of the status page
- `update_id` (`integer`, required): The ID of the status update

Example input: `{"report_id":1,"status_page_id":1,"update_id":1}`

### `betterstackmcp_status_page_report_updates`

Status Page Report Updates · Read-only

List status updates for a specific status report

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `report_id` (`integer`, required): The ID of the status report
- `status_page_id` (`integer`, required): The ID of the status page
- `page` (`integer`, optional): Page number for pagination (starts at 1)
- `per_page` (`integer`, optional): Number of results per page (default: 50, max: 250)

Example input: `{"report_id":1,"status_page_id":1}`

### `betterstackmcp_status_page_reports`

Status Page Reports · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

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

Example input: `{"status_page_id":1}`

### `betterstackmcp_status_page_resources`

Status Page Resources · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `status_page_id` (`integer`, required): The ID of the status page
- `page` (`integer`, optional): Page number for pagination (starts at 1)
- `per_page` (`integer`, optional): Number of results per page (default: 50, max: 250)

Example input: `{"status_page_id":1}`

### `betterstackmcp_status_page_sections`

Get Status Page Sections · Read-only

List the sections (resource groups) of a status page.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `status_page_id` (`integer`, required): The ID of the status page
- `page` (`integer`, optional): Page number for pagination (starts at 1)
- `per_page` (`integer`, optional): Number of results per page (default: 50, max: 250)

Example input: `{"status_page_id":1}`

### `betterstackmcp_status_pages`

Status Pages · Read-only

List all status pages with filtering and pagination options

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `page` (`integer`, optional): Page number for pagination (starts at 1)
- `per_page` (`integer`, optional): Number of results per page (default: 50, max: 250)

Example input: `{}`

### `betterstackmcp_team_members`

List Team Members · Read-only

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.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

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

Example input: `{}`

### `betterstackmcp_team_roles`

List Organization Roles · Read-only

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.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `team_id` (`integer`, optional): ID of a team in the target organization. Required when the token can access more than one team.
- `team_name` (`string`, optional): Name of a team in the target organization (alternative to team_id).

Example input: `{}`

### `betterstackmcp_teams`

Teams · Read-only

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

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `search` (`string`, optional): Filter teams by name (case-insensitive partial match)

Example input: `{}`

### `betterstackmcp_acknowledge_incident`

Acknowledge Incident · Write

Acknowledge an ongoing incident

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the incident to acknowledge
- `acknowledged_by` (`string`, optional): 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.

Example input: `{"id":1}`

### `betterstackmcp_add_chart_to_dashboard`

Add Chart To Dashboard · Write

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` MUST contain `{{source}}` in the FROM clause — queries without a source variable 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')`. 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.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `chart_type` (`string`, required): Type of chart to create. One of: `line_chart`, `bar_chart`, `number_chart`, `table_chart`, `pie_chart`, `heatmap_chart`, `scatter_chart`, `gauge_chart`, `map_chart`, `hierarchy_chart`, `static_text_chart`.
- `dashboard_id` (`integer`, required): The ID of the dashboard to add the chart to
- `name` (`string`, required): Name/title for the chart
- `query` (`string`, required): SQL query. MUST contain {{source}} in FROM (hardcoded collection names are rejected). Use {{start_time}}/{{end_time}} in the time filter and {{time}} for bucketing.
- `explanation` (`string`, optional): Short description of the chart.
- `height` (`integer`, optional): Chart height in grid units (default: 8)
- `section` (`string`, optional): Section name — chart is auto-placed within it. Section auto-created if it doesn't exist.
- `settings` (`object`, optional): Chart display settings
- `width` (`integer`, optional): Chart width in grid units (1-12, default: 6)

Example input: `{"chart_type":"line_chart","dashboard_id":1,"name":"Memory Metrics","query":"<query>"}`

### `betterstackmcp_add_dashboard_section`

Add Dashboard Section · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `dashboard_id` (`integer`, required): The ID of the dashboard
- `name` (`string`, required): Section title (e.g., 'Memory Metrics', 'Network')
- `y` (`integer`, required): Y position (row) where section should appear
- `explanation` (`string`, optional): 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.

Example input: `{"dashboard_id":1,"name":"Memory Metrics","y":1}`

### `betterstackmcp_application`

Application · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the application

Example input: `{"id":1}`

### `betterstackmcp_available_incident_escalation_policies`

Available Incident Escalation Policies · Write

Get available escalation policies for an incident

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

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

Example input: `{"id":1}`

### `betterstackmcp_change_team_member_role`

Change Team Member Role · Write

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).

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

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

Example input: `{"role_id":1}`

### `betterstackmcp_chart`

Chart · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the chart to retrieve

Example input: `{"id":1}`

### `betterstackmcp_chart_alert`

Chart Alert · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the chart alert to retrieve

Example input: `{"id":1}`

### `betterstackmcp_create_application`

Create Application · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `name` (`string`, required): The name of the application
- `platform` (`string`, required): The platform of the application. One of: `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`.
- `team_id` (`integer`, required): The ID of the team to create the application in (use teams to get team IDs)
- `data_region` (`string`, optional): 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`, optional): Whether to start with ingesting paused (default: false)

Example input: `{"name":"Memory Metrics","platform":"dot_net_errors","team_id":1}`

### `betterstackmcp_create_chart_alert`

Create Chart Alert · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `alert_type` (`string`, required): Alert type: 'threshold' (fixed value), 'relative' (percentage change), 'anomaly_rrcf' (ML-based anomaly detection). One of: `threshold`, `relative`, `anomaly_rrcf`.
- `chart_id` (`integer`, required): The ID of the chart to add the alert to
- `name` (`string`, required): Name of the alert
- `operator` (`string`, required): Comparison operator. For relative type also: increases_by, decreases_by, changes_by. One of: `equal`, `higher_than`, `higher_than_or_equal`, `lower_than`, `lower_than_or_equal`, `increases_by`, `decreases_by`, `changes_by`.
- `aggregation_interval` (`integer`, optional): Data range for threshold alerts on line/bar/number charts ('on data from' in UI, default: 60s). One of: `30`, `60`, `120`, `300`, `600`, `1800`, `3600`, `7200`, `10800`, `21600`, `43200`, `86400`.
- `anomaly_sensitivity` (`integer`, optional): 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
- `anomaly_training_range_days` (`integer`, optional): 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
- `anomaly_trigger` (`string`, optional): Anomaly trigger direction: 'any' (default), 'higher', 'lower'. Only for anomaly_rrcf alerts. One of: `any`, `higher`, `lower`.
- `call` (`boolean`, optional): Phone notifications (default: false)
- `check_period` (`integer`, optional): How often to run the alert check (seconds). Max 3600 for query-period-based alerts. One of: `30`, `60`, `120`, `300`, `600`, `1800`, `3600`, `7200`, `10800`, `21600`, `43200`, `86400`.
- `confirmation_period` (`integer`, optional): How long the condition must persist before creating an incident (seconds, default: 60). One of: `0`, `30`, `60`, `120`, `300`, `600`, `1800`, `3600`, `7200`, `14400`.
- `email` (`boolean`, optional): Email notifications (default: true)
- `escalation_target` (`string`, optional): 'current_team' (default) or a GID like gid://uptime/Policy/123 or gid://uptime/Team/456
- `push` (`boolean`, optional): Push notifications (default: false)
- `query_period` (`integer`, optional): Seconds to look back for relative alerts and tail/table charts. One of: `30`, `60`, `120`, `300`, `600`, `1800`, `3600`.
- `recovery_period` (`integer`, optional): How long the condition must be resolved before auto-resolving (seconds, default: 60). One of: `0`, `30`, `60`, `120`, `300`, `600`, `1800`, `3600`, `7200`, `14400`.
- `series_names` (`array`, optional): Specific series to monitor. Empty = all series. Mutually exclusive with series_names_except
- `series_names_except` (`array`, optional): Series to exclude; alert fires on every other series. Mutually exclusive with series_names
- `shown_interval` (`integer`, optional): Anomaly chart aggregation interval (seconds). Only for anomaly_rrcf alerts. One of: `30`, `60`, `120`, `300`, `600`, `1800`, `3600`, `7200`, `10800`, `21600`, `43200`, `86400`.
- `sms` (`boolean`, optional): SMS notifications (default: false)
- `value` (`number`, optional): Threshold value (required for threshold/relative types). For relative type, this is a percentage (e.g., 50 means 50%)

Example input: `{"alert_type":"threshold","chart_id":1,"name":"Memory Metrics","operator":"equal"}`

### `betterstackmcp_create_cloud_connection`

Create Cloud Connection · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `team_id` (`integer`, required): The ID of the team (use teams to get team IDs)
- `cluster_id` (`integer`, optional): The ID of the cluster to use (required, when source_id is empty)
- `note` (`string`, optional): Optional note for the connection
- `source_id` (`integer`, optional): The ID of the source (required, when cluster_id is empty)

Example input: `{"team_id":1}`

### `betterstackmcp_create_dashboard`

Create Dashboard · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `name` (`string`, required): Name for the new dashboard
- `team_id` (`integer`, required): The ID of the team to create the dashboard in (use teams to get team IDs)
- `resource_group_name` (`string`, optional): 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.
- `source_id` (`integer`, optional): Optional source ID to preconfigure dashboard with that source's metrics
- `template_id` (`integer`, optional): Optional template ID to create dashboard from (use dashboard_templates to see available templates)

Example input: `{"name":"Memory Metrics","team_id":1}`

### `betterstackmcp_create_heartbeat`

Create Heartbeat · Write

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.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `name` (`string`, required): Human-friendly name for the heartbeat.
- `call` (`boolean`, optional): Call the on-call person when the heartbeat goes down.
- `critical_alert` (`boolean`, optional): Send critical push notifications that ignore the device mute switch and Do Not Disturb.
- `email` (`boolean`, optional): Send e-mail alerts when the heartbeat goes down.
- `grace` (`integer`, optional): Extra seconds to wait after the period elapses before reporting the heartbeat as down. Defaults to 300.
- `heartbeat_group_id` (`integer`, optional): ID of the heartbeat group to add this heartbeat to.
- `maintenance_days` (`array`, optional): Days the maintenance window applies to (e.g. ["mon", "tue", "wed"]).
- `maintenance_from` (`string`, optional): Start of a daily maintenance window during which alerts are paused (e.g. "01:00:00").
- `maintenance_timezone` (`string`, optional): Timezone for the maintenance window (e.g. "UTC", "Europe/Berlin"). Defaults to UTC.
- `maintenance_to` (`string`, optional): End of the daily maintenance window (e.g. "03:00:00").
- `paused` (`boolean`, optional): Create the heartbeat in a paused state, so it expects no requests and raises no incidents until resumed.
- `period` (`integer`, optional): 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).
- `policy_id` (`integer`, optional): ID of the escalation policy to use for alerting.
- `push` (`boolean`, optional): Send push notification alerts when the heartbeat goes down.
- `sms` (`boolean`, optional): Send SMS alerts when the heartbeat goes down.
- `sort_index` (`integer`, optional): Position of the heartbeat in the list, set to NULL to sort by creation date.
- `team_id` (`integer`, optional): 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.
- `team_wait` (`integer`, optional): Seconds to wait before escalating to the whole team.

Example input: `{"name":"Memory Metrics"}`

### `betterstackmcp_create_incident`

Create Incident · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

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

Example input: `{"summary":"<summary>","team_id":1}`

### `betterstackmcp_create_incident_comment`

Create Incident Comment · Write

Create a comment on an incident

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `content` (`string`, required): The content of the comment (Markdown is supported for formatting)
- `incident_id` (`integer`, required): The ID of the incident to comment on

Example input: `{"content":"<content>","incident_id":1}`

### `betterstackmcp_create_metric_expression`

Create Metric Expression · Write

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.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `name` (`string`, required): Metric name. Letters, numbers, and underscores only
- `source_id` (`integer`, required): The ID of the source (use sources to get source IDs)
- `sql_expression` (`string`, required): ClickHouse SQL expression evaluated against each log row (e.g. "JSONExtractInt(raw, 'status')")
- `type` (`string`, required): ClickHouse storage type for the extracted value. One of: `string`, `string_low_cardinality`, `int64_delta`, `int64`, `uint64_delta`, `uint64`, `float64_delta`, `datetime64_delta`, `boolean`.
- `aggregations` (`array`, optional): 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
- `build_type` (`string`, optional): How to process existing data: 'new_data' (default, cheap) only applies to new logs; 'historical_logs' rebuilds metrics from existing logs. One of: `new_data`, `historical_logs`.

Example input: `{"name":"Memory Metrics","source_id":1,"sql_expression":"JSONExtractInt(raw, 'status')","type":"string"}`

### `betterstackmcp_create_monitor`

Create Monitor · Write

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.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

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

Example input: `{"url":"<url>"}`

### `betterstackmcp_create_source`

Create Source · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `name` (`string`, required): The name of the source
- `platform` (`string`, required): The platform for the source (e.g., nginx, docker, kubernetes, http, vector). One of: `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`.
- `team_id` (`integer`, required): The ID of the team to create the source in (use teams to get team IDs)
- `data_region` (`string`, optional): 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.
- `ingesting_paused` (`boolean`, optional): Whether to start with ingesting paused (default: false)
- `logs_retention` (`integer`, optional): Log retention in days (default: 30)

Example input: `{"name":"Memory Metrics","platform":"apache2","team_id":1}`

### `betterstackmcp_create_status_page_report`

Create Status Page Report · Write

Create a new status page report

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `message` (`string`, required): The initial status update message
- `status_page_id` (`integer`, required): The ID of the status page
- `title` (`string`, required): The title of the status report
- `affected_resources` (`array`, optional): Array of affected resources with status_page_resource_id and status
- `ends_at` (`string`, optional): End time for the report (ISO 8601 format, required for maintenance reports)
- `notify_subscribers` (`boolean`, optional): Whether to notify subscribers via email (default: false)
- `published_at` (`string`, optional): When the report should be published (ISO 8601 format, default: now)
- `report_type` (`string`, optional): Type of report - manual (incident) or maintenance (default: manual). One of: `manual`, `maintenance`.
- `starts_at` (`string`, optional): Start time for the report (ISO 8601 format)
- `team_id` (`integer`, optional): 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

Example input: `{"message":"<message>","status_page_id":1,"title":"<title>"}`

### `betterstackmcp_create_status_page_report_update`

Create Status Page Report Update · Write

Create a new status update for an existing status page report

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

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

Example input: `{"affected_resources":[],"report_id":1,"status_page_id":1}`

### `betterstackmcp_create_status_page_resource`

Create Status Page Resource · Write

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.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

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

Example input: `{"public_name":"<public_name>","resource_id":1,"resource_type":"Monitor","status_page_id":1}`

### `betterstackmcp_create_status_page_section`

Create Status Page Section · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `name` (`string`, required): The section heading shown to visitors
- `status_page_id` (`integer`, required): The ID of the status page
- `position` (`integer`, optional): Zero-based position of the section on the status page
- `team_id` (`integer`, optional): The ID of the team that owns the status page. Required only when the API token has access to multiple teams.

Example input: `{"name":"Memory Metrics","status_page_id":1}`

### `betterstackmcp_dashboard`

Dashboard · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the dashboard to retrieve

Example input: `{"id":1}`

### `betterstackmcp_edit_application`

Edit Application · Write

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.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the application to edit
- `ingesting_paused` (`boolean`, optional): Set to true to temporarily pause data ingesting for this application, false to resume it
- `name` (`string`, optional): New name for the application
- `vrl_transformation_exceptions` (`string`, optional): 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_logs` (`string`, optional): VRL transformation applied to logs during ingestion. Set to an empty string to remove, omit to leave unchanged.
- `vrl_transformation_replays` (`string`, optional): VRL transformation applied to session replays during ingestion. Set to an empty string to remove, omit to leave unchanged.
- `vrl_transformation_spans` (`string`, optional): VRL transformation applied to traces (spans) during ingestion. Set to an empty string to remove, omit to leave unchanged.
- `vrl_transformation_web_events` (`string`, optional): VRL transformation applied to web events (page views and web vitals) during ingestion. Set to an empty string to remove, omit to leave unchanged.

Example input: `{"id":1}`

### `betterstackmcp_edit_chart`

Edit Chart · Write

Edit an existing chart name, query, type, or settings. Only provide the fields you want to change. If changing the query: the new query MUST contain `{{source}}` in the FROM clause (queries without a source variable 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` or `query` before saving. Call `chart_building_help` for chart/settings reference.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the chart to edit
- `chart_type` (`string`, optional): New chart type. One of: `line_chart`, `bar_chart`, `number_chart`, `table_chart`, `pie_chart`, `heatmap_chart`, `scatter_chart`, `gauge_chart`, `map_chart`, `hierarchy_chart`, `static_text_chart`.
- `explanation` (`string`, optional): Short description of the chart. Set to empty string to clear.
- `height` (`integer`, optional): New height in grid units (1-50).
- `name` (`string`, optional): New name for the chart
- `query` (`string`, optional): New SQL query. MUST contain {{source}} in FROM (hardcoded collection names are rejected). Use {{start_time}}/{{end_time}} in the time filter and {{time}} for bucketing.
- `settings` (`object`, optional): Chart display settings
- `width` (`integer`, optional): New width in grid units (1-12). Grid is 12 columns wide.

Example input: `{"id":1}`

### `betterstackmcp_edit_chart_alert`

Edit Chart Alert · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the chart alert to edit
- `aggregation_interval` (`integer`, optional): Data range for threshold alerts ('on data from' in UI). One of: `30`, `60`, `120`, `300`, `600`, `1800`, `3600`, `7200`, `10800`, `21600`, `43200`, `86400`.
- `alert_type` (`string`, optional): New alert type. One of: `threshold`, `relative`, `anomaly_rrcf`.
- `anomaly_sensitivity` (`integer`, optional): 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
- `anomaly_training_range_days` (`integer`, optional): 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
- `anomaly_trigger` (`string`, optional): Anomaly trigger: 'any', 'higher', 'lower'. One of: `any`, `higher`, `lower`.
- `call` (`boolean`, optional): Phone notifications
- `check_period` (`integer`, optional): How often to run the alert check (seconds). One of: `30`, `60`, `120`, `300`, `600`, `1800`, `3600`, `7200`, `10800`, `21600`, `43200`, `86400`.
- `confirmation_period` (`integer`, optional): How long the condition must persist before creating an incident (seconds). One of: `0`, `30`, `60`, `120`, `300`, `600`, `1800`, `3600`, `7200`, `14400`.
- `email` (`boolean`, optional): Email notifications
- `escalation_target` (`string`, optional): 'current_team' or a GID like gid://uptime/Policy/123 or gid://uptime/Team/456
- `incident_per_series` (`boolean`, optional): When true, each alerting series opens its own incident instead of one shared incident
- `name` (`string`, optional): New name for the alert
- `operator` (`string`, optional): New comparison operator. One of: `equal`, `higher_than`, `higher_than_or_equal`, `lower_than`, `lower_than_or_equal`, `increases_by`, `decreases_by`, `changes_by`.
- `push` (`boolean`, optional): Push notifications
- `query_period` (`integer`, optional): Seconds to look back for relative alerts. One of: `30`, `60`, `120`, `300`, `600`, `1800`, `3600`.
- `recovery_period` (`integer`, optional): How long the condition must be resolved before auto-resolving (seconds). One of: `0`, `30`, `60`, `120`, `300`, `600`, `1800`, `3600`, `7200`, `14400`.
- `series_names` (`array`, optional): Specific series to monitor. Mutually exclusive with series_names_except
- `series_names_except` (`array`, optional): Series to exclude; alert fires on every other series. Mutually exclusive with series_names
- `shown_interval` (`integer`, optional): Anomaly chart aggregation interval (seconds). One of: `30`, `60`, `120`, `300`, `600`, `1800`, `3600`, `7200`, `10800`, `21600`, `43200`, `86400`.
- `sms` (`boolean`, optional): SMS notifications
- `value` (`number`, optional): New threshold value

Example input: `{"id":1}`

### `betterstackmcp_edit_dashboard`

Edit Dashboard · Write

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.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the dashboard to edit
- `name` (`string`, optional): New name for the dashboard
- `source_eligibility_sql` (`string`, optional): Source eligibility SQL — the ClickHouse query that decides which sources (and services) the dashboard applies to.

Example input: `{"id":1}`

### `betterstackmcp_edit_dashboard_section`

Edit Dashboard Section · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

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

Example input: `{"id":1}`

### `betterstackmcp_escalate_incident`

Escalate Incident · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

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

Example input: `{"escalation_type":"<escalation_type>","id":1}`

### `betterstackmcp_escalation_policy`

Escalation Policy · Write

Get detailed information about a specific escalation policy

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the escalation policy

Example input: `{"id":1}`

### `betterstackmcp_export_dashboard`

Export Dashboard · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the dashboard or dashboard template to export

Example input: `{"id":1}`

### `betterstackmcp_import_dashboard`

Import Dashboard · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `data` (`string`, required): The dashboard data as a JSON string (can be obtained from export_dashboard)
- `name` (`string`, required): The name for the new dashboard
- `team_id` (`integer`, required): The ID of the team to import the dashboard into (use teams to get team IDs)

Example input: `{"data":"<data>","name":"Memory Metrics","team_id":1}`

### `betterstackmcp_incident`

Incident · Write

Get detailed information about a specific incident

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the incident to retrieve

Example input: `{"id":1}`

### `betterstackmcp_incident_comments`

Incident Comments · Write

Get comments for an incident

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `incident_id` (`integer`, required): The ID of the incident

Example input: `{"incident_id":1}`

### `betterstackmcp_incident_timeline`

Incident Timeline · Write

Get the timeline of events for an incident

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the incident

Example input: `{"id":1}`

### `betterstackmcp_invite_team_member`

Invite Team Member · Write

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; an organization-wide role they hold (Admin, Billing admin) is kept. If the token can reach more than one team, pass team_id (or team_name).

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

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

Example input: `{"email":"<email>"}`

### `betterstackmcp_monitor`

Monitor · Write

Get details of a specific monitor

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the monitor

Example input: `{"id":1}`

### `betterstackmcp_move_charts`

Move Charts · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `dashboard_id` (`integer`, required): The ID of the dashboard
- `moves` (`array`, required): Array of chart moves

Example input: `{"dashboard_id":1,"moves":[]}`

### `betterstackmcp_render_chart`

Render Chart · Write

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).

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `query` (`string`, required): The SQL query to execute
- `source_id` (`number`, required): Source ID
- `table` (`string`, required): Table name, ie. `t123.my_source`
- `chart_type` (`string`, optional): 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). One of: `line`, `bar`, `pie`.
- `host` (`string`, optional): ClickHouse host URL.
- `name` (`string`, optional): Chart name or title.
- `password` (`string`, optional): Password for ClickHouse authentication.
- `stacked` (`boolean`, optional): Stack the series on top of each other. Applies to `line` and `bar` charts.
- `username` (`string`, optional): Username for ClickHouse authentication.

Example input: `{"query":"<query>","source_id":1,"table":"<table>"}`

### `betterstackmcp_reopen_incident`

Reopen Incident · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the incident to reopen
- `reopened_by` (`string`, optional): User email or identifier of who reopened the incident.

Example input: `{"id":1}`

### `betterstackmcp_resolve_incident`

Resolve Incident · Write

Resolve an ongoing incident

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the incident to resolve
- `resolved_by` (`string`, optional): User email or identifier of who resolved the incident.

Example input: `{"id":1}`

### `betterstackmcp_set_dashboard_variable`

Set Dashboard Variable · Write

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 (Static list) uses default_values (first = default selection); select_with_sql (Dynamic list) uses an option-yielding expression in sql_definition, e.g. label('_host'); both list types accept allow_multiple_values to let users pick several options at once; select_predefined_sql (Query per value) uses named full-query SQL filters in `filters`, default picked via selected_label; string/number/boolean use default_values as [default]; sql_expression uses default_values as [raw SQL] spliced unescaped; source uses source_ids to pick which sources the variable resolves to; date/datetime use an ISO date in default_values. SQL-backed types are validated at save time by running their SQL against the dashboard's source. The names source, start_time, end_time, and time are reserved.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `dashboard_id` (`integer`, required): The ID of the dashboard
- `name` (`string`, required): Variable name used as {{name}} in chart queries
- `variable_type` (`string`, required): The variable type. One of: `string`, `number`, `boolean`, `sql_expression`, `date`, `datetime`, `source`, `select_value`, `select_with_sql`, `multi_select_with_sql`, `select_predefined_sql`.
- `allow_multiple_values` (`boolean`, optional): select_value / select_with_sql: let users pick several options at once; the variable then interpolates as a quoted regex used with match(), never IN. Ignored for other types.
- `default_values` (`array`, optional): 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'].
- `filters` (`array`, optional): 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}}.
- `selected_label` (`string`, optional): select_predefined_sql: the default filter label.
- `source_ids` (`array`, optional): source: the source IDs this variable resolves to (must be accessible to the dashboard's team). Ignored for other types.
- `sql_definition` (`string`, optional): select_with_sql / multi_select_with_sql: an expression (NOT a full query) yielding the option values — interpolated as SELECT DISTINCT <sql_definition> AS option FROM {{source}} WHERE dt BETWEEN {{start_time}} AND {{end_time}} LIMIT 50. Example: label('_host').

Example input: `{"dashboard_id":1,"name":"Memory Metrics","variable_type":"string"}`

### `betterstackmcp_severity`

Severity · Write

Get detailed information about a specific severity (urgency level)

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the severity

Example input: `{"id":1}`

### `betterstackmcp_toggle_chart_alert_pause`

Toggle Chart Alert Pause · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the chart alert
- `paused` (`boolean`, required): Set to true to pause, false to unpause

Example input: `{"id":1,"paused":true}`

### `betterstackmcp_update_error_state`

Update Error State · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `application_id` (`integer`, required): The ID of the application
- `pattern` (`string`, required): The error pattern identifier
- `state` (`string`, required): The target state. One of: `ignored`, `resolved`, `unresolved`.
- `ignore_next_count` (`integer`, optional): Number of next occurrences to ignore (only valid when state is 'ignored'). Must be 1, 10, 100, or 1000. One of: `1`, `10`, `100`, `1000`.
- `notify_every_exception` (`boolean`, optional): Whether to notify for every occurrence of this error
- `resolve_in_release` (`string`, optional): 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'. One of: `current`.

Example input: `{"application_id":1,"pattern":"<pattern>","state":"ignored"}`

### `betterstackmcp_update_metric_expression`

Update Metric Expression · Write

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.

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

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

Example input: `{"id":"m-123","source_id":1}`

### `betterstackmcp_update_status_page`

Update Status Page · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

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

Example input: `{"id":1}`

### `betterstackmcp_update_status_page_resource`

Update Status Page Resource · Write

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.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

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

Example input: `{"resource_id":1,"status_page_id":1}`

### `betterstackmcp_update_status_page_section`

Update Status Page Section · Write

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

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `section_id` (`integer`, required): The ID of the section to update (from status_page_sections)
- `status_page_id` (`integer`, required): The ID of the status page
- `name` (`string`, optional): The section heading shown to visitors
- `position` (`integer`, optional): Zero-based position of the section on the status page

Example input: `{"section_id":1,"status_page_id":1}`

### `betterstackmcp_delete_chart_alert`

Delete Chart Alert · Destructive

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

Read only: no. Destructive: yes. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the chart alert to delete

Example input: `{"id":1}`

### `betterstackmcp_delete_metric_expression`

Delete Metric Expression · Destructive

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.

Read only: no. Destructive: yes. Idempotent (safe to retry): no.

Inputs:

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

Example input: `{"id":"m-123","source_id":1}`

### `betterstackmcp_remove_chart`

Remove Chart · Destructive

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

Read only: no. Destructive: yes. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the chart to remove

Example input: `{"id":1}`

### `betterstackmcp_remove_dashboard`

Remove Dashboard · Destructive

Remove a dashboard permanently. This action cannot be undone

Read only: no. Destructive: yes. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the dashboard to remove

Example input: `{"id":1}`

### `betterstackmcp_remove_dashboard_section`

Remove Dashboard Section · Destructive

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

Read only: no. Destructive: yes. Idempotent (safe to retry): no.

Inputs:

- `id` (`integer`, required): The ID of the section to remove

Example input: `{"id":1}`

### `betterstackmcp_remove_dashboard_variable`

Remove Dashboard Variable · Destructive

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.

Read only: no. Destructive: yes. Idempotent (safe to retry): no.

Inputs:

- `dashboard_id` (`integer`, required): The ID of the dashboard
- `name` (`string`, required): Name of the variable to remove

Example input: `{"dashboard_id":1,"name":"Memory Metrics"}`

### `betterstackmcp_remove_status_page_resource`

Remove Status Page Resource · Destructive

Remove a resource from a status page.

Read only: no. Destructive: yes. Idempotent (safe to retry): no.

Inputs:

- `resource_id` (`integer`, required): The ID of the status page resource to remove (from status_page_resources)
- `status_page_id` (`integer`, required): The ID of the status page

Example input: `{"resource_id":1,"status_page_id":1}`

### `betterstackmcp_remove_status_page_section`

Remove Status Page Section · Destructive

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

Read only: no. Destructive: yes. Idempotent (safe to retry): no.

Inputs:

- `section_id` (`integer`, required): The ID of the section to remove (from status_page_sections)
- `status_page_id` (`integer`, required): The ID of the status page

Example input: `{"section_id":1,"status_page_id":1}`

### `betterstackmcp_remove_team_member`

Remove Team Member · Destructive

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.

Read only: no. Destructive: yes. Idempotent (safe to retry): no.

Inputs:

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

Example input: `{}`

## Related

Other Monitoring connectors ([all 22](/agentkit/connectors/?category=monitoring)):

- [Datadog](/agentkit/connectors/datadog/): Scalekit connector, API key, 105 tools
- [PagerDuty](/agentkit/connectors/pagerduty/): Scalekit connector, OAuth, 71 tools
- [Agency Analytics MCP server](/agentkit/connectors/agencyanalyticsmcp/): Vendor MCP, OAuth, 35 tools


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
