@uptimizr/mcp 1.1.1 → 1.2.0

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.
@@ -1,5 +1,5 @@
1
1
  import { type EventType } from "@uptimizr/schema";
2
- import { type ColumnSemantics, type DimensionId, type FilterId, type MetricCategory, type MetricComparison, type MetricGrain } from "@uptimizr/metrics";
2
+ import { type ColumnSemantics, type DimensionId, type FilterId, type MetricCapability, type MetricCategory, type MetricComparison, type MetricGrain } from "@uptimizr/metrics";
3
3
  /**
4
4
  * One tool the server exposes, described for self-discovery: its name, a human
5
5
  * title, what it returns, and the parameter names it accepts.
@@ -34,11 +34,17 @@ export interface CapabilityMetricDescriptor {
34
34
  category: MetricCategory;
35
35
  /** What one row represents. */
36
36
  grain: MetricGrain;
37
- /** The collector route it is served on, when it has one. */
37
+ /**
38
+ * The collector route it is served on, when it has one. `capability` names the
39
+ * API-key capability the route requires; it is absent for the ordinary
40
+ * `query` surface and `"query:raw"` for a metric gated behind raw-session
41
+ * retention (ADR 0051 §7).
42
+ */
38
43
  endpoint?: {
39
44
  method: "GET";
40
45
  path: string;
41
46
  pathParams?: readonly FilterId[];
47
+ capability?: MetricCapability;
42
48
  };
43
49
  /** Group-by dimensions the rows are keyed by. */
44
50
  dimensions: readonly DimensionId[];
@@ -93,10 +99,22 @@ export interface CapabilitiesDescriptor {
93
99
  /** Human-oriented notes about scope and discovery. */
94
100
  notes: readonly string[];
95
101
  }
102
+ /**
103
+ * What the descriptor should describe.
104
+ */
105
+ export interface BuildCapabilitiesOptions {
106
+ /**
107
+ * The capability set of the key this descriptor is being built for, as
108
+ * `GET /api/v1/whoami` reports it. Defaults to `["query"]` — the ordinary
109
+ * aggregate read surface, and the safe answer for a caller that has not
110
+ * looked the key up.
111
+ */
112
+ capabilities?: readonly string[];
113
+ }
96
114
  /**
97
115
  * Build the capabilities descriptor from the metric registry and the event
98
116
  * schema. Pure and synchronous — it introspects definitions only, never the
99
117
  * collector, so it is safe to serve as a static resource.
100
118
  */
101
- export declare function buildCapabilities(): CapabilitiesDescriptor;
119
+ export declare function buildCapabilities(options?: BuildCapabilitiesOptions): CapabilitiesDescriptor;
102
120
  //# sourceMappingURL=capabilities.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE/E,OAAO,EAIL,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,gBAAgB,EAErB,KAAK,WAAW,EACjB,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;;GASG;AACH,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B;AAED,+DAA+D;AAC/D,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC;IACzB,+BAA+B;IAC/B,KAAK,EAAE,WAAW,CAAC;IACnB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE;QAAE,MAAM,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAA;KAAE,CAAC;IAC7E,iDAAiD;IACjD,UAAU,EAAE,SAAS,WAAW,EAAE,CAAC;IACnC,mCAAmC;IACnC,OAAO,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC7B,qCAAqC;IACrC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,kFAAkF;IAClF,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;IACnD,4EAA4E;IAC5E,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,8BAA8B;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,+DAA+D;IAC/D,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,4EAA4E;IAC5E,cAAc,EAAE,SAAS,SAAS,EAAE,CAAC;IACrC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B;;;OAGG;IACH,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACrC,oEAAoE;IACpE,aAAa,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,QAAQ,EAAE,IAAI,CAAC;IACf,oEAAoE;IACpE,UAAU,EAAE,SAAS,SAAS,EAAE,CAAC;IACjC,0DAA0D;IAC1D,MAAM,EAAE,SAAS,yBAAyB,EAAE,CAAC;IAC7C,+EAA+E;IAC/E,KAAK,EAAE,SAAS,wBAAwB,EAAE,CAAC;IAC3C;;;OAGG;IACH,OAAO,EAAE,SAAS,0BAA0B,EAAE,CAAC;IAC/C,sDAAsD;IACtD,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAmCD;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,sBAAsB,CA8C1D"}
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG/E,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EAErB,KAAK,WAAW,EACjB,MAAM,mBAAmB,CAAC;AAG3B;;;;;;;;;GASG;AACH,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B;AAED,+DAA+D;AAC/D,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC;IACzB,+BAA+B;IAC/B,KAAK,EAAE,WAAW,CAAC;IACnB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE;QACT,MAAM,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;QACjC,UAAU,CAAC,EAAE,gBAAgB,CAAC;KAC/B,CAAC;IACF,iDAAiD;IACjD,UAAU,EAAE,SAAS,WAAW,EAAE,CAAC;IACnC,mCAAmC;IACnC,OAAO,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC7B,qCAAqC;IACrC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,kFAAkF;IAClF,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;IACnD,4EAA4E;IAC5E,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,8BAA8B;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,+DAA+D;IAC/D,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,4EAA4E;IAC5E,cAAc,EAAE,SAAS,SAAS,EAAE,CAAC;IACrC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B;;;OAGG;IACH,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACrC,oEAAoE;IACpE,aAAa,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,QAAQ,EAAE,IAAI,CAAC;IACf,oEAAoE;IACpE,UAAU,EAAE,SAAS,SAAS,EAAE,CAAC;IACjC,0DAA0D;IAC1D,MAAM,EAAE,SAAS,yBAAyB,EAAE,CAAC;IAC7C,+EAA+E;IAC/E,KAAK,EAAE,SAAS,wBAAwB,EAAE,CAAC;IAC3C;;;OAGG;IACH,OAAO,EAAE,SAAS,0BAA0B,EAAE,CAAC;IAC/C,sDAAsD;IACtD,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AA0DD;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,sBAAsB,CAkGhG"}
@@ -1,6 +1,28 @@
1
1
  import { EVENT_TYPES, SCHEMA_VERSION } from "@uptimizr/schema";
