--- name: ottyl description: Query and configure a running ottyl observability instance (logs, params, metrics, dashboards, settings, alerts, profiles) via its MCP server. --- # ottyl ottyl turns a piped command's stdout into a searchable log timeline plus ad-hoc metrics and dashboards, served from a single process. This doc covers how an agent connects to and drives a *running* instance. Everything the web UI can do to change the running instance's state is exposed as an MCP tool — declarations, dashboards, settings, alerts, profiles. Chart panels aren't screenshotted: use `render_panel` / `render_dashboard` to get a chart's underlying series data back as JSON, so you can reason about it directly instead of needing a browser. ## Find a session Each `ottyl` process registers itself under a name (random, e.g. `comic-gazelle`, unless started with `--name `). List known sessions: ``` ottyl sessions # comic-gazelle port=51423 pid=8421 ``` ## Connect an MCP client Start the MCP server (a separate short-lived process) pointed at that session, and register it with your MCP client (e.g. Claude Code's `.mcp.json`): ``` ottyl mcp --session comic-gazelle # or, if you already know the port: ottyl mcp --port 51423 ``` This is a thin proxy onto the target instance's HTTP API — each tool below maps to one or more `/api/...` routes. ## Get the latest SKILL.md This file is compiled into the `ottyl` binary, so a copy you have on disk can lag behind the version a running instance actually serves (e.g. after an upgrade). A running instance always serves its own current copy read-only over HTTP — fetch it directly rather than trusting a stale local file: ``` curl http://localhost:/SKILL.md ``` Use the port from `ottyl sessions` (or the `--port`/`--session` you passed to `ottyl mcp`). There is no CLI subcommand for this and no way to update it at runtime — the served content only changes when the binary is rebuilt with a new `SKILL.md`. ## Tools Most tools that operate on a profile take an optional `profile` argument; omit it to use the instance's active profile. ### Logs, timeline, stats - **`query_logs`** — count or read log lines matching a FilterBar query, with time/sequence range and sort options. ```json { "filter": "regex(\"error\")", "count_only": true } ``` - **`get_timeline`** — bucketed log-count histogram matching an optional filter (the data behind the Log Timeline chart). - **`get_stats`** — overall ingest stats: log count, sequence/timestamp bounds, ingest lag. ### Params - **`list_params`** — list declared params (including auto-derived ones). - **`declare_param`** — extract a named value from matching log lines. ```json { "name": "status_code", "message_match_regex": "status=(\\d+)", "capture_group": "1", "kind": "number" } ``` - **`clear_params`** — clear all declared params and re-derive auto params from retained logs. ### Metrics - **`list_metrics`** — list declared metrics. - **`declare_metric`** — bucket event counts/values by label, derived from matching log lines. ```json { "name": "errors_total", "message_match_regex": "level=error", "label_params": ["status_code"] } ``` - **`update_metric`** — update an existing metric declaration in place (`name` plus the same fields as `declare_metric`). - **`delete_metric`** — delete a declared metric by name. - **`get_metric_bucket_values`** — read a metric's raw bucket values, optionally filtered by label (`labels: "status_code=500"`) and time/sequence range. ### PromQL - **`run_promql_query`** — evaluate a PromQL-style query directly, returning raw series data (`labels` + timestamped `points`) — the same evaluation dashboards use. ```json { "promql": "rate(errors_total[5m])" } ``` ### Dashboards & panels - **`list_dashboards`** — list dashboards saved in a profile. - **`create_dashboard`** — create an empty dashboard. ```json { "name": "Errors" } ``` - **`get_dashboard`** — read a dashboard's panel definitions (promql/chart_type per panel, not rendered data). - **`delete_dashboard`** — delete a dashboard. - **`add_panel`** — add a panel, or update one in place by `panel_id`. ```json { "dashboard_id": "", "title": "Errors over time", "promql": "rate(errors_total[5m])", "chart_type": "line" } ``` - **`delete_panel`** — remove a panel from a dashboard by `panel_id`. - **`render_panel`** — resolve one panel's promql, evaluate it, and return `{ panel, series }` as JSON — this is how to "see" a chart without a browser. ```json { "dashboard_id": "", "panel_id": "" } ``` - **`render_dashboard`** — same as `render_panel` but for every panel in a dashboard at once, returning `{ dashboard, panels: [{ panel, series }, ...] }`. ### Settings & theming - **`get_settings`** / **`update_settings`** — read/update color scheme, active profile, `max_logs`, custom theme, ntfy topic/server. - **`list_css`** — list imported/linked custom CSS theme entries. - **`import_css`** — import a CSS theme by file content. - **`link_css`** — link an external CSS file/URL as a theme instead of importing content. - **`remove_css`** / **`get_css_content`** — remove a CSS entry / read its raw content by id. ### Alerts - **`list_alert_rules`** — list configured alert rules. - **`create_alert_rule`** / **`update_alert_rule`** — `condition` is one of: - `{"kind":"immediate","query":"..."}` - `{"kind":"threshold","query":"...","op":"gt|lt|ge|le|eq|ne","threshold":N,"window_ms":N}` - `{"kind":"newvalue","field_regex":"...","capture_group":"..."}` - `{"kind":"ratio","query_a":"...","query_b":"...","op":"...","ratio":N,"window_ms":N}` - **`delete_alert_rule`** — delete a rule by id. - **`test_alert_notification`** — send a test ntfy notification to verify delivery config. ### Profiles - **`list_profiles`** — list saved profiles with summary counts. - **`create_profile`** — create a new, empty profile. ```json { "name": "my-service" } ``` - **`delete_profile`** — delete a profile by name. - **`activate_profile`** — activate a profile, swapping in its declarations and dashboards as the running instance's live state.