@gianpieropuleo/radix-mcp-server
Version:
A Model Context Protocol (MCP) server for Radix UI libraries (Themes, Primitives, Colors), providing AI assistants with access to component source code, installation guides, and design tokens.
113 lines (112 loc) • 3.95 kB
JavaScript
/**
* MCP Server Module
*
* Contains the core Model Context Protocol server logic, separated from CLI concerns.
* This module handles server initialization, configuration, and startup.
*/
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { DEFAULT_VERSION, PROGRAM_NAME } from "../cli/commands.js";
import { Action, ColorAction } from "../types/actions.js";
import { Library } from "../types/results.js";
import { logError, logInfo, logWarning } from "../utils/logger.js";
import { setupHandlers } from "./handler.js";
import { createTool } from "./tools.js";
function createToolsForLibrary(library) {
if (library === Library.Colors) {
return {
...createTool(library, ColorAction.ListScales),
...createTool(library, ColorAction.GetScale),
...createTool(library, ColorAction.GetScaleDocumentation),
};
}
return {
...createTool(library, Action.ListComponents),
...createTool(library, Action.GetComponentSource),
...createTool(library, Action.GetComponentDocumentation),
...createTool(library, Action.GetGettingStarted),
};
}
/**
* Get tools configuration based on library selection
*/
function getToolsForLibrary(library) {
if (library !== Library.All) {
return createToolsForLibrary(library);
}
return Object.values(Library)
.filter((lib) => lib !== Library.All)
.reduce((acc, library) => {
return {
...acc,
...createToolsForLibrary(library),
};
}, {});
}
/**
* Read version from package.json
*/
async function getVersion() {
try {
const fs = await import("fs");
const path = await import("path");
const { fileURLToPath } = await import("url");
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const packagePath = path.join(__dirname, "..", "..", "package.json");
const packageContent = fs.readFileSync(packagePath, "utf8");
const packageJson = JSON.parse(packageContent);
return packageJson.version;
}
catch (error) {
logWarning(`Could not read version from package.json, using default: ${DEFAULT_VERSION}`);
return DEFAULT_VERSION;
}
}
/**
* Configure HTTP client with GitHub API key if provided
*/
async function configureHttpClient(githubApiKey) {
const { http } = await import("../utils/http.js");
if (githubApiKey) {
http.setGitHubApiKey(githubApiKey);
logInfo("GitHub API configured with token");
}
else {
logWarning("No GitHub API key provided. Rate limited to 60 requests/hour.");
}
}
/**
* Create and start the MCP server with the given configuration
*/
export async function startMCPServer(config) {
try {
logInfo("Starting Radix UI MCP Server...");
logInfo(`Library selection: ${config.library}`);
// Configure HTTP client
await configureHttpClient(config.githubApiKey);
// Get version for server metadata
const version = await getVersion();
const tools = getToolsForLibrary(config.library);
// Initialize the MCP server with metadata and capabilities
const server = new Server({
name: PROGRAM_NAME,
version,
}, {
capabilities: {
tools,
},
});
// Set up request handlers and register components
setupHandlers(server, tools);
// Start server using stdio transport
const transport = new StdioServerTransport();
logInfo("Transport initialized: stdio");
await server.connect(transport);
logInfo("Server started successfully");
}
catch (error) {
logError("Failed to start server", error);
throw error;
}
}