@iyulab/u-widgets-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,166 @@
1
+ # @iyulab/u-widgets-mcp
2
+
3
+ MCP (Model Context Protocol) server for the [u-widgets](https://github.com/iyulab/u-widgets) declarative widget system.
4
+
5
+ Exposes u-widgets' developer tools as MCP tools, enabling AI assistants to create, validate, and suggest data-driven widget specs.
6
+
7
+ ## Tools
8
+
9
+ | Tool | Description |
10
+ |------|-------------|
11
+ | `help` | List available widget types. Filter by name or category. |
12
+ | `template` | Generate a minimal, valid widget spec with sample data. |
13
+ | `validate` | Check a widget spec for errors and warnings. |
14
+ | `suggest_mapping` | Analyze data and suggest the best widget type + mapping. |
15
+ | `auto_spec` | Generate a complete spec from raw data (one-call convenience). |
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install -g @iyulab/u-widgets-mcp
21
+ ```
22
+
23
+ Or run directly with npx:
24
+
25
+ ```bash
26
+ npx @iyulab/u-widgets-mcp
27
+ ```
28
+
29
+ ## Configuration
30
+
31
+ ### Claude Desktop
32
+
33
+ Add to your `claude_desktop_config.json`:
34
+
35
+ ```json
36
+ {
37
+ "mcpServers": {
38
+ "u-widgets": {
39
+ "command": "npx",
40
+ "args": ["-y", "@iyulab/u-widgets-mcp"]
41
+ }
42
+ }
43
+ }
44
+ ```
45
+
46
+ ### Claude Code
47
+
48
+ Add to your `.claude/settings.json` or project `.mcp.json`:
49
+
50
+ ```json
51
+ {
52
+ "mcpServers": {
53
+ "u-widgets": {
54
+ "command": "npx",
55
+ "args": ["-y", "@iyulab/u-widgets-mcp"]
56
+ }
57
+ }
58
+ }
59
+ ```
60
+
61
+ ### VS Code (Copilot)
62
+
63
+ Add to `.vscode/mcp.json`:
64
+
65
+ ```json
66
+ {
67
+ "servers": {
68
+ "u-widgets": {
69
+ "command": "npx",
70
+ "args": ["-y", "@iyulab/u-widgets-mcp"]
71
+ }
72
+ }
73
+ }
74
+ ```
75
+
76
+ ## Tool Examples
77
+
78
+ ### help
79
+
80
+ ```
81
+ List all widget types:
82
+ → help()
83
+
84
+ List chart types only:
85
+ → help({ widget: "chart" })
86
+
87
+ Get details for a specific widget:
88
+ → help({ widget: "chart.bar" })
89
+ ```
90
+
91
+ ### template
92
+
93
+ ```
94
+ Generate a bar chart template:
95
+ → template({ widget: "chart.bar" })
96
+
97
+ Result:
98
+ {
99
+ "widget": "chart.bar",
100
+ "data": [{ "category": "A", "value": 30 }, ...],
101
+ "mapping": { "x": "category", "y": "value" }
102
+ }
103
+ ```
104
+
105
+ ### validate
106
+
107
+ ```
108
+ Check if a spec is valid:
109
+ → validate({ spec: { "widget": "metric", "data": { "value": 42 } } })
110
+
111
+ Result:
112
+ { "valid": true, "errors": [], "warnings": [] }
113
+ ```
114
+
115
+ ### suggest_mapping
116
+
117
+ ```
118
+ Get widget suggestions for your data:
119
+ → suggest_mapping({ data: [{ "name": "A", "value": 30 }, { "name": "B", "value": 70 }] })
120
+
121
+ Result:
122
+ [
123
+ { "widget": "chart.bar", "confidence": 0.9, "mapping": { "x": "name", "y": "value" }, ... },
124
+ { "widget": "chart.line", ... },
125
+ ...
126
+ ]
127
+ ```
128
+
129
+ ### auto_spec
130
+
131
+ ```
132
+ Generate a complete spec from data:
133
+ → auto_spec({ data: [{ "quarter": "Q1", "revenue": 100 }, { "quarter": "Q2", "revenue": 150 }] })
134
+
135
+ Result:
136
+ {
137
+ "widget": "chart.bar",
138
+ "data": [{ "quarter": "Q1", "revenue": 100 }, ...],
139
+ "mapping": { "x": "quarter", "y": "revenue" }
140
+ }
141
+ ```
142
+
143
+ ## Development
144
+
145
+ ```bash
146
+ cd mcp
147
+
148
+ # Install dependencies
149
+ npm install
150
+
151
+ # Run in development mode
152
+ npm run dev
153
+
154
+ # Run tests
155
+ npm test
156
+
157
+ # Build
158
+ npm run build
159
+
160
+ # Interactive testing with MCP Inspector
161
+ npm run inspect
162
+ ```
163
+
164
+ ## License
165
+
166
+ MIT
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { createServer } from './server.js';
4
+ try {
5
+ const server = createServer();
6
+ const transport = new StdioServerTransport();
7
+ await server.connect(transport);
8
+ }
9
+ catch (err) {
10
+ process.stderr.write(`[u-widgets-mcp] Failed to start: ${err}\n`);
11
+ process.exit(1);
12
+ }
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,IAAI,CAAC;IACH,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAAC,OAAO,GAAG,EAAE,CAAC;IACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,GAAG,IAAI,CAAC,CAAC;IAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ /**
3
+ * Create and configure the u-widgets MCP server.
4
+ *
5
+ * Returns a configured McpServer instance without connecting
6
+ * to any transport — the caller is responsible for connecting.
7
+ */
8
+ export declare function createServer(): McpServer;
9
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAYpE;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,SAAS,CAiGxC"}
package/dist/server.js ADDED
@@ -0,0 +1,87 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { z } from 'zod';
3
+ import { help, template, suggestMapping, autoSpec } from '@iyulab/u-widgets/tools';
4
+ import { validate } from '@iyulab/u-widgets';
5
+ function errorResult(err) {
6
+ const msg = err instanceof Error ? err.message : String(err);
7
+ return { content: [{ type: 'text', text: `Internal error: ${msg}` }], isError: true };
8
+ }
9
+ /**
10
+ * Create and configure the u-widgets MCP server.
11
+ *
12
+ * Returns a configured McpServer instance without connecting
13
+ * to any transport — the caller is responsible for connecting.
14
+ */
15
+ export function createServer() {
16
+ const server = new McpServer({
17
+ name: 'u-widgets-mcp',
18
+ version: '0.1.0',
19
+ });
20
+ // ── Tool: help ──────────────────────────────────────────────
21
+ server.tool('help', 'List available u-widget types. Returns the full catalog when no argument is given, or filters by widget name or category (e.g. "chart", "chart.bar", "display").', { widget: z.string().max(100).optional().describe('Widget type or category to filter (e.g. "chart.bar", "chart", "display"). Omit for full catalog.') }, async ({ widget }) => {
22
+ try {
23
+ const result = widget ? help(widget) : help();
24
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
25
+ }
26
+ catch (err) {
27
+ return errorResult(err);
28
+ }
29
+ });
30
+ // ── Tool: template ──────────────────────────────────────────
31
+ server.tool('template', 'Generate a minimal, valid u-widget spec with sample data for a given widget type. Use this as a starting point when creating widgets.', { widget: z.string().max(100).describe('Widget type (e.g. "metric", "chart.bar", "table", "form").') }, async ({ widget }) => {
32
+ try {
33
+ const result = template(widget);
34
+ if (!result) {
35
+ return {
36
+ content: [{ type: 'text', text: `Unknown widget type: "${widget}". Use the "help" tool to list available types.` }],
37
+ isError: true,
38
+ };
39
+ }
40
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
41
+ }
42
+ catch (err) {
43
+ return errorResult(err);
44
+ }
45
+ });
46
+ // ── Tool: validate ─────────────────────────────────────────
47
+ server.tool('validate', 'Validate a u-widget spec. Returns errors (fatal) and warnings (non-fatal). Use this to check if a spec is correct before rendering.', { spec: z.record(z.unknown()).describe('The u-widget spec object to validate. Must be a plain object with a "widget" field.') }, async ({ spec }) => {
48
+ try {
49
+ const result = validate(spec);
50
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
51
+ }
52
+ catch (err) {
53
+ return errorResult(err);
54
+ }
55
+ });
56
+ // ── Tool: suggest_mapping ──────────────────────────────────
57
+ server.tool('suggest_mapping', 'Analyze data and suggest the best widget type with auto-inferred mapping. Returns ranked suggestions sorted by confidence. Optionally constrain to a specific widget type.', {
58
+ data: z.union([z.record(z.unknown()), z.array(z.record(z.unknown()))]).describe('The data to analyze — a single object or an array of records.'),
59
+ widget: z.string().max(100).optional().describe('Optional widget type to constrain the suggestion (e.g. "chart.pie"). Must be a known widget type from the catalog.'),
60
+ }, async ({ data, widget }) => {
61
+ try {
62
+ const result = suggestMapping(data, widget);
63
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
64
+ }
65
+ catch (err) {
66
+ return errorResult(err);
67
+ }
68
+ });
69
+ // ── Tool: auto_spec ────────────────────────────────────────
70
+ server.tool('auto_spec', 'Generate a complete, ready-to-use u-widget spec from raw data. Picks the best widget type and mapping automatically. One-call convenience for quick visualizations.', { data: z.union([z.record(z.unknown()), z.array(z.record(z.unknown()))]).describe('The data to visualize — a single object or an array of records.') }, async ({ data }) => {
71
+ try {
72
+ const result = autoSpec(data);
73
+ if (!result) {
74
+ return {
75
+ content: [{ type: 'text', text: 'Could not generate a spec from this data. The data may be empty or have no recognizable pattern.' }],
76
+ isError: true,
77
+ };
78
+ }
79
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
80
+ }
81
+ catch (err) {
82
+ return errorResult(err);
83
+ }
84
+ });
85
+ return server;
86
+ }
87
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@iyulab/u-widgets-mcp",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for the u-widgets declarative widget system",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "bin": {
8
+ "u-widgets-mcp": "./dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "start": "node dist/index.js",
16
+ "dev": "tsx src/index.ts",
17
+ "test": "vitest run",
18
+ "test:watch": "vitest",
19
+ "inspect": "npx @modelcontextprotocol/inspector dist/index.js",
20
+ "prepublishOnly": "npm run build"
21
+ },
22
+ "keywords": [
23
+ "mcp",
24
+ "model-context-protocol",
25
+ "widgets",
26
+ "ai",
27
+ "u-widgets"
28
+ ],
29
+ "license": "MIT",
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "https://github.com/iyulab/u-widgets",
36
+ "directory": "mcp"
37
+ },
38
+ "engines": {
39
+ "node": ">=18"
40
+ },
41
+ "dependencies": {
42
+ "@modelcontextprotocol/sdk": "^1.12.0",
43
+ "@iyulab/u-widgets": "^0.4.1",
44
+ "zod": "^3.25.0"
45
+ },
46
+ "devDependencies": {
47
+ "@types/node": "^22.0.0",
48
+ "tsx": "^4.19.0",
49
+ "typescript": "~5.7.0",
50
+ "vitest": "^3.0.0"
51
+ }
52
+ }