@plitzi/sdk-server 0.32.9 → 0.32.11
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/CHANGELOG.md +20 -0
- package/dist/core/http/dispatcher.js +45 -9
- package/dist/core/services/mcp.js +9 -7
- package/dist/helpers/serverLog.js +33 -0
- package/dist/index.js +2 -1
- package/dist/mcp.d.ts +2 -0
- package/dist/mcp.js +7 -0
- package/dist/modules/mcp/apps/example/view.tsx +70 -0
- package/dist/modules/mcp/apps/index.js +12 -0
- package/dist/modules/mcp/apps/render/index.js +16 -0
- package/dist/modules/mcp/apps/render/view.tsx +108 -0
- package/dist/modules/mcp/apps/shared/bundle.js +22 -0
- package/dist/modules/mcp/apps/shared/page.js +23 -0
- package/dist/modules/mcp/apps/shared/registerApp.js +27 -0
- package/dist/modules/mcp/apps/shared/resolve.js +5 -0
- package/dist/modules/mcp/apps/shared/shell.ejs +37 -0
- package/dist/modules/mcp/apps/shared/zodEnglishOnly.js +23 -0
- package/dist/modules/mcp/handler.js +8 -6
- package/dist/modules/mcp/helpers/log.js +20 -10
- package/dist/modules/mcp/resources/register.js +11 -5
- package/dist/modules/mcp/resources/renderGuide.js +17 -7
- package/dist/modules/mcp/server.js +21 -12
- package/dist/modules/mcp/tools/apply/index.js +1 -1
- package/dist/modules/mcp/tools/render.js +3 -3
- package/dist/modules/ssr/registerExternalPlugins.js +1 -1
- package/dist/modules/ssr/template.js +1 -1
- package/dist/plugins/compile.js +1 -1
- package/dist/plugins/copy.js +1 -1
- package/dist/plugins/manager.js +3 -1
- package/dist/plugins/validate.js +23 -0
- package/dist/src/core/http/dispatcher.test.d.ts +1 -0
- package/dist/src/core/http/types.d.ts +3 -0
- package/dist/src/core/requestParser.d.ts +3 -0
- package/dist/src/helpers/buildResponseHelpers.d.ts +2 -0
- package/dist/src/helpers/serverLog.d.ts +10 -0
- package/dist/src/index.d.ts +2 -1
- package/dist/src/mcp.d.ts +14 -0
- package/dist/src/modules/mcp/apps/apps.test.d.ts +1 -0
- package/dist/src/modules/mcp/apps/example/index.d.ts +8 -0
- package/dist/src/modules/mcp/apps/example/view.d.ts +1 -0
- package/dist/src/modules/mcp/apps/index.d.ts +8 -0
- package/dist/src/modules/mcp/apps/render/index.d.ts +3 -0
- package/dist/src/modules/mcp/apps/render/view.d.ts +1 -0
- package/dist/src/modules/mcp/apps/shared/bundle.d.ts +1 -0
- package/dist/src/modules/mcp/apps/shared/index.d.ts +2 -0
- package/dist/src/modules/mcp/apps/shared/page.d.ts +2 -0
- package/dist/src/modules/mcp/apps/shared/registerApp.d.ts +5 -0
- package/dist/src/modules/mcp/apps/shared/resolve.d.ts +1 -0
- package/dist/src/modules/mcp/apps/shared/zodEnglishOnly.d.ts +4 -0
- package/dist/src/modules/mcp/e2e/connector.test.d.ts +1 -0
- package/dist/src/modules/mcp/e2e/host.test.d.ts +1 -0
- package/dist/src/modules/mcp/e2e/index.d.ts +6 -0
- package/dist/src/modules/mcp/e2e/mcpEndpoint.d.ts +20 -0
- package/dist/src/modules/mcp/e2e/postMessageChannel.d.ts +22 -0
- package/dist/src/modules/mcp/e2e/renderingHost.d.ts +14 -0
- package/dist/src/modules/mcp/handler.d.ts +11 -7
- package/dist/src/modules/mcp/helpers/log.d.ts +3 -3
- package/dist/src/modules/mcp/index.d.ts +1 -0
- package/dist/src/modules/mcp/resources/register.d.ts +1 -1
- package/dist/src/modules/mcp/resources/renderGuide.d.ts +3 -2
- package/dist/src/modules/mcp/server.d.ts +4 -12
- package/dist/src/modules/mcp/tools/apply/index.d.ts +3 -3
- package/dist/src/modules/mcp/tools/operations/index.d.ts +6 -6
- package/dist/src/modules/mcp/tools/operations/schema/operations.d.ts +1 -1
- package/dist/src/modules/mcp/tools/operations/schema/settings/patchSettings.d.ts +1 -1
- package/dist/src/modules/mcp/tools/operations/style/operations.d.ts +2 -2
- package/dist/src/modules/mcp/tools/operations/style/shared.d.ts +1 -1
- package/dist/src/modules/mcp/tools/operations/style/variables/deleteStyleVariable.d.ts +1 -1
- package/dist/src/modules/mcp/tools/operations/style/variables/upsertStyleVariable.d.ts +1 -1
- package/dist/src/modules/mcp/tools/preview.d.ts +3 -3
- package/dist/src/modules/mcp/tools/render.d.ts +3 -3
- package/dist/src/modules/mcp/tools/screenshot.d.ts +3 -3
- package/dist/src/modules/mcp/tools/shared/tool.d.ts +4 -7
- package/dist/src/modules/mcp/tools/validate.d.ts +3 -3
- package/dist/src/modules/mcp/types/appTypes.d.ts +13 -0
- package/dist/src/modules/mcp/types/index.d.ts +1 -0
- package/dist/src/plugins/validate.d.ts +9 -0
- package/dist/src/plugins/validate.test.d.ts +1 -0
- package/package.json +13 -4
- package/dist/modules/mcp/resources/renderApp.js +0 -182
- package/dist/server.d.ts +0 -1
- package/dist/server.js +0 -107
- package/dist/src/modules/mcp/resources/renderApp.d.ts +0 -3
|
@@ -175,8 +175,8 @@ export declare const operation: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
175
175
|
userProvider: z.ZodOptional<z.ZodEnum<{
|
|
176
176
|
"": "";
|
|
177
177
|
custom: "custom";
|
|
178
|
-
basic: "basic";
|
|
179
178
|
auth0: "auth0";
|
|
179
|
+
basic: "basic";
|
|
180
180
|
}>>;
|
|
181
181
|
auth0Domain: z.ZodOptional<z.ZodString>;
|
|
182
182
|
auth0ClientId: z.ZodOptional<z.ZodString>;
|
|
@@ -391,9 +391,9 @@ export declare const operation: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
391
391
|
type: z.ZodLiteral<"upsertStyleVariable">;
|
|
392
392
|
category: z.ZodEnum<{
|
|
393
393
|
color: "color";
|
|
394
|
-
custom: "custom";
|
|
395
394
|
spacing: "spacing";
|
|
396
395
|
shadow: "shadow";
|
|
396
|
+
custom: "custom";
|
|
397
397
|
}>;
|
|
398
398
|
name: z.ZodString;
|
|
399
399
|
value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
|
|
@@ -405,9 +405,9 @@ export declare const operation: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
405
405
|
type: z.ZodLiteral<"deleteStyleVariable">;
|
|
406
406
|
category: z.ZodEnum<{
|
|
407
407
|
color: "color";
|
|
408
|
-
custom: "custom";
|
|
409
408
|
spacing: "spacing";
|
|
410
409
|
shadow: "shadow";
|
|
410
|
+
custom: "custom";
|
|
411
411
|
}>;
|
|
412
412
|
name: z.ZodString;
|
|
413
413
|
}, z.core.$strip>], "type">;
|
|
@@ -590,8 +590,8 @@ export declare const operations: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject
|
|
|
590
590
|
userProvider: z.ZodOptional<z.ZodEnum<{
|
|
591
591
|
"": "";
|
|
592
592
|
custom: "custom";
|
|
593
|
-
basic: "basic";
|
|
594
593
|
auth0: "auth0";
|
|
594
|
+
basic: "basic";
|
|
595
595
|
}>>;
|
|
596
596
|
auth0Domain: z.ZodOptional<z.ZodString>;
|
|
597
597
|
auth0ClientId: z.ZodOptional<z.ZodString>;
|
|
@@ -806,9 +806,9 @@ export declare const operations: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject
|
|
|
806
806
|
type: z.ZodLiteral<"upsertStyleVariable">;
|
|
807
807
|
category: z.ZodEnum<{
|
|
808
808
|
color: "color";
|
|
809
|
-
custom: "custom";
|
|
810
809
|
spacing: "spacing";
|
|
811
810
|
shadow: "shadow";
|
|
811
|
+
custom: "custom";
|
|
812
812
|
}>;
|
|
813
813
|
name: z.ZodString;
|
|
814
814
|
value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
|
|
@@ -820,9 +820,9 @@ export declare const operations: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject
|
|
|
820
820
|
type: z.ZodLiteral<"deleteStyleVariable">;
|
|
821
821
|
category: z.ZodEnum<{
|
|
822
822
|
color: "color";
|
|
823
|
-
custom: "custom";
|
|
824
823
|
spacing: "spacing";
|
|
825
824
|
shadow: "shadow";
|
|
825
|
+
custom: "custom";
|
|
826
826
|
}>;
|
|
827
827
|
name: z.ZodString;
|
|
828
828
|
}, z.core.$strip>], "type">>;
|
|
@@ -189,8 +189,8 @@ export declare const elementOps: {
|
|
|
189
189
|
userProvider: import('zod').ZodOptional<import('zod').ZodEnum<{
|
|
190
190
|
"": "";
|
|
191
191
|
custom: "custom";
|
|
192
|
-
basic: "basic";
|
|
193
192
|
auth0: "auth0";
|
|
193
|
+
basic: "basic";
|
|
194
194
|
}>>;
|
|
195
195
|
auth0Domain: import('zod').ZodOptional<import('zod').ZodString>;
|
|
196
196
|
auth0ClientId: import('zod').ZodOptional<import('zod').ZodString>;
|
|
@@ -12,8 +12,8 @@ export declare const patchSettingsOp: z.ZodObject<{
|
|
|
12
12
|
userProvider: z.ZodOptional<z.ZodEnum<{
|
|
13
13
|
"": "";
|
|
14
14
|
custom: "custom";
|
|
15
|
-
basic: "basic";
|
|
16
15
|
auth0: "auth0";
|
|
16
|
+
basic: "basic";
|
|
17
17
|
}>>;
|
|
18
18
|
auth0Domain: z.ZodOptional<z.ZodString>;
|
|
19
19
|
auth0ClientId: z.ZodOptional<z.ZodString>;
|
|
@@ -207,9 +207,9 @@ export declare const styleOps: {
|
|
|
207
207
|
type: import('zod').ZodLiteral<"upsertStyleVariable">;
|
|
208
208
|
category: import('zod').ZodEnum<{
|
|
209
209
|
color: "color";
|
|
210
|
-
custom: "custom";
|
|
211
210
|
spacing: "spacing";
|
|
212
211
|
shadow: "shadow";
|
|
212
|
+
custom: "custom";
|
|
213
213
|
}>;
|
|
214
214
|
name: import('zod').ZodString;
|
|
215
215
|
value: import('zod').ZodUnion<readonly [import('zod').ZodString, import('zod').ZodNumber, import('zod').ZodObject<{
|
|
@@ -222,9 +222,9 @@ export declare const styleOps: {
|
|
|
222
222
|
type: import('zod').ZodLiteral<"deleteStyleVariable">;
|
|
223
223
|
category: import('zod').ZodEnum<{
|
|
224
224
|
color: "color";
|
|
225
|
-
custom: "custom";
|
|
226
225
|
spacing: "spacing";
|
|
227
226
|
shadow: "shadow";
|
|
227
|
+
custom: "custom";
|
|
228
228
|
}>;
|
|
229
229
|
name: import('zod').ZodString;
|
|
230
230
|
}, import('zod/v4/core').$strip>;
|
|
@@ -43,9 +43,9 @@ declare const definitionSlotPatch: z.ZodObject<{
|
|
|
43
43
|
export type DefinitionSlotPatch = z.infer<typeof definitionSlotPatch>;
|
|
44
44
|
export declare const styleCategory: z.ZodEnum<{
|
|
45
45
|
color: "color";
|
|
46
|
-
custom: "custom";
|
|
47
46
|
spacing: "spacing";
|
|
48
47
|
shadow: "shadow";
|
|
48
|
+
custom: "custom";
|
|
49
49
|
}>;
|
|
50
50
|
export declare const themeValue: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
|
|
51
51
|
light: z.ZodOptional<z.ZodString>;
|
|
@@ -5,9 +5,9 @@ export declare const deleteStyleVariableOp: z.ZodObject<{
|
|
|
5
5
|
type: z.ZodLiteral<"deleteStyleVariable">;
|
|
6
6
|
category: z.ZodEnum<{
|
|
7
7
|
color: "color";
|
|
8
|
-
custom: "custom";
|
|
9
8
|
spacing: "spacing";
|
|
10
9
|
shadow: "shadow";
|
|
10
|
+
custom: "custom";
|
|
11
11
|
}>;
|
|
12
12
|
name: z.ZodString;
|
|
13
13
|
}, z.core.$strip>;
|
|
@@ -5,9 +5,9 @@ export declare const upsertStyleVariableOp: z.ZodObject<{
|
|
|
5
5
|
type: z.ZodLiteral<"upsertStyleVariable">;
|
|
6
6
|
category: z.ZodEnum<{
|
|
7
7
|
color: "color";
|
|
8
|
-
custom: "custom";
|
|
9
8
|
spacing: "spacing";
|
|
10
9
|
shadow: "shadow";
|
|
10
|
+
custom: "custom";
|
|
11
11
|
}>;
|
|
12
12
|
name: z.ZodString;
|
|
13
13
|
value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
|
|
@@ -175,8 +175,8 @@ export declare const previewShape: {
|
|
|
175
175
|
userProvider: z.ZodOptional<z.ZodEnum<{
|
|
176
176
|
"": "";
|
|
177
177
|
custom: "custom";
|
|
178
|
-
basic: "basic";
|
|
179
178
|
auth0: "auth0";
|
|
179
|
+
basic: "basic";
|
|
180
180
|
}>>;
|
|
181
181
|
auth0Domain: z.ZodOptional<z.ZodString>;
|
|
182
182
|
auth0ClientId: z.ZodOptional<z.ZodString>;
|
|
@@ -391,9 +391,9 @@ export declare const previewShape: {
|
|
|
391
391
|
type: z.ZodLiteral<"upsertStyleVariable">;
|
|
392
392
|
category: z.ZodEnum<{
|
|
393
393
|
color: "color";
|
|
394
|
-
custom: "custom";
|
|
395
394
|
spacing: "spacing";
|
|
396
395
|
shadow: "shadow";
|
|
396
|
+
custom: "custom";
|
|
397
397
|
}>;
|
|
398
398
|
name: z.ZodString;
|
|
399
399
|
value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
|
|
@@ -405,9 +405,9 @@ export declare const previewShape: {
|
|
|
405
405
|
type: z.ZodLiteral<"deleteStyleVariable">;
|
|
406
406
|
category: z.ZodEnum<{
|
|
407
407
|
color: "color";
|
|
408
|
-
custom: "custom";
|
|
409
408
|
spacing: "spacing";
|
|
410
409
|
shadow: "shadow";
|
|
410
|
+
custom: "custom";
|
|
411
411
|
}>;
|
|
412
412
|
name: z.ZodString;
|
|
413
413
|
}, z.core.$strip>], "type">>>;
|
|
@@ -175,8 +175,8 @@ export declare const renderShape: {
|
|
|
175
175
|
userProvider: import('zod').ZodOptional<import('zod').ZodEnum<{
|
|
176
176
|
"": "";
|
|
177
177
|
custom: "custom";
|
|
178
|
-
basic: "basic";
|
|
179
178
|
auth0: "auth0";
|
|
179
|
+
basic: "basic";
|
|
180
180
|
}>>;
|
|
181
181
|
auth0Domain: import('zod').ZodOptional<import('zod').ZodString>;
|
|
182
182
|
auth0ClientId: import('zod').ZodOptional<import('zod').ZodString>;
|
|
@@ -391,9 +391,9 @@ export declare const renderShape: {
|
|
|
391
391
|
type: import('zod').ZodLiteral<"upsertStyleVariable">;
|
|
392
392
|
category: import('zod').ZodEnum<{
|
|
393
393
|
color: "color";
|
|
394
|
-
custom: "custom";
|
|
395
394
|
spacing: "spacing";
|
|
396
395
|
shadow: "shadow";
|
|
396
|
+
custom: "custom";
|
|
397
397
|
}>;
|
|
398
398
|
name: import('zod').ZodString;
|
|
399
399
|
value: import('zod').ZodUnion<readonly [import('zod').ZodString, import('zod').ZodNumber, import('zod').ZodObject<{
|
|
@@ -405,9 +405,9 @@ export declare const renderShape: {
|
|
|
405
405
|
type: import('zod').ZodLiteral<"deleteStyleVariable">;
|
|
406
406
|
category: import('zod').ZodEnum<{
|
|
407
407
|
color: "color";
|
|
408
|
-
custom: "custom";
|
|
409
408
|
spacing: "spacing";
|
|
410
409
|
shadow: "shadow";
|
|
410
|
+
custom: "custom";
|
|
411
411
|
}>;
|
|
412
412
|
name: import('zod').ZodString;
|
|
413
413
|
}, import('zod/v4/core').$strip>], "type">>;
|
|
@@ -175,8 +175,8 @@ export declare const screenshotShape: {
|
|
|
175
175
|
userProvider: z.ZodOptional<z.ZodEnum<{
|
|
176
176
|
"": "";
|
|
177
177
|
custom: "custom";
|
|
178
|
-
basic: "basic";
|
|
179
178
|
auth0: "auth0";
|
|
179
|
+
basic: "basic";
|
|
180
180
|
}>>;
|
|
181
181
|
auth0Domain: z.ZodOptional<z.ZodString>;
|
|
182
182
|
auth0ClientId: z.ZodOptional<z.ZodString>;
|
|
@@ -391,9 +391,9 @@ export declare const screenshotShape: {
|
|
|
391
391
|
type: z.ZodLiteral<"upsertStyleVariable">;
|
|
392
392
|
category: z.ZodEnum<{
|
|
393
393
|
color: "color";
|
|
394
|
-
custom: "custom";
|
|
395
394
|
spacing: "spacing";
|
|
396
395
|
shadow: "shadow";
|
|
396
|
+
custom: "custom";
|
|
397
397
|
}>;
|
|
398
398
|
name: z.ZodString;
|
|
399
399
|
value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
|
|
@@ -405,9 +405,9 @@ export declare const screenshotShape: {
|
|
|
405
405
|
type: z.ZodLiteral<"deleteStyleVariable">;
|
|
406
406
|
category: z.ZodEnum<{
|
|
407
407
|
color: "color";
|
|
408
|
-
custom: "custom";
|
|
409
408
|
spacing: "spacing";
|
|
410
409
|
shadow: "shadow";
|
|
410
|
+
custom: "custom";
|
|
411
411
|
}>;
|
|
412
412
|
name: z.ZodString;
|
|
413
413
|
}, z.core.$strip>], "type">>>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z, ZodObject, ZodRawShape } from 'zod';
|
|
2
2
|
import { Space } from '../../helpers';
|
|
3
3
|
import { PreviewClient, ScreenshotClient, ScreenshotImage, Env, Persisters } from '../../types';
|
|
4
|
+
import { McpUiToolMeta } from '@modelcontextprotocol/ext-apps';
|
|
4
5
|
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
5
6
|
/** Everything a tool needs at call time: the loaded space, the target environment, and the persisters (only the
|
|
6
7
|
* write tools use them). Built by whoever hosts the tools — the standalone MCP server or the in-process AI
|
|
@@ -35,10 +36,8 @@ export interface ToolSpec<Shape extends ZodRawShape> {
|
|
|
35
36
|
* or load a space for it — that keeps it callable with no auth, on the public surface. */
|
|
36
37
|
spaceless?: boolean;
|
|
37
38
|
/** MCP Apps: link this tool to an interactive UI resource (a `ui://` HTML page the host renders in a sandboxed
|
|
38
|
-
* iframe, receiving the tool result).
|
|
39
|
-
ui?:
|
|
40
|
-
resourceUri: string;
|
|
41
|
-
};
|
|
39
|
+
* iframe, receiving the tool result). Registered as the tool's `_meta.ui` — see registerAppTool. */
|
|
40
|
+
ui?: McpUiToolMeta;
|
|
42
41
|
run: (input: z.infer<ZodObject<Shape>>, ctx: ToolContext) => unknown;
|
|
43
42
|
}
|
|
44
43
|
/** What the registry holds and the hosts register from: the same metadata plus a type-erased `execute` that
|
|
@@ -51,9 +50,7 @@ export interface ToolDef {
|
|
|
51
50
|
access: 'read' | 'write';
|
|
52
51
|
requires?: ToolRequires;
|
|
53
52
|
spaceless?: boolean;
|
|
54
|
-
ui?:
|
|
55
|
-
resourceUri: string;
|
|
56
|
-
};
|
|
53
|
+
ui?: McpUiToolMeta;
|
|
57
54
|
execute: (args: unknown, ctx: ToolContext) => unknown;
|
|
58
55
|
}
|
|
59
56
|
/** Author a tool: give it its metadata, its input shape and a typed `run`. The returned descriptor parses the
|
|
@@ -176,8 +176,8 @@ export declare const validateShape: {
|
|
|
176
176
|
userProvider: import('zod').ZodOptional<import('zod').ZodEnum<{
|
|
177
177
|
"": "";
|
|
178
178
|
custom: "custom";
|
|
179
|
-
basic: "basic";
|
|
180
179
|
auth0: "auth0";
|
|
180
|
+
basic: "basic";
|
|
181
181
|
}>>;
|
|
182
182
|
auth0Domain: import('zod').ZodOptional<import('zod').ZodString>;
|
|
183
183
|
auth0ClientId: import('zod').ZodOptional<import('zod').ZodString>;
|
|
@@ -392,9 +392,9 @@ export declare const validateShape: {
|
|
|
392
392
|
type: import('zod').ZodLiteral<"upsertStyleVariable">;
|
|
393
393
|
category: import('zod').ZodEnum<{
|
|
394
394
|
color: "color";
|
|
395
|
-
custom: "custom";
|
|
396
395
|
spacing: "spacing";
|
|
397
396
|
shadow: "shadow";
|
|
397
|
+
custom: "custom";
|
|
398
398
|
}>;
|
|
399
399
|
name: import('zod').ZodString;
|
|
400
400
|
value: import('zod').ZodUnion<readonly [import('zod').ZodString, import('zod').ZodNumber, import('zod').ZodObject<{
|
|
@@ -406,9 +406,9 @@ export declare const validateShape: {
|
|
|
406
406
|
type: import('zod').ZodLiteral<"deleteStyleVariable">;
|
|
407
407
|
category: import('zod').ZodEnum<{
|
|
408
408
|
color: "color";
|
|
409
|
-
custom: "custom";
|
|
410
409
|
spacing: "spacing";
|
|
411
410
|
shadow: "shadow";
|
|
411
|
+
custom: "custom";
|
|
412
412
|
}>;
|
|
413
413
|
name: import('zod').ZodString;
|
|
414
414
|
}, import('zod/v4/core').$strip>], "type">>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { McpUiResourceCsp } from '@modelcontextprotocol/ext-apps';
|
|
2
|
+
/** A `ui://` page the host renders in a sandboxed iframe, linked from a tool through `_meta.ui.resourceUri`. */
|
|
3
|
+
export interface McpApp {
|
|
4
|
+
uri: string;
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
title: string;
|
|
8
|
+
/** Absolute path to the view: the app's browser entry. */
|
|
9
|
+
entry: string;
|
|
10
|
+
/** Stylesheets to inline, by absolute path — lazy so a missing one only fails on read. */
|
|
11
|
+
styles?: () => string[];
|
|
12
|
+
csp?: McpUiResourceCsp;
|
|
13
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { PluginSource } from '@plitzi/sdk-shared';
|
|
2
|
+
/** The file a plugin source needs on disk, or null when nothing local is involved — a remote URL (fetched and
|
|
3
|
+
* cached at request time) or a component handed in directly. */
|
|
4
|
+
export declare const localSourcePath: (source: PluginSource) => string | null;
|
|
5
|
+
/** Fail at boot on a plugin whose entry file is missing. A plugin entry is a plain string path in the server
|
|
6
|
+
* config, so nothing — not tsc, not eslint — notices when that file is moved or deleted; without this check the
|
|
7
|
+
* server starts happily and only dies on the first render that needs the plugin, with an esbuild resolve error
|
|
8
|
+
* far from its cause. */
|
|
9
|
+
export declare const assertPluginSources: (plugins: Record<string, PluginSource>) => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plitzi/sdk-server",
|
|
3
|
-
"version": "0.32.
|
|
3
|
+
"version": "0.32.11",
|
|
4
4
|
"license": "AGPL-3.0",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -13,6 +13,11 @@
|
|
|
13
13
|
"types": "./dist/index.d.ts",
|
|
14
14
|
"import": "./dist/index.js",
|
|
15
15
|
"default": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./mcp": {
|
|
18
|
+
"types": "./dist/mcp.d.ts",
|
|
19
|
+
"import": "./dist/mcp.js",
|
|
20
|
+
"default": "./dist/mcp.js"
|
|
16
21
|
}
|
|
17
22
|
},
|
|
18
23
|
"repository": {
|
|
@@ -22,10 +27,11 @@
|
|
|
22
27
|
"type": "module",
|
|
23
28
|
"sideEffects": false,
|
|
24
29
|
"dependencies": {
|
|
30
|
+
"@modelcontextprotocol/ext-apps": "^1.7.5",
|
|
25
31
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
26
|
-
"@plitzi/plitzi-sdk": "0.32.
|
|
27
|
-
"@plitzi/sdk-schema": "0.32.
|
|
28
|
-
"@plitzi/sdk-shared": "0.32.
|
|
32
|
+
"@plitzi/plitzi-sdk": "0.32.11",
|
|
33
|
+
"@plitzi/sdk-schema": "0.32.11",
|
|
34
|
+
"@plitzi/sdk-shared": "0.32.11",
|
|
29
35
|
"ejs": "^6.0.1",
|
|
30
36
|
"esbuild": "^0.28.1",
|
|
31
37
|
"zod": "^4.4.3"
|
|
@@ -36,12 +42,14 @@
|
|
|
36
42
|
},
|
|
37
43
|
"devDependencies": {
|
|
38
44
|
"@types/ejs": "^3.1.5",
|
|
45
|
+
"@types/jsdom": "^28.0.3",
|
|
39
46
|
"@types/node": "^26.1.1",
|
|
40
47
|
"@types/react": "^19.2.17",
|
|
41
48
|
"@vitejs/plugin-react": "^6.0.4",
|
|
42
49
|
"@vitest/coverage-v8": "^4.1.10",
|
|
43
50
|
"eslint": "^9.39.5",
|
|
44
51
|
"eslint-plugin-import": "^2.32.0",
|
|
52
|
+
"jsdom": "^29.1.1",
|
|
45
53
|
"react": "^19.2.8",
|
|
46
54
|
"react-dom": "^19.2.8",
|
|
47
55
|
"tsx": "^4.23.1",
|
|
@@ -60,6 +68,7 @@
|
|
|
60
68
|
"lint": "TIMING=1 eslint ./src",
|
|
61
69
|
"typecheck": "tsc -p tsconfig.app.json --noEmit",
|
|
62
70
|
"test": "vitest run",
|
|
71
|
+
"test:e2e": "vitest run src/modules/mcp/e2e",
|
|
63
72
|
"test:coverage": "vitest run --coverage",
|
|
64
73
|
"bench": "vitest bench --run"
|
|
65
74
|
}
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
//#region src/modules/mcp/resources/renderApp.ts
|
|
2
|
-
var RENDER_APP_URI = "ui://plitzi/render.html";
|
|
3
|
-
var RENDER_APP_MIME = "text/html;profile=mcp-app";
|
|
4
|
-
var RENDER_APP_CSP = {
|
|
5
|
-
resourceDomains: [
|
|
6
|
-
"*",
|
|
7
|
-
"data:",
|
|
8
|
-
"blob:"
|
|
9
|
-
],
|
|
10
|
-
connectDomains: ["*"]
|
|
11
|
-
};
|
|
12
|
-
var RENDER_APP_META = {
|
|
13
|
-
ui: { csp: RENDER_APP_CSP },
|
|
14
|
-
"openai/widgetCSP": {
|
|
15
|
-
resource_domains: RENDER_APP_CSP.resourceDomains,
|
|
16
|
-
connect_domains: RENDER_APP_CSP.connectDomains
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
var appHtml = (sdkBase, devMode) => {
|
|
20
|
-
const js = `${sdkBase}/sdk-assets/plitzi-sdk.js`;
|
|
21
|
-
const vendor = `${sdkBase}/sdk-assets/${devMode ? "plitzi-sdk-dev-vendor.js" : "plitzi-sdk-vendor.js"}`;
|
|
22
|
-
return `<!doctype html>
|
|
23
|
-
<html lang="en">
|
|
24
|
-
<head>
|
|
25
|
-
<meta charset="utf-8" />
|
|
26
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
27
|
-
<title>Plitzi widget</title>
|
|
28
|
-
<link rel="modulepreload" href="${vendor}" crossorigin />
|
|
29
|
-
<script type="importmap">
|
|
30
|
-
{
|
|
31
|
-
"imports": {
|
|
32
|
-
"react": "${vendor}",
|
|
33
|
-
"react-dom": "${vendor}",
|
|
34
|
-
"react-dom/client": "${vendor}",
|
|
35
|
-
"react/jsx-runtime": "${vendor}",
|
|
36
|
-
"react/compiler-runtime": "${vendor}",
|
|
37
|
-
"@plitzi/plitzi-sdk": "${js}"
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
<\/script>
|
|
41
|
-
<link href="${`${sdkBase}/sdk-assets/plitzi-sdk.css`}" rel="stylesheet" />
|
|
42
|
-
<style>
|
|
43
|
-
html,
|
|
44
|
-
body {
|
|
45
|
-
margin: 0;
|
|
46
|
-
}
|
|
47
|
-
#plitzi:empty::after {
|
|
48
|
-
content: 'Rendering…';
|
|
49
|
-
display: block;
|
|
50
|
-
padding: 16px;
|
|
51
|
-
font: 14px system-ui, sans-serif;
|
|
52
|
-
color: #64748b;
|
|
53
|
-
}
|
|
54
|
-
</style>
|
|
55
|
-
</head>
|
|
56
|
-
<body>
|
|
57
|
-
<div id="plitzi" class="plitzi-root-container"></div>
|
|
58
|
-
<script type="module">
|
|
59
|
-
const send = msg => window.parent.postMessage(msg, '*');
|
|
60
|
-
const root = document.getElementById('plitzi');
|
|
61
|
-
let mounted = false;
|
|
62
|
-
|
|
63
|
-
// Replace the 'Rendering…' placeholder with an explicit failure panel — otherwise a tool that returns
|
|
64
|
-
// { rendered:false } (no offlineData) or an SDK that fails to load would leave the iframe stuck forever.
|
|
65
|
-
const showError = (title, details) => {
|
|
66
|
-
mounted = true;
|
|
67
|
-
root.textContent = '';
|
|
68
|
-
const box = document.createElement('div');
|
|
69
|
-
box.setAttribute('style', 'padding:16px;font:13px/1.5 system-ui,sans-serif;color:#b91c1c');
|
|
70
|
-
const h = document.createElement('strong');
|
|
71
|
-
h.textContent = title;
|
|
72
|
-
box.appendChild(h);
|
|
73
|
-
if (details) {
|
|
74
|
-
const pre = document.createElement('pre');
|
|
75
|
-
pre.setAttribute('style', 'margin:8px 0 0;white-space:pre-wrap;color:#7f1d1d;font-size:12px');
|
|
76
|
-
pre.textContent = details;
|
|
77
|
-
box.appendChild(pre);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
root.appendChild(box);
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
// The failed-render text is the tool's JSON summary ({ rendered:false, errors:[{path,message,hint}] }).
|
|
84
|
-
const errorText = params => {
|
|
85
|
-
const item = Array.isArray(params && params.content) ? params.content.find(c => c.type === 'text') : undefined;
|
|
86
|
-
if (!item) {
|
|
87
|
-
return '';
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
try {
|
|
91
|
-
const parsed = JSON.parse(item.text);
|
|
92
|
-
if (Array.isArray(parsed.errors)) {
|
|
93
|
-
return parsed.errors
|
|
94
|
-
.map(e => '• ' + (e.path ? e.path + ': ' : '') + e.message + (e.hint ? ' — ' + e.hint : ''))
|
|
95
|
-
.join('\\n');
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return item.text;
|
|
99
|
-
} catch {
|
|
100
|
-
return item.text;
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
const mount = async params => {
|
|
105
|
-
if (mounted) {
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const offlineData = params && params.structuredContent && params.structuredContent.offlineData;
|
|
110
|
-
if (!offlineData) {
|
|
111
|
-
showError('Render failed', errorText(params) || 'The tool returned no widget data.');
|
|
112
|
-
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
mounted = true;
|
|
117
|
-
try {
|
|
118
|
-
const { render } = await import('@plitzi/plitzi-sdk');
|
|
119
|
-
render('plitzi', { offlineData, offlineMode: true, environment: 'main', renderMode: 'raw' }, {}, false, false);
|
|
120
|
-
} catch (err) {
|
|
121
|
-
showError('SDK failed to load', String((err && err.message) || err));
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
window.addEventListener('message', event => {
|
|
126
|
-
const msg = event.data;
|
|
127
|
-
if (!msg || msg.jsonrpc !== '2.0') {
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Reply to the initialize result: the host withholds tool data until it gets our 'initialized' notification.
|
|
132
|
-
if (msg.id === 1 && 'result' in msg) {
|
|
133
|
-
send({ jsonrpc: '2.0', method: 'ui/notifications/initialized', params: {} });
|
|
134
|
-
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (msg.method === 'ui/notifications/tool-result') {
|
|
139
|
-
void mount(msg.params);
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
// Start the handshake immediately — nothing external blocks it, so the iframe is 'ready' at once.
|
|
144
|
-
send({
|
|
145
|
-
jsonrpc: '2.0',
|
|
146
|
-
id: 1,
|
|
147
|
-
method: 'ui/initialize',
|
|
148
|
-
params: {
|
|
149
|
-
protocolVersion: '2025-06-18',
|
|
150
|
-
appInfo: { name: 'Plitzi Widget', version: '1.0.0' },
|
|
151
|
-
appCapabilities: { availableDisplayModes: ['inline'] }
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
<\/script>
|
|
155
|
-
</body>
|
|
156
|
-
</html>`;
|
|
157
|
-
};
|
|
158
|
-
var appCache = /* @__PURE__ */ new Map();
|
|
159
|
-
var getAppHtml = (sdkBase, devMode) => {
|
|
160
|
-
const key = `${devMode ? "dev" : "prod"}|${sdkBase}`;
|
|
161
|
-
let html = appCache.get(key);
|
|
162
|
-
if (!html) {
|
|
163
|
-
html = appHtml(sdkBase, devMode);
|
|
164
|
-
appCache.set(key, html);
|
|
165
|
-
}
|
|
166
|
-
return html;
|
|
167
|
-
};
|
|
168
|
-
var registerRenderApp = (server, sdkBase, devMode) => {
|
|
169
|
-
const html = getAppHtml(sdkBase, devMode);
|
|
170
|
-
server.registerResource("plitzi-render-app", RENDER_APP_URI, {
|
|
171
|
-
description: "Interactive view that renders a plitzi_render widget with the Plitzi SDK (client-side).",
|
|
172
|
-
mimeType: RENDER_APP_MIME,
|
|
173
|
-
_meta: RENDER_APP_META
|
|
174
|
-
}, () => ({ contents: [{
|
|
175
|
-
uri: RENDER_APP_URI,
|
|
176
|
-
mimeType: RENDER_APP_MIME,
|
|
177
|
-
text: html,
|
|
178
|
-
_meta: RENDER_APP_META
|
|
179
|
-
}] }));
|
|
180
|
-
};
|
|
181
|
-
//#endregion
|
|
182
|
-
export { RENDER_APP_URI, registerRenderApp };
|
package/dist/server.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {}
|