2
2
  import { z } from "zod";
3
- import { FILTER_TARGETS, allMetrics, isResourceMetric, } from "@uptimizr/metrics";
3
+ import { queryTool } from "@uptimizr/agent-core";
4
+ import { FILTER_TARGETS, allMetrics, isResourceMetric, metricCapability, } from "@uptimizr/metrics";
5
+ import { NON_REGISTRY_READ_TOOLS } from "@uptimizr/agent-core";
6
+ /**
7
+ * The query DSL's own top-level fields (ADR 0051 §3), for the parameter
8
+ * glossary. The per-metric tools' parameters are all registry `FilterId`s and
9
+ * are described by `FILTER_TARGETS`; the `query` tool's are the grammar's, so
10
+ * they are described here. `limit` and `format` are deliberately absent: they
11
+ * are filter ids too, and `FILTER_TARGETS` already defines them.
12
+ */
13
+ const QUERY_DSL_PARAMS = {
14
+ v: "Grammar version. Always `1`.",
15
+ metric: "The registry metric to compute — any `id` in `metrics` below.",
16
+ dimensions: "Group-by dimensions. Must be the metric's own grain, or omitted: each metric is computed " +
17
+ "at one fixed grain.",
18
+ filters: "The filters the chosen metric declares, as a JSON object (a metric's `filters` list names " +
19
+ "them). `since`/`until` live in `range` and `format` is a top-level field.",
20
+ range: "The time window, `{ since, until }` in epoch milliseconds. Required.",
21
+ segment: "A named slice to hold fixed. Part of the grammar; not answered yet.",
22
+ compare: "A second range or segment to compare against. Part of the grammar; not answered yet.",
23
+ order: "Result ordering. Part of the grammar; not answered yet — each metric has its own order.",
24
+ explain: "Return the compiled plan instead of the rows. Part of the grammar; not answered yet.",
25
+ };
4
26
  /** Every request parameter a metric accepts: its path params, then its filters. */
