Skip to content
Closed
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
372fa7e
feat: migrate dashboard tools to v2 perses APIs
namanv3 Jun 29, 2026
343f345
Merge branch 'main' into nv/move-to-perses
namanv3 Jun 29, 2026
5fb74ba
fix: valid discriminated schema unions, write-path webUrl, honest lis…
namanv3 Jul 1, 2026
80a3312
Merge branch 'main' into nv/move-to-perses
namanv3 Jul 16, 2026
20bda3b
feat: update dashboard for mertics api version being used
namanv3 Jul 16, 2026
1fac96b
fix: accept numeric limit/offset in list tool for dashboard v2
namanv3 Jul 16, 2026
e9cb11c
chore: update context file
namanv3 Jul 16, 2026
806a57d
Merge branch 'main' into nv/move-to-perses
namanv3 Jul 17, 2026
b5249f2
Merge branch 'main' into nv/move-to-perses
namanv3 Jul 21, 2026
67ee7c7
Merge branch 'main' into nv/move-to-perses
namanv3 Jul 21, 2026
bda15ee
test: add better client side testing for list method
namanv3 Jul 21, 2026
11b7910
test: remove client's raw method tests
namanv3 Jul 21, 2026
f92a181
chore: remove files no longer needed by v2 dashboards flow
namanv3 Jul 21, 2026
032aac2
chore: update plan to reflect the removal of unneeded files
namanv3 Jul 21, 2026
1d8f18a
fix: remove read only fields from update dashboard request
namanv3 Jul 21, 2026
1df34c0
fix: don't pop nullable flag when rewriting refs
namanv3 Jul 21, 2026
fbca2a7
fix: align stale dashboard guidance with the v6 schema
namanv3 Jul 21, 2026
b0f62ab
fix: accept the fetched dashboard envelope on update
namanv3 Jul 21, 2026
a1d0d54
Merge branch 'main' into nv/move-to-perses
namanv3 Jul 22, 2026
adbdb89
feat: add support for query, sort, and order in list dashboards
namanv3 Jul 22, 2026
5296b13
fix: user correct error return method as enforced by TestGuardrail_Pr…
namanv3 Jul 22, 2026
ddc7742
fix: handle server side limit clamping in list dashboards
namanv3 Jul 22, 2026
4cd8307
chore: use panels instead of widgets
namanv3 Jul 22, 2026
dc31d0c
test: add test for generate name field
namanv3 Jul 22, 2026
62f3e57
fix: mention that update api still needs the top level name
namanv3 Jul 22, 2026
8a7fcfe
feat: add proper instructions for how patch tool works
namanv3 Jul 22, 2026
d3b712b
feat: add full dashboard v2 examples resource
namanv3 Jul 24, 2026
e773021
Merge branch 'main' into nv/move-to-perses
namanv3 Jul 25, 2026
598cde6
chore: regenerate schema
namanv3 Jul 25, 2026
5383016
fix: remove outdated note about links being required
namanv3 Jul 25, 2026
eedd0c2
chore: regenerate templates, fix import tool description, update plan…
namanv3 Jul 25, 2026
be64ed3
fix: wrap templates list response to make it an object instead of list
namanv3 Jul 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions .github/scripts/regenerate_dashboard_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
python3 .github/scripts/regenerate_dashboard_templates.py

Walks the SigNoz/dashboards repo at the tip of `main`, locates each template
JSON, extracts title/description/tags, and emits the bundled index at
JSON, extracts the title/description (v6 `spec.display.*`, falling back to v1
top-level fields) and tags, and emits the bundled index at
internal/handler/tools/dashboard_templates.json.

The runtime fetcher (signoz_import_dashboard) also reads from `main`, so the
Expand Down Expand Up @@ -105,11 +106,25 @@ def _build_entry(ref: str, path: str) -> dict[str, Any] | None:
except json.JSONDecodeError:
return None

