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

# Honeycomb MCP

Honeycomb is an observability platform for high-cardinality event data. The Honeycomb MCP server lets agents query datasets, run analyses and inspect telemetry.

- **Category:** developer tools
- **Auth:** DCR_OAUTH
- **Composio-managed OAuth available?** No
- **Tools:** 33
- **Triggers:** 0
- **Slug:** `HONEYCOMB_MCP`
- **Version:** 20260910_00

## Tools

### Canvas agent invoke

**Slug:** `HONEYCOMB_MCP_CANVAS_AGENT_INVOKE`

Kick off a single-turn run of the Honeycomb Canvas agent. Pass investigation_id to extend an existing investigation visible to the caller's team. Omit investigation_id to create a new investigation for this prompt; the new ID is returned in the response so the caller can reuse it on follow-up calls. Returns one of: status='running' with a session_id (call canvas_agent_poll_response next); status='busy' with a message (the user is mid-turn — wait at least 30 seconds, then retry, do NOT loop). Both responses also include investigation_url, a direct browser link to the canvas. On 'running', poll repeatedly until poll returns status='completed' or 'error'. Each poll waits up to 50 seconds. Best for asking the agent to summarize findings, run additional analysis, or kick off a new investigation.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `title` | string | No | Optional title for a newly-created investigation. Ignored when investigation_id is provided. Defaults to an auto-generated title. |
| `prompt` | string | Yes | Prompt to send to the canvas agent. Will be wrapped in <instructions> tags before delivery. |
| `investigation_id` | string | No | ID of an existing investigation (e.g. 'hcciv_…'). Omit to create a new investigation for this prompt. |

### Canvas agent poll response

**Slug:** `HONEYCOMB_MCP_CANVAS_AGENT_POLL_RESPONSE`

Poll for the result of a previously-issued canvas_agent_invoke call. Pass the investigation_id and session_id returned from canvas_agent_invoke. Each call waits up to wait_seconds (default 30, max 50) for a terminal event, then returns either status='completed' with the agent's chat reply, status='error' with a message, status='busy' if another invocation is contending for the same agent (retry canvas_agent_invoke), or status='running' if the agent is still working — in which case call this tool again with the same parameters. Cap on wait_seconds is intentional: longer single waits get killed by network infrastructure.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `session_id` | string | Yes | session_id returned from canvas_agent_invoke. Identifies which invocation to wait on. |
| `wait_seconds` | integer | No | Maximum whole seconds to wait for a terminal event before returning a 'running' response. Default 30, max 50. |
| `investigation_id` | string | Yes | ID of the investigation passed to canvas_agent_invoke (e.g. 'hcciv_…'). |

### Create board

**Slug:** `HONEYCOMB_MCP_CREATE_BOARD`

Create a board (dashboard) with query, SLO, and text panels.

When to use:
  - "Create a dashboard for service X" / "build a board with latency and error queries" — primary creation path.
  - After running queries and collecting their run IDs, assembling them into a board for sharing.
  - When a user wants an overview with both SLOs and queries side by side.
  - Before creating, call list_boards to check whether a similar board already exists.

Pairs with: list_boards (discover existing boards and tag conventions), get_slos (get SLO IDs for panels), find_queries (locate saved query IDs).

Panel type discriminator: each panel's "type" field determines which other fields are required.
  - type="query": id (query run PK) is required; name/description/chart_type/display_style/thresholds are optional.
  - type="slo":   id (SLO PK) is required.
  - type="text":  content (Markdown string, max 10 000 chars) is required; id must be omitted.

Panels render in the order you specify in the array. Size is optional (width 1-12, height in rows); omit size for auto-layout.
Thresholds (max 5 per chart) draw horizontal lines on query panel charts; each needs value + operation (gt/lt) + color + line_style, and optionally label and chart_index. Supported for chart_type 'default'/'line'/'stacked'/'bar'/'stat'; not for 'categorical_bar'/'pie'.
Preset filters (max 5) add filterable column dropdowns to the board — each needs column + alias.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | Yes | Board name. Maximum 255 characters. |
| `tags` | array | No | Tags in 'key:value' format (e.g. ['team:platform', 'tier:critical']). Keys: lowercase letters only, max 32 chars. Values: start with lowercase letter, alphanumeric plus '/' and '-', max 128 chars. |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `panels` | array | Yes | Ordered array of panels. Each panel has a required 'type' discriminator ('query', 'slo', or 'text') that determines which other fields are required. Panels render in array order. |
| `private` | boolean | No | When true the board is only visible to its creator. Defaults to false. |
| `description` | string | No | Board description (optional). |
| `preset_filters` | array | No | Up to 5 preset filter dropdowns for the board. Each creates a column-filter widget visible to all board viewers. Both column and alias are required per filter. |
| `environment_slug` | string | Yes | Environment slug where the board will be created. |

### Create marker

**Slug:** `HONEYCOMB_MCP_CREATE_MARKER`

Creates a marker (a vertical annotation on charts) to mark a point or window in time, such as a deploy, incident, or config change. Scope it to one dataset or, with dataset_slug='__all__', the whole environment.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `to` | string | No | Optional marker end time. Omit for a point marker; when present, it may equal from and must not be before from. Future marker times are allowed for scheduled events. Accepted timestamps are positive epoch seconds (at most 10 digits), RFC3339/ISO datetimes, or date-only values. Tool schemas require timestamps as strings, so quote epoch seconds (for example, "1723593600"). Zone-less datetimes and dates are UTC; dates mean midnight UTC (for an in-progress UTC day, use to: "now"). Relative values are "now" or explicitly signed durations such as "-2h" using lower-case s, m, h, d, or w. |
| `url` | string | No | Optional URL to link from the marker (max 8000 characters). |
| `from` | string | No | Marker start time. Defaults to now when omitted. Unlike read-tool ranges, future marker times are allowed for scheduled events. Accepted timestamps are positive epoch seconds (at most 10 digits), RFC3339/ISO datetimes, or date-only values. Tool schemas require timestamps as strings, so quote epoch seconds (for example, "1723593600"). Zone-less datetimes and dates are UTC; dates mean midnight UTC (for an in-progress UTC day, use to: "now"). Relative values are "now" or explicitly signed durations such as "-2h" using lower-case s, m, h, d, or w. |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `type` | string | No | Optional marker type (e.g. 'deploy', 'incident'). Markers of the same type share a color. |
| `message` | string | Yes | Marker label shown on the chart (required). |
| `dataset_slug` | string | Yes | Dataset slug (required). Use '__all__' for an environment-wide marker that appears on every dataset. |
| `environment_slug` | string | Yes | Environment slug where the marker will be created. |

### Create recipient

**Slug:** `HONEYCOMB_MCP_CREATE_RECIPIENT`

Create a notification recipient (email, Slack, PagerDuty, or webhook) so it can be attached to triggers and SLO burn alerts.

When to use:
  - "Alert the on-call channel when this trigger fires" — create a Slack recipient first, then pass its ID to create_trigger.
  - "Page the on-call team via PagerDuty" — create a pagerduty recipient with the integration key.
  - "Send a webhook when an SLO burns" — create a webhook recipient with optional custom headers and payload templates.
  - Before calling create_trigger or update_trigger when no suitable recipient exists in list_recipients.

Required fields per type:
  - type="email":     email_address
  - type="slack":     slack_channel (team must have Slack OAuth configured)
  - type="pagerduty": pagerduty_integration_key
  - type="webhook":   webhook_url + webhook_name

Pairs with: create_trigger, update_trigger (consume the returned recipient ID), list_recipients (check existing recipients before creating).

<gotchas>
- Slack recipients require your Honeycomb team to have Slack OAuth already configured; the call will fail with an error if it is not.
- Webhook custom headers cannot override Content-Type, User-Agent, or X-Honeycomb-Webhook-Token (max 5 headers).
- Webhook payload template variables: names must start with a lowercase letter; subsequent characters can be letters (upper or lower) or digits (max 10 variables, max 64 chars per name).
</gotchas>

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `type` | string ("email" | "slack" | "pagerduty" | "webhook") | Yes | Recipient type. Determines which additional fields are required. |
| `webhook_url` | string | No | Webhook endpoint URL. Required when type=webhook. |
| `webhook_name` | string | No | Display name for the webhook. Required when type=webhook. |
| `email_address` | string | No | Email address. Required when type=email. |
| `slack_channel` | string | No | Slack channel name or ID (e.g. '#alerts-prod'). Required when type=slack. Team must have Slack OAuth configured. |
| `webhook_secret` | string | No | Secret sent as the X-Honeycomb-Webhook-Token header (optional). Lets the receiving server verify the request origin. |
| `webhook_headers` | array | No | Custom HTTP headers for webhook requests (optional, max 5). Cannot override Content-Type, User-Agent, or X-Honeycomb-Webhook-Token. |
| `webhook_payloads` | object | No | Custom payload templates (optional). Lets you control the JSON body sent for each notification event type. Template variables use {{variable_name}} syntax. |
| `pagerduty_integration_key` | string | No | PagerDuty Events API v2 integration key. Required when type=pagerduty. |
| `pagerduty_integration_name` | string | No | Display name for the PagerDuty integration (optional). |

