@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.
- package/README.md +32 -0
- package/dist/engine/context-builder.d.ts +5 -0
- package/dist/engine/context-builder.d.ts.map +1 -0
- package/dist/engine/context-builder.js +22 -0
- package/dist/engine/context-builder.js.map +1 -0
- package/dist/engine/pipeline-executor.d.ts +21 -0
- package/dist/engine/pipeline-executor.d.ts.map +1 -0
- package/dist/engine/pipeline-executor.js +80 -0
- package/dist/engine/pipeline-executor.js.map +1 -0
- package/dist/framework/active-modules.d.ts +30 -0
- package/dist/framework/active-modules.d.ts.map +1 -0
- package/dist/framework/active-modules.js +44 -0
- package/dist/framework/active-modules.js.map +1 -0
- package/dist/framework/catalogue.d.ts +148 -0
- package/dist/framework/catalogue.d.ts.map +1 -0
- package/dist/framework/catalogue.js +132 -0
- package/dist/framework/catalogue.js.map +1 -0
- package/dist/framework/dashboard-store.d.ts +136 -0
- package/dist/framework/dashboard-store.d.ts.map +1 -0
- package/dist/framework/dashboard-store.js +301 -0
- package/dist/framework/dashboard-store.js.map +1 -0
- package/dist/framework/layout-schemas.d.ts +106 -0
- package/dist/framework/layout-schemas.d.ts.map +1 -0
- package/dist/framework/layout-schemas.js +67 -0
- package/dist/framework/layout-schemas.js.map +1 -0
- package/dist/framework/layout-types.d.ts +25 -0
- package/dist/framework/layout-types.d.ts.map +1 -0
- package/dist/framework/layout-types.js +7 -0
- package/dist/framework/layout-types.js.map +1 -0
- package/dist/framework/manifest.d.ts +65 -0
- package/dist/framework/manifest.d.ts.map +1 -0
- package/dist/framework/manifest.js +47 -0
- package/dist/framework/manifest.js.map +1 -0
- package/dist/framework/render-view.d.ts +53 -0
- package/dist/framework/render-view.d.ts.map +1 -0
- package/dist/framework/render-view.js +73 -0
- package/dist/framework/render-view.js.map +1 -0
- package/dist/framework/view-builders.d.ts +79 -0
- package/dist/framework/view-builders.d.ts.map +1 -0
- package/dist/framework/view-builders.js +113 -0
- package/dist/framework/view-builders.js.map +1 -0
- package/dist/i18n/index.d.ts +3 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +6 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/translator.d.ts +59 -0
- package/dist/i18n/translator.d.ts.map +1 -0
- package/dist/i18n/translator.js +48 -0
- package/dist/i18n/translator.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/org-gate.d.ts +22 -0
- package/dist/middleware/org-gate.d.ts.map +1 -0
- package/dist/middleware/org-gate.js +28 -0
- package/dist/middleware/org-gate.js.map +1 -0
- package/dist/middleware/role-filter.d.ts +79 -0
- package/dist/middleware/role-filter.d.ts.map +1 -0
- package/dist/middleware/role-filter.js +95 -0
- package/dist/middleware/role-filter.js.map +1 -0
- package/dist/registry/app-loader.d.ts +35 -0
- package/dist/registry/app-loader.d.ts.map +1 -0
- package/dist/registry/app-loader.js +55 -0
- package/dist/registry/app-loader.js.map +1 -0
- package/dist/registry/step-registry.d.ts +27 -0
- package/dist/registry/step-registry.d.ts.map +1 -0
- package/dist/registry/step-registry.js +53 -0
- package/dist/registry/step-registry.js.map +1 -0
- package/dist/registry/widget-registry.d.ts +15 -0
- package/dist/registry/widget-registry.d.ts.map +1 -0
- package/dist/registry/widget-registry.js +28 -0
- package/dist/registry/widget-registry.js.map +1 -0
- package/dist/rest/client.d.ts +3 -0
- package/dist/rest/client.d.ts.map +1 -0
- package/dist/rest/client.js +155 -0
- package/dist/rest/client.js.map +1 -0
- package/dist/rest/errors.d.ts +14 -0
- package/dist/rest/errors.d.ts.map +1 -0
- package/dist/rest/errors.js +21 -0
- package/dist/rest/errors.js.map +1 -0
- package/dist/rest/index.d.ts +6 -0
- package/dist/rest/index.d.ts.map +1 -0
- package/dist/rest/index.js +4 -0
- package/dist/rest/index.js.map +1 -0
- package/dist/rest/tool.d.ts +60 -0
- package/dist/rest/tool.d.ts.map +1 -0
- package/dist/rest/tool.js +81 -0
- package/dist/rest/tool.js.map +1 -0
- package/dist/rest/types.d.ts +66 -0
- package/dist/rest/types.d.ts.map +1 -0
- package/dist/rest/types.js +2 -0
- package/dist/rest/types.js.map +1 -0
- package/dist/tools/app-resource-uri.d.ts +28 -0
- package/dist/tools/app-resource-uri.d.ts.map +1 -0
- package/dist/tools/app-resource-uri.js +30 -0
- package/dist/tools/app-resource-uri.js.map +1 -0
- package/dist/tools/backend-registry.d.ts +111 -0
- package/dist/tools/backend-registry.d.ts.map +1 -0
- package/dist/tools/backend-registry.js +154 -0
- package/dist/tools/backend-registry.js.map +1 -0
- package/dist/tools/create-framework-app.d.ts +147 -0
- package/dist/tools/create-framework-app.d.ts.map +1 -0
- package/dist/tools/create-framework-app.js +111 -0
- package/dist/tools/create-framework-app.js.map +1 -0
- package/dist/tools/index.d.ts +22 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +15 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/register-catalogue-tool.d.ts +22 -0
- package/dist/tools/register-catalogue-tool.d.ts.map +1 -0
- package/dist/tools/register-catalogue-tool.js +45 -0
- package/dist/tools/register-catalogue-tool.js.map +1 -0
- package/dist/tools/register-dashboard-tools.d.ts +32 -0
- package/dist/tools/register-dashboard-tools.d.ts.map +1 -0
- package/dist/tools/register-dashboard-tools.js +149 -0
- package/dist/tools/register-dashboard-tools.js.map +1 -0
- package/dist/tools/register-framework-tools.d.ts +83 -0
- package/dist/tools/register-framework-tools.d.ts.map +1 -0
- package/dist/tools/register-framework-tools.js +154 -0
- package/dist/tools/register-framework-tools.js.map +1 -0
- package/dist/tools/register-tool.d.ts +45 -0
- package/dist/tools/register-tool.d.ts.map +1 -0
- package/dist/tools/register-tool.js +82 -0
- package/dist/tools/register-tool.js.map +1 -0
- package/dist/tools/register-widget-tool.d.ts +51 -0
- package/dist/tools/register-widget-tool.d.ts.map +1 -0
- package/dist/tools/register-widget-tool.js +45 -0
- package/dist/tools/register-widget-tool.js.map +1 -0
- package/dist/tools/tool-call-name.d.ts +53 -0
- package/dist/tools/tool-call-name.d.ts.map +1 -0
- package/dist/tools/tool-call-name.js +92 -0
- package/dist/tools/tool-call-name.js.map +1 -0
- package/dist/tools/with-tool-errors.d.ts +16 -0
- package/dist/tools/with-tool-errors.d.ts.map +1 -0
- package/dist/tools/with-tool-errors.js +28 -0
- package/dist/tools/with-tool-errors.js.map +1 -0
- package/dist/types/app.d.ts +44 -0
- package/dist/types/app.d.ts.map +1 -0
- package/dist/types/app.js +2 -0
- package/dist/types/app.js.map +1 -0
- package/dist/types/config.d.ts +15 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +2 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/context.d.ts +18 -0
- package/dist/types/context.d.ts.map +1 -0
- package/dist/types/context.js +2 -0
- package/dist/types/context.js.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/meta.d.ts +99 -0
- package/dist/types/meta.d.ts.map +1 -0
- package/dist/types/meta.js +66 -0
- package/dist/types/meta.js.map +1 -0
- package/dist/types/pipeline.d.ts +9 -0
- package/dist/types/pipeline.d.ts.map +1 -0
- package/dist/types/pipeline.js +2 -0
- package/dist/types/pipeline.js.map +1 -0
- package/dist/types/step.d.ts +51 -0
- package/dist/types/step.d.ts.map +1 -0
- package/dist/types/step.js +2 -0
- package/dist/types/step.js.map +1 -0
- package/dist/types/view-data.d.ts +67 -0
- package/dist/types/view-data.d.ts.map +1 -0
- package/dist/types/view-data.js +2 -0
- package/dist/types/view-data.js.map +1 -0
- package/dist/types/widget.d.ts +57 -0
- package/dist/types/widget.d.ts.map +1 -0
- package/dist/types/widget.js +2 -0
- package/dist/types/widget.js.map +1 -0
- 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":"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"}
|
|
@@ -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"}
|