Sign In

@parseable/parseable-mcp-server

Package Overview
Dependencies
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@parseable/parseable-mcp-server - npm Package Compare versions

Comparing version
0.1.1
to
0.2.0
+19
dist/init.d.ts
export interface ClientTarget {
id: string;
name: string;
configPath: string;
}
export interface InitArgs {
url?: string;
username?: string;
password?: string;
client?: string;
}
export declare function getClientTargets(home?: string, plat?: string): ClientTarget[];
export declare function parseInitArgs(argv: string[]): InitArgs;
export declare function mergeConfig(existing: Record<string, unknown>, creds: {
url: string;
username: string;
password: string;
}): Record<string, unknown>;
export declare function runInit(argv?: string[]): Promise<void>;
import { existsSync } from "node:fs";
import { mkdir, readFile, writeFile } from "node:fs/promises";
import { homedir, platform } from "node:os";
import { dirname, join } from "node:path";
import { createInterface } from "node:readline/promises";
export function getClientTargets(home = homedir(), plat = platform()) {
const targets = [];
let claudePath;
if (plat === "darwin") {
claudePath = join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
}
else if (plat === "win32") {
claudePath = join(process.env.APPDATA ?? home, "Claude", "claude_desktop_config.json");
}
else {
claudePath = join(home, ".config", "Claude", "claude_desktop_config.json");
}
targets.push({ id: "claude-desktop", name: "Claude Desktop", configPath: claudePath });
targets.push({ id: "cursor", name: "Cursor", configPath: join(home, ".cursor", "mcp.json") });
return targets;
}
export function parseInitArgs(argv) {
const args = {};
for (let i = 0; i < argv.length; i++) {
const a = argv[i];
if (a === "--url" && argv[i + 1])
args.url = argv[++i];
else if (a === "--username" && argv[i + 1])
args.username = argv[++i];
else if (a === "--password" && argv[i + 1])
args.password = argv[++i];
else if (a === "--client" && argv[i + 1])
args.client = argv[++i];
}
return args;
}
export function mergeConfig(existing, creds) {
const entry = {
command: "npx",
args: ["-y", "@parseable/parseable-mcp-server"],
env: {
PARSEABLE_URL: creds.url,
PARSEABLE_USERNAME: creds.username,
PARSEABLE_PASSWORD: creds.password,
},
};
const servers = existing.mcpServers ?? {};
servers.parseable = entry;
return { ...existing, mcpServers: servers };
}
async function writeClientConfig(target, creds) {
let existing = {};
if (existsSync(target.configPath)) {
const raw = await readFile(target.configPath, "utf8");
if (raw.trim()) {
try {
existing = JSON.parse(raw);
}
catch {
throw new Error(`Existing config at ${target.configPath} is not valid JSON. Refusing to overwrite.`);
}
}
await writeFile(`${target.configPath}.bak`, raw, "utf8");
}
else {
await mkdir(dirname(target.configPath), { recursive: true });
}
const merged = mergeConfig(existing, creds);
await writeFile(target.configPath, `${JSON.stringify(merged, null, 2)}\n`, "utf8");
}
async function ask(rl, question, fallback) {
const q = fallback ? `${question} [${fallback}]: ` : `${question}: `;
const answer = (await rl.question(q)).trim();
return answer || fallback || "";
}
export async function runInit(argv = process.argv.slice(3)) {
const args = parseInitArgs(argv);
console.log("Parseable MCP server — interactive setup\n");
const all = getClientTargets();
const detected = all.filter((t) => existsSync(t.configPath));
if (detected.length === 0) {
console.log("No MCP clients detected yet. Creating config files for both Claude Desktop and Cursor.");
console.log("If you only use one, you can delete the other later.\n");
}
else {
console.log("Detected MCP clients:");
for (const [i, t] of detected.entries()) {
console.log(` ${i + 1}. ${t.name} (${t.configPath})`);
}
console.log();
}
const rl = createInterface({ input: process.stdin, output: process.stdout });
let chosen;
if (args.client) {
const match = all.find((t) => t.id === args.client);
if (!match) {
rl.close();
console.error(`Unknown client "${args.client}". Use one of: ${all.map((t) => t.id).join(", ")}`);
process.exit(1);
}
chosen = [match];
}
else if (detected.length === 0) {
chosen = all;
}
else {
const pick = await ask(rl, "Configure which? (comma-separated numbers, or 'all')", "all");
if (pick === "all") {
chosen = detected;
}
else {
const indices = pick.split(",").map((s) => Number.parseInt(s.trim(), 10) - 1);
chosen = indices.map((i) => detected[i]).filter(Boolean);
}
}
if (chosen.length === 0) {
rl.close();
console.error("No clients selected. Aborting.");
process.exit(1);
}
const url = args.url || (await ask(rl, "Parseable URL"));
const username = args.username || (await ask(rl, "Username", "admin"));
const password = args.password || (await ask(rl, "Password"));
rl.close();
if (!url || !username || !password) {
console.error("URL, username, and password are all required.");
process.exit(1);
}
for (const target of chosen) {
try {
await writeClientConfig(target, { url, username, password });
console.log(`✓ Configured ${target.name}: ${target.configPath}`);
}
catch (err) {
console.error(`✗ Failed to configure ${target.name}: ${err.message}`);
}
}
console.log(`\nRestart ${chosen.map((t) => t.name).join(" / ")} to load 27 Parseable tools.`);
}
//# sourceMappingURL=init.js.map
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
+5
-0

