@uni-design-system/uni-mcp 4.0.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 +103 -0
- package/dist/chunk-WTQ4AVHO.js +9729 -0
- package/dist/chunk-WTQ4AVHO.js.map +1 -0
- package/dist/http.js +76 -0
- package/dist/http.js.map +1 -0
- package/dist/server.d.ts +11 -0
- package/dist/server.js +8 -0
- package/dist/server.js.map +1 -0
- package/dist/stdio.js +18 -0
- package/dist/stdio.js.map +1 -0
- package/package.json +47 -0
package/dist/http.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
createUniServer,
|
|
4
|
+
meta
|
|
5
|
+
} from "./chunk-WTQ4AVHO.js";
|
|
6
|
+
|
|
7
|
+
// src/server/http.ts
|
|
8
|
+
import { createServer } from "http";
|
|
9
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
10
|
+
var PORT = Number(process.env.PORT ?? 8080);
|
|
11
|
+
var HOST = process.env.HOST ?? "0.0.0.0";
|
|
12
|
+
var TOKEN = process.env.UNI_MCP_TOKEN;
|
|
13
|
+
var ALLOWED_HOSTS = process.env.UNI_ALLOWED_HOSTS?.split(",").map((h) => h.trim()).filter(Boolean);
|
|
14
|
+
function send(res, status, body) {
|
|
15
|
+
const payload = typeof body === "string" ? body : JSON.stringify(body);
|
|
16
|
+
res.writeHead(status, { "Content-Type": typeof body === "string" ? "text/plain" : "application/json" });
|
|
17
|
+
res.end(payload);
|
|
18
|
+
}
|
|
19
|
+
function readBody(req) {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
const chunks = [];
|
|
22
|
+
req.on("data", (c) => chunks.push(c));
|
|
23
|
+
req.on("end", () => {
|
|
24
|
+
const raw = Buffer.concat(chunks).toString("utf8");
|
|
25
|
+
if (!raw) return resolve(void 0);
|
|
26
|
+
try {
|
|
27
|
+
resolve(JSON.parse(raw));
|
|
28
|
+
} catch (e) {
|
|
29
|
+
reject(e);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
req.on("error", reject);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function authorized(req) {
|
|
36
|
+
if (!TOKEN) return true;
|
|
37
|
+
const header = req.headers.authorization ?? "";
|
|
38
|
+
return header === `Bearer ${TOKEN}`;
|
|
39
|
+
}
|
|
40
|
+
function rpcError(res, status, message) {
|
|
41
|
+
send(res, status, { jsonrpc: "2.0", error: { code: -32e3, message }, id: null });
|
|
42
|
+
}
|
|
43
|
+
async function handleMcp(req, res) {
|
|
44
|
+
if (!authorized(req)) return rpcError(res, 401, "Unauthorized");
|
|
45
|
+
const server = createUniServer();
|
|
46
|
+
const transport = new StreamableHTTPServerTransport({
|
|
47
|
+
sessionIdGenerator: void 0,
|
|
48
|
+
enableJsonResponse: true,
|
|
49
|
+
...ALLOWED_HOSTS?.length ? { enableDnsRebindingProtection: true, allowedHosts: ALLOWED_HOSTS } : {}
|
|
50
|
+
});
|
|
51
|
+
res.on("close", () => {
|
|
52
|
+
transport.close();
|
|
53
|
+
server.close();
|
|
54
|
+
});
|
|
55
|
+
try {
|
|
56
|
+
await server.connect(transport);
|
|
57
|
+
const body = await readBody(req);
|
|
58
|
+
await transport.handleRequest(req, res, body);
|
|
59
|
+
} catch (err) {
|
|
60
|
+
console.error("[uni-mcp] request error:", err);
|
|
61
|
+
if (!res.headersSent) rpcError(res, 500, "Internal server error");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
var httpServer = createServer((req, res) => {
|
|
65
|
+
const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
66
|
+
if (req.method === "GET" && (url.pathname === "/health" || url.pathname === "/")) {
|
|
67
|
+
return send(res, 200, { status: "ok", service: "uni-mcp", uniRelease: meta.version, ...meta.counts });
|
|
68
|
+
}
|
|
69
|
+
if (url.pathname === "/mcp") return void handleMcp(req, res);
|
|
70
|
+
return send(res, 404, { error: "Not found. POST JSON-RPC to /mcp; GET /health for status." });
|
|
71
|
+
});
|
|
72
|
+
httpServer.listen(PORT, HOST, () => {
|
|
73
|
+
console.error(`[uni-mcp] HTTP server on http://${HOST}:${PORT}/mcp (Uni v${meta.version})`);
|
|
74
|
+
if (!TOKEN) console.error("[uni-mcp] WARNING: no UNI_MCP_TOKEN set - endpoint is unauthenticated.");
|
|
75
|
+
});
|
|
76
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server/http.ts"],"sourcesContent":["/**\n * HTTP entry — Streamable HTTP transport for a shared, always-current team\n * endpoint. Runs stateless (a fresh server+transport per request) so it scales\n * horizontally and is trivial to host on Render.\n *\n * Env:\n * PORT port to bind (Render sets this) default 8080\n * HOST bind address default 0.0.0.0\n * UNI_MCP_TOKEN if set, require `Authorization: Bearer <it>` default none\n * UNI_ALLOWED_HOSTS comma list for DNS-rebinding protection default none\n */\nimport { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { createUniServer } from './core.js';\nimport { meta } from './store.js';\n\nconst PORT = Number(process.env.PORT ?? 8080);\nconst HOST = process.env.HOST ?? '0.0.0.0';\nconst TOKEN = process.env.UNI_MCP_TOKEN;\nconst ALLOWED_HOSTS = process.env.UNI_ALLOWED_HOSTS?.split(',').map((h) => h.trim()).filter(Boolean);\n\nfunction send(res: ServerResponse, status: number, body: unknown) {\n const payload = typeof body === 'string' ? body : JSON.stringify(body);\n res.writeHead(status, { 'Content-Type': typeof body === 'string' ? 'text/plain' : 'application/json' });\n res.end(payload);\n}\n\nfunction readBody(req: IncomingMessage): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', (c) => chunks.push(c as Buffer));\n req.on('end', () => {\n const raw = Buffer.concat(chunks).toString('utf8');\n if (!raw) return resolve(undefined);\n try {\n resolve(JSON.parse(raw));\n } catch (e) {\n reject(e);\n }\n });\n req.on('error', reject);\n });\n}\n\nfunction authorized(req: IncomingMessage): boolean {\n if (!TOKEN) return true;\n const header = req.headers.authorization ?? '';\n return header === `Bearer ${TOKEN}`;\n}\n\n/** JSON-RPC error envelope for pre-transport failures. */\nfunction rpcError(res: ServerResponse, status: number, message: string) {\n send(res, status, { jsonrpc: '2.0', error: { code: -32000, message }, id: null });\n}\n\nasync function handleMcp(req: IncomingMessage, res: ServerResponse) {\n if (!authorized(req)) return rpcError(res, 401, 'Unauthorized');\n\n // Stateless: isolate each request in its own server+transport instance.\n const server = createUniServer();\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n enableJsonResponse: true,\n ...(ALLOWED_HOSTS?.length ? { enableDnsRebindingProtection: true, allowedHosts: ALLOWED_HOSTS } : {}),\n });\n\n res.on('close', () => {\n transport.close();\n server.close();\n });\n\n try {\n await server.connect(transport);\n const body = await readBody(req);\n await transport.handleRequest(req, res, body);\n } catch (err) {\n console.error('[uni-mcp] request error:', err);\n if (!res.headersSent) rpcError(res, 500, 'Internal server error');\n }\n}\n\nconst httpServer = createServer((req, res) => {\n const url = new URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`);\n\n if (req.method === 'GET' && (url.pathname === '/health' || url.pathname === '/')) {\n return send(res, 200, { status: 'ok', service: 'uni-mcp', uniRelease: meta.version, ...meta.counts });\n }\n if (url.pathname === '/mcp') return void handleMcp(req, res);\n return send(res, 404, { error: 'Not found. POST JSON-RPC to /mcp; GET /health for status.' });\n});\n\nhttpServer.listen(PORT, HOST, () => {\n console.error(`[uni-mcp] HTTP server on http://${HOST}:${PORT}/mcp (Uni v${meta.version})`);\n if (!TOKEN) console.error('[uni-mcp] WARNING: no UNI_MCP_TOKEN set - endpoint is unauthenticated.');\n});\n"],"mappings":"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","names":[]}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Server core — builds a fully-wired `McpServer` (tools + resources) over the
|
|
5
|
+
* in-memory Uni index. Transport-agnostic: `stdio.ts` and `http.ts` both call
|
|
6
|
+
* `createUniServer()`, so local and remote share exactly one implementation.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
declare function createUniServer(): McpServer;
|
|
10
|
+
|
|
11
|
+
export { createUniServer };
|
package/dist/server.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/stdio.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
createUniServer
|
|
4
|
+
} from "./chunk-WTQ4AVHO.js";
|
|
5
|
+
|
|
6
|
+
// src/server/stdio.ts
|
|
7
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
8
|
+
async function main() {
|
|
9
|
+
const server = createUniServer();
|
|
10
|
+
const transport = new StdioServerTransport();
|
|
11
|
+
await server.connect(transport);
|
|
12
|
+
console.error("[uni-mcp] stdio server ready");
|
|
13
|
+
}
|
|
14
|
+
main().catch((err) => {
|
|
15
|
+
console.error("[uni-mcp] fatal:", err);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
});
|
|
18
|
+
//# sourceMappingURL=stdio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server/stdio.ts"],"sourcesContent":["/**\n * Stdio entry — the local transport. Runs as a spawned process wired into a\n * client's MCP config (Claude Code/Desktop, Cursor, ...). Zero infra, offline.\n *\n * npx @uni-design-system/uni-mcp\n */\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { createUniServer } from './core.js';\n\nasync function main() {\n const server = createUniServer();\n const transport = new StdioServerTransport();\n await server.connect(transport);\n // Never write to stdout here — stdout is the JSON-RPC channel.\n console.error('[uni-mcp] stdio server ready');\n}\n\nmain().catch((err) => {\n console.error('[uni-mcp] fatal:', err);\n process.exit(1);\n});\n"],"mappings":";;;;;;AAMA,SAAS,4BAA4B;AAGrC,eAAe,OAAO;AACpB,QAAM,SAAS,gBAAgB;AAC/B,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAE9B,UAAQ,MAAM,8BAA8B;AAC9C;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,MAAM,oBAAoB,GAAG;AACrC,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@uni-design-system/uni-mcp",
|
|
3
|
+
"version": "4.0.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"description": "Model Context Protocol server for the Uni Design System — gives AI coding assistants an authoritative interface to Uni components, tokens, themes, and guidelines.",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/uni-design-system/uni",
|
|
9
|
+
"directory": "packages/mcp"
|
|
10
|
+
},
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public",
|
|
13
|
+
"provenance": true
|
|
14
|
+
},
|
|
15
|
+
"private": false,
|
|
16
|
+
"type": "module",
|
|
17
|
+
"bin": {
|
|
18
|
+
"uni-mcp": "./dist/stdio.js"
|
|
19
|
+
},
|
|
20
|
+
"main": "./dist/server.js",
|
|
21
|
+
"types": "./dist/server.d.ts",
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build-index": "tsx src/build/index.ts",
|
|
27
|
+
"build": "pnpm build-index && tsup",
|
|
28
|
+
"build:server": "tsup",
|
|
29
|
+
"dev": "tsx watch src/server/stdio.ts",
|
|
30
|
+
"serve:http": "tsx src/server/http.ts",
|
|
31
|
+
"start": "node dist/http.js",
|
|
32
|
+
"inspect": "pnpm dlx @modelcontextprotocol/inspector tsx src/server/stdio.ts",
|
|
33
|
+
"type-check": "tsc --noEmit"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@modelcontextprotocol/sdk": "^1.22.0",
|
|
37
|
+
"zod": "^3.25.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^25.6.0",
|
|
41
|
+
"@uni-design-system/tsconfig": "workspace:*",
|
|
42
|
+
"@uni-design-system/uni-core": "workspace:*",
|
|
43
|
+
"tsup": "^8.5.0",
|
|
44
|
+
"tsx": "^4.20.0",
|
|
45
|
+
"typescript": "~5.9.0"
|
|
46
|
+
}
|
|
47
|
+
}
|