### Create slo

**Slug:** `HONEYCOMB_MCP_CREATE_SLO`

Create an SLO (Service Level Objective) backed by an auto-created SLI derived column.

When to use:
  - "Create an SLO for API latency" / "set a 99.9% availability target" — primary creation path.
  - When a user asks to track reliability for a service over a rolling time window.
  - After creating an SLO, call create_trigger with a baseline or threshold to alert on SLO burn.

Pairs with: get_slos (list existing SLOs before creating), update_slo (adjust target or window after creation), create_trigger (fire a burn alert when error budget is draining fast).

SLI expression syntax: Boolean derived-column expressions referencing span fields with a $ prefix.
  - LT($duration_ms, 1000)       — true when latency < 1 000 ms
  - EQUALS($http.status_code, 200) — true when status is 200
  - EQUALS($error, false)         — true when no error flag is set

target_per_million encoding: multiply the percentage by 10 000.
  - 99.9%  → 999000
  - 99.5%  → 995000
  - 99.0%  → 990000

Derived column auto-create behavior: the tool validates the SLI expression before persisting the derived column. Invalid SLI expressions are rejected without creating the derived column. If a matching SLI derived column already exists, it is reused rather than duplicated.

Multi-dataset SLOs: when dataset_slugs contains more than one slug, the SLI must be an environment-wide (shared) derived column — the tool handles this automatically, but both datasets must exist.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sli` | object | Yes | SLI (Service Level Indicator) definition. The derived column is auto-created if it does not exist. |
| `name` | string | Yes | SLO name. Maximum 255 characters. |
| `tags` | array | No | Tags in 'key:value' format (e.g. ['team:platform', 'tier:critical']). |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `description` | string | No | Human-readable SLO description (optional). |
| `dataset_slugs` | array | Yes | One or more dataset slugs this SLO applies to. For multi-dataset SLOs the SLI must be an environment-wide derived column (the tool manages this automatically). |
| `environment_slug` | string | Yes | Environment slug where the SLO will be created. |
| `time_period_days` | integer | Yes | Rolling evaluation window in whole days (minimum 1). Common values: 7, 28, 30. |
| `target_per_million` | integer | Yes | Success target expressed as whole parts-per-million (0-999999). Examples: 999000 = 99.9%, 995000 = 99.5%, 990000 = 99.0%. |

### Create trigger

**Slug:** `HONEYCOMB_MCP_CREATE_TRIGGER`

Create a trigger that fires alerts when a query result crosses a threshold.

When to use:
  - "Alert me when error rate exceeds 5%" / "page on-call when request count drops below 100" — primary alerting path.
  - "Create a trigger that only fires during business hours" — use evaluation_schedule with type=window.
  - "Alert when traffic is 50% above last week's baseline" — use baseline_details.
  - After creating an SLO, create a paired trigger with baseline_details to detect accelerating budget burn.

Pairs with: list_recipients / create_recipient (obtain recipient IDs before creating the trigger), find_queries (locate a saved query to reference by query_id), get_triggers (verify after creation).

Query source — mutually exclusive, exactly one required:
  - query:    inline query spec (calculations required; filters, breakdowns, formulas optional).
  - query_id: ID of a saved query (from find_queries). Cannot provide both.

Frequency encoding: frequency is in seconds (e.g. 900 = 15 min evaluation cycle).

<gotchas>
- query and query_id are mutually exclusive. Providing both returns an error.
- Baseline triggers: threshold.op must be '>=' or '<=' (not '>' or '<'). The comparison is at the boundary because the baseline value is a ratio, and strict inequality against a ratio wouldn't resolve reliably.
- Evaluation window vs frequency: when evaluation_schedule.type='window', the window duration must be at least 2x the trigger frequency.
- formula passthrough pattern: when your inline query has formulas, add a passthrough formula (not calculation) — e.g. {"name":"volume","expression":"$all_requests"} — that aliases an existing calculation by name so it is directly addressable in ordering or threshold expressions.
- frequency must be 60-86400 seconds and a multiple of 60.
</gotchas>

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | Yes | Trigger name (required). |
| `tags` | array | No | Tags in 'key:value' format (optional, e.g. ['team:platform', 'service:api']). |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `query` | object | No | Inline query spec. Mutually exclusive with 'query_id' — provide exactly one. |
| `disabled` | boolean | No | Create the trigger in a disabled state (optional, default false). |
| `query_id` | string | No | Saved query ID. Mutually exclusive with 'query' — provide exactly one. Obtain IDs from find_queries. |
| `frequency` | integer | No | Evaluation interval in whole seconds (optional, default 900). Must be 60-86400 and a multiple of 60. |
| `threshold` | object | Yes | Threshold configuration (required). Defines the condition that fires the trigger. |
| `alert_type` | string ("on_change" | "on_true") | No | Alert behavior (optional, default 'on_change'). 'on_change' fires only when state transitions (firing→resolved or vice versa); 'on_true' fires on every cycle the condition is met. |
| `recipients` | array | No | Recipient IDs to notify when the trigger fires (optional). Obtain IDs from list_recipients or create_recipient. |
| `description` | string | No | Trigger description (optional). |
| `dataset_slug` | string | Yes | Dataset slug (required). Use '__all__' for environment-wide triggers that span all datasets. |
| `baseline_details` | object | No | Compare current query values against a historical baseline (optional). When provided, threshold.op must be '>=' or '<=' — the comparison is at the boundary because the value is a ratio. |
| `environment_slug` | string | Yes | Environment slug (required). |
| `evaluation_schedule` | object | No | Restrict evaluation to specific time windows (optional). When type='window', the trigger only evaluates during the specified hours and days. The window duration must be at least 2x the trigger frequency. |

### Feedback

**Slug:** `HONEYCOMB_MCP_FEEDBACK`

Submit feedback about Honeycomb's MCP server to the agentic-intelligence team.

When to use:
  - A tool returned unexpected, wrong, or confusing data.
  - You wanted a capability that no tool in this server provides.
  - A workflow felt unnecessarily clunky or required too many tool calls.
  - A tool description was misleading and caused you to use the wrong tool.

Be specific: name the tool you used, what you tried, what you expected, and what you observed. Vague feedback is hard to act on.

Pairs with: any tool — call this after completing (or failing) a task to report quality issues.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `feedback_body` | string | No | Specific, human-readable description of the issue or suggestion. Include: which tool you used, what you tried, what you expected, what you observed. |

### Find columns

**Slug:** `HONEYCOMB_MCP_FIND_COLUMNS`

Search for columns and calculated fields by intent across one or all datasets in an environment.

When to use:
  - "What column has the error rate?" / "Find columns related to duration or latency" — intent-based discovery.
  - Before composing a run_query, to confirm that columns with the right names exist.
  - When you are not sure which dataset contains the column you need (omit dataset_slug to search all).
  - After get_dataset_columns returns too many results to scan, use this to narrow by semantic relevance.

Difference from get_dataset_columns: this tool ranks results by relevance to your search input across all datasets; get_dataset_columns returns the complete schema for one specific dataset.

Pairs with: get_dataset_columns (full schema once you know the right dataset); run_query (use validated column names here); get_dataset (confirm dataset exists before scoping search).

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | number | No | Page number for paginated results. Defaults to 1. |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `input` | string | Yes | Natural language or keywords describing the column you are looking for (e.g. 'http status code', 'request duration', 'user identifier'). |
| `dataset_slug` | string | No | Scope search to this dataset slug. Omit to search all datasets in the environment. Only specify when you are confident about the correct dataset. |
| `items_per_page` | number | No | Number of items per page. Defaults to 50. |
| `environment_slug` | string | Yes | Environment slug to search within. |
| `include_expressions` | boolean | No | When true, includes the expression for calculated fields in the response. Defaults to false. |

### Find queries

**Slug:** `HONEYCOMB_MCP_FIND_QUERIES`

Search query history and saved queries by intent; returns matching queries with their run PKs.

When to use:
  - "Has anyone queried the error rate for checkout?" — check existing work before composing a new query.
  - Before calling run_query, verify a semantically similar query does not already exist.
  - "Show me recent queries for service X" — surface what the team has been investigating.
  - When the user pastes a query name or description and wants to find the underlying spec.

Returns query specifications and run_pks. Pass a run_pk to get_query_results to retrieve the full results from that specific execution.

Pairs with: get_query_results (fetch results from a returned run_pk); run_query (run a new query once you've confirmed no similar one exists); create_board (add a found query_id as a panel).

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `input` | string | Yes | Natural language or keywords describing the queries you are looking for. |
| `max_queries` | integer | No | Maximum number of queries to return (1-50). Defaults to 25. |
| `dataset_slug` | string | No | Scope search to this dataset slug. Omit to search all datasets in the environment. |
| `recency_days` | integer | No | Consider queries executed within the last N days (1-365). Defaults to 30. Lower values surface more recent work. |
| `environment_slug` | string | Yes | Environment slug to search within. |

### Get aiconversation

**Slug:** `HONEYCOMB_MCP_GET_AICONVERSATION`

Fetch the full event timeline for a single AI conversation, identified by its OpenTelemetry gen_ai.conversation.id attribute value.
Prefer this over ad-hoc run_query filtered by conversation ID — it returns every LLM call, tool call, and related agent/task event
(with span name, operation/category, agent name, model, tool name, duration, and error detail per event) plus an aggregate summary
(LLM call count, tool call count, failure count, total tokens, total duration) in one call.
Use it to debug or analyze one specific AI conversation end-to-end.

PERFORMANCE: If you know a timestamp for any event, pass event_timestamp. It anchors the retention-capped lookup window ending at that timestamp and skips the backwards probe scan.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `conversation_id` | string | Yes | The gen_ai.conversation.id value identifying the conversation. Pass it as-is when the user or a prior tool result already supplied one; otherwise find conversations with list_aiconversations (its Conversation ID column). |
| `event_timestamp` | string | No | Optional timestamp of an event in the conversation. When provided, it anchors the retention-capped lookup window ending at that timestamp and skips the backwards probe scan. It must not be in the future. Accepted timestamps are positive epoch seconds (at most 10 digits), RFC3339/ISO datetimes, or date-only values. Tool schemas require timestamps as strings, so quote epoch seconds (for example, "1723593600"). Zone-less datetimes and dates are UTC; dates mean midnight UTC (for an in-progress UTC day, use to: "now"). Relative values are "now" or explicitly signed durations such as "-2h" using lower-case s, m, h, d, or w. |
| `environment_slug` | string | Yes | Environment slug to query. Source from get_workspace_context or a prior tool result rather than guessing. |

### Get dataset

**Slug:** `HONEYCOMB_MCP_GET_DATASET`

Get dataset metadata and its full column schema (columns + calculated fields), sorted by most recent write activity.

When to use:
  - "What columns does the api-service dataset have?" — retrieve the schema for one dataset.
  - Before run_query, to verify column names and types exist in the target dataset.
  - "When was this dataset last updated?" — dataset metadata includes oldest queryable event time.

Difference from get_dataset_columns: this tool returns dataset-level metadata (description, granularity, oldest event) alongside the column list. get_dataset_columns additionally supports fetching sample values for specific columns and has metrics-dataset support via metric_name.

Pairs with: get_environment (upstream — confirms the dataset slug); get_dataset_columns (fetch sample values for columns or explore metrics datasets); find_columns (search across all datasets when the right dataset is unknown).

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `column_page` | number | No | Page number for column pagination. Defaults to 1. |
| `dataset_slug` | string | Yes | Name or slug of the dataset to retrieve. Get valid slugs from get_environment. |
| `columns_per_page` | number | No | Number of columns per page. Defaults to 100, max 500. |
| `environment_slug` | string | Yes | Environment slug the dataset belongs to. |

### Get dataset columns

**Slug:** `HONEYCOMB_MCP_GET_DATASET_COLUMNS`

Get the full column schema for one dataset, with optional sample values for specific columns.

When to use:
  - Validating column names before composing a run_query (check the column exists and note its type).
  - "What values does the status column hold?" — pass the column name in 'columns' to fetch sample values.
  - Exploring a metrics dataset: list metric names first, then pass metric_name to discover filterable attributes.
  - When find_columns returns too many results and you want the authoritative schema for one dataset.

Pairs with: find_columns (intent-based search when you do not know the dataset); get_dataset (dataset metadata alongside schema); run_query (use validated column names here).

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | number | No | Page number for paginated results. Defaults to 1. |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `columns` | array | No | Specific column names to fetch recent sample values for (max 20). Omit to get schema metadata only, which is faster. |
| `metric_name` | string | No | For metrics datasets only: discover which resource and data-point attributes co-occur with this metric by sampling recent data. Returns attributes available for filtering and grouping. |
| `dataset_slug` | string | Yes | Slug of the dataset to get columns for. |
| `items_per_page` | number | No | Number of items per page. Defaults to 1000. |
| `environment_slug` | string | Yes | Environment slug the dataset belongs to. |

### Get environment

**Slug:** `HONEYCOMB_MCP_GET_ENVIRONMENT`

Get details for a specific environment, including its dataset list sorted by most recent activity.

When to use:
  - After get_workspace_context returns environment slugs, drill into one to see which datasets it contains.
  - "What datasets exist in staging?" — list mode for dataset discovery.
  - Before calling get_dataset or get_dataset_columns, confirm the dataset slug by checking environment contents.

Returns up to 100 datasets per page by default, sorted by most recent write activity.

Pairs with: get_workspace_context (upstream — provides environment slugs); get_dataset (drill into a specific dataset's schema); get_dataset_columns (full column schema once you know the dataset slug); find_columns (search across all datasets in this environment by intent).

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | number | No | Page number for dataset pagination. Defaults to 1. |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `items_per_page` | number | No | Number of datasets per page. Defaults to 100, max 500. |
| `environment_slug` | string | Yes | Slug of the environment to retrieve. Get valid slugs from get_workspace_context. |

### Get query results

**Slug:** `HONEYCOMB_MCP_GET_QUERY_RESULTS`

Retrieve results and metadata from an existing query execution. Accepts a Honeycomb URL, a run_pk, or a query_id (returns most recent run). Provide exactly one of these three inputs.

When to use:
  - After find_queries returns a run_pk and you want the actual result rows.
  - The user pastes a Honeycomb query URL from the browser — extract results without re-running.
  - After run_query executes a new query and returns a run_pk, use this to fetch the structured output.
  - You have a query_id and want the latest available result without triggering a new execution.

Pairs with: find_queries (source of run_pks); run_query (source of fresh run_pks); list_boards (board detail mode returns query_ids per panel — pass them as query_id here to get the most recent run).

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `url` | string | No | Full Honeycomb query result URL (e.g. https://ui.honeycomb.io/team/environments/env/datasets/ds/result/run-pk). Provide this OR query_run_pk OR query_id — not multiple. |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `query_id` | string | No | Saved query ID. Returns results from the most recent execution of this query. Provide this OR url OR query_run_pk. |
| `dataset_slug` | string | No | Dataset slug. Derived automatically from the query run when omitted. |
| `query_run_pk` | string | No | Query run primary key, as returned by run_query or find_queries. Provide this OR url OR query_id. |
| `include_results` | boolean | No | Include query result rows in the response. Defaults to true. Set to false to retrieve only metadata (query spec, run time, URLs) without fetching the data rows. |
| `environment_slug` | string | No | Environment slug. Derived automatically from the query run when omitted. |
| `wait_for_completion` | boolean | No | Wait for an in-progress query run to finish before reading persisted results. Defaults to true. Set to false to return immediately with the run's current state. |
| `wait_timeout_seconds` | integer | No | Maximum whole seconds to wait when wait_for_completion is true. Defaults to 120. Values <= 0 use the default; values above 300 are clamped to 300. |

### Get signals

**Slug:** `HONEYCOMB_MCP_GET_SIGNALS`

Returns Anomaly Signals for the current team. An Anomaly Signal tracks a service in a dataset and detects when its behavior deviates from its historical baseline. Use this tool to investigate a specific Anomaly Signal or to find relevant Anomaly Signals with the allowed filters.

Supports:
- Detail: pass signal_hcid (other filters ignored). Returns the full Anomaly Signal + query hints + (optional) historical anomalies.
- List: pass environment_slug (required) plus any combination of optional filters (service_name, dataset_slug, measured_signal, status, anomalous_only). Returns a table of Anomaly Signals. Use this to find a signal_hcid to pass back in detail mode. Defaults to active Anomaly Signals.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | List mode only. 1-indexed page number. Defaults to 1. |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `status` | string ("onboarding" | "normal" | "anomalous" | "off" | "ineligible") | No | Optional: filter by Anomaly Signal lifecycle status. Defaults to 'normal'. When status is provided, anomalous_only is ignored (status takes precedence). Only applies to list view. |
| `signal_hcid` | string | No | Anomaly Signal HCID. When provided, returns detailed information for the matching Anomaly Signal and other filters are ignored. |
| `dataset_slug` | string | No | Optional: match Anomaly Signals by dataset slug. Only applies to list view. |
| `service_name` | string | No | Optional: match Anomaly Signals by service name. Only applies to list view. |
| `anomalous_only` | boolean | No | Optional: if true, returns only Anomaly Signals currently in an anomalous state. Only applies when status is not specified, ignored when status is provided. Only applies to list view. |
| `items_per_page` | integer | No | List mode only. Items per page. Defaults to 50; maximum 100. |
| `measured_signal` | string ("error_rate" | "presence") | No | Optional: match Anomaly Signals by the kind of measurement they track. Only applies to list view. |
| `environment_slug` | string | No | Environment slug. Required when signal_hcid is not provided. |
| `historical_anomalies` | object | No | Detail mode only: include resolved historical anomalies when signal_hcid is non-empty. List mode rejects this field, including null. |

### Get span details

**Slug:** `HONEYCOMB_MCP_GET_SPAN_DETAILS`

Summarize attributes and their common values observed on spans with a specific name.

USE THIS AFTER list_spans (or whenever you already know a span_name) and BEFORE run_query. It tells you which attributes are populated on that operation, how many distinct values each has, and the top observed values — enough to answer most "what does X look like / what fields does X have / what status codes does X return / which users hit X" questions directly, without composing a custom query.

Only escalate to run_query when you need: exhaustive value distributions beyond the sample cap, custom calculations (P95/P99, HEATMAP, math across columns), per-attribute COUNT/SUM aggregates over the full time range, or comparison/baseline analysis.

Results are paginated with page and items_per_page after applying the sample cap. Paging is a presentation control, not an exhaustive cursor. Values are based on matching span samples, capped at 1000 rows across the selected time range.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `to` | string | No | End of the time range. Omit to use the current time; it must not be in the future. from must be before to. Accepted timestamps are positive epoch seconds (at most 10 digits), RFC3339/ISO datetimes, or date-only values. Tool schemas require timestamps as strings, so quote epoch seconds (for example, "1723593600"). Zone-less datetimes and dates are UTC; dates mean midnight UTC (for an in-progress UTC day, use to: "now"). Relative values are "now" or explicitly signed durations such as "-2h" using lower-case s, m, h, d, or w. |
| `from` | string | No | Start of the time range. Omit to use the default 2-hour lookback anchored to to. Relative from values anchor to an absolute to. Accepted timestamps are positive epoch seconds (at most 10 digits), RFC3339/ISO datetimes, or date-only values. Tool schemas require timestamps as strings, so quote epoch seconds (for example, "1723593600"). Zone-less datetimes and dates are UTC; dates mean midnight UTC (for an in-progress UTC day, use to: "now"). Relative values are "now" or explicitly signed durations such as "-2h" using lower-case s, m, h, d, or w. |
| `page` | integer | No | Page number for paginated results. Defaults to 1. |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `span_name` | string | Yes | Span name to inspect. |
| `dataset_slug` | string | No | Optional dataset slug. When omitted, scans trace-aware datasets in the environment. |
| `items_per_page` | integer | No | Number of rows per page. Defaults to 100, maximum 500. |
| `environment_slug` | string | Yes | Environment slug. |

### Get trace

**Slug:** `HONEYCOMB_MCP_GET_TRACE`

Retrieve all spans for a specific trace ID and render them as a waterfall.

When to use:
  - User pastes a trace ID from logs, a Slack alert, or the Honeycomb UI — fetch it here.
  - Drilling into a specific trace from a run_query result (trace.trace_id column).
  - Comparing parent/child span timing for a known trace to diagnose latency attribution.

Pairs with:
  - run_query — filter where trace.trace_id = <value> to find traces matching a pattern, then drill in here.
  - list_spans / get_span_details — use first to discover span names so you can focus this view with focus_span_id.
  - run_bubbleup — if a query surfaces an anomalous cluster, BubbleUp identifies why; get_trace lets you verify with individual examples.

<sampling>
Span counts are actual stored spans, not sample-rate-adjusted. When sampling is active, the output includes a mean sample rate. Do not compare corrected query COUNTs (which are sample-rate-adjusted) directly to trace span counts.
</sampling>

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `to` | string | No | End of the time range. Omit to use the current time; it must not be in the future. from must be before to. Accepted timestamps are positive epoch seconds (at most 10 digits), RFC3339/ISO datetimes, or date-only values. Tool schemas require timestamps as strings, so quote epoch seconds (for example, "1723593600"). Zone-less datetimes and dates are UTC; dates mean midnight UTC (for an in-progress UTC day, use to: "now"). Relative values are "now" or explicitly signed durations such as "-2h" using lower-case s, m, h, d, or w. |
| `from` | string | No | Start of the time range. Omit to use the default 7-day lookback anchored to to. Relative from values anchor to an absolute to. Accepted timestamps are positive epoch seconds (at most 10 digits), RFC3339/ISO datetimes, or date-only values. Tool schemas require timestamps as strings, so quote epoch seconds (for example, "1723593600"). Zone-less datetimes and dates are UTC; dates mean midnight UTC (for an in-progress UTC day, use to: "now"). Relative values are "now" or explicitly signed durations such as "-2h" using lower-case s, m, h, d, or w. |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `trace_id` | string | Yes | The trace ID to search for. |
| `view_mode` | string ("auto" | "compact" | "full" | "focused") | No | View mode: 'auto' (default, smart collapsing), 'compact' (aggressive collapsing), 'full' (show everything), 'focused' (requires focus_span_id). |
| `depth_limit` | integer | No | Maximum depth to traverse from root (inclusive, omit for unlimited). Only applies in focused mode or when specified. |
| `show_events` | boolean | No | Whether to include span events in the output (default: false for performance). |
| `focus_span_id` | string | No | Optional span ID to focus on. Shows this span and its descendants with proper context. |
| `environment_slug` | string | Yes | Environment slug. |

### Get triggers

**Slug:** `HONEYCOMB_MCP_GET_TRIGGERS`

List triggers (alert rules) for the team, or fetch full configuration for a single trigger.

When to use:
  - "What alerts are firing?" / "What triggers do we have?" — list mode (no trigger_id).
  - "Show me the config for trigger X" / "Who gets paged for this alert?" — detail mode by trigger_id.
  - Auditing trigger configurations before creating or updating triggers.
  - Investigating an active alert to understand its threshold, query, and recipients.

Modes:
  - List mode (no trigger_id): paginated table with name, status, threshold, frequency, recipients, and tags.
  - Detail mode (trigger_id provided): full query spec (calculations, filters, group-by, formulas), threshold, schedule, and recipient list.

Recipients are shown as: type (name/target) [id:ID] — e.g. 'pagerduty (Platform Rotation) [id:abc123]'.

Dynamic baseline vs static threshold: triggers with a populated 'baseline' column (list view) or 'Baseline' row (detail view) use a dynamic baseline — the threshold value is a delta (e.g. 50% higher than 1 hour prior), not an absolute count. The detail view formats Threshold as plain-English when baseline is in use.

Pairs with:
  - create_trigger / update_trigger — list first to avoid duplicates; detail view shows current config to inform updates.
  - list_recipients — to resolve recipient IDs to human-readable names before creating or updating a trigger.
  - find_queries — to inspect the underlying saved query for a saved-query-backed trigger.
  - get_slos — SLO burn alerts appear as triggers; cross-reference here when an SLO's burn alert fires.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | number | No | Page number for paginated results. Defaults to 1. Only applies to list view. |
| `tags` | array | No | Optional: Filter triggers by tags. Each tag should be in 'key:value' format. When multiple tags are specified, only triggers matching ALL tags are returned (AND semantics). |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `trigger_id` | string | No | Optional: Trigger ID (PK) to get detailed view. When provided, returns detailed information for a single trigger instead of the list view. |
| `items_per_page` | number | No | Number of items per page. Defaults to 50. Only applies to list view. |
| `environment_slug` | string | No | Optional: Environment slug to filter triggers by (ignored when trigger_id is provided) |
| `include_env_wide` | boolean | No | Whether to include environment-wide triggers. Defaults to true. Only applies to list view. |

### Get workspace context

**Slug:** `HONEYCOMB_MCP_GET_WORKSPACE_CONTEXT`

Call this tool first to orient yourself in a Honeycomb workspace. Takes no parameters. Returns the team name and slug, the current time, and a list of available environments with their slugs and dataset counts. Use the returned environment slugs with 'get_environment' to get dataset details for a specific environment.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |

### List aiconversations

**Slug:** `HONEYCOMB_MCP_LIST_AICONVERSATIONS`

Discover recent AI agent conversations (gen_ai.conversation.id values) in an environment, ordered by total event count (most active first) with per-agent activity.

Use this tool as the starting point for any investigation of a dataset containing OpenTelemetry GenAI telemetry (attributes like gen_ai.conversation.id, gen_ai.agent.name, gen_ai.operation.name, gen_ai.request.model, or gen_ai.usage.*) — including service-level agent health, latency, failure, or token-usage questions. Prefer it over ad-hoc run_query to first identify the conversations worth drilling into. Output is a table with one row per conversation and columns: Conversation ID, Event Count, Error Count, Total Tokens, Agents (events/errors), Services, Start Time, End Time. The Event Count, Error Count, and Total Tokens columns are conversation-wide totals summed across every agent in that conversation. Total Tokens is SUM(gen_ai.usage.input_tokens) + SUM(gen_ai.usage.output_tokens) across the conversation's events, matching the definition used by get_aiconversation; events that lack token attributes contribute 0, so tool-only conversations will show 0. The Agents (events/errors) column is a semicolon-separated list of "<gen_ai.agent.name>=<events>/<errors>" entries so you can attribute activity or errors to a specific agent. The Services column is a comma-separated, alphabetically sorted list of the service.name values that emitted events for the conversation. Start Time and End Time are the earliest and latest gen_ai event timestamps seen for the conversation, each formatted in RFC3339 UTC (empty string when unknown). Pass a returned gen_ai.conversation.id into get_aiconversation as conversation_id to load the full timeline for that conversation.

Events that carried no gen_ai.agent.name are excluded from the Agents column but their counts still roll up into the conversation-level Event Count and Error Count totals; likewise events with no service.name are excluded from the Services column. To answer questions like "which conversations had the most errors for agent X", parse the Agents column on each row for the entry whose name matches X and use its errors value.

Default window is the last 24 hours, matching the Honeycomb UI behavior.

Optional agent_name and service_name filters restrict the returned conversations to those that include at least one event for the given gen_ai.agent.name and/or service.name. Both filters are exact, case-sensitive string matches and are combined with AND when both are supplied. When agent_name is supplied the filter is applied at query time, so the Event Count, Error Count, and Total Tokens columns reflect only that agent's activity within each conversation (not the conversation-wide totals).

Time parameters use the shared flexible timestamp grammar documented on from and to below.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `to` | string | No | End of the conversation window. Omit to use the current time; it must not be in the future. from must be before to. Accepted timestamps are positive epoch seconds (at most 10 digits), RFC3339/ISO datetimes, or date-only values. Tool schemas require timestamps as strings, so quote epoch seconds (for example, "1723593600"). Zone-less datetimes and dates are UTC; dates mean midnight UTC (for an in-progress UTC day, use to: "now"). Relative values are "now" or explicitly signed durations such as "-2h" using lower-case s, m, h, d, or w. |
| `from` | string | No | Start of the conversation window. Omit to use a 24-hour lookback anchored to to. Relative from values anchor to an absolute to. Accepted timestamps are positive epoch seconds (at most 10 digits), RFC3339/ISO datetimes, or date-only values. Tool schemas require timestamps as strings, so quote epoch seconds (for example, "1723593600"). Zone-less datetimes and dates are UTC; dates mean midnight UTC (for an in-progress UTC day, use to: "now"). Relative values are "now" or explicitly signed durations such as "-2h" using lower-case s, m, h, d, or w. |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `limit` | integer | No | Maximum number of conversations to return. Default: 200. Maximum: 500. |
| `agent_name` | string | No | Optional filter: only include conversations that have at least one event with this gen_ai.agent.name (exact, case-sensitive). Combined with service_name (when provided) using AND. |
| `service_name` | string | No | Optional filter: only include conversations that have at least one event with this service.name (exact, case-sensitive). Combined with agent_name (when provided) using AND. |
| `environment_slug` | string | Yes | Environment slug to query. Source from get_workspace_context or a prior tool result rather than guessing. |

### List boards

**Slug:** `HONEYCOMB_MCP_LIST_BOARDS`

List boards (saved dashboards) in an environment, or fetch one board's full contents by ID.

When to use:
  - "What dashboards do we have for service X" / "is there an existing board for Y" — list mode with tag filters.
  - "Show me the contents of board Z" — detail mode by board_id, returns every panel (queries, SLOs, text) with descriptions.
  - Before calling create_board, to check whether a similar board already exists.

Modes:
  - List mode (default): pass environment_slug, optionally filter by tags (AND semantics across multiple tags). Returns paginated board metadata only.
  - Detail mode: pass board_id (environment_slug still required). Returns the single board with all panels and their underlying queries/SLOs resolved. Each query panel also reports chart_type, display_style, and thresholds in the exact forms create_board / update_board accept, so you can round-trip a panel's configuration.

Pairs with: create_board (this tool's output reveals existing tags and naming conventions to follow); get_query_results (panel query_ids from detail mode can be passed as query_id to fetch the most recent run's results).

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | number | No | Page number (1-indexed). Defaults to 1. List mode only. |
| `tags` | array | No | Filter to boards matching ALL of these tags (AND semantics). Format: ['key:value', ...]. List mode only. To discover existing tag values for a team, list once without tags and inspect the responses. |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `board_id` | string | No | Switches to detail mode. When provided, returns one board with every panel (queries, SLOs, text) resolved. Get IDs from list mode, or from create_board's response. |
| `items_per_page` | number | No | Page size. Defaults to 25. List mode only. |
| `environment_slug` | string | Yes | Environment slug to filter by. Required. |

### List recipients

**Slug:** `HONEYCOMB_MCP_LIST_RECIPIENTS`

List all pre-registered notification recipients (email, Slack, PagerDuty, webhook) for the team.

When to use:
  - Before create_trigger or update_trigger, to find the recipient IDs to attach.
  - "What Slack channels are configured for alerts?" — audit existing notification targets.
  - When a user asks which notification channels are available for a new alert.

Returns each recipient's ID, type, and routing details. Pass recipient IDs directly to create_trigger or update_trigger.

Pairs with: create_recipient (register a new notification target); create_trigger (attach recipients by ID); update_trigger (update which recipients a trigger notifies).

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |

### List spans

**Slug:** `HONEYCOMB_MCP_LIST_SPANS`

List span names in trace data, ranked by count, with how often each is a trace root and which dataset the count came from.

USE THIS FIRST for any question about what's happening in the system: "what's slow", "what's erroring", "what does service X do", "which endpoints exist", "what jobs run here", "show me the operations on Y". It is faster, cheaper, and more diagnostic than composing an equivalent run_query by hand, and it works across all trace-aware datasets in the environment without you having to know which dataset to target.

Workflow:
  1. Call list_spans (this tool) to see the span-name landscape and pick a candidate.
  2. Call get_span_details with that span_name (and its dataset_slug from the row) to learn which attributes and values are present.
  3. ONLY if you need a custom calculation, exhaustive value distribution, percentile/heatmap, or per-attribute aggregate that get_span_details cannot express — fall through to run_query, scoped to the dataset_slug from the row.

Reverse lookup — "which span carries attribute X": set populates_attribute to the attribute name to restrict results to only the span names that POPULATE that attribute, still ranked by count. Use this when you have an attribute and need the span that emits it (e.g. find the span that populates mcp.tool.name), instead of trusting whichever span happens to have the highest raw volume.

Each row has:
  - span_name: the operation/endpoint/job name.
  - dataset_slug: which dataset this row's counts came from. The same span_name can appear in multiple datasets (e.g. a service emits to several); each (span_name, dataset_slug) pair is a separate row. Use the dataset_slug in follow-up tool calls so aggregates aren't smeared across datasets.
  - count: total spans with that name in that dataset over the time range.
  - root_count: subset of those spans that have no parent (i.e. are trace roots).
  Names where root_count == count are always trace entry points (HTTP handlers, root jobs). Names where 0 < root_count < count are operations that appear as both roots and children — common for shared names across services. Names where root_count == 0 are always children (DB calls, internal helpers).

Results are paginated with page and items_per_page after applying the query cap. Paging is a presentation control, not an exhaustive cursor; narrow the time range or dataset when you need deeper coverage.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `to` | string | No | End of the time range. Omit to use the current time; it must not be in the future. from must be before to. Accepted timestamps are positive epoch seconds (at most 10 digits), RFC3339/ISO datetimes, or date-only values. Tool schemas require timestamps as strings, so quote epoch seconds (for example, "1723593600"). Zone-less datetimes and dates are UTC; dates mean midnight UTC (for an in-progress UTC day, use to: "now"). Relative values are "now" or explicitly signed durations such as "-2h" using lower-case s, m, h, d, or w. |
| `from` | string | No | Start of the time range. Omit to use the default 2-hour lookback anchored to to. Relative from values anchor to an absolute to. Accepted timestamps are positive epoch seconds (at most 10 digits), RFC3339/ISO datetimes, or date-only values. Tool schemas require timestamps as strings, so quote epoch seconds (for example, "1723593600"). Zone-less datetimes and dates are UTC; dates mean midnight UTC (for an in-progress UTC day, use to: "now"). Relative values are "now" or explicitly signed durations such as "-2h" using lower-case s, m, h, d, or w. |
| `page` | integer | No | Page number for paginated results. Defaults to 1. |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `usage_mode` | boolean | No | Return raw span counts without sampling rate correction. By default counts are sample-rate-weighted estimates; set true to see the literal number of spans ingested, e.g. when analyzing telemetry volume or pacing. |
| `dataset_slug` | string | No | Optional dataset slug. When omitted, scans trace-aware datasets in the environment. |
| `items_per_page` | integer | No | Number of rows per page. Defaults to 100, maximum 500. |
| `environment_slug` | string | Yes | Environment slug. |
| `populates_attribute` | string | No | Optional. Restrict results to span names that POPULATE this attribute, still ranked by count. Use this to answer 'which span carries attribute X' — e.g. find the span that emits mcp.tool.name. |

### Migration guide

**Slug:** `HONEYCOMB_MCP_MIGRATION_GUIDE`

Vendor-specific guidance for migrating existing telemetry to Honeycomb without disrupting the vendor setup. The onboarding flow's migration branch calls this when it detects a supported vendor.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `vendor` | string ("datadog") | Yes | The vendor the user's existing telemetry currently flows to. |

### Record onboarding state

**Slug:** `HONEYCOMB_MCP_RECORD_ONBOARDING_STATE`

Record the current onboarding step. The onboarding flow calls this at each step so the session's MCP activity is attributed to the step it happened in.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `state` | string | Yes | The current onboarding step name from the flow's state machine. |
| `vendor` | string | No | For an unsupported migration vendor, the vendor the user is coming from (for example new-relic). Omit otherwise. |

### Refinery docs

**Slug:** `HONEYCOMB_MCP_REFINERY_DOCS`

Read Honeycomb Refinery documentation. Refinery is Honeycomb's trace-aware tail-based sampling proxy.

Available topics:
- overview: Refinery overview and key concepts
- architecture: Architecture, deployment patterns, and how it works
- sampling-types: Sampling strategies (deterministic, dynamic, rules-based, throughput)
- stress-relief: How stress relief works and how to respond when it activates
- troubleshooting: Common Refinery issues, diagnostic queries, and solutions
- metrics: Complete reference of all Refinery metrics with descriptions
- configuration: Configuration reference for all Refinery settings
- rules: Guide to writing sampling rules for the rules-based sampler

Use this tool when you need detailed technical information about Honeycomb Refinery to answer user questions.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `topic` | string ("overview" | "architecture" | "sampling-types" | "stress-relief" | "troubleshooting" | "metrics" | "configuration" | "rules") | Yes | The documentation topic to read |

### Run bubbleup

**Slug:** `HONEYCOMB_MCP_RUN_BUBBLEUP`

Run BubbleUp analysis to find what makes a selected data subset different from the baseline.

BubbleUp compares value distributions across all schema columns between a "foreground" selection (the interesting region) and the remaining data (the baseline). Columns where the foreground and baseline distributions diverge most are ranked highest.

When to use:
  - User asks "why did latency spike at 14:00?" — pick a heatmap region and BubbleUp it.
  - Investigating a heatmap selection returned by run_query; you already have a query_pk.
  - "Compare this known-bad subset to baseline" — user wants to know what's different.
  - After a run_query heatmap shows an interesting region, surface the root-cause attributes.

Pairs with:
  - run_query — must run first to obtain a query_pk; that query's time range becomes the baseline.
  - get_trace — drill into specific traces that fall inside the anomalous selection.
  - find_columns / get_dataset_columns — if you need to know what columns exist before starting analysis.

Modes:
  - New analysis: provide query_pk + selection (heatmap or group selection). For a 2D selection, use either absolute or wall-clock-relative from/to, or source-query-relative time_start/time_end; do not combine them.
  - Paginate existing results: provide bubbleup_result_id (query_pk and selection are ignored).

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number for paginated results (1-based) |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `query_pk` | string | No | Primary key of the existing query to use as the baseline for BubbleUp analysis |
| `selection` | object | No | Selection criteria that defines the subset to analyze |
| `clause_name` | string | No | Optional name of a specific calculation or formula from the source query to run BubbleUp against. When specified, only the calculation filters relevant to that clause are used. For formulas, filters from all calculations referenced in the formula expression are included. |
| `max_columns` | integer | No | Maximum number of columns to return in results |
| `items_per_page` | integer | No | Number of columns per page |
| `bubbleup_result_id` | string | No | Primary key of an existing BubbleUp result to fetch additional pages from |

### Run query

**Slug:** `HONEYCOMB_MCP_RUN_QUERY`

Run an aggregate query or return a scoped set of raw rows from a Honeycomb dataset.

When to use this tool:
  - "Reconstruct the events for one session" — filter to the session and request the needed raw_row_columns.
  - "Compute a percentile / histogram of X" — use P50/P99/HEATMAP calculations.
  - "Show me error rate before and after deploy" — use two named calcs + a formula, scoped by time.
  - "Rank services by p99 latency" — use P99 with a breakdown + order.
  - "See distinct values of X and their frequency" — COUNT with a breakdown on X.
  - "Compare request volume across services" — COUNT breakdown on service.name.
  - "Find endpoints where tail latency exceeds 1s" — P99 + having clause.
  - "Generate a heatmap of request duration" — HEATMAP calculation.

When NOT to use this tool:
  - Discovering what spans or operations exist → use list_spans instead.
  - Looking at a specific trace → use get_trace instead.
  - Finding existing saved queries → use find_queries instead.
  - Exploring which columns a dataset has → use get_dataset_columns or find_columns first.

Pairs with: list_spans, get_span_details, find_columns, get_dataset_columns, get_trace, run_bubbleup.

<examples>
Basic COUNT over the last 24 hours:
```json
{"environment_slug": "production", "dataset_slug": "api",
 "query_spec": {"calculations": [{"op": "COUNT"}], "from": "-24h"}}