@@ -9,2 +9,7 @@ #!/usr/bin/env node

async function main() {
if (process.argv[2] === "init") {
const { runInit } = await import("./init.js");
await runInit();
return;
}
const config = loadConfig();

@@ -11,0 +16,0 @@ const client = new ParseableClient(config);

+1
-1

@@ -1,1 +0,1 @@

{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE3D,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAE/B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,sBAAsB;QAC5B,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,KAAK,EAAE,IAA6B,EAAE,EAAE;YACtD,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;gBAC3C,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,GAAG,YAAY,cAAc,EAAE,CAAC;oBAClC,OAAO,WAAW,CAAC,GAAG,GAAG,CAAC,OAAO,uBAAuB,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;gBACtE,CAAC;gBACD,OAAO,WAAW,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACvE,CAAC;QACH,CAAC,CAAC;QAEF,uEAAuE;QAErE,MAAM,CAAC,YAKR,CACC,IAAI,CAAC,IAAI,EACT;YACE,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,EACD,OAAO,CACR,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CACX,mCAAmC,KAAK,CAAC,MAAM,8BAA8B,MAAM,CAAC,GAAG,EAAE,CAC1F,CAAC;AACJ,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE3D,KAAK,UAAU,IAAI;IACjB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;QAC/B,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;QAC9C,MAAM,OAAO,EAAE,CAAC;QAChB,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAE/B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,sBAAsB;QAC5B,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,KAAK,EAAE,IAA6B,EAAE,EAAE;YACtD,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;gBAC3C,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,GAAG,YAAY,cAAc,EAAE,CAAC;oBAClC,OAAO,WAAW,CAAC,GAAG,GAAG,CAAC,OAAO,uBAAuB,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;gBACtE,CAAC;gBACD,OAAO,WAAW,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACvE,CAAC;QACH,CAAC,CAAC;QAEF,uEAAuE;QAErE,MAAM,CAAC,YAKR,CACC,IAAI,CAAC,IAAI,EACT;YACE,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,EACD,OAAO,CACR,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CACX,mCAAmC,KAAK,CAAC,MAAM,8BAA8B,MAAM,CAAC,GAAG,EAAE,CAC1F,CAAC;AACJ,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
{
"name": "@parseable/parseable-mcp-server",
"version": "0.1.1",
"version": "0.2.0",
"description": "Model Context Protocol server for Parseable. Lets LLMs discover and query Parseable datasets.",

@@ -5,0 +5,0 @@ "license": "Apache-2.0",

+88
-63

@@ -5,57 +5,85 @@ # Parseable MCP Server

> **Status:** v0.4 — 27 tools across discovery, query (SQL + PromQL), alerts, alert targets, diagnostics, RBAC (read-only), and admin (read-only). Tools-only over stdio for maximum cross-client compatibility.
> **Status:** v0.2 — 27 tools across discovery, query (SQL + PromQL), alerts, alert targets, diagnostics, RBAC (read-only), and admin (read-only). Tools-only over stdio for maximum cross-client compatibility.
## Quickstart
One command, interactive setup — detects Claude Desktop / Cursor, asks for your Parseable URL + credentials, writes their config files:
```bash
npx -y @parseable/parseable-mcp-server init
```
Restart your MCP client. Tools appear. Skip the rest of this README unless you want to configure manually.
For scripted / non-interactive setup:
```bash
npx -y @parseable/parseable-mcp-server init \
--client claude-desktop \
--url https://your-parseable.example.com \
--username admin \
--password "$PARSEABLE_PASSWORD"
```
Supported `--client` values: `claude-desktop`, `cursor`. Existing config files are backed up as `<config>.bak` before being modified. Other `mcpServers` entries are preserved.
## Tools
### Discovery
| Tool | Purpose |
|---|---|
| `list_datasets` | List all log datasets on the server. |
| `get_dataset_schema` | Get column names + types for a dataset. |
| `get_dataset_info` | Get dataset metadata (created_at, retention, owner, time window). |
| `get_dataset_stats` | Get event count and storage bytes for a dataset. |
| `sample_events` | Return the most recent N events from a dataset (time-bounded, row-capped). |
| Tool | Purpose |
| -------------------- | -------------------------------------------------------------------------- |
| `list_datasets` | List all log datasets on the server. |
| `get_dataset_schema` | Get column names + types for a dataset. |
| `get_dataset_info` | Get dataset metadata (created_at, retention, owner, time window). |
| `get_dataset_stats` | Get event count and storage bytes for a dataset. |
| `sample_events` | Return the most recent N events from a dataset (time-bounded, row-capped). |
### Query
| Tool | Purpose |
|---|---|
| `query_sql` | Run a SQL `SELECT` over a time window. DDL/DML blocked. Auto-injects `LIMIT`. |
| Tool | Purpose |
| -------------- | ------------------------------------------------------------------------------------------ |
| `query_sql` | Run a SQL `SELECT` over a time window. DDL/DML blocked. Auto-injects `LIMIT`. |
| `query_promql` | Run PromQL instant or range query against a metrics dataset. Auto-routes by `start`+`end`. |
### Alerts
| Tool | Purpose |
|---|---|
| `list_alerts` | List all alerts with state, severity, tags. |
| `get_alert` | Get full config for one alert. |
| `list_alert_tags` | List all alert tags in use. |
| `enable_alert` | Enable an alert. |
| `disable_alert` | Disable an alert. |
| `evaluate_alert` | Force-evaluate an alert now. **May fire real notifications.** |
| `create_alert` | Create a new alert. Walks user through 8 questions (title, dataset, condition, window, frequency, severity, tags, targets), confirms assembled spec before submitting. |
| Tool | Purpose |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `list_alerts` | List all alerts with state, severity, tags. |
| `get_alert` | Get full config for one alert. |
| `list_alert_tags` | List all alert tags in use. |
| `enable_alert` | Enable an alert. |
| `disable_alert` | Disable an alert. |
| `evaluate_alert` | Force-evaluate an alert now. **May fire real notifications.** |
| `create_alert` | Create a new alert. Walks user through 8 questions (title, dataset, condition, window, frequency, severity, tags, targets), confirms assembled spec before submitting. |
### Alert targets
Notification destinations referenced by alerts. Three supported types: **Slack**, **generic webhook**, **Alertmanager**.
| Tool | Purpose |
|---|---|
| `list_alert_targets` | List all configured targets with ID, name, type. Called automatically by `create_alert` so the user picks targets by name instead of typing UUIDs. |
| `get_alert_target` | Get full config for one target (endpoint, headers, auth, notification interval). |
| `create_alert_target` | Create a new Slack/webhook/Alertmanager target. |
| Tool | Purpose |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `list_alert_targets` | List all configured targets with ID, name, type. Called automatically by `create_alert` so the user picks targets by name instead of typing UUIDs. |
| `get_alert_target` | Get full config for one target (endpoint, headers, auth, notification interval). |
| `create_alert_target` | Create a new Slack/webhook/Alertmanager target. |
### Diagnostics
| Tool | Purpose |
|---|---|
| `ping` | Check server connectivity and return version/build info (`/about`), `/liveness`, `/readiness`. Use to debug MCP-server → Parseable connection issues. |
| `explain_query` | Run `EXPLAIN` on a SQL query without executing it. Returns DataFusion plan for debugging slow queries, predicate pushdown, partition pruning. |
| Tool | Purpose |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ping` | Check server connectivity and return version/build info (`/about`), `/liveness`, `/readiness`. Use to debug MCP-server → Parseable connection issues. |
| `explain_query` | Run `EXPLAIN` on a SQL query without executing it. Returns DataFusion plan for debugging slow queries, predicate pushdown, partition pruning. |
### RBAC (read-only)
Inspect users, roles, and effective access. **No tools for creating, modifying, or deleting users/roles** — RBAC mutation stays in the Parseable UI/CLI by design.
| Tool | Purpose |
|---|---|
| `list_users` | List all registered users. |
| `get_user_roles` | Get the roles assigned to a specific user. |
| `list_roles` | List all role names defined on the server. |
| `get_role` | Get the privilege definition for a role (actions + datasets). |
| `get_default_role` | Get the default role assigned to new users. |
| Tool | Purpose |
| ------------------ | ------------------------------------------------------------- |
| `list_users` | List all registered users. |
| `get_user_roles` | Get the roles assigned to a specific user. |
| `list_roles` | List all role names defined on the server. |
| `get_role` | Get the privilege definition for a role (actions + datasets). |
| `get_default_role` | Get the default role assigned to new users. |

@@ -65,9 +93,10 @@ These compose for permission audits: "Does user X have write access to dataset Y?" → call `get_user_roles(X)` → for each role call `get_role` → check if `Ingest` or `PutAlert` privilege covers Y.

### Admin (read-only)
Inspect cluster health and dataset lifecycle. **No tools for mutating cluster state or retention** — keep changes in UI/CLI by design.
| Tool | Purpose |
|---|---|
| `get_cluster_status` | List all nodes (Prism, Querier, Ingestor, Indexer) with status. Distributed mode only. |
| Tool | Purpose |
| --------------------- | ------------------------------------------------------------------------------------------------- |
| `get_cluster_status` | List all nodes (Prism, Querier, Ingestor, Indexer) with status. Distributed mode only. |
| `get_cluster_metrics` | Aggregated metrics across all nodes (ingest rate, query latency, storage). Distributed mode only. |
| `get_retention` | Get retention policy for a dataset. |
| `get_retention` | Get retention policy for a dataset. |

@@ -81,8 +110,4 @@ ## Prerequisites

No install step — every MCP client invokes the server via `npx`, which fetches it on demand:
No install step — every MCP client invokes the server via `npx`, which fetches it on demand. The [Quickstart](#quickstart) above wires it into Claude Desktop / Cursor automatically. Skip ahead to **Client setup** below if you prefer manual config.
```
npx -y @parseable/parseable-mcp-server
```
For local development (hacking on the server itself):

@@ -102,14 +127,14 @@

| Var | Required | Default | Purpose |
|---|---|---|---|
| `PARSEABLE_URL` | ✅ | — | Parseable server base URL, no trailing slash |
| `PARSEABLE_USERNAME` | ✅ | — | Basic auth username |
| `PARSEABLE_PASSWORD` | ✅ | — | Basic auth password |
| `PARSEABLE_DEFAULT_DATASET` | | — | Scope a tool prompt to one dataset (advisory) |
| `PARSEABLE_MAX_ROWS` | | 1000 | Hard cap on query result rows |
| `PARSEABLE_QUERY_TIMEOUT_MS` | | 30000 | HTTP request timeout |
| Var | Required | Default | Purpose |
| ---------------------------- | -------- | ------- | --------------------------------------------- |
| `PARSEABLE_URL` | ✅ | — | Parseable server base URL, no trailing slash |
| `PARSEABLE_USERNAME` | ✅ | — | Basic auth username |
| `PARSEABLE_PASSWORD` | ✅ | — | Basic auth password |
| `PARSEABLE_DEFAULT_DATASET` | | — | Scope a tool prompt to one dataset (advisory) |
| `PARSEABLE_MAX_ROWS` | | 1000 | Hard cap on query result rows |
| `PARSEABLE_QUERY_TIMEOUT_MS` | | 30000 | HTTP request timeout |
## Client setup
The command and args are the same for every client — only the config file location and syntax differ.
Manual config — only needed if [Quickstart](#quickstart) doesn't cover your client (Claude Code, Codex, VS Code, Windsurf, Continue, Cline, Zed). The command and args are the same for every client — only the config file location and syntax differ.

@@ -216,11 +241,11 @@ ### Claude Desktop

- *"What datasets do I have in Parseable?"*
- *"Show schema for `nginx_access`."*
- *"Run SQL: count events per status code in `nginx_access` over the last hour."*
- *"Plot rate(http_requests_total[5m]) from `otel_metrics` over last 30 min, step 1m."*
- *"List my alerts and which ones are disabled."*
- *"Disable alert `<id>`, too noisy."*
- *"Create an alert that fires when 5xx count in `nginx_access` > 50 over 5 min, severity high, notify the ops Slack channel."* — the client walks the 8-step Q&A, calls `list_alert_targets` to pick "ops Slack" by name, then submits.
- *"What notification targets are configured?"* — calls `list_alert_targets`.
- *"Add a Slack target pointing at `https://hooks.slack.com/services/...` named ops-alerts."* — calls `create_alert_target`.
- _"What datasets do I have in Parseable?"_
- _"Show schema for `nginx_access`."_
- _"Run SQL: count events per status code in `nginx_access` over the last hour."_
- _"Plot rate(http_requests_total[5m]) from `otel_metrics` over last 30 min, step 1m."_
- _"List my alerts and which ones are disabled."_
- _"Disable alert `<id>`, too noisy."_
- _"Create an alert that fires when 5xx count in `nginx_access` > 50 over 5 min, severity high, notify the ops Slack channel."_ — the client walks the 8-step Q&A, calls `list_alert_targets` to pick "ops Slack" by name, then submits.
- _"What notification targets are configured?"_ — calls `list_alert_targets`.
- _"Add a Slack target pointing at `https://hooks.slack.com/services/...` named ops-alerts."_ — calls `create_alert_target`.

@@ -227,0 +252,0 @@ ## Security notes