PettyUI/packages/mcp/src/server.ts
Mats Bosson e20b69d7e8 Wire up MCP CLI
- Add packages/mcp/src/cli.ts with init/list/inspect/discover/add commands
- Add packages/mcp/tests/cli.test.ts with 11 parseCommand tests (42 total)
- Update server.ts to register all 5 tools: discover, inspect, validate, add, compose
- Add @types/node devDep, switch to tsc --noCheck build to avoid re-checking
  core source under stricter NodeNext moduleResolution
- tsconfig: NodeNext module, types: [node], exclude core/src
2026-03-30 01:25:45 +07:00

36 lines
2.2 KiB
TypeScript

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod/v4";
import { ComponentRegistry } from "./registry.js";
import { handleDiscover } from "./tools/discover.js";
import { handleInspect } from "./tools/inspect.js";
import { handleValidate } from "./tools/validate.js";
import { handleAdd } from "./tools/add.js";
import { handleCompose } from "./tools/compose.js";
function toText(result: unknown): { content: [{ type: "text"; text: string }] } {
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
}
/** Creates and configures the PettyUI MCP server with all 5 tools registered. */
export function createPettyUIServer(): McpServer {
const server = new McpServer({ name: "pettyui", version: "0.1.0" });
const registry = new ComponentRegistry();
const name = z.string().describe("Component name");
server.tool("pettyui.discover", "Search for components by describing what you need",
{ intent: z.string().describe("Natural language description"), maxResults: z.number().optional() },
async ({ intent, maxResults }) => toText(handleDiscover(registry, { intent, maxResults })));
server.tool("pettyui.inspect", "Get full schema, parts, props, and usage example for a component",
{ component: name },
async ({ component }) => toText(handleInspect(registry, { component })));
server.tool("pettyui.validate", "Validate props against a component schema and check required parts",
{ component: name, schema: z.string().optional(), props: z.record(z.string(), z.unknown()).optional(), parts: z.array(z.string()).optional() },
async ({ component, schema, props, parts }) => toText(handleValidate(registry, { component, schema, props, parts })));
server.tool("pettyui.add", "Get styled component source files ready to copy into a project",
{ component: name, targetDir: z.string().optional() },
async ({ component, targetDir }) => toText(handleAdd(registry, { component, targetDir })));
server.tool("pettyui.compose", "Generate composed JSX and imports for multiple components together",
{ components: z.array(z.string()).describe("List of component names to compose") },
async ({ components }) => toText(handleCompose(registry, { components })));
return server;
}