```
Raw rows for one session, limited to ten selected columns and up to 100 matching events:
```json
{"environment_slug": "production", "dataset_slug": "agent-events",
 "query_spec": {
   "filters": [{"column": "session.id", "op": "=", "value": "session-123"}],
   "from": "-2h"},
 "raw_row_columns": [
   "session.id", "gen_ai.operation.name", "gen_ai.agent.name", "gen_ai.tool.name",
   "gen_ai.tool.call.id", "gen_ai.tool.call.arguments", "gen_ai.tool.call.result",
   "error", "duration_ms", "trace.trace_id"],
 "results_limit": 100}
```
When a raw-row response includes next_cursor, fetch the next page by repeating the request with the same scope, replace the prior time fields in query_spec with the response Metadata's absolute from and to, and pass next_cursor as cursor. Continue until next_cursor is omitted.

Error rate formula: two named calcs combined with a formula, ordered by the formula name (the correct ordering style when formulas are present). The passthrough formula "volume" surfaces a raw calc value alongside formulas:
```json
{"environment_slug": "production", "dataset_slug": "api",
 "query_spec": {
   "calculations": [
     {"op": "COUNT", "name": "total"},
     {"op": "COUNT", "name": "errors", "filters": [{"column": "error", "op": "=", "value": true}]}],
   "formulas": [
     {"name": "error_rate", "expression": "$errors / $total * 100"},
     {"name": "volume", "expression": "$total"}],
   "breakdowns": ["service.name"],
   "orders": [{"column": "error_rate", "order": "descending"}],
   "from": "-1h", "limit": 20}}
