@butlr/butlr-mcp-server 0.2.0 → 0.5.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.
- package/dist/cache/topology-cache.d.ts +18 -3
- package/dist/cache/topology-cache.d.ts.map +1 -1
- package/dist/cache/topology-cache.js +19 -3
- package/dist/cache/topology-cache.js.map +1 -1
- package/dist/clients/queries/tags.d.ts +63 -6
- package/dist/clients/queries/tags.d.ts.map +1 -1
- package/dist/clients/queries/tags.js +26 -4
- package/dist/clients/queries/tags.js.map +1 -1
- package/dist/clients/queries/topology.d.ts +8 -2
- package/dist/clients/queries/topology.d.ts.map +1 -1
- package/dist/clients/queries/topology.js +19 -2
- package/dist/clients/queries/topology.js.map +1 -1
- package/dist/clients/types.d.ts +4 -0
- package/dist/clients/types.d.ts.map +1 -1
- package/dist/errors/mcp-errors.d.ts +34 -0
- package/dist/errors/mcp-errors.d.ts.map +1 -1
- package/dist/errors/mcp-errors.js +71 -5
- package/dist/errors/mcp-errors.js.map +1 -1
- package/dist/tools/butlr-available-rooms.d.ts +5 -23
- package/dist/tools/butlr-available-rooms.d.ts.map +1 -1
- package/dist/tools/butlr-available-rooms.js +104 -51
- package/dist/tools/butlr-available-rooms.js.map +1 -1
- package/dist/tools/butlr-fetch-entity-details.d.ts +4 -0
- package/dist/tools/butlr-fetch-entity-details.d.ts.map +1 -1
- package/dist/tools/butlr-fetch-entity-details.js +31 -1
- package/dist/tools/butlr-fetch-entity-details.js.map +1 -1
- package/dist/tools/butlr-get-asset-details.d.ts.map +1 -1
- package/dist/tools/butlr-get-asset-details.js +29 -4
- package/dist/tools/butlr-get-asset-details.js.map +1 -1
- package/dist/tools/butlr-get-current-occupancy.d.ts.map +1 -1
- package/dist/tools/butlr-get-current-occupancy.js +15 -4
- package/dist/tools/butlr-get-current-occupancy.js.map +1 -1
- package/dist/tools/butlr-get-occupancy-timeseries.d.ts.map +1 -1
- package/dist/tools/butlr-get-occupancy-timeseries.js +16 -5
- package/dist/tools/butlr-get-occupancy-timeseries.js.map +1 -1
- package/dist/tools/butlr-list-tags.d.ts +28 -10
- package/dist/tools/butlr-list-tags.d.ts.map +1 -1
- package/dist/tools/butlr-list-tags.js +81 -24
- package/dist/tools/butlr-list-tags.js.map +1 -1
- package/dist/tools/butlr-list-topology.d.ts +7 -1
- package/dist/tools/butlr-list-topology.d.ts.map +1 -1
- package/dist/tools/butlr-list-topology.js +845 -35
- package/dist/tools/butlr-list-topology.js.map +1 -1
- package/dist/tools/butlr-search-assets.d.ts.map +1 -1
- package/dist/tools/butlr-search-assets.js +7 -1
- package/dist/tools/butlr-search-assets.js.map +1 -1
- package/dist/tools/butlr-space-busyness.d.ts.map +1 -1
- package/dist/tools/butlr-space-busyness.js +22 -4
- package/dist/tools/butlr-space-busyness.js.map +1 -1
- package/dist/tools/butlr-traffic-flow.d.ts.map +1 -1
- package/dist/tools/butlr-traffic-flow.js +9 -3
- package/dist/tools/butlr-traffic-flow.js.map +1 -1
- package/dist/types/responses.d.ts +123 -5
- package/dist/types/responses.d.ts.map +1 -1
- package/dist/utils/field-validator.d.ts +6 -0
- package/dist/utils/field-validator.d.ts.map +1 -1
- package/dist/utils/field-validator.js +5 -1
- package/dist/utils/field-validator.js.map +1 -1
- package/dist/utils/occupancy-helpers.d.ts +15 -2
- package/dist/utils/occupancy-helpers.d.ts.map +1 -1
- package/dist/utils/occupancy-helpers.js +116 -19
- package/dist/utils/occupancy-helpers.js.map +1 -1
- package/dist/utils/tag-resolver.d.ts +99 -0
- package/dist/utils/tag-resolver.d.ts.map +1 -0
- package/dist/utils/tag-resolver.js +108 -0
- package/dist/utils/tag-resolver.js.map +1 -0
- package/package.json +1 -1
|
@@ -9,15 +9,30 @@ interface CacheEntry {
|
|
|
9
9
|
*/
|
|
10
10
|
export declare const topologyCache: LRUCache<string, CacheEntry, unknown>;
|
|
11
11
|
/**
|
|
12
|
-
* Generate cache key for topology queries
|
|
12
|
+
* Generate cache key for topology queries.
|
|
13
|
+
*
|
|
14
|
+
* `devicesMerged` is part of the key because two consumers prime this cache
|
|
15
|
+
* with different shapes: `butlr_list_topology` runs sensors/hives through
|
|
16
|
+
* `mergeSensorsAndHivesIntoTopology` (so every floor carries `sensors` and
|
|
17
|
+
* `hives` arrays); `butlr_search_assets` writes the raw `sites` tree
|
|
18
|
+
* unmodified. A device-aware reader cannot trust an unmerged entry, so the
|
|
19
|
+
* two shapes must live under separate keys.
|
|
13
20
|
*/
|
|
14
|
-
export declare function generateTopologyCacheKey(orgId: string, includeDevices: boolean, includeZones: boolean, siteIds?: string[]): string;
|
|
21
|
+
export declare function generateTopologyCacheKey(orgId: string, includeDevices: boolean, includeZones: boolean, devicesMerged: boolean, siteIds?: string[]): string;
|
|
15
22
|
/**
|
|
16
23
|
* Get cached topology data
|
|
17
24
|
*/
|
|
18
25
|
export declare function getCachedTopology(key: string): CacheEntry | undefined;
|
|
19
26
|
/**
|
|
20
|
-
* Store topology data in cache
|
|
27
|
+
* Store topology data in cache.
|
|
28
|
+
*
|
|
29
|
+
* INVARIANT: callers MUST only cache COMPLETE topology. A partial fetch
|
|
30
|
+
* (Apollo `result.error` set, GraphQL returned errors alongside data) will
|
|
31
|
+
* silently launder its partiality through the cache otherwise — every
|
|
32
|
+
* subsequent cache-hit reader would treat the truncated tree as
|
|
33
|
+
* authoritative without seeing `partial_topology`. `butlr-list-topology`
|
|
34
|
+
* gates its `setCachedTopology` call on `!partialData`; any new caller
|
|
35
|
+
* must do the same.
|
|
21
36
|
*/
|
|
22
37
|
export declare function setCachedTopology(key: string, data: Record<string, unknown>): void;
|
|
23
38
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"topology-cache.d.ts","sourceRoot":"","sources":["../../src/cache/topology-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AASrC,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,uCAKxB,CAAC;AAEH
|
|
1
|
+
{"version":3,"file":"topology-cache.d.ts","sourceRoot":"","sources":["../../src/cache/topology-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AASrC,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,uCAKxB,CAAC;AAEH;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,OAAO,EACvB,YAAY,EAAE,OAAO,EACrB,aAAa,EAAE,OAAO,EACtB,OAAO,CAAC,EAAE,MAAM,EAAE,GACjB,MAAM,CAYR;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAUrE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CASlF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAIzC;AAED;;GAEG;AACH,wBAAgB,aAAa;;;;EAM5B"}
|
|
@@ -16,15 +16,23 @@ export const topologyCache = new LRUCache({
|
|
|
16
16
|
updateAgeOnHas: false,
|
|
17
17
|
});
|
|
18
18
|
/**
|
|
19
|
-
* Generate cache key for topology queries
|
|
19
|
+
* Generate cache key for topology queries.
|
|
20
|
+
*
|
|
21
|
+
* `devicesMerged` is part of the key because two consumers prime this cache
|
|
22
|
+
* with different shapes: `butlr_list_topology` runs sensors/hives through
|
|
23
|
+
* `mergeSensorsAndHivesIntoTopology` (so every floor carries `sensors` and
|
|
24
|
+
* `hives` arrays); `butlr_search_assets` writes the raw `sites` tree
|
|
25
|
+
* unmodified. A device-aware reader cannot trust an unmerged entry, so the
|
|
26
|
+
* two shapes must live under separate keys.
|
|
20
27
|
*/
|
|
21
|
-
export function generateTopologyCacheKey(orgId, includeDevices, includeZones, siteIds) {
|
|
28
|
+
export function generateTopologyCacheKey(orgId, includeDevices, includeZones, devicesMerged, siteIds) {
|
|
22
29
|
const parts = ["topo", orgId];
|
|
23
30
|
if (siteIds && siteIds.length > 0) {
|
|
24
31
|
parts.push(`sites:${siteIds.sort().join(",")}`);
|
|
25
32
|
}
|
|
26
33
|
parts.push(`devices:${includeDevices}`);
|
|
27
34
|
parts.push(`zones:${includeZones}`);
|
|
35
|
+
parts.push(`merged:${devicesMerged}`);
|
|
28
36
|
return parts.join(":");
|
|
29
37
|
}
|
|
30
38
|
/**
|
|
@@ -41,7 +49,15 @@ export function getCachedTopology(key) {
|
|
|
41
49
|
return cached;
|
|
42
50
|
}
|
|
43
51
|
/**
|
|
44
|
-
* Store topology data in cache
|
|
52
|
+
* Store topology data in cache.
|
|
53
|
+
*
|
|
54
|
+
* INVARIANT: callers MUST only cache COMPLETE topology. A partial fetch
|
|
55
|
+
* (Apollo `result.error` set, GraphQL returned errors alongside data) will
|
|
56
|
+
* silently launder its partiality through the cache otherwise — every
|
|
57
|
+
* subsequent cache-hit reader would treat the truncated tree as
|
|
58
|
+
* authoritative without seeing `partial_topology`. `butlr-list-topology`
|
|
59
|
+
* gates its `setCachedTopology` call on `!partialData`; any new caller
|
|
60
|
+
* must do the same.
|
|
45
61
|
*/
|
|
46
62
|
export function setCachedTopology(key, data) {
|
|
47
63
|
const entry = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"topology-cache.js","sourceRoot":"","sources":["../../src/cache/topology-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C;;GAEG;AACH,MAAM,iBAAiB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,KAAK,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,0BAA0B;AAClH,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAO9B;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,QAAQ,CAAqB;IAC5D,GAAG,EAAE,iBAAiB;IACtB,GAAG,EAAE,iBAAiB;IACtB,cAAc,EAAE,IAAI,EAAE,yBAAyB;IAC/C,cAAc,EAAE,KAAK;CACtB,CAAC,CAAC;AAEH
|
|
1
|
+
{"version":3,"file":"topology-cache.js","sourceRoot":"","sources":["../../src/cache/topology-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C;;GAEG;AACH,MAAM,iBAAiB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,KAAK,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,0BAA0B;AAClH,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAO9B;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,QAAQ,CAAqB;IAC5D,GAAG,EAAE,iBAAiB;IACtB,GAAG,EAAE,iBAAiB;IACtB,cAAc,EAAE,IAAI,EAAE,yBAAyB;IAC/C,cAAc,EAAE,KAAK;CACtB,CAAC,CAAC;AAEH;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB,CACtC,KAAa,EACb,cAAuB,EACvB,YAAqB,EACrB,aAAsB,EACtB,OAAkB;IAElB,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAE9B,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,WAAW,cAAc,EAAE,CAAC,CAAC;IACxC,KAAK,CAAC,IAAI,CAAC,SAAS,YAAY,EAAE,CAAC,CAAC;IACpC,KAAK,CAAC,IAAI,CAAC,UAAU,aAAa,EAAE,CAAC,CAAC;IAEtC,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAEtC,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,CAAC,gBAAgB,EAAE,sBAAsB,GAAG,EAAE,CAAC,CAAC;IACvD,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,gBAAgB,EAAE,uBAAuB,GAAG,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW,EAAE,IAA6B;IAC1E,MAAM,KAAK,GAAe;QACxB,IAAI;QACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IAEF,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAE9B,KAAK,CAAC,gBAAgB,EAAE,wBAAwB,GAAG,UAAU,iBAAiB,GAAG,IAAI,IAAI,CAAC,CAAC;AAC7F,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,aAAa,CAAC,KAAK,EAAE,CAAC;IAEtB,KAAK,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO;QACL,IAAI,EAAE,aAAa,CAAC,IAAI;QACxB,OAAO,EAAE,iBAAiB;QAC1B,GAAG,EAAE,iBAAiB,GAAG,IAAI,EAAE,sCAAsC;KACtE,CAAC;AACJ,CAAC"}
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
* Branded string types for tag identifiers.
|
|
10
10
|
*
|
|
11
11
|
* The Butlr API filter `roomsByTag` accepts tag *IDs*, not tag *names*.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* Both are `string` at runtime, which previously led to silent filter
|
|
13
|
+
* failures when names were sent in the IDs slot. Branding them keeps the
|
|
14
|
+
* distinction visible at the type level so the wrong one cannot be passed
|
|
15
|
+
* by accident.
|
|
16
16
|
*/
|
|
17
17
|
export type TagId = string & {
|
|
18
18
|
readonly __brand: "TagId";
|
|
@@ -20,13 +20,70 @@ export type TagId = string & {
|
|
|
20
20
|
export type TagName = string & {
|
|
21
21
|
readonly __brand: "TagName";
|
|
22
22
|
};
|
|
23
|
+
/** Multi-tag composition mode shared across every tag-aware tool surface. */
|
|
24
|
+
export type TagMatch = "all" | "any";
|
|
25
|
+
/**
|
|
26
|
+
* Brand a string as a tag id. Throws on empty/whitespace-only input — the
|
|
27
|
+
* brand exists to catch "wrong slot" mistakes at compile time, but a blank
|
|
28
|
+
* value would brand cleanly and slip through. Constructors that accept
|
|
29
|
+
* arbitrary strings need a runtime check too.
|
|
30
|
+
*/
|
|
23
31
|
export declare const asTagId: (value: string) => TagId;
|
|
32
|
+
/** Brand a string as a tag name. Same empty-input guard as `asTagId`. */
|
|
24
33
|
export declare const asTagName: (value: string) => TagName;
|
|
34
|
+
/**
|
|
35
|
+
* Shape of each tagged-entity reference returned by `GET_TAGS_WITH_USAGE`.
|
|
36
|
+
* `name` is best-effort: older API responses or partial entity records may
|
|
37
|
+
* omit it, so consumers must treat it as optional.
|
|
38
|
+
*
|
|
39
|
+
* Both `id` and `name` are runtime-guarded against partial GraphQL
|
|
40
|
+
* responses by `projectValidRefs` (src/utils/tag-resolver.ts) — refs with
|
|
41
|
+
* a missing/null/empty `id` are dropped, and a missing `name` is elided
|
|
42
|
+
* from the projection. Consumers should route through `projectValidRefs`
|
|
43
|
+
* rather than reading the fields directly, even though the type declares
|
|
44
|
+
* `id` as required.
|
|
45
|
+
*/
|
|
46
|
+
export interface TaggedEntityRef {
|
|
47
|
+
id: string;
|
|
48
|
+
name?: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Raw `tags` row returned by `GET_TAGS_WITH_USAGE`. Used by `butlr_list_tags`
|
|
52
|
+
* and the shared tag resolver — kept here so the GraphQL shape lives next
|
|
53
|
+
* to the query that produces it.
|
|
54
|
+
*/
|
|
55
|
+
export interface RawTagWithUsage {
|
|
56
|
+
id: string;
|
|
57
|
+
name: string;
|
|
58
|
+
organization_id?: string;
|
|
59
|
+
rooms?: TaggedEntityRef[] | null;
|
|
60
|
+
zones?: TaggedEntityRef[] | null;
|
|
61
|
+
floors?: TaggedEntityRef[] | null;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Inline tag projection returned when a Room/Zone/Floor query selects
|
|
65
|
+
* `tags { id name }` directly (e.g. `butlr_get_asset_details`).
|
|
66
|
+
*
|
|
67
|
+
* Lightweight `{id, name}` projection — both fields are required by
|
|
68
|
+
* the GraphQL schema and surfaced unchanged. Structurally similar to
|
|
69
|
+
* but intentionally distinct from `TaggedEntityRef`: `TaggedEntityRef`
|
|
70
|
+
* is best-effort (name optional) and represents the reverse direction
|
|
71
|
+
* (entities under a tag); `TagRef` represents tags applied to an
|
|
72
|
+
* entity. The bare name `Tag` is reserved for the full GraphQL Tag
|
|
73
|
+
* entity (with organization_id, associations, etc.); callers needing
|
|
74
|
+
* that shape go through `GET_TAGS_WITH_USAGE` instead.
|
|
75
|
+
*/
|
|
76
|
+
export interface TagRef {
|
|
77
|
+
id: string;
|
|
78
|
+
name: string;
|
|
79
|
+
}
|
|
25
80
|
/**
|
|
26
81
|
* List every tag in the org along with its application footprint.
|
|
27
82
|
*
|
|
28
|
-
* Each tag's `rooms`, `zones`, and `floors` arrays
|
|
29
|
-
*
|
|
83
|
+
* Each tag's `rooms`, `zones`, and `floors` arrays carry both `id` and
|
|
84
|
+
* `name` so callers (e.g. `butlr_list_tags { include_entities: true }`,
|
|
85
|
+
* `butlr_list_topology { tag_names: [...] }`) can render the tagged
|
|
86
|
+
* entities without an extra resolution step.
|
|
30
87
|
*/
|
|
31
88
|
export declare const GET_TAGS_WITH_USAGE: import("@apollo/client").DocumentNode;
|
|
32
89
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../../src/clients/queries/tags.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH;;;;;;;;GAQG;AACH,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAC3D,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAA;CAAE,CAAC;AAE/D,eAAO,MAAM,OAAO,GAAI,OAAO,MAAM,KAAG,
|
|
1
|
+
{"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../../src/clients/queries/tags.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH;;;;;;;;GAQG;AACH,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAC3D,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAA;CAAE,CAAC;AAE/D,6EAA6E;AAC7E,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,KAAK,CAAC;AAErC;;;;;GAKG;AACH,eAAO,MAAM,OAAO,GAAI,OAAO,MAAM,KAAG,KAKvC,CAAC;AAEF,yEAAyE;AACzE,eAAO,MAAM,SAAS,GAAI,OAAO,MAAM,KAAG,OAKzC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;IACjC,KAAK,CAAC,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;IACjC,MAAM,CAAC,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;CACnC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,uCAoB/B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,uCAO5B,CAAC"}
|
|
@@ -1,11 +1,30 @@
|
|
|
1
1
|
import { gql } from "@apollo/client";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Brand a string as a tag id. Throws on empty/whitespace-only input — the
|
|
4
|
+
* brand exists to catch "wrong slot" mistakes at compile time, but a blank
|
|
5
|
+
* value would brand cleanly and slip through. Constructors that accept
|
|
6
|
+
* arbitrary strings need a runtime check too.
|
|
7
|
+
*/
|
|
8
|
+
export const asTagId = (value) => {
|
|
9
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
10
|
+
throw new Error(`Invalid TagId: expected a non-empty string, got ${JSON.stringify(value)}`);
|
|
11
|
+
}
|
|
12
|
+
return value;
|
|
13
|
+
};
|
|
14
|
+
/** Brand a string as a tag name. Same empty-input guard as `asTagId`. */
|
|
15
|
+
export const asTagName = (value) => {
|
|
16
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
17
|
+
throw new Error(`Invalid TagName: expected a non-empty string, got ${JSON.stringify(value)}`);
|
|
18
|
+
}
|
|
19
|
+
return value;
|
|
20
|
+
};
|
|
4
21
|
/**
|
|
5
22
|
* List every tag in the org along with its application footprint.
|
|
6
23
|
*
|
|
7
|
-
* Each tag's `rooms`, `zones`, and `floors` arrays
|
|
8
|
-
*
|
|
24
|
+
* Each tag's `rooms`, `zones`, and `floors` arrays carry both `id` and
|
|
25
|
+
* `name` so callers (e.g. `butlr_list_tags { include_entities: true }`,
|
|
26
|
+
* `butlr_list_topology { tag_names: [...] }`) can render the tagged
|
|
27
|
+
* entities without an extra resolution step.
|
|
9
28
|
*/
|
|
10
29
|
export const GET_TAGS_WITH_USAGE = gql `
|
|
11
30
|
query GetTagsWithUsage {
|
|
@@ -15,12 +34,15 @@ export const GET_TAGS_WITH_USAGE = gql `
|
|
|
15
34
|
organization_id
|
|
16
35
|
rooms {
|
|
17
36
|
id
|
|
37
|
+
name
|
|
18
38
|
}
|
|
19
39
|
zones {
|
|
20
40
|
id
|
|
41
|
+
name
|
|
21
42
|
}
|
|
22
43
|
floors {
|
|
23
44
|
id
|
|
45
|
+
name
|
|
24
46
|
}
|
|
25
47
|
}
|
|
26
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../../../src/clients/queries/tags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../../../src/clients/queries/tags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAyBrC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,KAAa,EAAS,EAAE;IAC9C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,mDAAmD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC9F,CAAC;IACD,OAAO,KAAc,CAAC;AACxB,CAAC,CAAC;AAEF,yEAAyE;AACzE,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAa,EAAW,EAAE;IAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,qDAAqD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAChG,CAAC;IACD,OAAO,KAAgB,CAAC;AAC1B,CAAC,CAAC;AAmDF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;CAoBrC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,CAAA;;;;;;;CAOlC,CAAC"}
|
|
@@ -12,8 +12,14 @@ export declare const GET_SITES_LIST: import("@apollo/client").DocumentNode;
|
|
|
12
12
|
export declare const GET_SITE_STRUCTURE: import("@apollo/client").DocumentNode;
|
|
13
13
|
/**
|
|
14
14
|
* Full topology with all sites, buildings, floors, rooms, zones
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* Zones include a nested `sensors` selection — the only way to attribute sensors
|
|
16
|
+
* to zones, since GET_ALL_SENSORS selects no zone linkage. Verified live against
|
|
17
|
+
* the API: nested sensor selections are NOT truncated (an earlier note here
|
|
18
|
+
* claimed nested fields returned only 5 sensors; that does not reproduce — zone
|
|
19
|
+
* and floor nested counts match the flat sensors list exactly, and introspection
|
|
20
|
+
* shows no pagination args on the nested `sensors` field).
|
|
21
|
+
* Still use GET_ALL_SENSORS and GET_ALL_HIVES for full device detail (model,
|
|
22
|
+
* battery, heartbeat, ...), merged by floor_id/room_id.
|
|
17
23
|
*/
|
|
18
24
|
export declare const GET_FULL_TOPOLOGY: import("@apollo/client").DocumentNode;
|
|
19
25
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"topology.d.ts","sourceRoot":"","sources":["../../../src/clients/queries/topology.ts"],"names":[],"mappings":"AAEA;;GAEG;AAEH;;GAEG;AACH,eAAO,MAAM,cAAc,uCAY1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,uCA6B9B,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"topology.d.ts","sourceRoot":"","sources":["../../../src/clients/queries/topology.ts"],"names":[],"mappings":"AAEA;;GAEG;AAEH;;GAEG;AACH,eAAO,MAAM,cAAc,uCAY1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,uCA6B9B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,uCA4E7B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,uCAwB3B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,uCAqBzB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,uCAgEnC,CAAC"}
|
|
@@ -54,8 +54,14 @@ export const GET_SITE_STRUCTURE = gql `
|
|
|
54
54
|
`;
|
|
55
55
|
/**
|
|
56
56
|
* Full topology with all sites, buildings, floors, rooms, zones
|
|
57
|
-
*
|
|
58
|
-
*
|
|
57
|
+
* Zones include a nested `sensors` selection — the only way to attribute sensors
|
|
58
|
+
* to zones, since GET_ALL_SENSORS selects no zone linkage. Verified live against
|
|
59
|
+
* the API: nested sensor selections are NOT truncated (an earlier note here
|
|
60
|
+
* claimed nested fields returned only 5 sensors; that does not reproduce — zone
|
|
61
|
+
* and floor nested counts match the flat sensors list exactly, and introspection
|
|
62
|
+
* shows no pagination args on the nested `sensors` field).
|
|
63
|
+
* Still use GET_ALL_SENSORS and GET_ALL_HIVES for full device detail (model,
|
|
64
|
+
* battery, heartbeat, ...), merged by floor_id/room_id.
|
|
59
65
|
*/
|
|
60
66
|
export const GET_FULL_TOPOLOGY = gql `
|
|
61
67
|
query GetFullTopology {
|
|
@@ -116,6 +122,17 @@ export const GET_FULL_TOPOLOGY = gql `
|
|
|
116
122
|
room_id
|
|
117
123
|
customID
|
|
118
124
|
coordinates
|
|
125
|
+
sensors {
|
|
126
|
+
id
|
|
127
|
+
name
|
|
128
|
+
mac_address
|
|
129
|
+
mode
|
|
130
|
+
floor_id
|
|
131
|
+
room_id
|
|
132
|
+
hive_serial
|
|
133
|
+
is_entrance
|
|
134
|
+
is_online
|
|
135
|
+
}
|
|
119
136
|
}
|
|
120
137
|
}
|
|
121
138
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"topology.js","sourceRoot":"","sources":["../../../src/clients/queries/topology.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAErC;;GAEG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAA;;;;;;;;;;;;CAYhC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BpC,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"topology.js","sourceRoot":"","sources":["../../../src/clients/queries/topology.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAErC;;GAEG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAA;;;;;;;;;;;;CAYhC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BpC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4EnC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;CAwBjC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;CAqB/B,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgEzC,CAAC"}
|
package/dist/clients/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* TypeScript type definitions for Butlr GraphQL API
|
|
3
3
|
*/
|
|
4
|
+
import type { TagRef } from "./queries/tags.js";
|
|
4
5
|
export interface Capacity {
|
|
5
6
|
max?: number;
|
|
6
7
|
mid?: number;
|
|
@@ -70,6 +71,7 @@ export interface Floor {
|
|
|
70
71
|
hives?: Hive[];
|
|
71
72
|
floor_plans?: FloorPlan[];
|
|
72
73
|
building: Building;
|
|
74
|
+
tags: TagRef[];
|
|
73
75
|
}
|
|
74
76
|
/**
|
|
75
77
|
* Room - Defined space within a floor
|
|
@@ -92,6 +94,7 @@ export interface Room {
|
|
|
92
94
|
pir_zero_window?: number;
|
|
93
95
|
sensors?: Sensor[];
|
|
94
96
|
floor: Floor;
|
|
97
|
+
tags: TagRef[];
|
|
95
98
|
}
|
|
96
99
|
/**
|
|
97
100
|
* Zone - Sub-area within a floor or room
|
|
@@ -111,6 +114,7 @@ export interface Zone {
|
|
|
111
114
|
customID?: string;
|
|
112
115
|
note?: string;
|
|
113
116
|
sensors?: Sensor[];
|
|
117
|
+
tags: TagRef[];
|
|
114
118
|
}
|
|
115
119
|
/**
|
|
116
120
|
* Sensor - Individual detection device
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/clients/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,QAAQ;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,IAAI;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,QAAQ,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,IAAI,EAAE,IAAI,CAAC;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC;IAC1B,QAAQ,EAAE,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/clients/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,13 @@ import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* Wraps a tool handler to catch errors and return them as MCP tool errors
|
|
4
4
|
* with isError: true, so the LLM can see and handle the error.
|
|
5
|
+
*
|
|
6
|
+
* If the underlying error message already carries a `[CODE]` prefix
|
|
7
|
+
* (added by `formatMCPError` upstream), the message passes through. If
|
|
8
|
+
* it doesn't — non-Apollo Error classes, unrelated `throw new Error(...)`
|
|
9
|
+
* sites, ServerParseError, etc. — we wrap with an INTERNAL_ERROR prefix
|
|
10
|
+
* so consumers branching on `[XXX]` still see a structured code. Stack
|
|
11
|
+
* traces survive in the `debug` log but never reach the response body.
|
|
5
12
|
*/
|
|
6
13
|
export declare function withToolErrorHandling(handler: (args: Record<string, unknown>) => Promise<CallToolResult>): (args: Record<string, unknown>) => Promise<CallToolResult>;
|
|
7
14
|
/**
|
|
@@ -52,6 +59,33 @@ export declare function translateGraphQLError(error: GraphQLClientError): MCPErr
|
|
|
52
59
|
* Format MCP error for user-friendly display
|
|
53
60
|
*/
|
|
54
61
|
export declare function formatMCPError(error: MCPError): string;
|
|
62
|
+
/**
|
|
63
|
+
* Validate that an upstream-supplied value is array-shaped, returning the
|
|
64
|
+
* array (treating `null`/`undefined` as a legitimately-empty signal) or
|
|
65
|
+
* throwing INTERNAL_ERROR for any other shape. Centralizes the pattern
|
|
66
|
+
* that callers like `butlr_list_topology` / `butlr_list_tags` /
|
|
67
|
+
* `butlr_available_rooms` use on nested response fields where a
|
|
68
|
+
* `value || []` would otherwise launder a contract regression into
|
|
69
|
+
* silently-empty results.
|
|
70
|
+
*
|
|
71
|
+
* Pass `fieldName` for a useful error message; the lenient null/undefined
|
|
72
|
+
* branch reflects that legitimately-empty lists arrive as
|
|
73
|
+
* `[]`/`null`/missing depending on upstream resolver.
|
|
74
|
+
*/
|
|
75
|
+
export declare function ensureArrayOrEmpty<T>(value: ReadonlyArray<T> | null | undefined | unknown, fieldName: string): ReadonlyArray<T>;
|
|
76
|
+
/**
|
|
77
|
+
* Throw a properly MCP-formatted INTERNAL_ERROR. Use for upstream contract
|
|
78
|
+
* violations (unexpected response shape, missing data envelope, etc.) so
|
|
79
|
+
* the failure surfaces with a structured `[INTERNAL_ERROR]` prefix that
|
|
80
|
+
* `withToolErrorHandling` translates uniformly. Without this, every tool
|
|
81
|
+
* would have a different error-shape contract for the same class of bug.
|
|
82
|
+
*
|
|
83
|
+
* `retryable: false` — contract violations are not transient. If the
|
|
84
|
+
* upstream returned a non-array where an array was contracted, retrying
|
|
85
|
+
* will yield the same broken response. MCP clients that auto-retry
|
|
86
|
+
* `retryable: true` errors would spin against this signal otherwise.
|
|
87
|
+
*/
|
|
88
|
+
export declare function throwInternalError(message: string): never;
|
|
55
89
|
/**
|
|
56
90
|
* Error subclass for MCP errors — provides stack traces and works with instanceof checks.
|
|
57
91
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-errors.d.ts","sourceRoot":"","sources":["../../src/errors/mcp-errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAGzE
|
|
1
|
+
{"version":3,"file":"mcp-errors.d.ts","sourceRoot":"","sources":["../../src/errors/mcp-errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAGzE;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,cAAc,CAAC,GAClE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,cAAc,CAAC,CAsB5D;AAED;;;GAGG;AACH,UAAU,kBAAkB;IAC1B,YAAY,CAAC,EAAE;QACb,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE;gBAAE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;aAAE,CAAA;SAAE,CAAC;KAC/D,CAAC;IACF,aAAa,CAAC,EAAE,KAAK,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACtC,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,oBAAY,YAAY;IACtB,YAAY,iBAAiB;IAC7B,YAAY,iBAAiB;IAC7B,iBAAiB,sBAAsB;IACvC,cAAc,mBAAmB;IACjC,SAAS,cAAc;IACvB,aAAa,kBAAkB;CAChC;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,kBAAkB,GAAG,QAAQ,CA6GzE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAgBtD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,EACpD,SAAS,EAAE,MAAM,GAChB,aAAa,CAAC,CAAC,CAAC,CAOlB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAOzD;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;gBAEP,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAO/D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,kBAAkB,CAEpB"}
|
|
@@ -2,6 +2,13 @@ import { debug } from "../utils/debug.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* Wraps a tool handler to catch errors and return them as MCP tool errors
|
|
4
4
|
* with isError: true, so the LLM can see and handle the error.
|
|
5
|
+
*
|
|
6
|
+
* If the underlying error message already carries a `[CODE]` prefix
|
|
7
|
+
* (added by `formatMCPError` upstream), the message passes through. If
|
|
8
|
+
* it doesn't — non-Apollo Error classes, unrelated `throw new Error(...)`
|
|
9
|
+
* sites, ServerParseError, etc. — we wrap with an INTERNAL_ERROR prefix
|
|
10
|
+
* so consumers branching on `[XXX]` still see a structured code. Stack
|
|
11
|
+
* traces survive in the `debug` log but never reach the response body.
|
|
5
12
|
*/
|
|
6
13
|
export function withToolErrorHandling(handler) {
|
|
7
14
|
return async (args) => {
|
|
@@ -9,10 +16,19 @@ export function withToolErrorHandling(handler) {
|
|
|
9
16
|
return await handler(args);
|
|
10
17
|
}
|
|
11
18
|
catch (error) {
|
|
12
|
-
const
|
|
13
|
-
|
|
19
|
+
const rawMessage = error instanceof Error ? error.message : String(error);
|
|
20
|
+
const stack = error instanceof Error ? error.stack : undefined;
|
|
21
|
+
debug("tool-error", rawMessage, stack ?? error);
|
|
22
|
+
// Already-translated errors carry the `[CODE]` prefix; preserve them.
|
|
23
|
+
const text = /^\[[A-Z_]+\]/.test(rawMessage)
|
|
24
|
+
? rawMessage
|
|
25
|
+
: formatMCPError({
|
|
26
|
+
code: MCPErrorCode.INTERNAL_ERROR,
|
|
27
|
+
message: rawMessage || "Unknown internal error",
|
|
28
|
+
retryable: false,
|
|
29
|
+
});
|
|
14
30
|
return {
|
|
15
|
-
content: [{ type: "text", text
|
|
31
|
+
content: [{ type: "text", text }],
|
|
16
32
|
isError: true,
|
|
17
33
|
};
|
|
18
34
|
}
|
|
@@ -59,11 +75,20 @@ export function translateGraphQLError(error) {
|
|
|
59
75
|
retryAfter,
|
|
60
76
|
};
|
|
61
77
|
}
|
|
62
|
-
// Bad request / validation
|
|
78
|
+
// Bad request / validation. Surface the upstream message in the
|
|
79
|
+
// user-visible string so an LLM caller debugging a 400 doesn't have
|
|
80
|
+
// to wait for DEBUG=butlr-mcp to see "Unknown tag id: foo_bar". Fall
|
|
81
|
+
// back to the generic phrasing only when no message can be extracted.
|
|
63
82
|
if (networkError.statusCode === 400) {
|
|
83
|
+
const body = networkError.result;
|
|
84
|
+
const upstreamMessage = body?.errors?.find((e) => typeof e?.message === "string")?.message ??
|
|
85
|
+
(typeof networkError.message === "string" ? networkError.message : undefined);
|
|
86
|
+
const truncate = (s) => (s.length > 240 ? `${s.slice(0, 240)}…` : s);
|
|
64
87
|
return {
|
|
65
88
|
code: MCPErrorCode.VALIDATION_FAILED,
|
|
66
|
-
message:
|
|
89
|
+
message: upstreamMessage
|
|
90
|
+
? `Invalid request: ${truncate(String(upstreamMessage))}`
|
|
91
|
+
: "Invalid request parameters.",
|
|
67
92
|
details: {
|
|
68
93
|
statusCode: 400,
|
|
69
94
|
body: networkError.result,
|
|
@@ -140,6 +165,47 @@ export function formatMCPError(error) {
|
|
|
140
165
|
}
|
|
141
166
|
return message;
|
|
142
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Validate that an upstream-supplied value is array-shaped, returning the
|
|
170
|
+
* array (treating `null`/`undefined` as a legitimately-empty signal) or
|
|
171
|
+
* throwing INTERNAL_ERROR for any other shape. Centralizes the pattern
|
|
172
|
+
* that callers like `butlr_list_topology` / `butlr_list_tags` /
|
|
173
|
+
* `butlr_available_rooms` use on nested response fields where a
|
|
174
|
+
* `value || []` would otherwise launder a contract regression into
|
|
175
|
+
* silently-empty results.
|
|
176
|
+
*
|
|
177
|
+
* Pass `fieldName` for a useful error message; the lenient null/undefined
|
|
178
|
+
* branch reflects that legitimately-empty lists arrive as
|
|
179
|
+
* `[]`/`null`/missing depending on upstream resolver.
|
|
180
|
+
*/
|
|
181
|
+
export function ensureArrayOrEmpty(value, fieldName) {
|
|
182
|
+
if (value === null || value === undefined)
|
|
183
|
+
return [];
|
|
184
|
+
if (Array.isArray(value))
|
|
185
|
+
return value;
|
|
186
|
+
throwInternalError(`Unexpected response shape from ${fieldName} (expected array, got ${typeof value}). ` +
|
|
187
|
+
"Please retry; if persistent, the upstream API contract may have changed.");
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Throw a properly MCP-formatted INTERNAL_ERROR. Use for upstream contract
|
|
191
|
+
* violations (unexpected response shape, missing data envelope, etc.) so
|
|
192
|
+
* the failure surfaces with a structured `[INTERNAL_ERROR]` prefix that
|
|
193
|
+
* `withToolErrorHandling` translates uniformly. Without this, every tool
|
|
194
|
+
* would have a different error-shape contract for the same class of bug.
|
|
195
|
+
*
|
|
196
|
+
* `retryable: false` — contract violations are not transient. If the
|
|
197
|
+
* upstream returned a non-array where an array was contracted, retrying
|
|
198
|
+
* will yield the same broken response. MCP clients that auto-retry
|
|
199
|
+
* `retryable: true` errors would spin against this signal otherwise.
|
|
200
|
+
*/
|
|
201
|
+
export function throwInternalError(message) {
|
|
202
|
+
const mcpError = {
|
|
203
|
+
code: MCPErrorCode.INTERNAL_ERROR,
|
|
204
|
+
message,
|
|
205
|
+
retryable: false,
|
|
206
|
+
};
|
|
207
|
+
throw new Error(formatMCPError(mcpError));
|
|
208
|
+
}
|
|
143
209
|
/**
|
|
144
210
|
* Error subclass for MCP errors — provides stack traces and works with instanceof checks.
|
|
145
211
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-errors.js","sourceRoot":"","sources":["../../src/errors/mcp-errors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C
|
|
1
|
+
{"version":3,"file":"mcp-errors.js","sourceRoot":"","sources":["../../src/errors/mcp-errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { type TagName } from "../clients/queries/tags.js";
|
|
4
3
|
import type { AvailableRoomsResponse } from "../types/responses.js";
|
|
5
4
|
export declare const AvailableRoomsArgsSchema: z.ZodEffects<z.ZodObject<{
|
|
6
5
|
min_capacity: z.ZodOptional<z.ZodNumber>;
|
|
@@ -13,15 +12,15 @@ export declare const AvailableRoomsArgsSchema: z.ZodEffects<z.ZodObject<{
|
|
|
13
12
|
}, "strict", z.ZodTypeAny, {
|
|
14
13
|
max_results: number;
|
|
15
14
|
tag_match: "all" | "any";
|
|
16
|
-
building_id?: string | undefined;
|
|
17
15
|
tags?: string[] | undefined;
|
|
16
|
+
building_id?: string | undefined;
|
|
18
17
|
min_capacity?: number | undefined;
|
|
19
18
|
max_capacity?: number | undefined;
|
|
20
19
|
floor_id?: string | undefined;
|
|
21
20
|
}, {
|
|
22
21
|
max_results?: number | undefined;
|
|
23
|
-
building_id?: string | undefined;
|
|
24
22
|
tags?: string[] | undefined;
|
|
23
|
+
building_id?: string | undefined;
|
|
25
24
|
min_capacity?: number | undefined;
|
|
26
25
|
max_capacity?: number | undefined;
|
|
27
26
|
tag_match?: "all" | "any" | undefined;
|
|
@@ -29,15 +28,15 @@ export declare const AvailableRoomsArgsSchema: z.ZodEffects<z.ZodObject<{
|
|
|
29
28
|
}>, {
|
|
30
29
|
max_results: number;
|
|
31
30
|
tag_match: "all" | "any";
|
|
32
|
-
building_id?: string | undefined;
|
|
33
31
|
tags?: string[] | undefined;
|
|
32
|
+
building_id?: string | undefined;
|
|
34
33
|
min_capacity?: number | undefined;
|
|
35
34
|
max_capacity?: number | undefined;
|
|
36
35
|
floor_id?: string | undefined;
|
|
37
36
|
}, {
|
|
38
37
|
max_results?: number | undefined;
|
|
39
|
-
building_id?: string | undefined;
|
|
40
38
|
tags?: string[] | undefined;
|
|
39
|
+
building_id?: string | undefined;
|
|
41
40
|
min_capacity?: number | undefined;
|
|
42
41
|
max_capacity?: number | undefined;
|
|
43
42
|
tag_match?: "all" | "any" | undefined;
|
|
@@ -48,24 +47,7 @@ export declare const GET_ROOMS_BY_TAG: import("@apollo/client").DocumentNode;
|
|
|
48
47
|
/**
|
|
49
48
|
* Execute available rooms tool
|
|
50
49
|
*/
|
|
51
|
-
export declare function executeAvailableRooms(args: AvailableRoomsArgs): Promise<AvailableRoomsResponse
|
|
52
|
-
summary: string;
|
|
53
|
-
available_rooms: never[];
|
|
54
|
-
total_available: number;
|
|
55
|
-
showing: number;
|
|
56
|
-
timestamp: string;
|
|
57
|
-
filtered_by: {
|
|
58
|
-
max_results: number;
|
|
59
|
-
tag_match: "all" | "any";
|
|
60
|
-
building_id?: string | undefined;
|
|
61
|
-
tags?: string[] | undefined;
|
|
62
|
-
min_capacity?: number | undefined;
|
|
63
|
-
max_capacity?: number | undefined;
|
|
64
|
-
floor_id?: string | undefined;
|
|
65
|
-
};
|
|
66
|
-
unknown_tags: TagName[];
|
|
67
|
-
warning: string;
|
|
68
|
-
}>;
|
|
50
|
+
export declare function executeAvailableRooms(args: AvailableRoomsArgs): Promise<AvailableRoomsResponse>;
|
|
69
51
|
/**
|
|
70
52
|
* Register butlr_available_rooms with an McpServer instance
|
|
71
53
|
*/
|