PettyUI/packages/mcp/src/server.ts
1986-04-26 01:23:45 +03:00

48 lines
3.4 KiB
TypeScript

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";
import { discoverInput, handleDiscover } from "./tools/discover.js";
import { inspectInput, handleInspect } from "./tools/inspect.js";
import { composeInput, handleCompose } from "./tools/compose.js";
import { validateInput, handleValidate } from "./tools/validate.js";
import { patternsInput, handlePatterns } from "./tools/patterns.js";
import { stylingInput, handleStyling } from "./tools/styling.js";
import { resourcesInput, handleResources } from "./tools/resources.js";
const TOOLS = [
{ name: "pettyui_discover", description: "List available PettyUI components, optionally filtered by category", inputSchema: z.toJSONSchema(discoverInput) },
{ name: "pettyui_inspect", description: "Get full details for a PettyUI component: attributes, data-parts, events, and example HTML", inputSchema: z.toJSONSchema(inspectInput) },
{ name: "pettyui_compose", description: "Generate valid HTML for a PettyUI component with attributes and content", inputSchema: z.toJSONSchema(composeInput) },
{ name: "pettyui_validate", description: "Validate HTML against a PettyUI component schema, checking parts, attributes, and nesting", inputSchema: z.toJSONSchema(validateInput) },
{ name: "pettyui_patterns", description: "Get multi-component composition patterns: login-form, signup-form, settings-form, dialog-confirm, dialog-form, tabbed-content, select-field, data-entry, feedback, navigation", inputSchema: z.toJSONSchema(patternsInput) },
{ name: "pettyui_styling", description: "Get CSS guidance: design tokens, data-part selectors, data-state selectors, or per-component CSS. Topics: tokens, data-parts, data-states, petty-select, petty-tabs, petty-switch, petty-dialog, petty-toast-region", inputSchema: z.toJSONSchema(stylingInput) },
{ name: "pettyui_resources", description: "Get full source for PettyUI APIs: theme-css, signals-api, router-api, animations-css", inputSchema: z.toJSONSchema(resourcesInput) },
];
type Handler = (args: Record<string, unknown>) => unknown;
const handlers: Record<string, Handler> = {
pettyui_discover: (args) => handleDiscover(discoverInput.parse(args)),
pettyui_inspect: (args) => handleInspect(inspectInput.parse(args)),
pettyui_compose: (args) => handleCompose(composeInput.parse(args)),
pettyui_validate: (args) => handleValidate(validateInput.parse(args)),
pettyui_patterns: (args) => handlePatterns(patternsInput.parse(args)),
pettyui_styling: (args) => handleStyling(stylingInput.parse(args)),
pettyui_resources: (args) => handleResources(resourcesInput.parse(args)),
};
function dispatchTool(name: string, args: Record<string, unknown>): unknown {
const handler = handlers[name];
if (!handler) throw new Error(`Unknown tool: ${name}`);
return handler(args);
}
export function createServer(): Server {
const server = new Server({ name: "pettyui", version: "2.0.0-alpha.0" }, { capabilities: { tools: {} } });
server.setRequestHandler(ListToolsRequestSchema, () => ({ tools: TOOLS }));
server.setRequestHandler(CallToolRequestSchema, (request) => {
const result = dispatchTool(request.params.name, (request.params.arguments ?? {}) as Record<string, unknown>);
return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
});
return server;
}