@uptimizr/mcp 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/AGENTS.md +53 -0
  2. package/llms.txt +39 -0
  3. package/package.json +2 -2
package/AGENTS.md CHANGED
@@ -19,6 +19,20 @@ collector remains the single gateway that enforces auth, per-project scoping, an
19
19
  UPTIMIZR_COLLECTOR_URL="https://collect.example.com" UPTIMIZR_API_KEY="utk_…" npx @uptimizr/mcp
20
20
  ```
21
21
 
22
+ ## Required key capability
23
+
24
+ `UPTIMIZR_API_KEY` must hold the **`query`** capability — and only that. Mint one with
25
+ `uptimizr new-key <projectId> --capabilities query --label "mcp-agent"` (`query` is the default).
26
+ `GET /api/v1/whoami` reports what a key holds, so a client can check before it registers tools; an
27
+ authenticated key missing a capability is refused with `403`, not `401`.
28
+
29
+ **`query:raw` is deliberately not needed.** Every tool here is an aggregate read; the server exposes
30
+ no raw per-session, replay or live-follow tool, so granting its key `query:raw` widens the blast
31
+ radius for nothing. `annotate` (metadata writes) and `ingest` are likewise never used. Prefer a
32
+ dedicated, labelled key with its own `--rate-limit-max` / `--rate-limit-window-ms` budget: the
33
+ collector's agent audit log records activity per key id, which is what makes an agent's reads
34
+ reviewable.
35
+
22
36
  ## Tools (read-only)
23
37
 
24
38
  <!-- generated:registry-tool-names:start — generated by `pnpm gen:docs`; edit the metric registry, not this table -->
@@ -64,6 +78,45 @@ returns `structuredContent` (`{ rows }`) alongside the JSON text — read the sc
64
78
  guessing the row shape, and read the tool description for the metric's caveats before trusting a
65
79
  small sample.
66
80
 
81
+ ## Result formats (`format`)
82
+
83
+ Every **aggregate** tool takes a `format` argument choosing the envelope its rows arrive in
84
+ (ADR 0051 §2). It filters nothing.
85
+
86
+ | `format` | Returns | Use it when |
87
+ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- |
88
+ | `summary` | A bounded digest — `ranked` top rows, a `series` trend, merged spatial `clusters`, or a single `record` — with shares, a sample size, the metric's `caveats` and a templated `reading` sentence. | **The default choice for an agent.** Always, unless you specifically need the rows. |
89
+ | `table` | `{ meta, rows }`: the same rows plus the metric, range, applied filters, sample size, row count, a truncation flag and the registry's limits. | You need every row _and_ the context to judge how far to trust it. |
90
+ | `full` | The bare rows, unchanged. Today's default. | You are post-processing the rows yourself and already know the sample is adequate. |
91
+
92
+ - `summary` is capped at the metric's `limits.maxSummaryRows`, so a 500-bin heatmap costs the same
93
+ as a 5-bin one. That is the whole point: a heatmap, voxel cloud or long leaderboard returned as
94
+ `full` can fill a context window on its own.
95
+ - `reading` and `caveats` are templated from the registry's column semantics by pure code — no model
96
+ is involved, so identical rows always produce identical words. Quote them; don't re-derive them.
97
+ - Shares appear only where the measure can honestly be summed. A metric in FPS or a ratio reports
98
+ `total: null` and no shares — do not compute a percentage from those rows.
99
+ - Cluster coordinates are **grid indices**: multiply by the effective `cellSize` for world space.
100
+ - `session_meta` and `scene_representation` are single stored records, not aggregations, and take no
101
+ `format`. Raw `/api/v1/sessions/:id/events` has an unrelated `format=json|ndjson`, and this server
102
+ exposes no tool for it.
103
+ - The catalog's default is still `full` — pass `format` explicitly.
104
+
105
+ ## Resources and prompts
106
+
107
+ - `uptimizr://capabilities` (`application/json`) — the machine-readable descriptor: schema version,
108
+ the canonical event types, the tool catalog, the parameter-semantics glossary, and `metrics`, the
109
+ whole registry with each metric's grain, column units, row JSON Schema, filters, limits,
110
+ interpretation, caveats, source channels and related metrics. Served from the package; **no
111
+ collector call**. Read it first — it is how to plan a query without trial and error.
112
+ - `uptimizr://scenes` (`application/json`) — the **live** list of scene ids with recent activity,
113
+ fetched through the read-only query API. These are the valid values for the `scene` parameter, so
114
+ resolve a user's scene name against it instead of guessing a string.
115
+ - Prompts: `weekly_scene_health` (optional `scene`), `attention_hotspots` (required `scene`) and
116
+ `xr_comfort_review` (optional `scene`). Each renders one user message that sequences the existing
117
+ read-only tools; they fetch nothing themselves and name no exact arguments, so the agent still
118
+ resolves the epoch-ms range and the filters.
119
+
67
120
  ## Rules for agents
