We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/cbuntingde/magic-mcp-local'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";
import {
componentLibrary,
searchComponents,
getComponentById,
getComponentsByCategory,
categories,
type ComponentTemplate,
} from "./components/componentLibrary.js";
const CreateUIComponentSchema = z.object({
description: z.string().describe("Description of the UI component you want to create"),
});
const SearchComponentsSchema = z.object({
query: z.string().describe("Search query for components"),
category: z.string().optional().describe("Filter by category"),
});
const GetComponentSchema = z.object({
componentId: z.string().describe("The ID of the component to retrieve"),
});
const ListCategoriesSchema = z.object({});
const server = new Server(
{
name: "local-magic-mcp",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "create_ui_component",
description: "Create a UI component based on a natural language description. This tool searches the local component library and returns the best matching component template.",
inputSchema: {
type: "object",
properties: {
description: {
type: "string",
description: "Description of the UI component you want to create",
},
},
required: ["description"],
},
},
{
name: "search_components",
description: "Search for UI components in the local library by keyword or category",
inputSchema: {
type: "object",
properties: {
query: {
type: "string",
description: "Search query for components",
},
category: {
type: "string",
description: "Filter by category (optional)",
},
},
required: ["query"],
},
},
{
name: "get_component",
description: "Get a specific component by its ID",
inputSchema: {
type: "object",
properties: {
componentId: {
type: "string",
description: "The ID of the component to retrieve",
},
},
required: ["componentId"],
},
},
{
name: "list_categories",
description: "List all available component categories",
inputSchema: {
type: "object",
properties: {},
},
},
{
name: "list_components",
description: "List all available components or filter by category",
inputSchema: {
type: "object",
properties: {
category: {
type: "string",
description: "Filter by category (optional)",
},
},
},
},
],
};
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
switch (name) {
case "create_ui_component": {
const parsed = CreateUIComponentSchema.parse(args);
const results = searchComponents(parsed.description);
if (results.length === 0) {
return {
content: [
{
type: "text",
text: JSON.stringify({
success: false,
message: "No matching components found. Try a different description or use search_components to browse available components.",
suggestions: [
"button",
"input",
"card",
"navbar",
"modal",
"table",
"form elements",
],
}, null, 2),
},
],
};
}
const bestMatch = results[0];
return {
content: [
{
type: "text",
text: JSON.stringify({
success: true,
component: {
id: bestMatch.id,
name: bestMatch.name,
description: bestMatch.description,
category: bestMatch.category,
code: bestMatch.code,
},
matchedComponents: results.slice(0, 5).map((c) => ({
id: c.id,
name: c.name,
category: c.category,
})),
}, null, 2),
},
],
};
}
case "search_components": {
const parsed = SearchComponentsSchema.parse(args);
let results: ComponentTemplate[];
if (parsed.category) {
const categoryResults = getComponentsByCategory(parsed.category);
results = searchComponents(parsed.query).filter(
(c) => categoryResults.some((cr) => cr.id === c.id)
);
} else {
results = searchComponents(parsed.query);
}
return {
content: [
{
type: "text",
text: JSON.stringify({
count: results.length,
components: results.map((c) => ({
id: c.id,
name: c.name,
description: c.description,
category: c.category,
keywords: c.keywords,
})),
}, null, 2),
},
],
};
}
case "get_component": {
const parsed = GetComponentSchema.parse(args);
const component = getComponentById(parsed.componentId);
if (!component) {
return {
content: [
{
type: "text",
text: JSON.stringify({
success: false,
message: `Component with ID "${parsed.componentId}" not found`,
availableIds: componentLibrary.map((c) => c.id),
}, null, 2),
},
],
};
}
return {
content: [
{
type: "text",
text: JSON.stringify({
success: true,
component: {
id: component.id,
name: component.name,
description: component.description,
category: component.category,
keywords: component.keywords,
code: component.code,
},
}, null, 2),
},
],
};
}
case "list_categories": {
return {
content: [
{
type: "text",
text: JSON.stringify({
categories: categories.map((cat) => ({
name: cat,
count: getComponentsByCategory(cat).length,
})),
}, null, 2),
},
],
};
}
case "list_components": {
const { category } = args as { category?: string };
const components = category
? getComponentsByCategory(category)
: componentLibrary;
return {
content: [
{
type: "text",
text: JSON.stringify({
count: components.length,
components: components.map((c) => ({
id: c.id,
name: c.name,
description: c.description,
category: c.category,
keywords: c.keywords,
})),
}, null, 2),
},
],
};
}
default:
return {
content: [
{
type: "text",
text: JSON.stringify({ error: `Unknown tool: ${name}` }),
},
],
};
}
} catch (error) {
return {
content: [
{
type: "text",
text: JSON.stringify({
error: error instanceof Error ? error.message : String(error),
}),
},
],
};
}
});
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Local Magic MCP Server running on stdio");
}
main().catch((error) => {
console.error("Server error:", error);
process.exit(1);
});