title = data.get("title") or path.rsplit("/", 1)[-1].removesuffix(".json")
description = data.get("description") or ""
tags = data.get("tags") or []
if not isinstance(tags, list):
tags = []
# v6 puts the human title/description under spec.display; fall back to the
# v1 top-level fields so the catalog regenerates cleanly through the
# migration, then to the filename.
spec = data.get("spec") or {}
display = spec.get("display") or {}
title = display.get("name") or data.get("title") or path.rsplit("/", 1)[-1].removesuffix(".json")
description = display.get("description") or data.get("description") or ""

# Tags feed the keyword index only (the entry has no tags field). v6 tags
# are {key, value} objects, v1 tags are plain strings; flatten both to text
# so _derive_keywords can tokenize them, indexing key AND value for v6.
raw_tags = data.get("tags")
tags: list[str] = []
if isinstance(raw_tags, list):
for t in raw_tags:
if isinstance(t, dict):
tags.extend(str(v) for v in (t.get("key"), t.get("value")) if v)
elif isinstance(t, str):
tags.append(t)

return {
"id": path.split("/", 1)[0],
Expand Down
56 changes: 33 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -357,9 +357,10 @@ HTTP mode exposes unauthenticated probe endpoints. New Kubernetes deployments sh
| `signoz_update_alert` | Fully replace an alert after fetching it and verifying notification-channel names |
| `signoz_delete_alert` | Permanently delete a confirmed alert rule by UUIDv7 `id` |
| `signoz_list_dashboards` | List tenant-dashboard summaries and discover UUIDs |
| `signoz_get_dashboard` | Get one dashboard's full layout, variables, widgets, and queries |
| `signoz_create_dashboard` | Create a custom multi-widget dashboard |
| `signoz_get_dashboard` | Get one dashboard's full layout, variables, panels, and queries |
| `signoz_create_dashboard` | Create a custom multi-panel dashboard |
| `signoz_update_dashboard` | Fully replace a fetched dashboard while preserving unrequested fields |
| `signoz_patch_dashboard` | Apply a partial RFC 6902 JSON Patch without resending the whole dashboard |
| `signoz_delete_dashboard` | Permanently delete a confirmed dashboard by `id` |
| `signoz_import_dashboard` | Create a dashboard from a known curated template path |
| `signoz_list_dashboard_templates` | List curated templates and discover an import path |
Expand All @@ -386,7 +387,7 @@ HTTP mode exposes unauthenticated probe endpoints. New Kubernetes deployments sh

For detailed usage and examples, see the [full documentation](https://signoz.io/docs/ai/signoz-mcp-server/).

> **Resource deep links:** the resource read tools (`signoz_list_dashboards`, `signoz_get_dashboard`, `signoz_list_alerts`, `signoz_list_alert_rules`, `signoz_get_alert`, `signoz_list_services`, `signoz_search_traces`, `signoz_get_trace_details`) include a `webUrl` field — an absolute deep link to the resource in the SigNoz web UI (per result row for `signoz_search_traces`) — when the request carries a SigNoz instance URL.
> **Resource deep links:** the resource read tools (`signoz_list_dashboards`, `signoz_get_dashboard`, `signoz_list_alerts`, `signoz_list_alert_rules`, `signoz_get_alert`, `signoz_list_services`, `signoz_search_traces`, `signoz_get_trace_details`) and the dashboard write tools (`signoz_create_dashboard`, `signoz_update_dashboard`, `signoz_patch_dashboard`) include a `webUrl` field — an absolute deep link to the resource in the SigNoz web UI (per result row for `signoz_search_traces`) — when the request carries a SigNoz instance URL.

### Agent Routing Guidance

Expand All @@ -403,6 +404,7 @@ Docs tools use the same authentication path as other MCP tools.
| `signoz://dashboard/instructions` | Dashboard fields, variables, chaining, and layout |
| `signoz://dashboard/widgets-instructions` | Panel choices and query-specific guides |
| `signoz://dashboard/widgets-examples` | Panel examples and validation patterns |
| `signoz://dashboard/list-filter-guide` | `signoz_list_dashboards` filter DSL: grammar, per-key operators, and examples |
| `signoz://dashboard/query-builder-example` | Dashboard Query Builder aggregations, filters, legends, and functions |
| `signoz://promql/instructions` | PromQL widgets or alerts, especially dotted OTel metric names |
| `signoz://dashboard/clickhouse-schema-for-logs` | Bundled logs schema snapshot for dashboard SQL |
Expand Down Expand Up @@ -514,29 +516,35 @@ Gets one alert rule's full definition (`GET /api/v2/rules/{id}`). Use `signoz_li

#### `signoz_list_dashboards`

Lists paginated tenant-dashboard summaries (name, UUID, description, tags, timestamps). Use `signoz_get_dashboard` for widget and query definitions, and follow `pagination.nextOffset` while `pagination.hasMore` is true before concluding a dashboard is absent.
Lists paginated tenant-dashboard summaries (name, UUID, description, tags, timestamps). Use `signoz_get_dashboard` for panel and query definitions, and page by raising `offset` by `limit` until you have covered `total` before concluding a dashboard is absent.

- **Parameters:**
- `limit` (default 50), `offset` (default 0) – offset-based pagination
- `filter` (optional) – server-side filter DSL over dashboard metadata (name, description, tags, creator, timestamps, locked state)
- `sort` (optional) – `updated_at` (default), `created_at`, or `name`
- `order` (optional) – `asc` or `desc` (default `desc`)

The `filter` DSL is a boolean expression of `key operator value` terms and bare free-text words joined with `AND`/`OR`/`NOT` and parentheses (e.g. `name CONTAINS 'overview' AND locked = true`). Read [`signoz://dashboard/list-filter-guide`](#mcp-resources) for the full grammar, the filterable keys with their operators, value formats, and worked examples; the list response also echoes the authoritative reserved-key set in `reservedKeywords`.

#### `signoz_get_dashboard`

Gets one known tenant dashboard's complete layout, variables, widgets, and queries. Use `signoz_list_dashboards` to discover the UUID.
Gets one known tenant dashboard's complete layout, variables, panels, and queries. Use `signoz_list_dashboards` to discover the UUID.

- **Parameters**: `id` (required) - Dashboard UUID

#### `signoz_create_dashboard`

Creates a custom multi-widget dashboard. Use `signoz_import_dashboard` when a curated template fits, or `signoz_create_view` to save one Explorer query. Read `signoz://dashboard/instructions`, `signoz://dashboard/widgets-instructions`, and `signoz://dashboard/widgets-examples` before composing the payload.
Creates a custom multi-panel dashboard. Use `signoz_import_dashboard` when a curated template fits, or `signoz_create_view` to save one Explorer query. Read `signoz://dashboard/instructions`, `signoz://dashboard/widgets-instructions`, and `signoz://dashboard/widgets-examples` before composing the payload.

- **Parameters:**
- `title` (required) – Dashboard name
- `description` (optional) – Short summary of what the dashboard shows
- `tags` (optional) – List of tags
- `layout` (required) – Widget positioning grid
- `variables` (optional) – Map of variables available for use in queries
- `widgets` (required) – List of widgets added to the dashboard
- `schemaVersion` (required) – Must be `"v6"`
- `name` (DNS-1123 label) or `generateName: true` to derive it from `spec.display.name`
- `tags` (required) – Array of key/value tags (may be empty)
- `spec` (required) – Perses spec: `display`, `variables` (array), `panels` (map keyed by panel id), `layouts` (array)

#### `signoz_import_dashboard`

Creates a dashboard from a curated template hosted in the [SigNoz/dashboards](https://github.com/SigNoz/dashboards) repo (`main` branch). The server fetches the template JSON, validates it, and creates the dashboard in one call.
Creates a dashboard from a curated template hosted in the [SigNoz/dashboards](https://github.com/SigNoz/dashboards) repo (`main` branch). The server fetches the template JSON and creates the dashboard in one call.

When the relative template path is unknown, call `signoz_list_dashboard_templates` first. Pass its `path`, not a URL or absolute path.

Expand All @@ -554,14 +562,16 @@ Returns the full bundled catalog of curated SigNoz dashboard templates (id, titl
Fully replaces an existing dashboard. Fetch it with `signoz_get_dashboard`, merge only the requested changes, and preserve every other field. Use `signoz_update_view` for a saved Explorer query.

- **Parameters:**
- `id` (required) – Unique identifier of the dashboard to update
- `dashboard` (required) – Complete dashboard object representing the post-update state
- `title` (required) – Dashboard name
- `description` (optional) – Short summary of what the dashboard shows
- `tags` (optional) – List of tags applied to the dashboard
- `layout` (required) – Full widget positioning grid
- `variables` (optional) – Map of variables available for use in queries
- `widgets` (required) – Complete set of widgets defining the updated dashboard
- `id` (required) – Dashboard id (the legacy `uuid` key is also accepted)
- `schemaVersion`, `name`, `tags`, `spec` – the complete post-update state (see the tool's JSON Schema)

#### `signoz_patch_dashboard`

Applies an RFC 6902 JSON Patch to a dashboard — a partial update without re-sending the entire dashboard. Prefer this over `signoz_update_dashboard` for targeted edits (rename, add/edit one panel or query, tweak a variable).

- **Parameters:**
- `id` (required) – Dashboard id (the legacy `uuid` key is also accepted)
- `patch` (required) – Array of `{op, path, value}` operations; paths are JSON Pointers into the dashboard's postable shape, e.g. `/spec/display/name`, `/spec/panels/<panelId>`, `/tags/-`

#### `signoz_list_services`

Expand Down Expand Up @@ -608,7 +618,7 @@ The response is `{ "status": "success", "data": { "items": [...], "total": <n>,

#### `signoz_list_views`

List saved Explorer views or discover a view UUID for one Logs, Traces, Metrics, or Cost Meter page. A view stores one reusable Explorer query; it is not a multi-widget dashboard. Apply name/category filters before pagination and follow `pagination.nextOffset` while `pagination.hasMore` is true.
List saved Explorer views or discover a view UUID for one Logs, Traces, Metrics, or Cost Meter page. A view stores one reusable Explorer query; it is not a multi-panel dashboard. Apply name/category filters before pagination and follow `pagination.nextOffset` while `pagination.hasMore` is true.

- **Parameters**:
- `sourcePage` (required) - One of: `traces`, `logs`, `metrics`, `meter`. Cost Meter views are filed under `meter` (a distinct Explorer page), not `metrics`
Expand Down Expand Up @@ -644,7 +654,7 @@ Fetch one known official SigNoz docs page's full Markdown or a requested heading

#### `signoz_create_view`

Save one reusable Explorer query. Use `signoz_create_dashboard` for a multi-widget dashboard. Cost Meter views use `sourcePage="meter"` with `signal="metrics"` and `source="meter"` in builder specs.
Save one reusable Explorer query. Use `signoz_create_dashboard` for a multi-panel dashboard. Cost Meter views use `sourcePage="meter"` with `signal="metrics"` and `source="meter"` in builder specs.

- **Parameters**: JSON payload matching the `SavedView` schema.
- **Required**: Read both MCP resources `signoz://view/instructions` and `signoz://view/examples` before composing any payload.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.25.5
require (
github.com/SigNoz/signoz-otel-collector v0.129.12
github.com/blevesearch/bleve/v2 v2.5.4
github.com/google/jsonschema-go v0.4.2
github.com/google/uuid v1.6.0
github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/mark3labs/mcp-go v0.56.0
Expand Down Expand Up @@ -59,7 +60,6 @@ require (
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang/snappy v1.0.0 // indirect
github.com/google/jsonschema-go v0.4.2 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.18.0 // indirect
Expand Down
Loading
Loading