@seed-ship/mcp-ui-spec 1.0.2
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 +37 -0
- package/LICENSE +21 -0
- package/README.md +68 -0
- package/dist/index.cjs +14 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas.cjs +75 -0
- package/dist/schemas.cjs.map +1 -0
- package/dist/schemas.d.ts +76 -0
- package/dist/schemas.js +75 -0
- package/dist/schemas.js.map +1 -0
- package/package.json +66 -0
- package/schemas/component-registry-v1.json +227 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# @mcp-ui/spec Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [1.0.0] - 2025-01-14
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- Initial release of `@mcp-ui/spec` package
|
|
9
|
+
- JSON Schema v7 specification for component registries
|
|
10
|
+
- Zod validation schemas with TypeScript types
|
|
11
|
+
- Comprehensive example registry with 3 components:
|
|
12
|
+
- quickchart-bar (Bar chart visualization)
|
|
13
|
+
- metric-card (KPI metric card)
|
|
14
|
+
- data-table (Tabular data display)
|
|
15
|
+
- Security constraints specification:
|
|
16
|
+
- Authentication requirements
|
|
17
|
+
- Domain whitelisting
|
|
18
|
+
- Iframe sandboxing
|
|
19
|
+
- Maximum nesting depth
|
|
20
|
+
- Performance constraints:
|
|
21
|
+
- Maximum render time limits
|
|
22
|
+
- Maximum data size limits
|
|
23
|
+
- Component versioning and deprecation support
|
|
24
|
+
- Grid positioning system (12-column layout)
|
|
25
|
+
|
|
26
|
+
### Features
|
|
27
|
+
- **JSON Schema**: Industry-standard v7 schema for validation
|
|
28
|
+
- **Zod Integration**: Runtime validation with TypeScript inference
|
|
29
|
+
- **Type Safety**: Complete TypeScript definitions
|
|
30
|
+
- **Examples**: Working examples for each component type
|
|
31
|
+
- **Extensible**: Easy to add new component types
|
|
32
|
+
- **Validation**: Built-in validation for security and performance
|
|
33
|
+
|
|
34
|
+
### Documentation
|
|
35
|
+
- Complete JSON Schema with descriptions
|
|
36
|
+
- Example registry with real-world use cases
|
|
37
|
+
- TypeScript types for all schema entities
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Gabriel Brument
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# @mcp-ui/spec
|
|
2
|
+
|
|
3
|
+
Component registry specification and JSON Schemas for MCP UI.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @mcp-ui/spec
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Import JSON Schema
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { registrySchema } from '@mcp-ui/spec/schemas'
|
|
17
|
+
import Ajv from 'ajv'
|
|
18
|
+
|
|
19
|
+
const ajv = new Ajv()
|
|
20
|
+
const validate = ajv.compile(registrySchema)
|
|
21
|
+
|
|
22
|
+
const valid = validate(myRegistry)
|
|
23
|
+
if (!valid) {
|
|
24
|
+
console.error(validate.errors)
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Import Zod Schema
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { ComponentRegistrySchema } from '@mcp-ui/spec'
|
|
32
|
+
|
|
33
|
+
const result = ComponentRegistrySchema.safeParse(myRegistry)
|
|
34
|
+
if (!result.success) {
|
|
35
|
+
console.error(result.error)
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Registry Format
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"version": "1.0.0",
|
|
44
|
+
"components": [
|
|
45
|
+
{
|
|
46
|
+
"id": "quickchart-bar",
|
|
47
|
+
"type": "chart",
|
|
48
|
+
"name": "Bar Chart",
|
|
49
|
+
"description": "Renders a bar chart",
|
|
50
|
+
"schema": { /* JSON Schema */ },
|
|
51
|
+
"examples": [ /* Working examples */ ],
|
|
52
|
+
"security": {
|
|
53
|
+
"requiresAuth": true,
|
|
54
|
+
"allowedDomains": ["quickchart.io"]
|
|
55
|
+
},
|
|
56
|
+
"tags": ["chart", "visualization"]
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Documentation
|
|
63
|
+
|
|
64
|
+
See the [full documentation](../../docs/features/generative-ui/) for more details.
|
|
65
|
+
|
|
66
|
+
## License
|
|
67
|
+
|
|
68
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const schemas = require("./schemas.cjs");
|
|
4
|
+
exports.ComponentExampleSchema = schemas.ComponentExampleSchema;
|
|
5
|
+
exports.ComponentRegistrySchema = schemas.ComponentRegistrySchema;
|
|
6
|
+
exports.ComponentSchema = schemas.ComponentSchema;
|
|
7
|
+
exports.ComponentSchemaSchema = schemas.ComponentSchemaSchema;
|
|
8
|
+
exports.ComponentTypeSchema = schemas.ComponentTypeSchema;
|
|
9
|
+
exports.GridPositionSchema = schemas.GridPositionSchema;
|
|
10
|
+
exports.PerformanceConstraintsSchema = schemas.PerformanceConstraintsSchema;
|
|
11
|
+
exports.RegistryMetadataSchema = schemas.RegistryMetadataSchema;
|
|
12
|
+
exports.SandboxFlagSchema = schemas.SandboxFlagSchema;
|
|
13
|
+
exports.SecurityConstraintsSchema = schemas.SecurityConstraintsSchema;
|
|
14
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './schemas';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ComponentExampleSchema, ComponentRegistrySchema, ComponentSchema, ComponentSchemaSchema, ComponentTypeSchema, GridPositionSchema, PerformanceConstraintsSchema, RegistryMetadataSchema, SandboxFlagSchema, SecurityConstraintsSchema } from "./schemas.js";
|
|
2
|
+
export {
|
|
3
|
+
ComponentExampleSchema,
|
|
4
|
+
ComponentRegistrySchema,
|
|
5
|
+
ComponentSchema,
|
|
6
|
+
ComponentSchemaSchema,
|
|
7
|
+
ComponentTypeSchema,
|
|
8
|
+
GridPositionSchema,
|
|
9
|
+
PerformanceConstraintsSchema,
|
|
10
|
+
RegistryMetadataSchema,
|
|
11
|
+
SandboxFlagSchema,
|
|
12
|
+
SecurityConstraintsSchema
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
package/dist/schemas.cjs
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const zod = require("zod");
|
|
4
|
+
const GridPositionSchema = zod.z.object({
|
|
5
|
+
colStart: zod.z.number().int().min(1).max(12),
|
|
6
|
+
colSpan: zod.z.number().int().min(1).max(12),
|
|
7
|
+
rowStart: zod.z.number().int().min(1).optional(),
|
|
8
|
+
rowSpan: zod.z.number().int().min(1).default(1).optional()
|
|
9
|
+
});
|
|
10
|
+
const ComponentTypeSchema = zod.z.enum(["chart", "table", "metric", "text", "composite"]);
|
|
11
|
+
const SandboxFlagSchema = zod.z.enum([
|
|
12
|
+
"allow-scripts",
|
|
13
|
+
"allow-same-origin",
|
|
14
|
+
"allow-forms",
|
|
15
|
+
"allow-popups",
|
|
16
|
+
"allow-modals"
|
|
17
|
+
]);
|
|
18
|
+
const SecurityConstraintsSchema = zod.z.object({
|
|
19
|
+
requiresAuth: zod.z.boolean().default(false).optional(),
|
|
20
|
+
allowedDomains: zod.z.array(zod.z.string()).optional(),
|
|
21
|
+
maxIframeDepth: zod.z.number().int().min(0).max(3).default(1).optional(),
|
|
22
|
+
sandboxFlags: zod.z.array(SandboxFlagSchema).optional()
|
|
23
|
+
});
|
|
24
|
+
const PerformanceConstraintsSchema = zod.z.object({
|
|
25
|
+
maxRenderTime: zod.z.number().int().min(100).default(5e3).optional(),
|
|
26
|
+
maxDataSize: zod.z.number().int().min(1024).default(102400).optional()
|
|
27
|
+
});
|
|
28
|
+
const ComponentSchemaSchema = zod.z.object({
|
|
29
|
+
type: zod.z.literal("object"),
|
|
30
|
+
required: zod.z.array(zod.z.string()).optional(),
|
|
31
|
+
properties: zod.z.record(zod.z.unknown()),
|
|
32
|
+
additionalProperties: zod.z.boolean().optional()
|
|
33
|
+
});
|
|
34
|
+
const ComponentExampleSchema = zod.z.object({
|
|
35
|
+
name: zod.z.string().min(1),
|
|
36
|
+
description: zod.z.string().optional(),
|
|
37
|
+
params: zod.z.record(zod.z.unknown()),
|
|
38
|
+
position: GridPositionSchema.optional()
|
|
39
|
+
});
|
|
40
|
+
const ComponentSchema = zod.z.object({
|
|
41
|
+
id: zod.z.string().regex(/^[a-z0-9-]+$/),
|
|
42
|
+
type: ComponentTypeSchema,
|
|
43
|
+
name: zod.z.string().min(1),
|
|
44
|
+
description: zod.z.string().optional(),
|
|
45
|
+
schema: ComponentSchemaSchema,
|
|
46
|
+
examples: zod.z.array(ComponentExampleSchema).min(1),
|
|
47
|
+
security: SecurityConstraintsSchema.optional(),
|
|
48
|
+
performance: PerformanceConstraintsSchema.optional(),
|
|
49
|
+
tags: zod.z.array(zod.z.string().regex(/^[a-z0-9-]+$/)).optional(),
|
|
50
|
+
version: zod.z.string().regex(/^\d+\.\d+\.\d+$/).optional(),
|
|
51
|
+
deprecated: zod.z.boolean().default(false).optional(),
|
|
52
|
+
deprecationMessage: zod.z.string().optional()
|
|
53
|
+
});
|
|
54
|
+
const RegistryMetadataSchema = zod.z.object({
|
|
55
|
+
name: zod.z.string().optional(),
|
|
56
|
+
description: zod.z.string().optional(),
|
|
57
|
+
author: zod.z.string().optional(),
|
|
58
|
+
repository: zod.z.string().url().optional()
|
|
59
|
+
});
|
|
60
|
+
const ComponentRegistrySchema = zod.z.object({
|
|
61
|
+
version: zod.z.literal("1.0.0"),
|
|
62
|
+
metadata: RegistryMetadataSchema.optional(),
|
|
63
|
+
components: zod.z.array(ComponentSchema).min(1)
|
|
64
|
+
});
|
|
65
|
+
exports.ComponentExampleSchema = ComponentExampleSchema;
|
|
66
|
+
exports.ComponentRegistrySchema = ComponentRegistrySchema;
|
|
67
|
+
exports.ComponentSchema = ComponentSchema;
|
|
68
|
+
exports.ComponentSchemaSchema = ComponentSchemaSchema;
|
|
69
|
+
exports.ComponentTypeSchema = ComponentTypeSchema;
|
|
70
|
+
exports.GridPositionSchema = GridPositionSchema;
|
|
71
|
+
exports.PerformanceConstraintsSchema = PerformanceConstraintsSchema;
|
|
72
|
+
exports.RegistryMetadataSchema = RegistryMetadataSchema;
|
|
73
|
+
exports.SandboxFlagSchema = SandboxFlagSchema;
|
|
74
|
+
exports.SecurityConstraintsSchema = SecurityConstraintsSchema;
|
|
75
|
+
//# sourceMappingURL=schemas.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.cjs","sources":["../src/schemas/index.ts"],"sourcesContent":["/**\n * Zod validation schemas for component registry\n */\n\nimport { z } from 'zod'\n\n// Grid position schema\nexport const GridPositionSchema = z.object({\n colStart: z.number().int().min(1).max(12),\n colSpan: z.number().int().min(1).max(12),\n rowStart: z.number().int().min(1).optional(),\n rowSpan: z.number().int().min(1).default(1).optional(),\n})\n\n// Component types\nexport const ComponentTypeSchema = z.enum(['chart', 'table', 'metric', 'text', 'composite'])\n\n// Sandbox flags\nexport const SandboxFlagSchema = z.enum([\n 'allow-scripts',\n 'allow-same-origin',\n 'allow-forms',\n 'allow-popups',\n 'allow-modals',\n])\n\n// Security constraints\nexport const SecurityConstraintsSchema = z.object({\n requiresAuth: z.boolean().default(false).optional(),\n allowedDomains: z.array(z.string()).optional(),\n maxIframeDepth: z.number().int().min(0).max(3).default(1).optional(),\n sandboxFlags: z.array(SandboxFlagSchema).optional(),\n})\n\n// Performance constraints\nexport const PerformanceConstraintsSchema = z.object({\n maxRenderTime: z.number().int().min(100).default(5000).optional(),\n maxDataSize: z.number().int().min(1024).default(102400).optional(),\n})\n\n// Component schema (JSON Schema definition)\nexport const ComponentSchemaSchema = z.object({\n type: z.literal('object'),\n required: z.array(z.string()).optional(),\n properties: z.record(z.unknown()),\n additionalProperties: z.boolean().optional(),\n})\n\n// Component example\nexport const ComponentExampleSchema = z.object({\n name: z.string().min(1),\n description: z.string().optional(),\n params: z.record(z.unknown()),\n position: GridPositionSchema.optional(),\n})\n\n// Component definition\nexport const ComponentSchema = z.object({\n id: z.string().regex(/^[a-z0-9-]+$/),\n type: ComponentTypeSchema,\n name: z.string().min(1),\n description: z.string().optional(),\n schema: ComponentSchemaSchema,\n examples: z.array(ComponentExampleSchema).min(1),\n security: SecurityConstraintsSchema.optional(),\n performance: PerformanceConstraintsSchema.optional(),\n tags: z.array(z.string().regex(/^[a-z0-9-]+$/)).optional(),\n version: z\n .string()\n .regex(/^\\d+\\.\\d+\\.\\d+$/)\n .optional(),\n deprecated: z.boolean().default(false).optional(),\n deprecationMessage: z.string().optional(),\n})\n\n// Registry metadata\nexport const RegistryMetadataSchema = z.object({\n name: z.string().optional(),\n description: z.string().optional(),\n author: z.string().optional(),\n repository: z.string().url().optional(),\n})\n\n// Component registry\nexport const ComponentRegistrySchema = z.object({\n version: z.literal('1.0.0'),\n metadata: RegistryMetadataSchema.optional(),\n components: z.array(ComponentSchema).min(1),\n})\n\n// Export types inferred from schemas\nexport type ComponentRegistry = z.infer<typeof ComponentRegistrySchema>\nexport type Component = z.infer<typeof ComponentSchema>\nexport type ComponentExample = z.infer<typeof ComponentExampleSchema>\nexport type GridPosition = z.infer<typeof GridPositionSchema>\nexport type SecurityConstraints = z.infer<typeof SecurityConstraintsSchema>\nexport type PerformanceConstraints = z.infer<typeof PerformanceConstraintsSchema>\nexport type ComponentType = z.infer<typeof ComponentTypeSchema>\nexport type SandboxFlag = z.infer<typeof SandboxFlagSchema>\n"],"names":["z"],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
export declare const GridPositionSchema: z.ZodObject<{
|
|
4
|
+
colStart: z.ZodNumber;
|
|
5
|
+
colSpan: z.ZodNumber;
|
|
6
|
+
rowStart: z.ZodOptional<z.ZodNumber>;
|
|
7
|
+
rowSpan: z.ZodOptional<z.ZodNumber>;
|
|
8
|
+
}>;
|
|
9
|
+
|
|
10
|
+
export declare const ComponentTypeSchema: z.ZodEnum<['chart', 'table', 'metric', 'text', 'composite']>;
|
|
11
|
+
export declare const SandboxFlagSchema: z.ZodEnum<['allow-scripts', 'allow-same-origin', 'allow-forms', 'allow-popups', 'allow-modals']>;
|
|
12
|
+
|
|
13
|
+
export declare const SecurityConstraintsSchema: z.ZodObject<{
|
|
14
|
+
requiresAuth: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
15
|
+
allowedDomains: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
16
|
+
maxIframeDepth: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
17
|
+
sandboxFlags: z.ZodOptional<z.ZodArray<typeof SandboxFlagSchema>>;
|
|
18
|
+
}>;
|
|
19
|
+
|
|
20
|
+
export declare const PerformanceConstraintsSchema: z.ZodObject<{
|
|
21
|
+
maxRenderTime: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
22
|
+
maxDataSize: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
23
|
+
}>;
|
|
24
|
+
|
|
25
|
+
export declare const ComponentSchemaSchema: z.ZodObject<{
|
|
26
|
+
type: z.ZodLiteral<'object'>;
|
|
27
|
+
required: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
28
|
+
properties: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
29
|
+
additionalProperties: z.ZodOptional<z.ZodBoolean>;
|
|
30
|
+
}>;
|
|
31
|
+
|
|
32
|
+
export declare const ComponentExampleSchema: z.ZodObject<{
|
|
33
|
+
name: z.ZodString;
|
|
34
|
+
description: z.ZodOptional<z.ZodString>;
|
|
35
|
+
params: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
36
|
+
position: z.ZodOptional<typeof GridPositionSchema>;
|
|
37
|
+
}>;
|
|
38
|
+
|
|
39
|
+
export declare const ComponentSchema: z.ZodObject<{
|
|
40
|
+
id: z.ZodString;
|
|
41
|
+
type: typeof ComponentTypeSchema;
|
|
42
|
+
name: z.ZodString;
|
|
43
|
+
description: z.ZodOptional<z.ZodString>;
|
|
44
|
+
schema: typeof ComponentSchemaSchema;
|
|
45
|
+
examples: z.ZodArray<typeof ComponentExampleSchema>;
|
|
46
|
+
security: z.ZodOptional<typeof SecurityConstraintsSchema>;
|
|
47
|
+
performance: z.ZodOptional<typeof PerformanceConstraintsSchema>;
|
|
48
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
49
|
+
version: z.ZodOptional<z.ZodString>;
|
|
50
|
+
deprecated: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
51
|
+
deprecationMessage: z.ZodOptional<z.ZodString>;
|
|
52
|
+
}>;
|
|
53
|
+
|
|
54
|
+
export declare const RegistryMetadataSchema: z.ZodObject<{
|
|
55
|
+
name: z.ZodOptional<z.ZodString>;
|
|
56
|
+
description: z.ZodOptional<z.ZodString>;
|
|
57
|
+
author: z.ZodOptional<z.ZodString>;
|
|
58
|
+
repository: z.ZodOptional<z.ZodString>;
|
|
59
|
+
}>;
|
|
60
|
+
|
|
61
|
+
export declare const ComponentRegistrySchema: z.ZodObject<{
|
|
62
|
+
version: z.ZodLiteral<'1.0.0'>;
|
|
63
|
+
metadata: z.ZodOptional<typeof RegistryMetadataSchema>;
|
|
64
|
+
components: z.ZodArray<typeof ComponentSchema>;
|
|
65
|
+
}>;
|
|
66
|
+
|
|
67
|
+
export type ComponentRegistry = z.infer<typeof ComponentRegistrySchema>;
|
|
68
|
+
export type Component = z.infer<typeof ComponentSchema>;
|
|
69
|
+
export type ComponentExample = z.infer<typeof ComponentExampleSchema>;
|
|
70
|
+
export type ComponentSchema = z.infer<typeof ComponentSchemaSchema>;
|
|
71
|
+
export type GridPosition = z.infer<typeof GridPositionSchema>;
|
|
72
|
+
export type SecurityConstraints = z.infer<typeof SecurityConstraintsSchema>;
|
|
73
|
+
export type PerformanceConstraints = z.infer<typeof PerformanceConstraintsSchema>;
|
|
74
|
+
export type ComponentType = z.infer<typeof ComponentTypeSchema>;
|
|
75
|
+
export type SandboxFlag = z.infer<typeof SandboxFlagSchema>;
|
|
76
|
+
export type RegistryMetadata = z.infer<typeof RegistryMetadataSchema>;
|
package/dist/schemas.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const GridPositionSchema = z.object({
|
|
3
|
+
colStart: z.number().int().min(1).max(12),
|
|
4
|
+
colSpan: z.number().int().min(1).max(12),
|
|
5
|
+
rowStart: z.number().int().min(1).optional(),
|
|
6
|
+
rowSpan: z.number().int().min(1).default(1).optional()
|
|
7
|
+
});
|
|
8
|
+
const ComponentTypeSchema = z.enum(["chart", "table", "metric", "text", "composite"]);
|
|
9
|
+
const SandboxFlagSchema = z.enum([
|
|
10
|
+
"allow-scripts",
|
|
11
|
+
"allow-same-origin",
|
|
12
|
+
"allow-forms",
|
|
13
|
+
"allow-popups",
|
|
14
|
+
"allow-modals"
|
|
15
|
+
]);
|
|
16
|
+
const SecurityConstraintsSchema = z.object({
|
|
17
|
+
requiresAuth: z.boolean().default(false).optional(),
|
|
18
|
+
allowedDomains: z.array(z.string()).optional(),
|
|
19
|
+
maxIframeDepth: z.number().int().min(0).max(3).default(1).optional(),
|
|
20
|
+
sandboxFlags: z.array(SandboxFlagSchema).optional()
|
|
21
|
+
});
|
|
22
|
+
const PerformanceConstraintsSchema = z.object({
|
|
23
|
+
maxRenderTime: z.number().int().min(100).default(5e3).optional(),
|
|
24
|
+
maxDataSize: z.number().int().min(1024).default(102400).optional()
|
|
25
|
+
});
|
|
26
|
+
const ComponentSchemaSchema = z.object({
|
|
27
|
+
type: z.literal("object"),
|
|
28
|
+
required: z.array(z.string()).optional(),
|
|
29
|
+
properties: z.record(z.unknown()),
|
|
30
|
+
additionalProperties: z.boolean().optional()
|
|
31
|
+
});
|
|
32
|
+
const ComponentExampleSchema = z.object({
|
|
33
|
+
name: z.string().min(1),
|
|
34
|
+
description: z.string().optional(),
|
|
35
|
+
params: z.record(z.unknown()),
|
|
36
|
+
position: GridPositionSchema.optional()
|
|
37
|
+
});
|
|
38
|
+
const ComponentSchema = z.object({
|
|
39
|
+
id: z.string().regex(/^[a-z0-9-]+$/),
|
|
40
|
+
type: ComponentTypeSchema,
|
|
41
|
+
name: z.string().min(1),
|
|
42
|
+
description: z.string().optional(),
|
|
43
|
+
schema: ComponentSchemaSchema,
|
|
44
|
+
examples: z.array(ComponentExampleSchema).min(1),
|
|
45
|
+
security: SecurityConstraintsSchema.optional(),
|
|
46
|
+
performance: PerformanceConstraintsSchema.optional(),
|
|
47
|
+
tags: z.array(z.string().regex(/^[a-z0-9-]+$/)).optional(),
|
|
48
|
+
version: z.string().regex(/^\d+\.\d+\.\d+$/).optional(),
|
|
49
|
+
deprecated: z.boolean().default(false).optional(),
|
|
50
|
+
deprecationMessage: z.string().optional()
|
|
51
|
+
});
|
|
52
|
+
const RegistryMetadataSchema = z.object({
|
|
53
|
+
name: z.string().optional(),
|
|
54
|
+
description: z.string().optional(),
|
|
55
|
+
author: z.string().optional(),
|
|
56
|
+
repository: z.string().url().optional()
|
|
57
|
+
});
|
|
58
|
+
const ComponentRegistrySchema = z.object({
|
|
59
|
+
version: z.literal("1.0.0"),
|
|
60
|
+
metadata: RegistryMetadataSchema.optional(),
|
|
61
|
+
components: z.array(ComponentSchema).min(1)
|
|
62
|
+
});
|
|
63
|
+
export {
|
|
64
|
+
ComponentExampleSchema,
|
|
65
|
+
ComponentRegistrySchema,
|
|
66
|
+
ComponentSchema,
|
|
67
|
+
ComponentSchemaSchema,
|
|
68
|
+
ComponentTypeSchema,
|
|
69
|
+
GridPositionSchema,
|
|
70
|
+
PerformanceConstraintsSchema,
|
|
71
|
+
RegistryMetadataSchema,
|
|
72
|
+
SandboxFlagSchema,
|
|
73
|
+
SecurityConstraintsSchema
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sources":["../src/schemas/index.ts"],"sourcesContent":["/**\n * Zod validation schemas for component registry\n */\n\nimport { z } from 'zod'\n\n// Grid position schema\nexport const GridPositionSchema = z.object({\n colStart: z.number().int().min(1).max(12),\n colSpan: z.number().int().min(1).max(12),\n rowStart: z.number().int().min(1).optional(),\n rowSpan: z.number().int().min(1).default(1).optional(),\n})\n\n// Component types\nexport const ComponentTypeSchema = z.enum(['chart', 'table', 'metric', 'text', 'composite'])\n\n// Sandbox flags\nexport const SandboxFlagSchema = z.enum([\n 'allow-scripts',\n 'allow-same-origin',\n 'allow-forms',\n 'allow-popups',\n 'allow-modals',\n])\n\n// Security constraints\nexport const SecurityConstraintsSchema = z.object({\n requiresAuth: z.boolean().default(false).optional(),\n allowedDomains: z.array(z.string()).optional(),\n maxIframeDepth: z.number().int().min(0).max(3).default(1).optional(),\n sandboxFlags: z.array(SandboxFlagSchema).optional(),\n})\n\n// Performance constraints\nexport const PerformanceConstraintsSchema = z.object({\n maxRenderTime: z.number().int().min(100).default(5000).optional(),\n maxDataSize: z.number().int().min(1024).default(102400).optional(),\n})\n\n// Component schema (JSON Schema definition)\nexport const ComponentSchemaSchema = z.object({\n type: z.literal('object'),\n required: z.array(z.string()).optional(),\n properties: z.record(z.unknown()),\n additionalProperties: z.boolean().optional(),\n})\n\n// Component example\nexport const ComponentExampleSchema = z.object({\n name: z.string().min(1),\n description: z.string().optional(),\n params: z.record(z.unknown()),\n position: GridPositionSchema.optional(),\n})\n\n// Component definition\nexport const ComponentSchema = z.object({\n id: z.string().regex(/^[a-z0-9-]+$/),\n type: ComponentTypeSchema,\n name: z.string().min(1),\n description: z.string().optional(),\n schema: ComponentSchemaSchema,\n examples: z.array(ComponentExampleSchema).min(1),\n security: SecurityConstraintsSchema.optional(),\n performance: PerformanceConstraintsSchema.optional(),\n tags: z.array(z.string().regex(/^[a-z0-9-]+$/)).optional(),\n version: z\n .string()\n .regex(/^\\d+\\.\\d+\\.\\d+$/)\n .optional(),\n deprecated: z.boolean().default(false).optional(),\n deprecationMessage: z.string().optional(),\n})\n\n// Registry metadata\nexport const RegistryMetadataSchema = z.object({\n name: z.string().optional(),\n description: z.string().optional(),\n author: z.string().optional(),\n repository: z.string().url().optional(),\n})\n\n// Component registry\nexport const ComponentRegistrySchema = z.object({\n version: z.literal('1.0.0'),\n metadata: RegistryMetadataSchema.optional(),\n components: z.array(ComponentSchema).min(1),\n})\n\n// Export types inferred from schemas\nexport type ComponentRegistry = z.infer<typeof ComponentRegistrySchema>\nexport type Component = z.infer<typeof ComponentSchema>\nexport type ComponentExample = z.infer<typeof ComponentExampleSchema>\nexport type GridPosition = z.infer<typeof GridPositionSchema>\nexport type SecurityConstraints = z.infer<typeof SecurityConstraintsSchema>\nexport type PerformanceConstraints = z.infer<typeof PerformanceConstraintsSchema>\nexport type ComponentType = z.infer<typeof ComponentTypeSchema>\nexport type SandboxFlag = z.infer<typeof SandboxFlagSchema>\n"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@seed-ship/mcp-ui-spec",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Component registry specification and JSON Schemas for MCP UI",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.cjs",
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
|
+
},
|
|
15
|
+
"./schemas": {
|
|
16
|
+
"import": "./dist/schemas/index.js",
|
|
17
|
+
"require": "./dist/schemas/index.cjs",
|
|
18
|
+
"types": "./dist/schemas/index.d.ts"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"schemas",
|
|
24
|
+
"README.md",
|
|
25
|
+
"CHANGELOG.md"
|
|
26
|
+
],
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"zod": "^3.22.4"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^20.10.0",
|
|
32
|
+
"@typescript-eslint/eslint-plugin": "^6.15.0",
|
|
33
|
+
"@typescript-eslint/parser": "^6.15.0",
|
|
34
|
+
"eslint": "^8.56.0",
|
|
35
|
+
"typescript": "^5.3.3",
|
|
36
|
+
"vite": "^5.0.10",
|
|
37
|
+
"vitest": "^1.1.0"
|
|
38
|
+
},
|
|
39
|
+
"keywords": [
|
|
40
|
+
"mcp",
|
|
41
|
+
"ui",
|
|
42
|
+
"specification",
|
|
43
|
+
"json-schema",
|
|
44
|
+
"component-registry"
|
|
45
|
+
],
|
|
46
|
+
"author": "Gabriel Brument",
|
|
47
|
+
"license": "MIT",
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "https://github.com/theseedship/mcp-ui.git",
|
|
51
|
+
"directory": "mcp-ui-spec"
|
|
52
|
+
},
|
|
53
|
+
"homepage": "https://github.com/theseedship/mcp-ui#readme",
|
|
54
|
+
"bugs": {
|
|
55
|
+
"url": "https://github.com/theseedship/mcp-ui/issues"
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "vite build && node ./scripts/generate-dts.js",
|
|
59
|
+
"dev": "vite build --watch",
|
|
60
|
+
"test": "vitest run",
|
|
61
|
+
"test:watch": "vitest",
|
|
62
|
+
"lint": "eslint src",
|
|
63
|
+
"typecheck": "tsc --noEmit",
|
|
64
|
+
"clean": "rm -rf dist"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://mcp-ui.dev/schemas/component-registry-v1.json",
|
|
4
|
+
"title": "MCP UI Component Registry",
|
|
5
|
+
"description": "Schema for defining UI components that can be rendered by MCP UI renderers",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["version", "components"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"version": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"const": "1.0.0",
|
|
12
|
+
"description": "Schema version (semver)"
|
|
13
|
+
},
|
|
14
|
+
"metadata": {
|
|
15
|
+
"type": "object",
|
|
16
|
+
"description": "Optional registry metadata",
|
|
17
|
+
"properties": {
|
|
18
|
+
"name": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"description": "Registry name"
|
|
21
|
+
},
|
|
22
|
+
"description": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"description": "Registry description"
|
|
25
|
+
},
|
|
26
|
+
"author": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"description": "Registry author"
|
|
29
|
+
},
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"format": "uri",
|
|
33
|
+
"description": "Repository URL"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"components": {
|
|
38
|
+
"type": "array",
|
|
39
|
+
"description": "Array of component definitions",
|
|
40
|
+
"items": {
|
|
41
|
+
"$ref": "#/definitions/Component"
|
|
42
|
+
},
|
|
43
|
+
"minItems": 1
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"definitions": {
|
|
47
|
+
"Component": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"required": ["id", "type", "name", "schema", "examples"],
|
|
50
|
+
"properties": {
|
|
51
|
+
"id": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"pattern": "^[a-z0-9-]+$",
|
|
54
|
+
"description": "Unique component identifier (kebab-case)",
|
|
55
|
+
"examples": ["quickchart-bar", "metric-card", "data-table"]
|
|
56
|
+
},
|
|
57
|
+
"type": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"enum": ["chart", "table", "metric", "text", "composite"],
|
|
60
|
+
"description": "Component category"
|
|
61
|
+
},
|
|
62
|
+
"name": {
|
|
63
|
+
"type": "string",
|
|
64
|
+
"description": "Human-readable component name",
|
|
65
|
+
"minLength": 1
|
|
66
|
+
},
|
|
67
|
+
"description": {
|
|
68
|
+
"type": "string",
|
|
69
|
+
"description": "Component description for documentation"
|
|
70
|
+
},
|
|
71
|
+
"schema": {
|
|
72
|
+
"type": "object",
|
|
73
|
+
"description": "JSON Schema for component params validation",
|
|
74
|
+
"required": ["type", "properties"],
|
|
75
|
+
"properties": {
|
|
76
|
+
"type": {
|
|
77
|
+
"const": "object"
|
|
78
|
+
},
|
|
79
|
+
"required": {
|
|
80
|
+
"type": "array",
|
|
81
|
+
"items": {
|
|
82
|
+
"type": "string"
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"properties": {
|
|
86
|
+
"type": "object",
|
|
87
|
+
"additionalProperties": true
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"examples": {
|
|
92
|
+
"type": "array",
|
|
93
|
+
"description": "Working examples for testing and documentation",
|
|
94
|
+
"items": {
|
|
95
|
+
"$ref": "#/definitions/Example"
|
|
96
|
+
},
|
|
97
|
+
"minItems": 1
|
|
98
|
+
},
|
|
99
|
+
"security": {
|
|
100
|
+
"type": "object",
|
|
101
|
+
"description": "Security constraints for the component",
|
|
102
|
+
"properties": {
|
|
103
|
+
"requiresAuth": {
|
|
104
|
+
"type": "boolean",
|
|
105
|
+
"default": false,
|
|
106
|
+
"description": "Whether component requires authentication"
|
|
107
|
+
},
|
|
108
|
+
"allowedDomains": {
|
|
109
|
+
"type": "array",
|
|
110
|
+
"items": {
|
|
111
|
+
"type": "string",
|
|
112
|
+
"format": "hostname"
|
|
113
|
+
},
|
|
114
|
+
"description": "Whitelisted domains for external resources"
|
|
115
|
+
},
|
|
116
|
+
"maxIframeDepth": {
|
|
117
|
+
"type": "integer",
|
|
118
|
+
"minimum": 0,
|
|
119
|
+
"maximum": 3,
|
|
120
|
+
"default": 1,
|
|
121
|
+
"description": "Maximum iframe nesting depth"
|
|
122
|
+
},
|
|
123
|
+
"sandboxFlags": {
|
|
124
|
+
"type": "array",
|
|
125
|
+
"items": {
|
|
126
|
+
"type": "string",
|
|
127
|
+
"enum": [
|
|
128
|
+
"allow-scripts",
|
|
129
|
+
"allow-same-origin",
|
|
130
|
+
"allow-forms",
|
|
131
|
+
"allow-popups",
|
|
132
|
+
"allow-modals"
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
"description": "Iframe sandbox flags"
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
"performance": {
|
|
140
|
+
"type": "object",
|
|
141
|
+
"description": "Performance constraints",
|
|
142
|
+
"properties": {
|
|
143
|
+
"maxRenderTime": {
|
|
144
|
+
"type": "integer",
|
|
145
|
+
"minimum": 100,
|
|
146
|
+
"default": 5000,
|
|
147
|
+
"description": "Maximum render time in milliseconds"
|
|
148
|
+
},
|
|
149
|
+
"maxDataSize": {
|
|
150
|
+
"type": "integer",
|
|
151
|
+
"minimum": 1024,
|
|
152
|
+
"default": 102400,
|
|
153
|
+
"description": "Maximum data size in bytes (100KB default)"
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
"tags": {
|
|
158
|
+
"type": "array",
|
|
159
|
+
"items": {
|
|
160
|
+
"type": "string",
|
|
161
|
+
"pattern": "^[a-z0-9-]+$"
|
|
162
|
+
},
|
|
163
|
+
"description": "Tags for categorization and search"
|
|
164
|
+
},
|
|
165
|
+
"version": {
|
|
166
|
+
"type": "string",
|
|
167
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+$",
|
|
168
|
+
"description": "Component version (semver)"
|
|
169
|
+
},
|
|
170
|
+
"deprecated": {
|
|
171
|
+
"type": "boolean",
|
|
172
|
+
"default": false,
|
|
173
|
+
"description": "Whether component is deprecated"
|
|
174
|
+
},
|
|
175
|
+
"deprecationMessage": {
|
|
176
|
+
"type": "string",
|
|
177
|
+
"description": "Deprecation message and migration guide"
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
"Example": {
|
|
182
|
+
"type": "object",
|
|
183
|
+
"required": ["name", "params"],
|
|
184
|
+
"properties": {
|
|
185
|
+
"name": {
|
|
186
|
+
"type": "string",
|
|
187
|
+
"description": "Example name",
|
|
188
|
+
"minLength": 1
|
|
189
|
+
},
|
|
190
|
+
"description": {
|
|
191
|
+
"type": "string",
|
|
192
|
+
"description": "Example description"
|
|
193
|
+
},
|
|
194
|
+
"params": {
|
|
195
|
+
"type": "object",
|
|
196
|
+
"description": "Component params for this example"
|
|
197
|
+
},
|
|
198
|
+
"position": {
|
|
199
|
+
"type": "object",
|
|
200
|
+
"description": "Optional grid position for example",
|
|
201
|
+
"properties": {
|
|
202
|
+
"colStart": {
|
|
203
|
+
"type": "integer",
|
|
204
|
+
"minimum": 1,
|
|
205
|
+
"maximum": 12
|
|
206
|
+
},
|
|
207
|
+
"colSpan": {
|
|
208
|
+
"type": "integer",
|
|
209
|
+
"minimum": 1,
|
|
210
|
+
"maximum": 12
|
|
211
|
+
},
|
|
212
|
+
"rowStart": {
|
|
213
|
+
"type": "integer",
|
|
214
|
+
"minimum": 1
|
|
215
|
+
},
|
|
216
|
+
"rowSpan": {
|
|
217
|
+
"type": "integer",
|
|
218
|
+
"minimum": 1,
|
|
219
|
+
"default": 1
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
"required": ["colStart", "colSpan"]
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|