5
27
  function paramsOf(metric) {
6
28
  return [...(metric.endpoint?.pathParams ?? []), ...metric.filters];
@@ -37,22 +59,56 @@ function toMetricDescriptor(metric) {
37
59
  * schema. Pure and synchronous — it introspects definitions only, never the
38
60
  * collector, so it is safe to serve as a static resource.
39
61
  */
40
- export function buildCapabilities() {
62
+ export function buildCapabilities(options = {}) {
63
+ const granted = new Set(options.capabilities ?? ["query"]);
41
64
  const metrics = allMetrics();
42
- const served = metrics.filter((metric) => metric.endpoint != null);
43
- const tools = served.map((metric) => ({
44
- name: metric.id,
45
- title: metric.title,
46
- description: metric.description,
47
- params: paramsOf(metric),
48
- }));
65
+ // `tools` describes what THIS key can call, so a capability-gated metric is
66
+ // listed only when the key holds its capability (ADR 0051 §7). `metrics` below
67
+ // still documents the whole registry, each entry carrying the capability its
68
+ // endpoint needs — the difference between "you cannot call this" and "this
69
+ // does not exist" is worth keeping.
70
+ const served = metrics.filter((metric) => metric.endpoint != null && granted.has(metricCapability(metric)));
71
+ const tools = [
72
+ ...served.map((metric) => ({
73
+ name: metric.id,
74
+ title: metric.title,
75
+ description: metric.description,
76
+ params: paramsOf(metric),
77
+ })),
78
+ // The descriptor must describe what the server actually registers, and the
79
+ // server registers `readTools` — which carries a short tail of collector
80
+ // reads that are configuration rather than measurements and so have no
81
+ // registry entry (#311). They take no filters, hence the empty `params`.
82
+ ...NON_REGISTRY_READ_TOOLS.map((tool) => ({
83
+ name: tool.name,
84
+ title: tool.title,
85
+ description: tool.description,
86
+ params: [],
87
+ })),
88
+ ];
89
+ // The one tool that is not per-metric: the query DSL (ADR 0051 §3). It is
90
+ // described here too, because this descriptor is what an agent reads to learn
91
+ // the surface — and the DSL tool's own description sends the agent *back*
92
+ // here for the metric vocabulary, so leaving it out would close the loop on
93
+ // nothing.
94
+ tools.push({
95
+ name: queryTool.name,
96
+ title: queryTool.title,
97
+ description: queryTool.description,
98
+ params: Object.keys(queryTool.inputSchema),
99
+ });
49
100
  const usedParams = new Set();
50
101
  for (const metric of served)
51
102
  for (const param of paramsOf(metric))
52
103
  usedParams.add(param);
53
- const params = [...usedParams]
54
- .sort()
55
- .map((name) => ({ name, description: FILTER_TARGETS[name].description }));
104
+ const params = [
105
+ ...[...usedParams]
106
+ .sort()
107
+ .map((name) => ({ name, description: FILTER_TARGETS[name].description })),
108
+ ...Object.entries(QUERY_DSL_PARAMS)
109
+ .filter(([name]) => !usedParams.has(name))
110
+ .map(([name, description]) => ({ name, description })),
111
+ ];
56
112
  return {
57
113
  schemaVersion: SCHEMA_VERSION,
58
114
  readOnly: true,
@@ -61,8 +117,16 @@ export function buildCapabilities() {
61
117
  tools,
62
118
  metrics: metrics.map(toMetricDescriptor),
63
119
  notes: [
120
+ "Read the uptimizr://context resource FIRST. It describes the project in front of you — " +
121
+ "its scene ids and named regions, the custom events this application emits and the props " +
122
+ "they carry, how fresh the data is, whether raw session retention is on, and which of the " +
123
+ "metrics below are empty because their capture channel is off. Use the names it gives " +
124
+ "you; do not infer a scene id, a region id or a custom-event name.",
64
125
  "This MCP surface is strictly read-only: aggregate, privacy-preserving queries only. " +
65
- "There are no ingestion, mutation, or raw per-session event tools (ADR 0003 / ADR 0017).",
126
+ "There are no ingestion or mutation tools, and no raw per-session event tools " +
127
+ "(ADR 0003 / ADR 0017). The one per-session read, `session_narrative`, is a bounded " +
128
+ "compaction rather than an event stream, and the collector serves it only to a key " +
129
+ "holding `query:raw` on a deployment with raw-session retention enabled.",
66
130
  "`metrics` is the collector's semantic metric registry (ADR 0051 §1): for each metric it " +
67
131
  "gives the result `grain` (what one row is), the `columns` with their units, the JSON " +
68
132
  "Schema of a row, `limits`, how to read it (`interpretation`) and how far to trust it " +
@@ -70,12 +134,19 @@ export function buildCapabilities() {
70
134
  "`sourceChannels` names the capture channels (ADR 0012) that feed a metric. If a project " +
71
135
  "has that channel disabled or sampled down, the metric is empty or proportional rather " +
72
136
  "than exact — say so instead of reporting a zero as a finding.",
137
+ "`query` (the last tool) runs any metric above through the query DSL (ADR 0051 §3): one " +
138
+ "request naming the `metric`, a required `range`, the filters that metric declares, a " +
139
+ "`limit` and a `format`. Prefer it when a question needs a filter the per-metric tool " +
140
+ "does not expose. Its `compare`, `segment`, `order` and `explain` fields are part of the " +
141
+ "published grammar but are not answered yet — run two queries and subtract instead.",
73
142
  "`tools` lists the registry's served read surface and the request parameters of each " +
74
143
  "underlying endpoint. It is exactly the set this server registers, because the tool " +
75
144
  "catalog is generated from the same registry (ADR 0051 §1) — the authoritative input " +
76
145
  "and output schemas of a registered tool are still the ones returned by `tools/list`.",
77
- "Enumerate the concrete scene ids for the `scene` parameter with the uptimizr://scenes " +
78
- "resource or the list_scenes tool; enumerate sessions with the list_sessions tool.",
146
+ "Enumerate the concrete scene ids for the `scene` parameter with the uptimizr://context or " +
147
+ "uptimizr://scenes resource, or the list_scenes tool; enumerate sessions with the " +
148
+ "list_sessions tool. Custom-event names and their prop keys come from " +
149
+ "uptimizr://context or the custom_event_vocabulary tool.",
79
150
  "All time ranges use epoch-millisecond `since`/`until`. Omit both for all-time.",
80
151
  "The same registry drives the collector's OpenAPI document at GET /api/v1/openapi.json, " +
81
152
  "which describes every endpoint below with its parameters and response schema.",
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  export { readMcpConfig, type McpConfig } from "./config.js";
2
- export { createCollectorClient, CollectorError, readTools, type CollectorClient, type CollectorClientConfig, type QueryParams, type ReadTool, type ReadToolRequest, } from "@uptimizr/agent-core";
3
- export { createMcpServer } from "./server.js";
4
- export { buildCapabilities, type CapabilitiesDescriptor, type CapabilityToolDescriptor, type CapabilityParamDescriptor, } from "./capabilities.js";
5
- export { registerResources, CAPABILITIES_URI, SCENES_URI } from "./resources.js";
2
+ export { createCollectorClient, CollectorError, readTools, rawTools, type CollectorClient, type CollectorClientConfig, type QueryParams, type ReadTool, type ReadToolRequest, } from "@uptimizr/agent-core";
3
+ export { writeTools, mutatingWriteTools, type WriteTool } from "@uptimizr/agent-core";
4
+ export { createMcpServer, fetchKeyCapabilities, type CreateMcpServerOptions } from "./server.js";
5
+ export { buildCapabilities, type BuildCapabilitiesOptions, type CapabilitiesDescriptor, type CapabilityToolDescriptor, type CapabilityParamDescriptor, } from "./capabilities.js";
6
+ export { registerResources, CAPABILITIES_URI, SCENES_URI, SKILLS_URI } from "./resources.js";
6
7
  export { registerPrompts } from "./prompts.js";
7
8
  export { version } from "./version.js";
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,SAAS,EACT,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,eAAe,GACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EACL,iBAAiB,EACjB,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,GAC/B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,SAAS,EACT,QAAQ,EACR,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,eAAe,GACrB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtF,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,KAAK,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACjG,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,GAC/B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -1,8 +1,12 @@
1
1
  export { readMcpConfig } from "./config.js";
2
- export { createCollectorClient, CollectorError, readTools, } from "@uptimizr/agent-core";
3
- export { createMcpServer } from "./server.js";
2
+ export { createCollectorClient, CollectorError, readTools, rawTools, } from "@uptimizr/agent-core";
3
+ // The metadata write tools (#310) — deliberately a separate export from
4
+ // `readTools` above, so an integration's read-only stance stays inspectable
5
+ // (ADR 0017): events are read-only, metadata writes sit behind `annotate`.
6
+ export { writeTools, mutatingWriteTools } from "@uptimizr/agent-core";
7
+ export { createMcpServer, fetchKeyCapabilities } from "./server.js";
4
8
  export { buildCapabilities, } from "./capabilities.js";
5
- export { registerResources, CAPABILITIES_URI, SCENES_URI } from "./resources.js";
9
+ export { registerResources, CAPABILITIES_URI, SCENES_URI, SKILLS_URI } from "./resources.js";
6
10
  export { registerPrompts } from "./prompts.js";
7
11
  export { version } from "./version.js";
8
12
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAkB,MAAM,aAAa,CAAC;AAC5D,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,SAAS,GAMV,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EACL,iBAAiB,GAIlB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAkB,MAAM,aAAa,CAAC;AAC5D,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,SAAS,EACT,QAAQ,GAMT,MAAM,sBAAsB,CAAC;AAC9B,wEAAwE;AACxE,4EAA4E;AAC5E,2EAA2E;AAC3E,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAkB,MAAM,sBAAsB,CAAC;AACtF,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAA+B,MAAM,aAAa,CAAC;AACjG,OAAO,EACL,iBAAiB,GAKlB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAuBzE,2DAA2D;AAC3D,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAiGvD"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA+BzE,2DAA2D;AAC3D,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAmBvD"}
package/dist/prompts.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { AGENT_SKILLS } from "@uptimizr/agent-core";
1
2
  import { z } from "zod";
2
3
  /**
3
4
  * Curated prompt templates for common 3D-analytics investigations (ADR 0050 §7).
@@ -5,92 +6,40 @@ import { z } from "zod";
5
6
  * read-only tools in a sensible order — no data is fetched here; the agent runs
6
7
  * the tools. Templates are intentionally tool-agnostic about exact arguments so
7
8
  * the agent can adapt (e.g. resolve the current epoch-ms range itself).
9
+ *
10
+ * The templates themselves are the **agent skills** of `@uptimizr/agent-core`
11
+ * (`AGENT_SKILLS`). They live there because the headless `uptimizr agent report`
12
+ * CLI seeds its transcript with the same text (ADR 0051 §6, design sketch §F.4)
13
+ * and the eval bank asks the same questions; this module is the MCP *binding* —
14
+ * it turns each skill's argument list into a Zod `argsSchema` and its `render`
15
+ * into the single user message `prompts/get` returns. Reword a skill once and
16
+ * every client changes with it.
8
17
  */
9
- const sceneArg = z
10
- .string()
11
- .optional()
12
- .describe("Optional scene id to scope the analysis to (see the uptimizr://scenes resource).");
13
- const requiredSceneArg = z
14
- .string()
15
- .describe("The scene id to analyse (see the uptimizr://scenes resource).");
16
- const forScene = (scene) => scene ? `scene "${scene}"` : "the project (all scenes)";
18
+ /** Build a prompt template's Zod `argsSchema` from a skill's argument list. */
19
+ function argsSchemaFor(skill) {
20
+ const shape = {};
21
+ for (const arg of skill.args) {
22
+ shape[arg.name] = arg.required
23
+ ? z.string().describe(arg.description)
24
+ : z.string().optional().describe(arg.description);
25
+ }
26
+ return shape;
27
+ }
17
28
  /** Register the curated prompt templates on the server. */
18
29
  export function registerPrompts(server) {
19
- server.registerPrompt("weekly_scene_health", {
20
- title: "Weekly scene health",
21
- description: "A weekly health check for a scene (or the whole project): traffic, event mix, " +
22
- "performance, and the most-interacted meshes.",
23
- argsSchema: { scene: sceneArg },
24
- }, ({ scene }) => ({
25
- messages: [
26
- {
27
- role: "user",
28
- content: {
29
- type: "text",
30
- text: `Give me a weekly health report for ${forScene(scene)} covering the last 7 days.\n\n` +
31
- "Use these read-only tools and summarise the findings:\n" +
32
- "- `event_counts` for the per-event-type mix" +
33
- (scene ? ` (scene="${scene}")` : "") +
34
- ".\n" +
35
- "- `timeseries` (interval ~86400s) to show the day-by-day event volume and average FPS trend.\n" +
36
- "- `perf_summary` for avg/min/p50 FPS.\n" +
37
- "- `top_meshes` for the most-interacted meshes.\n" +
38
- "- `list_sessions` for how many sessions were recorded.\n\n" +
39
- "Call out anything unusual (traffic spikes/drops, FPS regressions, error events) and " +
40
- "end with 2–3 concrete recommendations.",
41
- },
42
- },
43
- ],
44
- }));
45
- server.registerPrompt("attention_hotspots", {
46
- title: "Attention hot-spots for a scene",
47
- description: "Find where visitors look and click in a scene: view-direction concentration, " +
48
- "gaze→mesh flow, and the objects that draw the most interaction.",
49
- argsSchema: { scene: requiredSceneArg },
50
- }, ({ scene }) => ({
51
- messages: [
52
- {
53
- role: "user",
54
- content: {
55
- type: "text",
56
- text: `Where does attention concentrate in scene "${scene}"?\n\n` +
57
- 'Use these read-only tools (all scoped with scene="' +
58
- scene +
59
- '") and synthesise the result:\n' +
60
- "- `camera_heatmap` for the view-direction distribution (what people look at).\n" +
61
- "- `flow_links` for how gaze flows into clicked meshes.\n" +
62
- "- `click_rays` for view-gated clicks per voxel/mesh.\n" +
63
- "- `top_meshes` for the most-interacted objects.\n\n" +
64
- "Describe the main hot-spots, any ignored/cold areas, and what that implies for the " +
65
- "scene's layout or call-to-action placement.",
66
- },
67
- },
68
- ],
69
- }));
70
- server.registerPrompt("xr_comfort_review", {
71
- title: "XR comfort & drop-off review",
72
- description: "Review VR/AR comfort signals for a scene (or the whole project): rapid head rotation, " +
73
- "locomotion style, session abandonment, and input-source mix.",
74
- argsSchema: { scene: sceneArg },
75
- }, ({ scene }) => ({
76
- messages: [
77
- {
78
- role: "user",
79
- content: {
80
- type: "text",
81
- text: `Review XR/immersive comfort and drop-off for ${forScene(scene)}.\n\n` +
82
- "Use these read-only tools" +
83
- (scene ? ` (scene="${scene}")` : "") +
84
- " and correlate the signals:\n" +
85
- "- `xr_rotation` for rapid head/view turns (a motion-sickness proxy).\n" +
86
- "- `xr_locomotion` for the fly/navigate/teleport mix and session span.\n" +
87
- "- `xr_abandonment` for short XR sessions that signal headset drop-off.\n" +
88
- "- `xr_sources` for the hand vs. controller vs. gaze input split.\n\n" +
89
- "Flag likely-uncomfortable patterns (heavy rapid rotation or continuous locomotion " +
90
- "paired with early exits) and suggest comfort mitigations.",
30
+ for (const skill of AGENT_SKILLS) {
31
+ server.registerPrompt(skill.name, {
32
+ title: skill.title,
33
+ description: skill.description,
34
+ argsSchema: argsSchemaFor(skill),
35
+ }, ((args) => ({
36
+ messages: [
37
+ {
38
+ role: "user",
39
+ content: { type: "text", text: skill.render(args) },
91
40
  },
92
- },
93
- ],
94
- }));
41
+ ],
42
+ })));
43
+ }
95
44
  }
96
45
  //# sourceMappingURL=prompts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;GAMG;AAEH,MAAM,QAAQ,GAAG,CAAC;KACf,MAAM,EAAE;KACR,QAAQ,EAAE;KACV,QAAQ,CAAC,kFAAkF,CAAC,CAAC;AAEhG,MAAM,gBAAgB,GAAG,CAAC;KACvB,MAAM,EAAE;KACR,QAAQ,CAAC,+DAA+D,CAAC,CAAC;AAE7E,MAAM,QAAQ,GAAG,CAAC,KAAyB,EAAU,EAAE,CACrD,KAAK,CAAC,CAAC,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,0BAA0B,CAAC;AAE1D,2DAA2D;AAC3D,MAAM,UAAU,eAAe,CAAC,MAAiB;IAC/C,MAAM,CAAC,cAAc,CACnB,qBAAqB,EACrB;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACT,gFAAgF;YAChF,8CAA8C;QAChD,UAAU,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE;KAChC,EACD,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QACd,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EACF,sCAAsC,QAAQ,CAAC,KAAK,CAAC,gCAAgC;wBACrF,yDAAyD;wBACzD,6CAA6C;wBAC7C,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;wBACpC,KAAK;wBACL,gGAAgG;wBAChG,yCAAyC;wBACzC,kDAAkD;wBAClD,4DAA4D;wBAC5D,sFAAsF;wBACtF,wCAAwC;iBAC3C;aACF;SACF;KACF,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,cAAc,CACnB,oBAAoB,EACpB;QACE,KAAK,EAAE,iCAAiC;QACxC,WAAW,EACT,+EAA+E;YAC/E,iEAAiE;QACnE,UAAU,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE;KACxC,EACD,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QACd,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EACF,8CAA8C,KAAK,QAAQ;wBAC3D,oDAAoD;wBACpD,KAAK;wBACL,iCAAiC;wBACjC,iFAAiF;wBACjF,0DAA0D;wBAC1D,wDAAwD;wBACxD,qDAAqD;wBACrD,qFAAqF;wBACrF,6CAA6C;iBAChD;aACF;SACF;KACF,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,cAAc,CACnB,mBAAmB,EACnB;QACE,KAAK,EAAE,8BAA8B;QACrC,WAAW,EACT,wFAAwF;YACxF,8DAA8D;QAChE,UAAU,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE;KAChC,EACD,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QACd,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EACF,gDAAgD,QAAQ,CAAC,KAAK,CAAC,OAAO;wBACtE,2BAA2B;wBAC3B,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;wBACpC,+BAA+B;wBAC/B,wEAAwE;wBACxE,yEAAyE;wBACzE,0EAA0E;wBAC1E,sEAAsE;wBACtE,oFAAoF;wBACpF,2DAA2D;iBAC9D;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAmB,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;GAcG;AAEH,+EAA+E;AAC/E,SAAS,aAAa,CAAC,KAAiB;IACtC,MAAM,KAAK,GAA8B,EAAE,CAAC;IAC5C,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,QAAQ;YAC5B,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC;YACtC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,eAAe,CAAC,MAAiB;IAC/C,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;QACjC,MAAM,CAAC,cAAc,CACnB,KAAK,CAAC,IAAI,EACV;YACE,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,UAAU,EAAE,aAAa,CAAC,KAAK,CAAU;SAC1C,EACD,CAAC,CAAC,IAAwC,EAAE,EAAE,CAAC,CAAC;YAC9C,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;iBAC7D;aACF;SACF,CAAC,CAAU,CACb,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -1,9 +1,14 @@
1
1
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import type { CollectorClient } from "@uptimizr/agent-core";
2
+ import { type CollectorClient } from "@uptimizr/agent-core";
3
+ import { type BuildCapabilitiesOptions } from "./capabilities.js";
3
4
  /** URI of the static, machine-readable capabilities/schema descriptor. */
4
5
  export declare const CAPABILITIES_URI = "uptimizr://capabilities";
5
6
  /** URI of the live list of scenes with recent activity. */
6
7
  export declare const SCENES_URI = "uptimizr://scenes";
8
+ /** URI of the live project context document (ADR 0051 §5). */
9
+ export declare const CONTEXT_URI = "uptimizr://context";
10
+ /** URI of the packaged methodology skills catalog (ADR 0051 §7). */
11
+ export declare const SKILLS_URI = "uptimizr://skills";
7
12
  /**
8
13
  * Register read-only MCP resources so an agent can **self-discover** the surface
9
14
  * (ADR 0050 §7):
@@ -11,11 +16,25 @@ export declare const SCENES_URI = "uptimizr://scenes";
11
16
  * - `uptimizr://capabilities` — a static descriptor (event types, tool catalog,
12
17
  * parameter semantics) built from the shared catalog + `@uptimizr/schema`. No
13
18
  * collector call; it documents *what can be asked*.
19
+ * - `uptimizr://context` — the live **project context document** (ADR 0051 §5):
20
+ * the scenes and their named regions, the custom-event vocabulary this
21
+ * application emits, data freshness and retention flags, and which metrics are
22
+ * empty because their capture channel is off. Read it **first**: it is the
23
+ * difference between filtering on a real scene id or custom-event name and
24
+ * guessing one.
14
25
  * - `uptimizr://scenes` — the live set of scene ids with activity, fetched via
15
26
  * the read-only collector client, so the `scene` parameter can be filled in
16
- * with real values.
27
+ * with real values. A narrower view of what `uptimizr://context` already
28
+ * carries; kept for clients that only need the ids.
29
+ * - `uptimizr://skills` — the packaged **methodology skills** (ADR 0051 §7): the
30
+ * same investigations this server offers as prompt templates, listed with what
31
+ * each one produces, the tools its method uses and the arguments it takes. A
32
+ * client whose UI has no prompt picker can still read the catalog and ask for
33
+ * one by name; the full text stays behind `prompts/get`. No collector call.
17
34
  *
18
- * Both are read-only; resources never mutate or expose raw per-session events.
35
+ * All four are read-only; resources never mutate or expose raw per-session
36
+ * events. A collector too old to serve `GET /api/v1/context` makes the context
37
+ * resource fail its read — the other resources and every tool keep working.
19
38
  */
20
- export declare function registerResources(server: McpServer, client: CollectorClient): void;
39
+ export declare function registerResources(server: McpServer, client: CollectorClient, options?: BuildCapabilitiesOptions): void;
21
40
  //# sourceMappingURL=resources.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG5D,0EAA0E;AAC1E,eAAO,MAAM,gBAAgB,4BAA4B,CAAC;AAC1D,2DAA2D;AAC3D,eAAO,MAAM,UAAU,sBAAsB,CAAC;AAE9C;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAuClF"}
1
+ {"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAqB,KAAK,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAErF,0EAA0E;AAC1E,eAAO,MAAM,gBAAgB,4BAA4B,CAAC;AAC1D,2DAA2D;AAC3D,eAAO,MAAM,UAAU,sBAAsB,CAAC;AAC9C,8DAA8D;AAC9D,eAAO,MAAM,WAAW,uBAAuB,CAAC;AAChD,oEAAoE;AACpE,eAAO,MAAM,UAAU,sBAAsB,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,eAAe,EACvB,OAAO,GAAE,wBAA6B,GACrC,IAAI,CAoGN"}
package/dist/resources.js CHANGED
@@ -1,8 +1,13 @@
1
+ import { AGENT_SKILLS } from "@uptimizr/agent-core";
1
2
  import { buildCapabilities } from "./capabilities.js";
2
3
  /** URI of the static, machine-readable capabilities/schema descriptor. */
3
4
  export const CAPABILITIES_URI = "uptimizr://capabilities";
4
5
  /** URI of the live list of scenes with recent activity. */
5
6
  export const SCENES_URI = "uptimizr://scenes";
7
+ /** URI of the live project context document (ADR 0051 §5). */
8
+ export const CONTEXT_URI = "uptimizr://context";
9
+ /** URI of the packaged methodology skills catalog (ADR 0051 §7). */
10
+ export const SKILLS_URI = "uptimizr://skills";
6
11
  /**
7
12
  * Register read-only MCP resources so an agent can **self-discover** the surface
8
13
  * (ADR 0050 §7):
@@ -10,13 +15,27 @@ export const SCENES_URI = "uptimizr://scenes";
10
15
  * - `uptimizr://capabilities` — a static descriptor (event types, tool catalog,
11
16
  * parameter semantics) built from the shared catalog + `@uptimizr/schema`. No
12
17
  * collector call; it documents *what can be asked*.
18
+ * - `uptimizr://context` — the live **project context document** (ADR 0051 §5):
19
+ * the scenes and their named regions, the custom-event vocabulary this
20
+ * application emits, data freshness and retention flags, and which metrics are
21
+ * empty because their capture channel is off. Read it **first**: it is the
22
+ * difference between filtering on a real scene id or custom-event name and
23
+ * guessing one.
13
24
  * - `uptimizr://scenes` — the live set of scene ids with activity, fetched via
14
25
  * the read-only collector client, so the `scene` parameter can be filled in
15
- * with real values.
26
+ * with real values. A narrower view of what `uptimizr://context` already
27
+ * carries; kept for clients that only need the ids.
28
+ * - `uptimizr://skills` — the packaged **methodology skills** (ADR 0051 §7): the
29
+ * same investigations this server offers as prompt templates, listed with what
30
+ * each one produces, the tools its method uses and the arguments it takes. A
31
+ * client whose UI has no prompt picker can still read the catalog and ask for
32
+ * one by name; the full text stays behind `prompts/get`. No collector call.
16
33
  *
17
- * Both are read-only; resources never mutate or expose raw per-session events.
34
+ * All four are read-only; resources never mutate or expose raw per-session
35
+ * events. A collector too old to serve `GET /api/v1/context` makes the context
36
+ * resource fail its read — the other resources and every tool keep working.
18
37
  */
19
- export function registerResources(server, client) {
38
+ export function registerResources(server, client, options = {}) {
20
39
  server.registerResource("capabilities", CAPABILITIES_URI, {
21
40
  title: "Uptimizr capabilities",
22
41
  description: "Machine-readable descriptor of the read-only analytics surface: event types, the tool " +
@@ -27,10 +46,23 @@ export function registerResources(server, client) {
27
46
  {
28
47
  uri: uri.href,
29
48
  mimeType: "application/json",
30
- text: JSON.stringify(buildCapabilities(), null, 2),
49
+ text: JSON.stringify(buildCapabilities(options), null, 2),
31
50
  },
32
51
  ],
33
52
  }));
53
+ server.registerResource("context", CONTEXT_URI, {
54
+ title: "Project context",
55
+ description: "Read this first. The live description of THIS project: scenes and their named regions, " +
56
+ "the custom events the application emits and the props they carry, data freshness and " +
57
+ "retention flags, the store engine, and which metrics will be empty because their capture " +
58
+ "channel is off. Use the ids and names it gives you instead of inferring your own.",
59
+ mimeType: "application/json",
60
+ }, async (uri) => {
61
+ const data = await client.get("api/v1/context", {});
62
+ return {
63
+ contents: [{ uri: uri.href, mimeType: "application/json", text: JSON.stringify(data) }],
64
+ };
65
+ });
34
66
  server.registerResource("scenes", SCENES_URI, {
35
67
  title: "Active scenes",
36
68
  description: "Live list of developer-assigned scene ids with recent activity — the valid values for " +
@@ -42,5 +74,35 @@ export function registerResources(server, client) {
42
74
  contents: [{ uri: uri.href, mimeType: "application/json", text: JSON.stringify(data) }],
43
75
  };
44
76
  });
77
+ server.registerResource("skills", SKILLS_URI, {
78
+ title: "Methodology skills",
79
+ description: "The packaged investigation methodologies this server also offers as prompt templates: " +
80
+ "what each one produces, when to use it, the tools its method relies on, the API-key " +
81
+ "capabilities it needs and the arguments it takes. Ask for one by name with " +
82
+ "`prompts/get` to receive the method itself. No collector call.",
83
+ mimeType: "application/json",
84
+ }, async (uri) => ({
85
+ contents: [
86
+ {
87
+ uri: uri.href,
88
+ mimeType: "application/json",
89
+ // The body is deliberately left out: it is a template, and rendering it
90
+ // needs the arguments `prompts/get` collects. Listing it here would put
91
+ // an unrendered `{{scene}}` in front of a model as if it were the method.
92
+ text: JSON.stringify({
93
+ skills: AGENT_SKILLS.map((skill) => ({
94
+ name: skill.name,
95
+ title: skill.title,
96
+ description: skill.description,
97
+ tools: skill.tools,
98
+ capabilities: skill.capabilities,
99
+ args: skill.args,
100
+ prompt: skill.name,
101
+ file: `skills/${skill.id}/SKILL.md`,
102
+ })),
103
+ }, null, 2),
104
+ },
105
+ ],
106
+ }));
45
107
  }
46
108
  //# sourceMappingURL=resources.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,0EAA0E;AAC1E,MAAM,CAAC,MAAM,gBAAgB,GAAG,yBAAyB,CAAC;AAC1D,2DAA2D;AAC3D,MAAM,CAAC,MAAM,UAAU,GAAG,mBAAmB,CAAC;AAE9C;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAiB,EAAE,MAAuB;IAC1E,MAAM,CAAC,gBAAgB,CACrB,cAAc,EACd,gBAAgB,EAChB;QACE,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EACT,wFAAwF;YACxF,8EAA8E;QAChF,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QACd,QAAQ,EAAE;YACR;gBACE,GAAG,EAAE,GAAG,CAAC,IAAI;gBACb,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;aACnD;SACF;KACF,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,gBAAgB,CACrB,QAAQ,EACR,UAAU,EACV;QACE,KAAK,EAAE,eAAe;QACtB,WAAW,EACT,wFAAwF;YACxF,yCAAyC;QAC3C,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;QACZ,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QACnD,OAAO;YACL,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,kBAAkB,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;SACxF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAwB,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAiC,MAAM,mBAAmB,CAAC;AAErF,0EAA0E;AAC1E,MAAM,CAAC,MAAM,gBAAgB,GAAG,yBAAyB,CAAC;AAC1D,2DAA2D;AAC3D,MAAM,CAAC,MAAM,UAAU,GAAG,mBAAmB,CAAC;AAC9C,8DAA8D;AAC9D,MAAM,CAAC,MAAM,WAAW,GAAG,oBAAoB,CAAC;AAChD,oEAAoE;AACpE,MAAM,CAAC,MAAM,UAAU,GAAG,mBAAmB,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAiB,EACjB,MAAuB,EACvB,UAAoC,EAAE;IAEtC,MAAM,CAAC,gBAAgB,CACrB,cAAc,EACd,gBAAgB,EAChB;QACE,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EACT,wFAAwF;YACxF,8EAA8E;QAChF,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QACd,QAAQ,EAAE;YACR;gBACE,GAAG,EAAE,GAAG,CAAC,IAAI;gBACb,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;aAC1D;SACF;KACF,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,gBAAgB,CACrB,SAAS,EACT,WAAW,EACX;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,yFAAyF;YACzF,uFAAuF;YACvF,2FAA2F;YAC3F,mFAAmF;QACrF,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;QACZ,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;QACpD,OAAO;YACL,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,kBAAkB,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;SACxF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,gBAAgB,CACrB,QAAQ,EACR,UAAU,EACV;QACE,KAAK,EAAE,eAAe;QACtB,WAAW,EACT,wFAAwF;YACxF,yCAAyC;QAC3C,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;QACZ,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QACnD,OAAO;YACL,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,kBAAkB,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;SACxF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,gBAAgB,CACrB,QAAQ,EACR,UAAU,EACV;QACE,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EACT,wFAAwF;YACxF,sFAAsF;YACtF,6EAA6E;YAC7E,gEAAgE;QAClE,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QACd,QAAQ,EAAE;YACR;gBACE,GAAG,EAAE,GAAG,CAAC,IAAI;gBACb,QAAQ,EAAE,kBAAkB;gBAC5B,wEAAwE;gBACxE,wEAAwE;gBACxE,0EAA0E;gBAC1E,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;oBACE,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;wBACnC,IAAI,EAAE,KAAK,CAAC,IAAI;wBAChB,KAAK,EAAE,KAAK,CAAC,KAAK;wBAClB,WAAW,EAAE,KAAK,CAAC,WAAW;wBAC9B,KAAK,EAAE,KAAK,CAAC,KAAK;wBAClB,YAAY,EAAE,KAAK,CAAC,YAAY;wBAChC,IAAI,EAAE,KAAK,CAAC,IAAI;wBAChB,MAAM,EAAE,KAAK,CAAC,IAAI;wBAClB,IAAI,EAAE,UAAU,KAAK,CAAC,EAAE,WAAW;qBACpC,CAAC,CAAC;iBACJ,EACD,IAAI,EACJ,CAAC,CACF;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}