@miragon/mcp-toolkit-core 0.10.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 (174) hide show
  1. package/README.md +32 -0
  2. package/dist/engine/context-builder.d.ts +5 -0
  3. package/dist/engine/context-builder.d.ts.map +1 -0
  4. package/dist/engine/context-builder.js +22 -0
  5. package/dist/engine/context-builder.js.map +1 -0
  6. package/dist/engine/pipeline-executor.d.ts +21 -0
  7. package/dist/engine/pipeline-executor.d.ts.map +1 -0
  8. package/dist/engine/pipeline-executor.js +80 -0
  9. package/dist/engine/pipeline-executor.js.map +1 -0
  10. package/dist/framework/active-modules.d.ts +30 -0
  11. package/dist/framework/active-modules.d.ts.map +1 -0
  12. package/dist/framework/active-modules.js +44 -0
  13. package/dist/framework/active-modules.js.map +1 -0
  14. package/dist/framework/catalogue.d.ts +148 -0
  15. package/dist/framework/catalogue.d.ts.map +1 -0
  16. package/dist/framework/catalogue.js +132 -0
  17. package/dist/framework/catalogue.js.map +1 -0
  18. package/dist/framework/dashboard-store.d.ts +136 -0
  19. package/dist/framework/dashboard-store.d.ts.map +1 -0
  20. package/dist/framework/dashboard-store.js +301 -0
  21. package/dist/framework/dashboard-store.js.map +1 -0
  22. package/dist/framework/layout-schemas.d.ts +106 -0
  23. package/dist/framework/layout-schemas.d.ts.map +1 -0
  24. package/dist/framework/layout-schemas.js +67 -0
  25. package/dist/framework/layout-schemas.js.map +1 -0
  26. package/dist/framework/layout-types.d.ts +25 -0
  27. package/dist/framework/layout-types.d.ts.map +1 -0
  28. package/dist/framework/layout-types.js +7 -0
  29. package/dist/framework/layout-types.js.map +1 -0
  30. package/dist/framework/manifest.d.ts +65 -0
  31. package/dist/framework/manifest.d.ts.map +1 -0
  32. package/dist/framework/manifest.js +47 -0
  33. package/dist/framework/manifest.js.map +1 -0
  34. package/dist/framework/render-view.d.ts +53 -0
  35. package/dist/framework/render-view.d.ts.map +1 -0
  36. package/dist/framework/render-view.js +73 -0
  37. package/dist/framework/render-view.js.map +1 -0
  38. package/dist/framework/view-builders.d.ts +79 -0
  39. package/dist/framework/view-builders.d.ts.map +1 -0
  40. package/dist/framework/view-builders.js +113 -0
  41. package/dist/framework/view-builders.js.map +1 -0
  42. package/dist/i18n/index.d.ts +3 -0
  43. package/dist/i18n/index.d.ts.map +1 -0
  44. package/dist/i18n/index.js +6 -0
  45. package/dist/i18n/index.js.map +1 -0
  46. package/dist/i18n/translator.d.ts +59 -0
  47. package/dist/i18n/translator.d.ts.map +1 -0
  48. package/dist/i18n/translator.js +48 -0
  49. package/dist/i18n/translator.js.map +1 -0
  50. package/dist/index.d.ts +31 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +27 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/middleware/org-gate.d.ts +22 -0
  55. package/dist/middleware/org-gate.d.ts.map +1 -0
  56. package/dist/middleware/org-gate.js +28 -0
  57. package/dist/middleware/org-gate.js.map +1 -0
  58. package/dist/middleware/role-filter.d.ts +79 -0
  59. package/dist/middleware/role-filter.d.ts.map +1 -0
  60. package/dist/middleware/role-filter.js +95 -0
  61. package/dist/middleware/role-filter.js.map +1 -0
  62. package/dist/registry/app-loader.d.ts +35 -0
  63. package/dist/registry/app-loader.d.ts.map +1 -0
  64. package/dist/registry/app-loader.js +55 -0
  65. package/dist/registry/app-loader.js.map +1 -0
  66. package/dist/registry/step-registry.d.ts +27 -0
  67. package/dist/registry/step-registry.d.ts.map +1 -0
  68. package/dist/registry/step-registry.js +53 -0
  69. package/dist/registry/step-registry.js.map +1 -0
  70. package/dist/registry/widget-registry.d.ts +15 -0
  71. package/dist/registry/widget-registry.d.ts.map +1 -0
  72. package/dist/registry/widget-registry.js +28 -0
  73. package/dist/registry/widget-registry.js.map +1 -0
  74. package/dist/rest/client.d.ts +3 -0
  75. package/dist/rest/client.d.ts.map +1 -0
  76. package/dist/rest/client.js +155 -0
  77. package/dist/rest/client.js.map +1 -0
  78. package/dist/rest/errors.d.ts +14 -0
  79. package/dist/rest/errors.d.ts.map +1 -0
  80. package/dist/rest/errors.js +21 -0
  81. package/dist/rest/errors.js.map +1 -0
  82. package/dist/rest/index.d.ts +6 -0
  83. package/dist/rest/index.d.ts.map +1 -0
  84. package/dist/rest/index.js +4 -0
  85. package/dist/rest/index.js.map +1 -0
  86. package/dist/rest/tool.d.ts +60 -0
  87. package/dist/rest/tool.d.ts.map +1 -0
  88. package/dist/rest/tool.js +81 -0
  89. package/dist/rest/tool.js.map +1 -0
  90. package/dist/rest/types.d.ts +66 -0
  91. package/dist/rest/types.d.ts.map +1 -0
  92. package/dist/rest/types.js +2 -0
  93. package/dist/rest/types.js.map +1 -0
  94. package/dist/tools/app-resource-uri.d.ts +28 -0
  95. package/dist/tools/app-resource-uri.d.ts.map +1 -0
  96. package/dist/tools/app-resource-uri.js +30 -0
  97. package/dist/tools/app-resource-uri.js.map +1 -0
  98. package/dist/tools/backend-registry.d.ts +111 -0
  99. package/dist/tools/backend-registry.d.ts.map +1 -0
  100. package/dist/tools/backend-registry.js +154 -0
  101. package/dist/tools/backend-registry.js.map +1 -0
  102. package/dist/tools/create-framework-app.d.ts +147 -0
  103. package/dist/tools/create-framework-app.d.ts.map +1 -0
  104. package/dist/tools/create-framework-app.js +111 -0
  105. package/dist/tools/create-framework-app.js.map +1 -0
  106. package/dist/tools/index.d.ts +22 -0
  107. package/dist/tools/index.d.ts.map +1 -0
  108. package/dist/tools/index.js +15 -0
  109. package/dist/tools/index.js.map +1 -0
  110. package/dist/tools/register-catalogue-tool.d.ts +22 -0
  111. package/dist/tools/register-catalogue-tool.d.ts.map +1 -0
  112. package/dist/tools/register-catalogue-tool.js +45 -0
  113. package/dist/tools/register-catalogue-tool.js.map +1 -0
  114. package/dist/tools/register-dashboard-tools.d.ts +32 -0
  115. package/dist/tools/register-dashboard-tools.d.ts.map +1 -0
  116. package/dist/tools/register-dashboard-tools.js +149 -0
  117. package/dist/tools/register-dashboard-tools.js.map +1 -0
  118. package/dist/tools/register-framework-tools.d.ts +83 -0
  119. package/dist/tools/register-framework-tools.d.ts.map +1 -0
  120. package/dist/tools/register-framework-tools.js +154 -0
  121. package/dist/tools/register-framework-tools.js.map +1 -0
  122. package/dist/tools/register-tool.d.ts +45 -0
  123. package/dist/tools/register-tool.d.ts.map +1 -0
  124. package/dist/tools/register-tool.js +82 -0
  125. package/dist/tools/register-tool.js.map +1 -0
  126. package/dist/tools/register-widget-tool.d.ts +51 -0
  127. package/dist/tools/register-widget-tool.d.ts.map +1 -0
  128. package/dist/tools/register-widget-tool.js +45 -0
  129. package/dist/tools/register-widget-tool.js.map +1 -0
  130. package/dist/tools/tool-call-name.d.ts +53 -0
  131. package/dist/tools/tool-call-name.d.ts.map +1 -0
  132. package/dist/tools/tool-call-name.js +92 -0
  133. package/dist/tools/tool-call-name.js.map +1 -0
  134. package/dist/tools/with-tool-errors.d.ts +16 -0
  135. package/dist/tools/with-tool-errors.d.ts.map +1 -0
  136. package/dist/tools/with-tool-errors.js +28 -0
  137. package/dist/tools/with-tool-errors.js.map +1 -0
  138. package/dist/types/app.d.ts +44 -0
  139. package/dist/types/app.d.ts.map +1 -0
  140. package/dist/types/app.js +2 -0
  141. package/dist/types/app.js.map +1 -0
  142. package/dist/types/config.d.ts +15 -0
  143. package/dist/types/config.d.ts.map +1 -0
  144. package/dist/types/config.js +2 -0
  145. package/dist/types/config.js.map +1 -0
  146. package/dist/types/context.d.ts +18 -0
  147. package/dist/types/context.d.ts.map +1 -0
  148. package/dist/types/context.js +2 -0
  149. package/dist/types/context.js.map +1 -0
  150. package/dist/types/index.d.ts +10 -0
  151. package/dist/types/index.d.ts.map +1 -0
  152. package/dist/types/index.js +2 -0
  153. package/dist/types/index.js.map +1 -0
  154. package/dist/types/meta.d.ts +99 -0
  155. package/dist/types/meta.d.ts.map +1 -0
  156. package/dist/types/meta.js +66 -0
  157. package/dist/types/meta.js.map +1 -0
  158. package/dist/types/pipeline.d.ts +9 -0
  159. package/dist/types/pipeline.d.ts.map +1 -0
  160. package/dist/types/pipeline.js +2 -0
  161. package/dist/types/pipeline.js.map +1 -0
  162. package/dist/types/step.d.ts +51 -0
  163. package/dist/types/step.d.ts.map +1 -0
  164. package/dist/types/step.js +2 -0
  165. package/dist/types/step.js.map +1 -0
  166. package/dist/types/view-data.d.ts +67 -0
  167. package/dist/types/view-data.d.ts.map +1 -0
  168. package/dist/types/view-data.js +2 -0
  169. package/dist/types/view-data.js.map +1 -0
  170. package/dist/types/widget.d.ts +57 -0
  171. package/dist/types/widget.d.ts.map +1 -0
  172. package/dist/types/widget.js +2 -0
  173. package/dist/types/widget.js.map +1 -0
  174. package/package.json +50 -0