```
Relational fields: any.X in a breakdown requires a matching WHERE filter on the same any.X column:
```json
{"environment_slug": "production", "dataset_slug": "traces",
 "query_spec": {
   "calculations": [{"op": "COUNT"}, {"op": "P99", "column": "duration_ms"}],
   "filters": [{"column": "any.http.route", "op": "exists"}],
   "breakdowns": ["any.http.route"],
   "from": "-2h"}}
```
</examples>

<interpreting_results>
The response is rendered as Markdown with these sections (each is omitted if empty):

  - "# Results" — a Markdown table of aggregate rows. Headers are breakdown columns followed by calculation columns. When formulas are present, the table contains ONLY breakdown columns and formula columns — raw calculation columns (including percentiles like P50/P95, and even named COUNTs) are NOT rendered. To surface a raw calculation's value alongside formulas, add a passthrough formula such as {"name": "p95", "expression": "$p95_latency"}. If a breakdown's cardinality exceeded the spec's limit, an "OTHER" row collapses the remainder; a "TOTAL" row may also appear summing across groups. A "Truncated: shown N / total M" footer indicates more rows than the table displays.
  - 1D heatmaps render inline within Results when a HEATMAP calculation has no breakdown.
  - "# Raw Rows" — present when raw_row_columns is provided. Contains matching events restricted to those columns, plus timestamp. The row and column counts share a 1000-value budget. Metadata includes the effective absolute from and to. A full page also includes next_cursor; pass it as cursor in an otherwise equivalent request with those absolute time bounds to fetch more rows. Pagination is not a snapshot.
  - "# Time Series" — ASCII line graphs per group when the spec has a granularity (time-bucketed series). Width 120, height 12.
  - "# Heatmaps" — 2D time-series heatmaps when a HEATMAP calculation is paired with breakdowns or granularity.
  - "# Markers" — deploy/incident markers overlapping the time range, when present. Includes both dataset-scoped and environment-wide markers; the Scope column labels each row "dataset" or "environment".
  - "# Query Spec" — the canonicalized JSON spec the server actually executed. Useful when comparing what you sent to what ran.
  - "Metadata:" YAML block at the bottom — contains query_run_pk (passable to get_query_results), query_url (Honeycomb permalink to share with humans), query_result_json / query_result_image (download URLs), elapsed_str, granularity, total (result count), rows_examined. When the requested or auto-selected granularity was adjusted (clamped to the valid window, or raised to the metrics-dataset floor), granularity_note explains the change and granularity_requested echoes an explicit request.

When data is sampled, a sampling banner appears above Results listing the mean sample rate and which calculations are sample-rate-weighted vs. raw. If mean_sample_rate > 10x and usage_mode is off, an extra warning notes that COUNT values are corrected estimates and won't match raw trace span counts.

When results contain a trace.trace_id column (grouped-by or in raw rows), a "Trace links" block above Results lists ready-to-use UI URLs for those traces. These are already scoped to this query's time range — pass them through verbatim. Do NOT hand-build a trace URL from a trace ID: a link without the query's time scope resolves against a default 2h window and fails to load older traces.
</interpreting_results>

Important: filter operators use symbols (=, >=, !=). Expression functions inside calculated_fields use words (GTE, EQUALS). Never use GTE/LTE as filter operators.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `cursor` | string | No | Continue a raw-row query from the previous page. Copy the previous response's next_cursor value and repeat the same environment, dataset, filters, calculated fields, and selected columns. Replace all prior time fields with the absolute from and to values from the previous response's Metadata. Only valid with raw_row_columns. |
| `query_spec` | object | Yes | Core query parameters.  Time fields: use from/to. When omitted, the default 2-hour lookback is queried.  <relational_fields> Each result row is a span. Prefix a column with one of these to read or test it on a related span in the same trace:   - root.X    — X taken from the trace's root span (the span whose parent_id is empty).   - parent.X  — X taken from this span's immediate parent (joined on parent_id = span_id).   - child.X   — X taken from a direct child span (joined on span_id = child's parent_id). Direct children only — does not reach grandchildren.   - any.X     — matches when at least one span in the trace populates X.   - none.X    — matches when no span in the trace populates X (excludes the whole trace if any span matches).   - any2.X / any3.X — additional independent any-matchers. Use these when two or three filters must each be satisfied, but possibly by different spans. Filters that share a single any. prefix must all hold on the same span; switching to any2./any3. lets each filter land on a different span.  Constraints:   - Relational prefixes are not allowed inside calculations or per-calculation filters.   - "any" in breakdowns requires a matching WHERE filter on the same prefixed column.   - "none" is valid only in filters, not in breakdowns.   - Relational filters compose with AND only — express OR by issuing two queries or via a calculated_field.  Note: To filter to root spans without joining, use a does-not-exist filter on the dataset's parent-id column. There is no "is_root" column in the query API. </relational_fields>  <metrics_datasets> On metrics datasets, temporal aggregation (LAST, SUMMARIZE, INCREASE) is applied automatically based on metric type. Do not use these as calculated_field expressions. Operators not allowed on metrics datasets: RATE_SUM, RATE_AVG, RATE_MAX, CONCURRENCY, bare COUNT (without column). Use SUM, AVG, MAX, or percentiles on metric fields instead. COUNT_DATAPOINTS(column) counts how many raw metric datapoints (samples) were reported for a metric column. HISTOGRAM_COUNT(column) returns the total number of observations recorded across a Metrics 2.0 histogram or summary column — the sum of its per-bucket counts. Reach for it when asked for the "sum of counts from a histogram", "total observations", "how many observations/samples are in this histogram", or "total request count from a latency histogram". COUNT_DATAPOINTS and HISTOGRAM_COUNT are only allowed on metrics datasets. For histogram metrics, use AVG/P50/P99/MAX/HEATMAP directly on the histogram column name. </metrics_datasets>  <sampling> When data is sampled, results include sampling metadata. COUNT, SUM, AVG, percentiles, HEATMAP, CONCURRENCY, RATE_SUM, and RATE_AVG are weighted by sample rate. COUNT_DISTINCT, MIN, MAX, and RATE_MAX are not corrected. Set usage_mode=true to disable all sample rate correction and see raw event counts. </sampling> |
| `usage_mode` | string | No | Return raw event counts without sampling rate correction. Applies only to aggregate queries. Default: false. |
| `dataset_slug` | string | No | Dataset identifier. Required unless environment_wide_query is true. |
| `results_limit` | string | No | Maximum raw rows to return. Raw-row results are limited to 1000 returned values, including the timestamp column, so results_limit × (number of raw_row_columns + 1) must be at most 1000. If omitted, returns the largest number of rows that fits that budget. For aggregate queries, this legacy argument is accepted and ignored. |
| `raw_row_columns` | string | No | Return raw matching events with only these columns. A non-empty list selects raw-row mode; omit calculations and other aggregate-only query fields. The event timestamp is always returned and does not need to be listed. Rows are returned in storage order, not time order; sort by the returned timestamp column before interpreting a sequence. Between 1 and 100 unique column names. |
| `environment_slug` | string | Yes | Environment identifier. |
| `environment_wide_query` | string | No | Query all datasets in the environment. When true, dataset_slug is not required. Not compatible with legacy environments. Default: false. |

### Semconv

**Slug:** `HONEYCOMB_MCP_SEMCONV`

Query the semantic convention registry: the latest embedded OTel semconv release merged with Honeycomb's overlay, plus the team's custom schema when one exists.

Actions:
- search: substring match on names/briefs; requires query; concise results.
- get: exact ids; full definitions; unknown ids appear in not_found.
- list_namespaces: top-level namespaces; optional signal_type filter.

Use returned canonical names in queries; Honeycomb normalises names at ingest.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `ids` | array | No | get only: exact attribute names, e.g. ["http.response.status_code", "db.system"] |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `limit` | integer | No | search only: maximum results (default 20, max 50) |
| `query` | string | No | search only: term matched against attribute names and descriptions, e.g. "http status" |
| `action` | string ("search" | "get" | "list_namespaces") | Yes | Operation to perform |
| `signal_type` | string ("span" | "metric" | "attribute_group" | "event" | "entity") | No | search and list_namespaces: restrict to attributes of one signal type |
| `include_enum` | boolean | No | get only: include the full enum member list; default returns a count and sample |
| `include_deprecated` | boolean | No | search and get: include deprecated attributes; defaults to current attributes only |

### Update board

**Slug:** `HONEYCOMB_MCP_UPDATE_BOARD`

Edit an existing board (dashboard) in place. Add, remove, update, or reorder panels; rename; and replace preset filters or tags.

When to use:
  - "Add the new error-rate query to the API board" — append panels to an existing board.
  - "Remove the deprecated SLO panel from this dashboard" — drop a panel by id.
  - "Rename the panel" / "switch this query to a table view" — modify an existing panel's name, description, chart_type, display_style, thresholds, or size.
  - "Add a 500ms threshold line to the latency panel" — set thresholds on a query panel via update_panels or add_panels.
  - "Reorder the board so SLOs come first" — reorder panels via panel_order.
  - "Update the preset filters / tags" — replace the full set (replace, not merge).
  - Always run list_boards with board_id first so you have the current type+id of each panel.

Pairs with: list_boards (board_id and per-panel ids; the IDs you reference here come from there), find_queries (query run PKs for new query panels), get_slos (SLO PKs for new SLO panels), create_board (create instead of update).

Operations apply in this order: remove_panels -> update_panels -> add_panels -> panel_order. Within a single call: removed panels can be referenced in remove_panels but not anywhere else; newly added text panels can not be referenced in panel_order or update_panels because they have no stable id until saved (added text panels are appended after any ordered panels).

Replacement-set semantics: tags and preset_filters replace the full set when provided. To add one tag, read the current tags from list_boards, append, and pass the full updated list. Pass an empty array to clear. Omit entirely to leave unchanged. Per-panel thresholds also replace the full set: pass [] to clear, omit to leave unchanged.

Sizing: if you omit size on an added panel, MCP auto-sizes it (queries by complexity; SLO/text use defaults). For updated panels, size is preserved unless you explicitly supply a new size or set auto_size_updated_panels=true (which auto-sizes query panels in update_panels when their size is omitted).

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | No | New name for the board (optional). Maximum 255 characters. |
| `tags` | array | No | Replacement tags in 'key:value' format (optional). When provided, replaces all existing tags. Pass empty array [] to clear tags. Omit entirely to leave tags unchanged. Keys: lowercase letters only, max 32 chars. Values: start with lowercase letter, alphanumeric plus '/' and '-', max 128 chars. |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `board_id` | string | Yes | Board ID to update. Obtain from list_boards. |
| `add_panels` | array | No | Panels to add to the board (optional). Same shape as create_board panels: each has a type discriminator ('query', 'slo', or 'text'). For queries, provide the query run PK as id. For SLOs, provide the SLO PK as id. For text, provide content. Query panels accept the same thresholds field as create_board. New panels are appended after existing panels in the order listed here. If size is omitted, MCP auto-sizes new panels (queries by complexity; SLO/text use defaults). Newly added text panels cannot be referenced in panel_order (they have no ID until saved). |
| `description` | string | No | New description for the board (optional). Maximum 1023 characters. |
| `panel_order` | array | No | Desired order of existing panels (optional). Array of panel references (type + id). Panels listed here are arranged in this exact order; any unlisted existing panels are appended after. Cannot reference newly added text panels (they have no id until saved). Duplicate entries are rejected. |
| `remove_panels` | array | No | Panels to remove from the board (optional). Reference each panel by its type and id from list_boards detail view. Duplicate entries are rejected. |
| `update_panels` | array | No | Existing panels to modify (optional). Reference each by type and id from list_boards, then supply only the fields to change. Per-type fields: queries accept name, description, chart_type, display_style, thresholds, size; text panels accept content, size; SLO panels accept size. Updating a text panel's content preserves its BoardTextID. For queries, supplying chart_type alone replaces visualization settings but preserves existing thresholds; supplying display_style alone preserves both. |
| `preset_filters` | array | No | Replacement preset filters. When provided, replaces all existing preset filters. Pass empty array to clear filters. Omit to keep current filters (max 5). |
| `environment_slug` | string | Yes | Environment slug where the board exists. |
| `auto_size_updated_panels` | boolean | No | Optional. When true, query panels listed in update_panels are auto-sized by MCP when size is omitted, using query complexity and display style. When false or omitted, existing panel size is preserved unless size is explicitly provided. |

### Update slo

**Slug:** `HONEYCOMB_MCP_UPDATE_SLO`

Update an existing SLO. Only the fields you supply change; omitted fields keep their current values.

When to use:
  - "Tighten the SLO target to 99.95%" / "extend the window to 30 days" — adjust reliability parameters.
  - "Rename this SLO" / "update the SLO description" — housekeeping changes.
  - "Replace the SLO's tags" — tag management (tags replace entirely; pass empty array to clear all).
  - Datasets cannot be changed after creation; create a new SLO if you need different datasets.

Pairs with: get_slos (retrieve slo_id and current values), create_slo (create instead of update), update_trigger (update a paired burn-alert trigger simultaneously).

Tag replacement semantics: when tags is provided it replaces the entire tag set. To add one tag, first read the current tags via get_slos, append the new tag, and pass the full updated list.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sli` | object | No | New SLI configuration (optional). When provided, a new derived column is auto-created if needed. Both alias and expression are required together. |
| `name` | string | No | New name for the SLO (optional). Maximum 255 characters. |
| `tags` | array | No | Replace all existing tags with this set (optional). Tags in 'key:value' format. Pass an empty array [] to clear all tags. Omit entirely to leave tags unchanged. |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `slo_id` | string | Yes | SLO ID to update. Obtain from get_slos. |
| `description` | string | No | New description for the SLO (optional). |
| `time_period_days` | integer | No | New evaluation window in whole days (minimum 1, optional). |
| `target_per_million` | integer | No | New target in whole parts-per-million (0-999999, optional). Examples: 999500 = 99.95%, 999000 = 99.9%, 990000 = 99.0%. |