68
121
 
69
122
  - **Read-only and privacy-preserving.** Never add ingestion, mutation, or raw per-session event
package/llms.txt CHANGED
@@ -32,6 +32,45 @@
32
32
 
33
33
  <!-- generated:registry-tool-names:end -->
34
34
 
35
+ ## Result formats (`format`)
36
+
37
+ Every aggregate tool takes `format` — the envelope its rows arrive in, not a filter (ADR 0051 §2).
38
+
39
+ - `summary` — **prefer this.** A bounded digest: `ranked` top rows, a `series` trend, merged spatial
40
+ `clusters`, or a single `record`, with shares, a sample size, the metric's `caveats` and a
41
+ templated `reading` sentence. Capped at the metric's `limits.maxSummaryRows`, so a 500-bin heatmap
42
+ costs the same as a 5-bin one. `reading` and `caveats` are templated by pure code — no model —
43
+ so identical rows always produce identical words.
44
+ - `table` — `{ meta, rows }`: every row plus the metric, range, applied filters, sample size, row
45
+ count, a truncation flag and the registry limits. Use it when you need the rows *and* the context
46
+ to judge them.
47
+ - `full` — the bare rows, unchanged. Today's catalog default; pass `format` explicitly.
48
+
49
+ Shares appear only where the measure can honestly be summed (an FPS or ratio metric reports
50
+ `total: null` and no shares). Cluster coordinates are grid indices — multiply by the effective
51
+ `cellSize` for world space. `session_meta` and `scene_representation` are stored records, not
52
+ aggregations, and take no `format`.
53
+
54
+ ## Resources and prompts
55
+
56
+ - `uptimizr://capabilities` (`application/json`) — static descriptor: schema version, canonical
57
+ event types, the tool catalog, the parameter-semantics glossary, and `metrics` (the whole registry
58
+ with grain, column units, row JSON Schema, filters, limits, interpretation, caveats, source
59
+ channels). No collector call. Read it first.
60
+ - `uptimizr://scenes` (`application/json`) — the live scene ids with recent activity, i.e. the valid
61
+ values for the `scene` parameter. Fetched through the read-only query API.
62
+ - Prompts: `weekly_scene_health` (optional `scene`), `attention_hotspots` (required `scene`),
63
+ `xr_comfort_review` (optional `scene`) — each renders one user message sequencing the read-only
64
+ tools; they fetch nothing themselves.
65
+
66
+ ## Required key capability
67
+
68
+ `UPTIMIZR_API_KEY` needs the `query` capability, and only that
69
+ (`uptimizr new-key <projectId> --capabilities query --label "mcp-agent"`; `query` is the default).
70
+ `query:raw` is **deliberately not required** — no tool here reads raw per-session, replay or
71
+ live-follow data. `annotate` and `ingest` are never used either. `GET /api/v1/whoami` reports what a
72
+ key holds; a key missing a required capability is refused with `403`.
73
+
35
74
  ## Key exports
36
75
 
37
76
  - `createMcpServer(client)` — build the read-only MCP server.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uptimizr/mcp",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Read-only Model Context Protocol (MCP) server over an Uptimizr collector's query API — let an agent ask questions of your own 3D analytics, on your own infrastructure.",
5
5
  "keywords": [
6
6
  "uptimizr",
@@ -49,7 +49,7 @@
49
49
  "dependencies": {
50
50
  "@modelcontextprotocol/sdk": "^1.30.0",
51
51
  "zod": "^4.5.4",
52
- "@uptimizr/agent-core": "1.1.0",
52
+ "@uptimizr/agent-core": "1.1.1",
53
53
  "@uptimizr/metrics": "0.1.0",
54
54
  "@uptimizr/schema": "1.1.0"
55
55
  },