@@ -0,0 +1,154 @@
1
+ import { getRequestContext } from "mcp-use/server";
2
+ /**
3
+ * Default backend-selection TTL: how long a session's sticky pick survives
4
+ * without being re-set. `mcp-use` exposes no session-close hook to plugins, so
5
+ * without eviction the per-session selection map would grow with every MCP
6
+ * session that ever selected a backend. 24h comfortably outlives any real
7
+ * session.
8
+ */
9
+ export const DEFAULT_BACKEND_SESSION_TTL_MS = 24 * 60 * 60 * 1000;
10
+ /**
11
+ * Reads the active MCP session id for the in-flight tool call.
12
+ *
13
+ * `mcp-use` ships an internal session-id helper but it's not part of the
14
+ * public `mcp-use/server` surface — we read the `Mcp-Session-Id` header off
15
+ * the Hono request context that `mcp-use` propagates via AsyncLocalStorage to
16
+ * every tool handler. Returns `undefined` for the stdio transport or when no
17
+ * session header was negotiated (single-backend config keeps working anyway
18
+ * because resolution falls back to the lone default).
19
+ */
20
+ function defaultGetSessionId() {
21
+ const ctx = getRequestContext();
22
+ if (!ctx)
23
+ return undefined;
24
+ return ctx.req.header("Mcp-Session-Id") ?? ctx.req.header("mcp-session-id") ?? undefined;
25
+ }
26
+ /**
27
+ * Thrown when a tool is invoked but no backend has been selected for the
28
+ * current MCP session and the registry holds more than one backend.
29
+ *
30
+ * The message lists the available ids because the error path commonly only
31
+ * serialises `code` + `message` (the structured `availableIds` field may not
32
+ * reach the model) — naming them saves the model a discovery roundtrip before
33
+ * it can pick one and select it.
34
+ */
35
+ export class BackendNotSelectedError extends Error {
36
+ code = "BACKEND_NOT_SELECTED";
37
+ availableIds;
38
+ constructor(availableIds, label) {
39
+ super(`No ${label} selected for this session. Available ${label}s: ${availableIds.join(", ")}. ` +
40
+ `Select one for this session first.`);
41
+ this.name = "BackendNotSelectedError";
42
+ this.availableIds = availableIds;
43
+ }
44
+ }
45
+ /** Thrown when an override or sticky selection names a backend that isn't registered. */
46
+ export class UnknownBackendError extends Error {
47
+ code = "UNKNOWN_BACKEND";
48
+ requestedId;
49
+ availableIds;
50
+ constructor(requestedId, availableIds, label) {
51
+ super(`Unknown ${label} id "${requestedId}". Available: ${availableIds.join(", ")}.`);
52
+ this.name = "UnknownBackendError";
53
+ this.requestedId = requestedId;
54
+ this.availableIds = availableIds;
55
+ }
56
+ }
57
+ /**
58
+ * Builds a {@link BackendRegistry} from a non-empty list of backend entries.
59
+ * Throws if `entries` is empty or contains duplicate ids — both are
60
+ * programmer errors that should fail at boot rather than at the first tool
61
+ * call.
62
+ */
63
+ export function createBackendRegistry(entries, opts = {}) {
64
+ if (entries.length === 0) {
65
+ throw new Error("createBackendRegistry requires at least one backend entry");
66
+ }
67
+ const byId = new Map();
68
+ for (const entry of entries) {
69
+ if (byId.has(entry.id)) {
70
+ throw new Error(`createBackendRegistry: duplicate backend id "${entry.id}"`);
71
+ }
72
+ byId.set(entry.id, entry);
73
+ }
74
+ const label = opts.label ?? "backend";
75
+ const ttlMs = opts.sessionTtlMs ?? DEFAULT_BACKEND_SESSION_TTL_MS;
76
+ const getSessionId = opts.getSessionId ?? defaultGetSessionId;
77
+ const now = opts.now ?? Date.now;
78
+ const sessionSelections = new Map();
79
+ const availableIds = () => [...byId.keys()];
80
+ const isExpired = (entry) => now() - entry.selectedAt > ttlMs;
81
+ const sweepExpired = () => {
82
+ for (const [sid, entry] of sessionSelections) {
83
+ if (isExpired(entry))
84
+ sessionSelections.delete(sid);
85
+ }
86
+ };
87
+ const stickySelection = () => {
88
+ const sid = getSessionId();
89
+ if (!sid)
90
+ return undefined;
91
+ const entry = sessionSelections.get(sid);
92
+ if (!entry)
93
+ return undefined;
94
+ if (isExpired(entry)) {
95
+ sessionSelections.delete(sid);
96
+ return undefined;
97
+ }
98
+ return entry.id;
99
+ };
100
+ const get = (id) => {
101
+ const entry = byId.get(id);
102
+ if (!entry)
103
+ throw new UnknownBackendError(id, availableIds(), label);
104
+ return { id: entry.id, client: entry.client, meta: entry.meta };
105
+ };
106
+ return {
107
+ resolve(override) {
108
+ if (override)
109
+ return get(override);
110
+ const sticky = stickySelection();
111
+ if (sticky)
112
+ return get(sticky);
113
+ if (byId.size === 1) {
114
+ const [only] = byId.values();
115
+ return { id: only.id, client: only.client, meta: only.meta };
116
+ }
117
+ throw new BackendNotSelectedError(availableIds(), label);
118
+ },
119
+ select(id) {
120
+ if (!byId.has(id))
121
+ throw new UnknownBackendError(id, availableIds(), label);
122
+ const sid = getSessionId();
123
+ if (!sid) {
124
+ throw new Error(`No active MCP session — cannot store a ${label} selection`);
125
+ }
126
+ sweepExpired();
127
+ sessionSelections.set(sid, { id, selectedAt: now() });
128
+ },
129
+ clear(sessionId) {
130
+ sessionSelections.delete(sessionId);
131
+ },
132
+ list() {
133
+ return [...byId.values()].map((entry) => ({ id: entry.id, meta: entry.meta }));
134
+ },
135
+ getSelected() {
136
+ return stickySelection();
137
+ },
138
+ };
139
+ }
140
+ /**
141
+ * Lifts a handler written against a single resolved backend into one that
142
+ * resolves the backend from `registry` (override > sticky > single default)
143
+ * before delegating. The override is read from `args[paramName]`, so a tool
144
+ * adds backend selection by spreading an optional `{ [paramName]: z.string() }`
145
+ * into its input schema and wrapping its handler in `withBackend(...)`.
146
+ */
147
+ export function withBackend(registry, paramName, fn) {
148
+ return (args) => {
149
+ const override = args[paramName];
150
+ const backend = registry.resolve(typeof override === "string" ? override : undefined);
151
+ return fn(backend, args);
152
+ };
153
+ }
154
+ //# sourceMappingURL=backend-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend-registry.js","sourceRoot":"","sources":["../../src/tools/backend-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAElD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;AAgBjE;;;;;;;;;GASG;AACH,SAAS,mBAAmB;IAC1B,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAA;IAC/B,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAA;IAC1B,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,SAAS,CAAA;AAC1F,CAAC;AAwBD;;;;;;;;GAQG;AACH,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IACvC,IAAI,GAAG,sBAA+B,CAAA;IACtC,YAAY,CAAU;IAC/B,YAAY,YAAsB,EAAE,KAAa;QAC/C,KAAK,CACH,MAAM,KAAK,yCAAyC,KAAK,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YACxF,oCAAoC,CACvC,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAA;QACrC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;IAClC,CAAC;CACF;AAED,yFAAyF;AACzF,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IACnC,IAAI,GAAG,iBAA0B,CAAA;IACjC,WAAW,CAAQ;IACnB,YAAY,CAAU;IAC/B,YAAY,WAAmB,EAAE,YAAsB,EAAE,KAAa;QACpE,KAAK,CAAC,WAAW,KAAK,QAAQ,WAAW,iBAAiB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACrF,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAA;QACjC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAA;QAC9B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;IAClC,CAAC;CACF;AAsCD;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAAuC,EACvC,OAAqC,EAAE;IAEvC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAA;IAC9E,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAwC,CAAA;IAC5D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,gDAAgD,KAAK,CAAC,EAAE,GAAG,CAAC,CAAA;QAC9E,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;IAC3B,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,SAAS,CAAA;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,IAAI,8BAA8B,CAAA;IACjE,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,mBAAmB,CAAA;IAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAA;IAEhC,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAA4B,CAAA;IAC7D,MAAM,YAAY,GAAG,GAAa,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;IAErD,MAAM,SAAS,GAAG,CAAC,KAAuB,EAAW,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,UAAU,GAAG,KAAK,CAAA;IAExF,MAAM,YAAY,GAAG,GAAS,EAAE;QAC9B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,iBAAiB,EAAE,CAAC;YAC7C,IAAI,SAAS,CAAC,KAAK,CAAC;gBAAE,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QACrD,CAAC;IACH,CAAC,CAAA;IAED,MAAM,eAAe,GAAG,GAAuB,EAAE;QAC/C,MAAM,GAAG,GAAG,YAAY,EAAE,CAAA;QAC1B,IAAI,CAAC,GAAG;YAAE,OAAO,SAAS,CAAA;QAC1B,MAAM,KAAK,GAAG,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACxC,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAA;QAC5B,IAAI,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACrB,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YAC7B,OAAO,SAAS,CAAA;QAClB,CAAC;QACD,OAAO,KAAK,CAAC,EAAE,CAAA;IACjB,CAAC,CAAA;IAED,MAAM,GAAG,GAAG,CAAC,EAAU,EAAmC,EAAE;QAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAC1B,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,mBAAmB,CAAC,EAAE,EAAE,YAAY,EAAE,EAAE,KAAK,CAAC,CAAA;QACpE,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAA;IACjE,CAAC,CAAA;IAED,OAAO;QACL,OAAO,CAAC,QAAiB;YACvB,IAAI,QAAQ;gBAAE,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAA;YAElC,MAAM,MAAM,GAAG,eAAe,EAAE,CAAA;YAChC,IAAI,MAAM;gBAAE,OAAO,GAAG,CAAC,MAAM,CAAC,CAAA;YAE9B,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACpB,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAA;gBAC5B,OAAO,EAAE,EAAE,EAAE,IAAK,CAAC,EAAE,EAAE,MAAM,EAAE,IAAK,CAAC,MAAM,EAAE,IAAI,EAAE,IAAK,CAAC,IAAI,EAAE,CAAA;YACjE,CAAC;YAED,MAAM,IAAI,uBAAuB,CAAC,YAAY,EAAE,EAAE,KAAK,CAAC,CAAA;QAC1D,CAAC;QAED,MAAM,CAAC,EAAU;YACf,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAE,MAAM,IAAI,mBAAmB,CAAC,EAAE,EAAE,YAAY,EAAE,EAAE,KAAK,CAAC,CAAA;YAC3E,MAAM,GAAG,GAAG,YAAY,EAAE,CAAA;YAC1B,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,MAAM,IAAI,KAAK,CAAC,0CAA0C,KAAK,YAAY,CAAC,CAAA;YAC9E,CAAC;YACD,YAAY,EAAE,CAAA;YACd,iBAAiB,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,CAAC,CAAA;QACvD,CAAC;QAED,KAAK,CAAC,SAAiB;YACrB,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QACrC,CAAC;QAED,IAAI;YACF,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QAChF,CAAC;QAED,WAAW;YACT,OAAO,eAAe,EAAE,CAAA;QAC1B,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CACzB,QAAyC,EACzC,SAAiB,EACjB,EAA+E;IAE/E,OAAO,CAAC,IAAW,EAAE,EAAE;QACrB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAA;QAChC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;QACrF,OAAO,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;IAC1B,CAAC,CAAA;AACH,CAAC"}
@@ -0,0 +1,147 @@
1
+ import { type McpServerInstance, type OAuthProvider, type ServerConfig } from "mcp-use/server";
2
+ import { type DashboardStore } from "../framework/dashboard-store.js";
3
+ import type { AppConfig, AppPlugin } from "../types/index.js";
4
+ import { type AppResourceCsp } from "./register-framework-tools.js";
5
+ export interface CreateFrameworkAppOptionsBase {
6
+ name: string;
7
+ version?: string;
8
+ /**
9
+ * Human-readable description of what the server does. Shown on mcp-use's
10
+ * built-in landing page (a browser `GET` on the MCP endpoint) and in
11
+ * `serverInfo`-adjacent surfaces.
12
+ */
13
+ description?: string;
14
+ /** Public base URL the server advertises (resource URIs, oauth callbacks). */
15
+ baseUrl?: string;
16
+ host?: string;
17
+ /**
18
+ * Pass-through of the remaining mcp-use {@link ServerConfig} handed to the
19
+ * `MCPServer` constructor. The main use case is wiring session/stream
20
+ * backends — e.g. Redis-backed `sessionStore` / `streamManager` so several
21
+ * server instances can share sessions — but any mcp-use server option
22
+ * (`stateless`, `cors`, `sessionIdleTimeoutMs`, `instructions`, …) works
23
+ * without the toolkit having to mirror it. The six toolkit-owned keys
24
+ * (`name`, `version`, `description`, `host`, `baseUrl`, `oauth`) are
25
+ * excluded via `Omit` because they are first-class options on this
26
+ * interface already; `oauth` additionally stays out because it selects the
27
+ * `MCPServer<true | false>` constructor overload.
28
+ */
29
+ serverOptions?: Omit<ServerConfig, "name" | "version" | "description" | "host" | "baseUrl" | "oauth">;
30
+ plugins: AppPlugin[];
31
+ middleware?: {
32
+ /** When set, every RPC must come from a token with this organization_id. */
33
+ orgGate?: string;
34
+ /** role → allowed module prefixes. Empty / missing → no restriction. */
35
+ roleFilter?: Record<string, string[]>;
36
+ /**
37
+ * When `true`, a `tools/call` whose tool name can't be resolved is *denied*
38
+ * rather than allowed through the {@link roleFilter} guard. Defaults to
39
+ * `false` for backward compatibility, but production deployments that rely
40
+ * on `roleFilter` for access control should set this to `true` so an
41
+ * unresolved name never slips past the module guard. Only meaningful
42
+ * alongside `roleFilter`.
43
+ */
44
+ roleFilterFailClosed?: boolean;
45
+ };
46
+ app: {
47
+ /**
48
+ * MCP UI resource URI that hosts the widget bundle. Optional — when
49
+ * omitted it is derived as `ui://<name>/mcp-app.<hash>.html`, content-
50
+ * hashing the file at {@link htmlPath} so each build yields a distinct,
51
+ * cache-busting URI (see `deriveAppResourceUri`). Pass an explicit value
52
+ * only to pin the URI.
53
+ */
54
+ resourceUri?: string;
55
+ /** Absolute path to the bundled `mcp-app.html` served under `resourceUri`. */
56
+ htmlPath: string;
57
+ /** Override the refresh tool name (default: `refresh-view`). */
58
+ refreshToolName?: string;
59
+ /**
60
+ * Additional CSP origins advertised on the widget resource
61
+ * (`_meta.ui.csp`) and widget tools (`openai/widgetCSP`). The origin of
62
+ * {@link CreateFrameworkAppOptionsBase.baseUrl} is always merged in, so
63
+ * most deployments never need this — set it only when widgets fetch from
64
+ * origins other than the server itself (e.g. a CDN).
65
+ */
66
+ csp?: AppResourceCsp;
67
+ /**
68
+ * Opt-in switch for the visual in-iframe builder platform and dashboard
69
+ * persistence. **Defaults to `false` (lean by default).**
70
+ *
71
+ * Widget rendering always works regardless of this flag:
72
+ * `get-framework-manifest`, `render-view`, and `refresh-view` (plus the
73
+ * `mcp-app.html` resource) are registered unconditionally — that is the
74
+ * core surface every MCP server gets.
75
+ *
76
+ * Setting `builder: true` additionally registers:
77
+ * - `get-builder-catalogue` — the app-only data source the in-iframe
78
+ * LayoutBuilder calls to populate its palette / key catalogue, and
79
+ * - `save-dashboard` / `list-dashboards` / `load-dashboard` /
80
+ * `delete-dashboard` — dashboard CRUD persistence.
81
+ *
82
+ * These belong together: the visual builder reads the catalogue and saves
83
+ * its results as dashboards. Most lean MCP servers don't need either and
84
+ * should leave this off so the builder/dashboard tools never get forced
85
+ * onto their tool surface. The `McpAppView`'s Build/edit affordance hides
86
+ * itself when the catalogue tool isn't present, so the iframe UI degrades
87
+ * gracefully when `builder` is `false`.
88
+ */
89
+ builder?: boolean;
90
+ /**
91
+ * Override the catalogue tool name (default: `get-builder-catalogue`).
92
+ * The catalogue tool is app-only — it powers the in-iframe builder
93
+ * and never appears in the LLM's tool surface. Only relevant when
94
+ * {@link builder} is `true`; ignored otherwise.
95
+ */
96
+ catalogueToolName?: string;
97
+ /**
98
+ * Persistence backing for `save-dashboard` / `list-dashboards` /
99
+ * `load-dashboard` / `delete-dashboard`. Defaults to an in-memory store
100
+ * (process-local, lost on restart). Inject a filesystem or DB-backed
101
+ * store for real deployments. Only relevant when {@link builder} is
102
+ * `true` — with `builder` off the dashboard tools aren't registered, so
103
+ * this option has no effect.
104
+ */
105
+ dashboardStore?: DashboardStore;
106
+ };
107
+ /** Supplies the non-empty set of apps each plugin represents. */
108
+ appConfig?: AppConfig;
109
+ }
110
+ /**
111
+ * `createFrameworkApp` options when OAuth is enabled. The returned server is
112
+ * typed as `MCPServer<true>`, so tool callbacks receive a non-nullable
113
+ * `ctx.auth`.
114
+ */
115
+ export interface CreateFrameworkAppOptionsWithOAuth extends CreateFrameworkAppOptionsBase {
116
+ oauth: OAuthProvider;
117
+ }
118
+ /**
119
+ * `createFrameworkApp` options with OAuth disabled. The returned server is
120
+ * typed as `MCPServer<false>`, so tool callbacks treat `ctx.auth` as
121
+ * nullable.
122
+ */
123
+ export interface CreateFrameworkAppOptionsWithoutOAuth extends CreateFrameworkAppOptionsBase {
124
+ oauth?: undefined;
125
+ }
126
+ export type CreateFrameworkAppOptions = CreateFrameworkAppOptionsWithOAuth | CreateFrameworkAppOptionsWithoutOAuth;
127
+ /**
128
+ * Orchestrates a full Miranum-style MCP server: MCPServer construction,
129
+ * org-gate + role-filter middleware, per-plugin tool registration, and the
130
+ * framework-level tool trio (`get-framework-manifest`, `render-view`,
131
+ * `refresh-view`) + mcp-app.html resource.
132
+ *
133
+ * The server is deliberately self-contained: it serves only the first-party
134
+ * plugins passed in. Aggregating several MCP servers into one surface is an
135
+ * external gateway's job (e.g. agentgateway), not this framework's.
136
+ *
137
+ * OAuth is opt-in: pass an `oauth` provider to enable OAuth-gated routes and
138
+ * get an `MCPServer<true>` back, or omit it to boot without OAuth and get an
139
+ * `MCPServer<false>`. `ctx.auth` is still optionally present at runtime in
140
+ * both modes; the generic just reflects what's guaranteed.
141
+ *
142
+ * Returns the booted server before `.listen()` — the caller decides the port
143
+ * and the moment the server starts accepting traffic.
144
+ */
145
+ export declare function createFrameworkApp(options: CreateFrameworkAppOptionsWithOAuth): Promise<McpServerInstance<true>>;
146
+ export declare function createFrameworkApp(options: CreateFrameworkAppOptionsWithoutOAuth): Promise<McpServerInstance<false>>;
147
+ //# sourceMappingURL=create-framework-app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-framework-app.d.ts","sourceRoot":"","sources":["../../src/tools/create-framework-app.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAA;AAMvB,OAAO,EAAgC,KAAK,cAAc,EAAE,MAAM,iCAAiC,CAAA;AACnG,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAM3F,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;;;;;;;OAWG;IACH,aAAa,CAAC,EAAE,IAAI,CAClB,YAAY,EACZ,MAAM,GAAG,SAAS,GAAG,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAClE,CAAA;IACD,OAAO,EAAE,SAAS,EAAE,CAAA;IACpB,UAAU,CAAC,EAAE;QACX,4EAA4E;QAC5E,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,wEAAwE;QACxE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;QACrC;;;;;;;WAOG;QACH,oBAAoB,CAAC,EAAE,OAAO,CAAA;KAC/B,CAAA;IACD,GAAG,EAAE;QACH;;;;;;WAMG;QACH,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,8EAA8E;QAC9E,QAAQ,EAAE,MAAM,CAAA;QAChB,gEAAgE;QAChE,eAAe,CAAC,EAAE,MAAM,CAAA;QACxB;;;;;;WAMG;QACH,GAAG,CAAC,EAAE,cAAc,CAAA;QACpB;;;;;;;;;;;;;;;;;;;;;WAqBG;QACH,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB;;;;;WAKG;QACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;QAC1B;;;;;;;WAOG;QACH,cAAc,CAAC,EAAE,cAAc,CAAA;KAChC,CAAA;IACD,iEAAiE;IACjE,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,kCAAmC,SAAQ,6BAA6B;IACvF,KAAK,EAAE,aAAa,CAAA;CACrB;AAED;;;;GAIG;AACH,MAAM,WAAW,qCAAsC,SAAQ,6BAA6B;IAC1F,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB;AAED,MAAM,MAAM,yBAAyB,GACnC,kCAAkC,GAAG,qCAAqC,CAAA;AAE5E;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,kCAAkC,GAC1C,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAA;AACnC,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,qCAAqC,GAC7C,OAAO,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAA"}
@@ -0,0 +1,111 @@
1
+ import { MCPServer, } from "mcp-use/server";
2
+ import { loadApps } from "../registry/app-loader.js";
3
+ import { StepRegistry } from "../registry/step-registry.js";
4
+ import { WidgetRegistry } from "../registry/widget-registry.js";
5
+ import { createOrgGateMiddleware } from "../middleware/org-gate.js";
6
+ import { createRoleFilterMiddleware } from "../middleware/role-filter.js";
7
+ import { createInMemoryDashboardStore } from "../framework/dashboard-store.js";
8
+ import { registerFrameworkTools } from "./register-framework-tools.js";
9
+ import { registerCatalogueTool } from "./register-catalogue-tool.js";
10
+ import { registerDashboardTools } from "./register-dashboard-tools.js";
11
+ import { installToolCallNameCapture } from "./tool-call-name.js";
12
+ import { deriveAppResourceUri } from "./app-resource-uri.js";
13
+ // Async without an internal await today: the boot path became fully
14
+ // synchronous when upstream discovery was removed, but the Promise return
15
+ // stays — consumers `await` it, and future boot steps may be async again.
16
+ // eslint-disable-next-line @typescript-eslint/require-await
17
+ export async function createFrameworkApp(options) {
18
+ const baseConfig = {
19
+ name: options.name,
20
+ version: options.version ?? "0.1.0",
21
+ description: options.description,
22
+ host: options.host ?? "localhost",
23
+ baseUrl: options.baseUrl,
24
+ };
25
+ // `serverOptions` is statically disjoint from `baseConfig` (its type Omits
26
+ // every toolkit-owned key); the spread order is defense-in-depth so the
27
+ // toolkit's first-class options always win at runtime.
28
+ const server = options.oauth
29
+ ? new MCPServer({ ...options.serverOptions, ...baseConfig, oauth: options.oauth })
30
+ : new MCPServer({ ...options.serverOptions, ...baseConfig });
31
+ const orgGateId = options.middleware?.orgGate;
32
+ if (orgGateId) {
33
+ server.use("mcp:*", createOrgGateMiddleware(orgGateId));
34
+ }
35
+ // Capture the `tools/call` tool name from the JSON-RPC envelope at the HTTP
36
+ // layer. mcp-use 1.28 populates `mcp:tools/call` middleware's `ctx.params`
37
+ // with the tool *arguments*, not `{ name, arguments }`, so the role filter
38
+ // can't read the name from there. The resolver is request-scoped via
39
+ // `getRequestContext()` and is safe to install unconditionally.
40
+ const resolveToolName = installToolCallNameCapture(server);
41
+ const roleFilter = options.middleware?.roleFilter;
42
+ if (roleFilter && Object.keys(roleFilter).length > 0) {
43
+ const { toolsList, toolsCall } = createRoleFilterMiddleware(roleFilter, {
44
+ resolveToolName,
45
+ // Batch-aware: a JSON-RPC batch envelope can carry several tools/call
46
+ // requests; the guard must check all of them, not just the first.
47
+ resolveToolNames: resolveToolName.all,
48
+ failClosed: options.middleware?.roleFilterFailClosed ?? false,
49
+ });
50
+ server.use("mcp:tools/list", toolsList);
51
+ server.use("mcp:tools/call", toolsCall);
52
+ }
53
+ const stepRegistry = new StepRegistry();
54
+ const widgetRegistry = new WidgetRegistry();
55
+ // Plugin step/widget ids are author-controlled, so a collision is a real
56
+ // bug and must fail loud (hard throw).
57
+ const allPlugins = options.plugins;
58
+ loadApps(allPlugins.map((p) => p.definition), stepRegistry, widgetRegistry);
59
+ for (const plugin of allPlugins) {
60
+ plugin.registerTools?.(server);
61
+ }
62
+ // Per-app step configuration: each plugin's `appConfig` keyed by app name.
63
+ // A plugin may inject closures here (e.g. a typed `callTool`) — the pipeline
64
+ // executor pre-binds the per-request user context on any `callTool` it finds
65
+ // (see `pipeline-executor.ts:bindAppConfig`).
66
+ const appConfigs = Object.fromEntries(allPlugins.map((p) => [p.definition.name, p.appConfig ?? {}]));
67
+ const appConfig = options.appConfig ?? {
68
+ activeApps: allPlugins.map((p) => ({ app: p.definition.name, config: {} })),
69
+ pipelines: {},
70
+ };
71
+ // Derive a content-hashed resource URI when one isn't pinned, so each build
72
+ // busts the host's widget-bundle cache (a fixed URI would keep serving a
73
+ // stale bundle across restarts). `deriveAppResourceUri` warns and falls back
74
+ // to a stable dev URI when the bundle file is missing.
75
+ const resourceUri = options.app.resourceUri ??
76
+ deriveAppResourceUri({ appName: options.name, htmlPath: options.app.htmlPath });
77
+ registerFrameworkTools(server, {
78
+ stepRegistry,
79
+ widgetRegistry,
80
+ config: appConfig,
81
+ appConfigs,
82
+ plugins: allPlugins,
83
+ resourceUri,
84
+ htmlPath: options.app.htmlPath,
85
+ refreshToolName: options.app.refreshToolName,
86
+ // Advertise builder availability in the view payload so the iframe shell
87
+ // shows its Build affordance only when the catalogue/dashboard tools below
88
+ // are actually registered.
89
+ builderAvailable: options.app.builder ?? false,
90
+ // Feeds the widget-resource CSP (`_meta.ui.csp` + `openai/widgetCSP`):
91
+ // the baseUrl origin is auto-injected next to any explicit `app.csp`.
92
+ baseUrl: options.baseUrl,
93
+ csp: options.app.csp,
94
+ });
95
+ // The visual builder platform is opt-in: the catalogue (its data source)
96
+ // and the dashboard CRUD tools (its persistence) are registered together
97
+ // only when `app.builder` is true. Lean servers leave it off so render-view
98
+ // / the widget core stay the entire surface. See the `app.builder` TSDoc.
99
+ if (options.app.builder) {
100
+ registerCatalogueTool(server, {
101
+ stepRegistry,
102
+ widgetRegistry,
103
+ appConfigs,
104
+ toolName: options.app.catalogueToolName,
105
+ });
106
+ const dashboardStore = options.app.dashboardStore ?? createInMemoryDashboardStore();
107
+ registerDashboardTools(server, { store: dashboardStore, widgetRegistry });
108
+ }
109
+ return server;
110
+ }
111
+ //# sourceMappingURL=create-framework-app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-framework-app.js","sourceRoot":"","sources":["../../src/tools/create-framework-app.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export { createToolRegistrar } from "./register-tool.js";
2
+ export type { ToolConfig, RegisteredToolMeta } from "./register-tool.js";
3
+ export { createWidgetToolRegistrar } from "./register-widget-tool.js";
4
+ export type { WidgetToolConfig, WidgetToolVisibility } from "./register-widget-tool.js";
5
+ export { withToolErrors } from "./with-tool-errors.js";
6
+ export { registerFrameworkTools, buildAppResourceCsp } from "./register-framework-tools.js";
7
+ export type { RegisterFrameworkToolsOptions, AppResourceCsp } from "./register-framework-tools.js";
8
+ export { registerCatalogueTool } from "./register-catalogue-tool.js";
9
+ export type { RegisterCatalogueToolOptions } from "./register-catalogue-tool.js";
10
+ export { registerDashboardTools } from "./register-dashboard-tools.js";
11
+ export type { RegisterDashboardToolsOptions } from "./register-dashboard-tools.js";
12
+ export { createFrameworkApp } from "./create-framework-app.js";
13
+ export type { CreateFrameworkAppOptions } from "./create-framework-app.js";
14
+ export { deriveAppResourceUri } from "./app-resource-uri.js";
15
+ export type { DeriveAppResourceUriInput } from "./app-resource-uri.js";
16
+ export { createBackendRegistry, withBackend, BackendNotSelectedError, UnknownBackendError, DEFAULT_BACKEND_SESSION_TTL_MS, } from "./backend-registry.js";
17
+ export type { BackendRegistry, BackendEntry, ResolvedBackend, CreateBackendRegistryOptions, } from "./backend-registry.js";
18
+ export { installToolCallNameCapture, extractToolCallName, extractToolCallNames, } from "./tool-call-name.js";
19
+ export type { ToolNameResolver, ToolNameCapture } from "./tool-call-name.js";
20
+ export { createInMemoryDashboardStore, createFileSystemDashboardStore, DashboardOwnershipError, resolveSavedRecord, parseDashboardRecord, DASHBOARD_SCHEMA_VERSION, } from "../framework/dashboard-store.js";
21
+ export type { DashboardStore, DashboardRecord, DashboardSaveInput, DashboardSummary, DashboardListFilter, FileSystemDashboardStoreOptions, } from "../framework/dashboard-store.js";
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AACxE,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAA;AACrE,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AACvF,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAA;AAC3F,YAAY,EAAE,6BAA6B,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAClG,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AACpE,YAAY,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAA;AAChF,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AACtE,YAAY,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAA;AAClF,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,YAAY,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAA;AAC1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAC5D,YAAY,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAA;AACtE,OAAO,EACL,qBAAqB,EACrB,WAAW,EACX,uBAAuB,EACvB,mBAAmB,EACnB,8BAA8B,GAC/B,MAAM,uBAAuB,CAAA;AAC9B,YAAY,EACV,eAAe,EACf,YAAY,EACZ,eAAe,EACf,4BAA4B,GAC7B,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAK5E,OAAO,EACL,4BAA4B,EAC5B,8BAA8B,EAC9B,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,iCAAiC,CAAA;AACxC,YAAY,EACV,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,+BAA+B,GAChC,MAAM,iCAAiC,CAAA"}
@@ -0,0 +1,15 @@
1
+ export { createToolRegistrar } from "./register-tool.js";
2
+ export { createWidgetToolRegistrar } from "./register-widget-tool.js";
3
+ export { withToolErrors } from "./with-tool-errors.js";
4
+ export { registerFrameworkTools, buildAppResourceCsp } from "./register-framework-tools.js";
5
+ export { registerCatalogueTool } from "./register-catalogue-tool.js";
6
+ export { registerDashboardTools } from "./register-dashboard-tools.js";
7
+ export { createFrameworkApp } from "./create-framework-app.js";
8
+ export { deriveAppResourceUri } from "./app-resource-uri.js";
9
+ export { createBackendRegistry, withBackend, BackendNotSelectedError, UnknownBackendError, DEFAULT_BACKEND_SESSION_TTL_MS, } from "./backend-registry.js";
10
+ export { installToolCallNameCapture, extractToolCallName, extractToolCallNames, } from "./tool-call-name.js";
11
+ // Dashboard-store implementations are server-side (the filesystem impl
12
+ // imports `node:fs`). Consumers wire them through `createFrameworkApp`'s
13
+ // `app.dashboardStore`.
14
+ export { createInMemoryDashboardStore, createFileSystemDashboardStore, DashboardOwnershipError, resolveSavedRecord, parseDashboardRecord, DASHBOARD_SCHEMA_VERSION, } from "../framework/dashboard-store.js";
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAExD,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAA;AAErE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAA;AAE3F,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AAEpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AAEtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAE9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAE5D,OAAO,EACL,qBAAqB,EACrB,WAAW,EACX,uBAAuB,EACvB,mBAAmB,EACnB,8BAA8B,GAC/B,MAAM,uBAAuB,CAAA;AAO9B,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,qBAAqB,CAAA;AAG5B,uEAAuE;AACvE,yEAAyE;AACzE,wBAAwB;AACxB,OAAO,EACL,4BAA4B,EAC5B,8BAA8B,EAC9B,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,iCAAiC,CAAA"}
@@ -0,0 +1,22 @@
1
+ import { type MCPServer } from "mcp-use/server";
2
+ import type { StepRegistry } from "../registry/step-registry.js";
3
+ import type { WidgetRegistry } from "../registry/widget-registry.js";
4
+ export interface RegisterCatalogueToolOptions {
5
+ stepRegistry: StepRegistry;
6
+ widgetRegistry: WidgetRegistry;
7
+ appConfigs: Record<string, Record<string, unknown>>;
8
+ /** Override the tool name (default: `get-builder-catalogue`). */
9
+ toolName?: string;
10
+ }
11
+ /**
12
+ * Registers `get-builder-catalogue` — the in-iframe builder's data
13
+ * source. App-only (`visibility: ["app"]`), so it never appears in the
14
+ * LLM's `tools/list`. The LayoutBuilder calls it on mount and on each
15
+ * keys/steps edit; the LLM uses `render-view` for its own work.
16
+ *
17
+ * Registered by `createFrameworkApp` only when `app.builder` is `true` —
18
+ * the visual builder platform is opt-in (lean by default). When the builder
19
+ * is off this tool is absent and the `McpAppView` hides its Build affordance.
20
+ */
21
+ export declare function registerCatalogueTool(server: MCPServer, options: RegisterCatalogueToolOptions): void;
22
+ //# sourceMappingURL=register-catalogue-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-catalogue-tool.d.ts","sourceRoot":"","sources":["../../src/tools/register-catalogue-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAG/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAGpE,MAAM,WAAW,4BAA4B;IAC3C,YAAY,EAAE,YAAY,CAAA;IAC1B,cAAc,EAAE,cAAc,CAAA;IAC9B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IACnD,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAkBD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,4BAA4B,GACpC,IAAI,CAsBN"}
@@ -0,0 +1,45 @@
1
+ import { z } from "zod";
2
+ import { getBuilderCatalogue } from "../framework/catalogue.js";
3
+ import { APP_ONLY_META } from "../types/meta.js";
4
+ const stepRefSchema = z.object({
5
+ id: z.string(),
6
+ step: z.string(),
7
+ optional: z.boolean().optional(),
8
+ });
9
+ const catalogueSchema = z.object({
10
+ keys: z.record(z.string(), z.unknown()).optional(),
11
+ steps: z.array(stepRefSchema).optional(),
12
+ });
13
+ function extractUserId(ctx) {
14
+ const user = ctx?.auth?.user;
15
+ return typeof user?.userId === "string" ? user.userId : undefined;
16
+ }
17
+ /**
18
+ * Registers `get-builder-catalogue` — the in-iframe builder's data
19
+ * source. App-only (`visibility: ["app"]`), so it never appears in the
20
+ * LLM's `tools/list`. The LayoutBuilder calls it on mount and on each
21
+ * keys/steps edit; the LLM uses `render-view` for its own work.
22
+ *
23
+ * Registered by `createFrameworkApp` only when `app.builder` is `true` —
24
+ * the visual builder platform is opt-in (lean by default). When the builder
25
+ * is off this tool is absent and the `McpAppView` hides its Build affordance.
26
+ */
27
+ export function registerCatalogueTool(server, options) {
28
+ const { stepRegistry, widgetRegistry, appConfigs, toolName = "get-builder-catalogue" } = options;
29
+ server.tool({
30
+ name: toolName,
31
+ title: "Get Builder Catalogue",
32
+ description: "App-only. Returns the live pipeline context plus the reachable / unreachable widgets, available steps and key catalogue for the current keys + steps. Used by the in-iframe LayoutBuilder.",
33
+ schema: catalogueSchema,
34
+ _meta: APP_ONLY_META,
35
+ }, async (params, ctx) => {
36
+ return getBuilderCatalogue({
37
+ input: { keys: params.keys, steps: params.steps },
38
+ stepRegistry,
39
+ widgetRegistry,
40
+ appConfigs,
41
+ ctx: { userId: extractUserId(ctx) },
42
+ });
43
+ });
44
+ }
45
+ //# sourceMappingURL=register-catalogue-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-catalogue-tool.js","sourceRoot":"","sources":["../../src/tools/register-catalogue-tool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAG/D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAUhD,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7B,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACjC,CAAC,CAAA;AAEF,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/B,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;IAClD,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,QAAQ,EAAE;CACzC,CAAC,CAAA;AAEF,SAAS,aAAa,CAAC,GAAY;IACjC,MAAM,IAAI,GAAI,GAA8D,EAAE,IAAI,EAAE,IAAI,CAAA;IACxF,OAAO,OAAO,IAAI,EAAE,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;AACnE,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAAiB,EACjB,OAAqC;IAErC,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,GAAG,uBAAuB,EAAE,GAAG,OAAO,CAAA;IAEhG,MAAM,CAAC,IAAI,CACT;QACE,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EACT,4LAA4L;QAC9L,MAAM,EAAE,eAAe;QACvB,KAAK,EAAE,aAAa;KACrB,EACD,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;QACpB,OAAO,mBAAmB,CAAC;YACzB,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE;YACjD,YAAY;YACZ,cAAc;YACd,UAAU;YACV,GAAG,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,EAAE;SACpC,CAAC,CAAA;IACJ,CAAC,CACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { type MCPServer } from "mcp-use/server";
2
+ import type { DashboardStore } from "../framework/dashboard-store.js";
3
+ import type { WidgetRegistry } from "../registry/widget-registry.js";
4
+ export interface RegisterDashboardToolsOptions {
5
+ store: DashboardStore;
6
+ /**
7
+ * Optional widget registry used by `save-dashboard` to warn (never reject)
8
+ * when a layout references widget ids the server doesn't know about —
9
+ * usually a typo, surfaced as a non-fatal warning so a save is never
10
+ * blocked on a cosmetic mistake. Omit to skip the check entirely.
11
+ */
12
+ widgetRegistry?: WidgetRegistry;
13
+ }
14
+ /**
15
+ * Registers `save-dashboard`, `list-dashboards`, `load-dashboard`, and
16
+ * `delete-dashboard`. The tools are thin CRUD wrappers around the injected
17
+ * `DashboardStore`; auth scoping is applied here (never in the store) via
18
+ * the standard `ctx.auth.user.userId` extraction.
19
+ *
20
+ * `load-dashboard` returns the full record as JSON in `content[0].text`
21
+ * (mirrored into `structuredContent`) so the model itself receives the
22
+ * bundle — `structuredContent` alone is "not added to model context" per
23
+ * MCP. The `{ keys, steps, layout, title }` fields can be piped straight
24
+ * into `render-view` to re-render the saved dashboard.
25
+ *
26
+ * Registered by `createFrameworkApp` only when `app.builder` is `true` —
27
+ * dashboard persistence is part of the opt-in visual builder platform
28
+ * (lean by default). With the builder off, none of these tools exist and
29
+ * the `app.dashboardStore` option has no effect.
30
+ */
31
+ export declare function registerDashboardTools(server: MCPServer, options: RegisterDashboardToolsOptions): void;
32
+ //# sourceMappingURL=register-dashboard-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-dashboard-tools.d.ts","sourceRoot":"","sources":["../../src/tools/register-dashboard-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAU,MAAM,gBAAgB,CAAA;AAEvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;AAGrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAEpE,MAAM,WAAW,6BAA6B;IAC5C,KAAK,EAAE,cAAc,CAAA;IACrB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,cAAc,CAAA;CAChC;AA8BD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,6BAA6B,GACrC,IAAI,CA0HN"}