### Update trigger

**Slug:** `HONEYCOMB_MCP_UPDATE_TRIGGER`

Update an existing trigger. Partial update — only the fields you supply change; omitted fields keep their current values.

When to use:
  - "Disable this trigger temporarily" — set disabled=true without touching other fields.
  - "Add a Slack channel to the trigger's recipients" — replace recipients with the full updated list (note: replaces, does not merge).
  - "Lower the threshold from 5% to 3%" — update threshold.value.
  - "Slow down the evaluation frequency" — change frequency.

Pairs with: get_triggers (retrieve trigger_id and current state), list_recipients / create_recipient (get recipient IDs before updating), update_slo (update the paired SLO at the same time).

Recipients replacement semantics: when recipients is provided, it replaces the entire recipients list. To add one recipient, read current recipients from get_triggers, append the new ID, then pass the full list here. Pass an empty array [] to remove all recipients.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | No | New trigger name (optional). |
| `tags` | array | No | Replace all existing tags (optional). Pass [] to clear. Omit to leave unchanged. |
| `team` | string | No | Team to run this tool against; only needed when your authorization covers multiple teams |
| `query` | object | No | Inline query spec to replace the current query (optional). Mutually exclusive with 'query_id'. |
| `disabled` | boolean | No | Enable or disable the trigger (optional). true = paused, false = active. |
| `query_id` | string | No | Saved query ID to switch to (optional). Mutually exclusive with 'query'. |
| `frequency` | integer | No | Evaluation interval in whole seconds (60-86400, multiple of 60, optional). |
| `threshold` | object | No | Threshold configuration (optional). When using baseline_details, threshold.op must be '>=' or '<='. |
| `alert_type` | string ("on_change" | "on_true") | No | Alert behavior: 'on_change' (fire on state transition) or 'on_true' (fire every cycle condition is met). Optional. |
| `recipients` | array | No | Full replacement list of recipient IDs (optional). Replaces all existing recipients. Pass [] to remove all. Omit to leave recipients unchanged. |
| `trigger_id` | string | Yes | Trigger ID to update. Obtain from get_triggers. |
| `description` | string | No | New trigger description (optional). |
| `baseline_details` | object | No | Baseline comparison configuration (optional). When provided, threshold.op must be '>=' or '<='. |
| `evaluation_schedule` | object | No | Evaluation schedule (optional). When type='window', the window must be at least 2x the trigger frequency. |
