# MCP Tools Reference

The groundcover MCP server exposes tools for **querying** observability data (logs, traces, events, live entities, monitor issues, metrics, monitor definitions) and for **discovering metadata** (field names and values) before writing those queries. Most query tools accept a [gcQL](/use-groundcover/querying-your-groundcover-data/groundcover-query-language/groundcover-query-language-gcql-reference.md) pipeline; `query_metrics` accepts PromQL.

{% hint style="info" %}
**Tenant & backend scoping**

Every tool call is automatically scoped to the tenant and backend configured when you [set up the MCP server](/getting-started/groundcover-mcp/configure-groundcovers-mcp-server.md#request-parameters). These are set once at the connection level — you do not pass them per tool call.
{% endhint %}

## Tool Overview

| Tool                                                  | Category           | Signal                | Query language   | Time-bound      |
| ----------------------------------------------------- | ------------------ | --------------------- | ---------------- | --------------- |
| [`query_logs`](#query_logs)                           | Signal query       | Logs                  | gcQL             | yes             |
| [`query_traces`](#query_traces)                       | Signal query       | Traces / spans        | gcQL             | yes             |
| [`query_events`](#query_events)                       | Signal query       | Kubernetes events     | gcQL             | yes             |
| [`query_entities`](#query_entities)                   | Signal query       | Live entities         | gcQL             | no (live state) |
| [`query_issues`](#query_issues)                       | Signal query       | Monitor issue firings | gcQL             | yes             |
| [`query_metrics`](#query_metrics)                     | Signal query       | Metrics               | PromQL (4 modes) | yes             |
| [`query_monitors`](#query_monitors)                   | Signal query       | Monitor definitions   | gcQL filter      | no              |
| [`search_logs_metadata`](#search_logs_metadata)       | Metadata discovery | Logs                  | n/a              | yes             |
| [`search_traces_metadata`](#search_traces_metadata)   | Metadata discovery | Traces                | n/a              | yes             |
| [`search_events_metadata`](#search_events_metadata)   | Metadata discovery | Events                | n/a              | yes             |
| [`search_metrics_metadata`](#search_metrics_metadata) | Metadata discovery | Metrics               | n/a              | yes             |

## Signal Query Tools (gcQL)

### Common Parameters

All gcQL signal tools share the parameters below. `query_entities` is the exception on time: it queries live state and ignores `start` / `end` / `period`.

| Parameter | Type                       | Required | Description                                                                      |
| --------- | -------------------------- | -------- | -------------------------------------------------------------------------------- |
| `query`   | string                     | yes      | gcQL query string. Must start with a filter or `*`. Always include `\| limit N`. |
| `start`   | string (RFC3339)           | no       | Window start. Defaults to 1 hour ago.                                            |
| `end`     | string (RFC3339)           | no       | Window end. Defaults to now.                                                     |
| `period`  | string (ISO 8601 duration) | no       | Relative window, for example `PT15M`, `PT1H`, `P1D`. Defaults to `PT1H`.         |

`query_metrics` and `query_monitors` use a different shape - see their dedicated sections below.

Every gcQL `query_*` tool returns the JSON response of the executed pipeline. When the row count exactly equals the effective `limit`, the server appends a follow-up text block warning that results were truncated, plus a link to the gcQL reference - the agent should refine the query rather than paginate.

### query\_logs

Run a gcQL query against logs.

**When to use it**

* Investigate errors, warnings, or arbitrary log text for a workload, namespace, or trace.
* Aggregate log volume, error rates, or latest message per group.
* Correlate logs with traces or issues via `_from` subqueries inside `join` / `union` / `in()`.

**Examples**

Latest 10 production errors, newest first:

```
filter env:production level:error | sort by (_time desc) | limit 10
```

Error rate per workload, surfacing only workloads above 5% errors, in a single query:

```
* | stats by (env, cluster, namespace, workload)
    count() as total,
    count() if (level:error) as errors
| math errors / total * 100 as error_pct
| filter error_pct > 5
| sort by (error_pct desc)
| limit 20
```

### query\_traces

Run a gcQL query against trace spans.

**When to use it**

* Identify slow services, endpoints, or operations.
* Quantify HTTP error rates (4xx / 5xx) or span-level errors.
* Pull the spans behind a specific `trace_id` to investigate a request.

**Examples**

Slow checkout calls (>500 ms):

```
* | filter service.name:checkout | filter duration_seconds>0.5 | limit 10
```

5xx count per service:

```
* | filter http_status_code>=500 | stats by (service.name) count() as errors | sort by (errors desc) | limit 20
```

p95 latency per workload, top 5:

```
* | stats by (workload) quantile(0.95, duration_seconds) as p95
| sort by (p95 desc)
| limit 5
```

### query\_events

Run a gcQL query against Kubernetes events.

**When to use it**

* Find OOMKills, crash loops, scheduling failures, or any abnormal cluster event.
* Correlate cluster activity with logs and traces during an incident.

**Examples**

Recent OOMKilled events:

```
* | filter type:Warning reason:OOMKilled | sort by (_time desc) | limit 10
```

Top warning reasons in production:

```
* | filter env:production type:Warning
| stats by (reason) count() as count
| sort by (count desc)
| limit 20
```

### query\_entities

Run a gcQL query against the **live state** of entities tracked by groundcover. This includes Kubernetes resources (Pods, Deployments, Services, Nodes, etc.) as well as non-Kubernetes entities. Reflects the current snapshot - does **not** accept time parameters.

**When to use it**

* Inspect the spec or status of a specific resource (a Deployment, a Pod, a Node).
* Count or group entities by current state (Running / Pending / Failed).
* Discover which entity kinds and fields exist in the cluster.

**Examples**

Fetch a single deployment:

```
kind:Deployment name:chat-app | limit 1
```

Running pods, top 10:

```
kind:Pod status_phase:Running | limit 10
```

Deployment readiness summary:

```
kind:Deployment | fields name, namespace, ready_replicas, replicas | limit 20
```

Node count by status:

```
kind:Node | stats by (status) count() | limit 10
```

**Drilling into the underlying Kubernetes object**

The full Kubernetes object is exposed as discoverable `raw_json.*` paths (not as a single scalar column - `| fields raw_json` returns empty). Project specific paths and filter by them directly:

```
kind:Pod namespace:flux-system | fields name, raw_json.spec.serviceAccountName, raw_json.spec.containers | limit 5
```

The exact paths depend on the kind. For Pods the container/SA paths are `raw_json.spec.containers` and `raw_json.spec.serviceAccountName`. For Deployments and other workloads that wrap a Pod template they are `raw_json.spec.template.spec.containers` and `raw_json.spec.template.spec.serviceAccountName`. Use `kind:<EntityKind> | field_names` to enumerate every available path for that kind.

{% hint style="info" %}
**Notes**

* Field discovery for entities is **kind-scoped**: `kind:Pod | field_names`, `kind:Deployment | field_names`, etc. The available fields differ between kinds. See the [field discovery cheat sheet](#field-discovery-cheat-sheet).
* `raw_json` itself has no scalar column; it surfaces only via dotted paths like `raw_json.metadata.*`, `raw_json.spec.*`, `raw_json.status.*`.
  {% endhint %}

### query\_issues

Run a gcQL query against monitor issue instances - active alerts and historical firings produced by your monitors. Use [`query_monitors`](#query_monitors) first to find a monitor's identity, then drill into its firings here.

**When to use it**

* List active alerts in an environment or namespace.
* Identify the noisiest monitors (most firings) over a window.
* Drill from a monitor's identity into the underlying signals (with `query_logs` / `query_traces` afterward).

**Examples**

Recent issues in production:

```
* | filter env:production | sort by (_time desc) | limit 10
```

CPU-related monitors, most recent firing first:

```
* | filter monitor_name:*cpu* | sort by (_time desc) | limit 10
```

Firing count per monitor:

```
* | stats by (monitor_name) count() as firings | sort by (firings desc) | limit 20
```

{% hint style="info" %}
**Notes**

* Common fields: `id`, `monitor_id`, `monitor_name`, `state`, `previous_state`, `severity`, `cluster`, `env`, `namespace`, `workload`, `summary`, `silence_ids`, `timestamp`. Use `* | field_names` to discover the full list.
* An issue is silenced when `silence_ids` is non-empty.
  {% endhint %}

***

## query\_metrics

Query metrics from groundcover. Unlike the gcQL signal tools, `query_metrics` runs **PromQL** and exposes several modes:

| Mode            | Purpose                                                                    |
| --------------- | -------------------------------------------------------------------------- |
| `get_names`     | Discover metric names, optionally filtered by substring or required names. |
| `get_labels`    | List the label keys for a specific metric.                                 |
| `query_instant` | Execute a PromQL query at a point in time.                                 |
| `query_range`   | Execute a PromQL range query over a time window.                           |

### Parameters

| Parameter                  | Type              | Required         | Description                                                       |
| -------------------------- | ----------------- | ---------------- | ----------------------------------------------------------------- |
| `mode`                     | enum              | yes              | One of `get_names`, `get_labels`, `query_instant`, `query_range`. |
| `metricName`               | string            | for `get_labels` | The metric to inspect.                                            |
| `promql`                   | string            | for query modes  | PromQL expression. Use names verified via `get_names`.            |
| `filter`                   | string            | no               | Substring filter for `get_names` / `get_labels`.                  |
| `required`                 | string\[]         | no               | Required metric names for `get_names`.                            |
| `step`                     | string            | no               | Step interval for range queries (default `1m`).                   |
| `clusters` / `envs`        | string\[]         | no               | Optional cluster / environment filters.                           |
| `start` / `end` / `period` | see common params | no               | Time window.                                                      |
| `limit` / `skip`           | integer           | no               | Pagination for discovery modes.                                   |

### Examples

Discover CPU-related groundcover metrics:

```json
{
  "mode": "get_names",
  "filter": "groundcover_node_cpu",
  "limit": 10
}
```

Get the labels for a metric:

```json
{
  "mode": "get_labels",
  "metricName": "groundcover_node_capacity_cpum_cpu",
  "period": "PT15M"
}
```

Instant query - total CPU capacity per cluster:

```json
{
  "mode": "query_instant",
  "promql": "sum(groundcover_node_capacity_cpum_cpu) by (cluster)",
  "period": "PT5M"
}
```

{% hint style="info" %}
**Notes**

* Native groundcover metrics start with the `groundcover_` prefix and include both a description and a unit in the `get_names` response.
* Always pull names with `get_names` first - the response carries the canonical name to plug into `promql`.
* Returned timestamps are in UTC.
  {% endhint %}

***

## query\_monitors

List configured monitor definitions and their current health status. Use this to discover monitors before drilling into their firings via [`query_issues`](#query_issues).

### Parameters

| Parameter        | Type    | Required | Description                                                                                                      |
| ---------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------- |
| `query`          | string  | no       | gcQL filter string. Supported fields: `monitor_name`, `type`. Examples: `monitor_name:*api*`, `type:prometheus`. |
| `limit` / `skip` | integer | no       | Pagination.                                                                                                      |

This tool is **not time-bound** and does not accept `start` / `end` / `period`.

### Examples

List all monitors (paged):

```
(no query)
```

Find checkout-related Prometheus monitors:

```
monitor_name:*checkout* type:prometheus
```

Find all traces-driven monitors:

```
type:traces
```

{% hint style="info" %}
**Notes**

* Returns objects shaped `{ uuid, title, type }`. Note the field-name mapping when crossing tools: the **filter** field here is `monitor_name`, but the **result** field is `title`; both carry the same value. In `query_issues`, the corresponding fields are `monitor_id` (matches `uuid`) and `monitor_name` (matches `title`).
* Use `query_monitors` for definitions, `query_issues` for instances - don't try to fetch alert history here.
  {% endhint %}

***

## Metadata Discovery Tools

These tools take a list of keywords and return matching field names with sample values. Use them to discover what fields exist before writing a `query_*` call.

### Common Parameters

| Parameter  | Type                       | Required | Description                                                                         |
| ---------- | -------------------------- | -------- | ----------------------------------------------------------------------------------- |
| `keywords` | string\[]                  | yes      | Search terms matched against field names and values. At least one keyword required. |
| `limit`    | integer                    | no       | Max results to return. Defaults to 1000.                                            |
| `start`    | string (RFC3339)           | no       | Window start. Defaults to 1 hour ago.                                               |
| `end`      | string (RFC3339)           | no       | Window end. Defaults to now.                                                        |
| `period`   | string (ISO 8601 duration) | no       | Relative window. Defaults to `PT1H`.                                                |

### Field Discovery Cheat Sheet

Pick the right discovery method based on what you're querying:

| To discover...             | Use                                                                                                                          |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| Log fields                 | `search_logs_metadata`                                                                                                       |
| Trace / span fields        | `search_traces_metadata`                                                                                                     |
| Event fields               | `search_events_metadata`                                                                                                     |
| Metric names and labels    | `search_metrics_metadata` (or `query_metrics` with `mode:get_names` / `mode:get_labels`)                                     |
| Entity fields (live state) | `kind:<EntityKind> \| field_names` inside `query_entities` (kind-scoped)                                                     |
| Issue fields               | `* \| field_names` inside `query_issues`                                                                                     |
| Monitor definitions        | `query_monitors` (filter on `monitor_name` / `type`; results return `title` and `uuid` - same values, different field names) |

### search\_logs\_metadata

Search log field names and sample values.

**When to use it**

* The agent doesn't know the exact log attribute name (`workload` vs `k8s.workload.name`, etc.).
* The user mentions a domain term ("checkout", "tenant", "request\_id") and the agent needs to find which fields surface it.

**Example call**

```json
{
  "keywords": ["checkout"],
  "period": "PT1H"
}
```

### search\_traces\_metadata

Search span attribute keys and sample values.

**When to use it**

* Discover trace attributes for a service (`service.name`, `http.path`, `http_status_code`, etc.).
* Find which span attributes carry a particular business identifier.

**Example call**

```json
{
  "keywords": ["http", "status"],
  "period": "PT15M"
}
```

### search\_events\_metadata

Search Kubernetes event fields and sample values.

**When to use it**

* Look up event reasons (`OOMKilled`, `BackOff`, `FailedScheduling`) before filtering.
* Find the correct entity / object fields for a specific resource kind.

**Example call**

```json
{
  "keywords": ["OOMKilled"],
  "period": "P1D"
}
```

### search\_metrics\_metadata

Search metric names and their label keys / values.

**When to use it**

* Quick keyword-based discovery of what metrics exist.
* For more structured discovery (filtered name lists, label keys for a single metric), prefer `query_metrics` with `mode:get_names` or `mode:get_labels`.

**Example call**

```json
{
  "keywords": ["cpu", "container"],
  "period": "PT1H"
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.groundcover.com/getting-started/groundcover-mcp/mcp-tools-reference.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
