#
tokens: 6765/50000 10/10 files
lines: on (toggle) GitHub
raw markdown copy reset
# Directory Structure

```
├── .gitignore
├── LICENSE.md
├── package-lock.json
├── package.json
├── public
│   └── mcp.png
├── README.md
├── src
│   ├── server.ts
│   └── utils
│       ├── api.ts
│       ├── formatters.ts
│       ├── index.ts
│       └── schemas.ts
└── tsconfig.json
```

# Files

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
1 | node_modules/
2 | .DS_Store
3 | dist/
4 | tsconfig.tsbuildinfo
```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
 1 | # @magicuidesign/mcp
 2 | 
 3 | [![npm version](https://badge.fury.io/js/@magicuidesign%2Fmcp.svg?icon=si%3Anpm)](https://badge.fury.io/js/@magicuidesign%2Fmcp)
 4 | 
 5 | Official ModelContextProtocol (MCP) server for [Magic UI](https://magicui.design/).
 6 | 
 7 | <div align="center">
 8 |   <img src="https://github.com/magicuidesign/mcp/blob/main/public/mcp.png" alt="MCP" />
 9 | </div>
10 | 
11 | ## Install MCP configuration
12 | 
13 | ```bash
14 | npx @magicuidesign/cli@latest install <client>
15 | ```
16 | 
17 | ### Supported Clients
18 | 
19 | - [x] cursor
20 | - [x] windsurf
21 | - [x] claude
22 | - [x] cline
23 | - [x] roo-cline
24 | 
25 | ## Manual Installation
26 | 
27 | Add to your IDE's MCP config:
28 | 
29 | ```json
30 | {
31 |   "mcpServers": {
32 |     "@magicuidesign/mcp": {
33 |       "command": "npx",
34 |       "args": ["-y", "@magicuidesign/mcp@latest"]
35 |     }
36 |   }
37 | }
38 | ```
39 | 
40 | ## Example Usage
41 | 
42 | Once configured, you can questions like:
43 | 
44 | > "Make a marquee of logos"
45 | 
46 | > "Add a blur fade text animation"
47 | 
48 | > "Add a grid background"
49 | 
50 | ## Available Tools
51 | 
52 | The server provides the following tools callable via MCP:
53 | 
54 | | Tool Name       | Description                                                                                                                                                                                                                                                                                                                                                                                             |
55 | |-----------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
56 | | `getUIComponents` | Provides a comprehensive list of all Magic UI components.                                                                                                                                                                                                                                                                                                                                                     |
57 | | `getLayout`       | Provides implementation details for [bento-grid](https://magicui.design/docs/components/bento-grid), [dock](https://magicui.design/docs/components/dock), [file-tree](https://magicui.design/docs/components/file-tree), [grid-pattern](https://magicui.design/docs/components/grid-pattern), [interactive-grid-pattern](https://magicui.design/docs/components/interactive-grid-pattern), [dot-pattern](https://magicui.design/docs/components/dot-pattern) components.         |
58 | | `getMedia`        | Provides implementation details for [hero-video-dialog](https://magicui.design/docs/components/hero-video-dialog), [terminal](https://magicui.design/docs/components/terminal), [marquee](https://magicui.design/docs/components/marquee), [script-copy-btn](https://magicui.design/docs/components/script-copy-btn), [code-comparison](https://magicui.design/docs/components/code-comparison) components.                                                               |
59 | | `getMotion`       | Provides implementation details for [blur-fade](https://magicui.design/docs/components/blur-fade), [scroll-progress](https://magicui.design/docs/components/scroll-progress), [scroll-based-velocity](https://magicui.design/docs/components/scroll-based-velocity), [orbiting-circles](https://magicui.design/docs/components/orbiting-circles), [animated-circular-progress-bar](https://magicui.design/docs/components/animated-circular-progress-bar) components. |
60 | | `getTextReveal`   | Provides implementation details for [text-animate](https://magicui.design/docs/components/text-animate), [line-shadow-text](https://magicui.design/docs/components/line-shadow-text), [aurora-text](https://magicui.design/docs/components/aurora-text), [animated-shiny-text](https://magicui.design/docs/components/animated-shiny-text), [animated-gradient-text](https://magicui.design/docs/components/animated-gradient-text), [text-reveal](https://magicui.design/docs/components/text-reveal), [typing-animation](https://magicui.design/docs/components/typing-animation), [box-reveal](https://magicui.design/docs/components/box-reveal), [number-ticker](https://magicui.design/docs/components/number-ticker) components. |
61 | | `getTextEffects`  | Provides implementation details for [word-rotate](https://magicui.design/docs/components/word-rotate), [flip-text](https://magicui.design/docs/components/flip-text), [hyper-text](https://magicui.design/docs/components/hyper-text), [morphing-text](https://magicui.design/docs/components/morphing-text), [spinning-text](https://magicui.design/docs/components/spinning-text), [sparkles-text](https://magicui.design/docs/components/sparkles-text) components.       |
62 | | `getButtons`      | Provides implementation details for [rainbow-button](https://magicui.design/docs/components/rainbow-button), [shimmer-button](https://magicui.design/docs/components/shimmer-button), [shiny-button](https://magicui.design/docs/components/shiny-button), [interactive-hover-button](https://magicui.design/docs/components/interactive-hover-button), [animated-subscribe-button](https://magicui.design/docs/components/animated-subscribe-button), [pulsating-button](https://magicui.design/docs/components/pulsating-button), [ripple-button](https://magicui.design/docs/components/ripple-button) components. |
63 | | `getEffects`      | Provides implementation details for [animated-beam](https://magicui.design/docs/components/animated-beam), [border-beam](https://magicui.design/docs/components/border-beam), [shine-border](https://magicui.design/docs/components/shine-border), [magic-card](https://magicui.design/docs/components/magic-card), [meteors](https://magicui.design/docs/components/meteors), [neon-gradient-card](https://magicui.design/docs/components/neon-gradient-card), [confetti](https://magicui.design/docs/components/confetti), [particles](https://magicui.design/docs/components/particles), [cool-mode](https://magicui.design/docs/components/cool-mode), [scratch-to-reveal](https://magicui.design/docs/components/scratch-to-reveal) components. |
64 | | `getWidgets`      | Provides implementation details for [animated-list](https://magicui.design/docs/components/animated-list), [tweet-card](https://magicui.design/docs/components/tweet-card), [client-tweet-card](https://magicui.design/docs/components/client-tweet-card), [lens](https://magicui.design/docs/components/lens), [pointer](https://magicui.design/docs/components/pointer), [avatar-circles](https://magicui.design/docs/components/avatar-circles), [icon-cloud](https://magicui.design/docs/components/icon-cloud), [globe](https://magicui.design/docs/components/globe) components.                                |
65 | | `getBackgrounds`  | Provides implementation details for [warp-background](https://magicui.design/docs/components/warp-background), [flickering-grid](https://magicui.design/docs/components/flickering-grid), [animated-grid-pattern](https://magicui.design/docs/components/animated-grid-pattern), [retro-grid](https://magicui.design/docs/components/retro-grid), [ripple](https://magicui.design/docs/components/ripple) components.                                                               |
66 | | `getDevices`      | Provides implementation details for [safari](https://magicui.design/docs/components/safari), [iphone-15-pro](https://magicui.design/docs/components/iphone-15-pro), [android](https://magicui.design/docs/components/android) components.                                                                                                                                                            |
67 | 
68 | ## MCP Limitations
69 | 
70 | Some clients have a [limit](https://docs.cursor.com/context/model-context-protocol#limitations) on the number of tools they can call. This is why we opted to group the tools into categories. Note: For more specific context on each component, run the MCP locally and modify the logic that groups the components.
71 | 
72 | ## Credits
73 | 
74 | Big thanks to [@beaubhp](https://github.com/beaubhp) for creating the MCP server 🙏
75 | 
76 | [MIT](https://github.com/magicuidesign/mcp/blob/main/LICENSE.md)
```

--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------

```markdown
 1 | MIT License
 2 | 
 3 | Copyright (c) Magic UI
 4 | 
 5 | Permission is hereby granted, free of charge, to any person obtaining a copy
 6 | of this software and associated documentation files (the "Software"), to deal
 7 | in the Software without restriction, including without limitation the rights
 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 | 
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 | 
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 | 
```

--------------------------------------------------------------------------------
/src/utils/index.ts:
--------------------------------------------------------------------------------

```typescript
1 | export * from "./api.js";
2 | export * from "./formatters.js";
3 | export * from "./schemas.js";
4 | 
```

--------------------------------------------------------------------------------
/src/utils/formatters.ts:
--------------------------------------------------------------------------------

```typescript
 1 | // Helper function to format component names
 2 | export function formatComponentName(name: string): string {
 3 |   return name
 4 |     .split("-")
 5 |     .map((part) => {
 6 |       return part.charAt(0).toUpperCase() + part.slice(1);
 7 |     })
 8 |     .join("");
 9 | }
10 | 
```

--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "compilerOptions": {
 3 |     "baseUrl": ".",
 4 |     "esModuleInterop": true,
 5 |     "skipLibCheck": true,
 6 |     "target": "ES2022",
 7 |     "allowJs": true,
 8 |     "resolveJsonModule": true,
 9 |     "moduleDetection": "force",
10 |     "isolatedModules": true,
11 |     "strict": true,
12 |     "noUncheckedIndexedAccess": true,
13 |     "noImplicitAny": true, 
14 |     "module": "esnext",
15 |     "moduleResolution": "bundler",
16 |     "outDir": "dist",
17 |     "rootDir": "src",
18 |     "sourceMap": true,
19 |     "declaration": true,
20 |     "incremental": true,
21 |   },
22 |   "include": ["**/*.ts"],
23 |   "exclude": ["node_modules", "dist"]
24 | } 
```

--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "@magicuidesign/mcp",
 3 |   "version": "1.0.6",
 4 |   "description": "Official MCP server for Magic UI.",
 5 |   "homepage": "https://magicui.design",
 6 |   "repository": {
 7 |     "type": "git",
 8 |     "url": "git+https://github.com/magicuidesign/mcp.git"
 9 |   },
10 |   "scripts": {
11 |     "build": "tsc && shx chmod +x dist/*.js",
12 |     "start": "node dist/server.js",
13 |     "dev": "nodemon --watch src --ext ts,json --exec \"npm run build\""
14 |   },
15 |   "type": "module",
16 |   "main": "./dist/server.js",
17 |   "module": "./dist/server.js",
18 |   "types": "./dist/server.d.ts",
19 |   "bin": {
20 |     "mcp": "./dist/server.js"
21 |   },
22 |   "files": [
23 |     "dist"
24 |   ],
25 |   "dependencies": {
26 |     "@modelcontextprotocol/sdk": "^1.9.0",
27 |     "zod": "^3.24.2"
28 |   },
29 |   "devDependencies": {
30 |     "@types/node": "^22.14.1",
31 |     "nodemon": "^3.1.0",
32 |     "shx": "^0.4.0",
33 |     "typescript": "^5.8.3"
34 |   },
35 |   "author": "Beau Hayes-Pollard <[email protected]>",
36 |   "license": "ISC"
37 | }
38 | 
```

--------------------------------------------------------------------------------
/src/utils/schemas.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { z } from "zod";
 2 | 
 3 | // Define schema for general component
 4 | export const ComponentSchema = z.object({
 5 |   name: z.string(),
 6 |   type: z.string(),
 7 |   description: z.string().optional(), // Only optional because of interactive-hover-button
 8 | });
 9 | 
10 | // Define schema for an individual example
11 | const ExampleSchema = z.object({
12 |   name: z.string(),
13 |   type: z.string(),
14 |   description: z.string(),
15 |   content: z.string(),
16 | });
17 | 
18 | // Define schema for individual component with content and examples
19 | export const IndividualComponentSchema = ComponentSchema.extend({
20 |   install: z.string(),
21 |   content: z.string(),
22 |   examples: z.array(ExampleSchema),
23 | });
24 | 
25 | // Define schema for component detail response
26 | export const ComponentDetailSchema = z.object({
27 |   name: z.string(),
28 |   type: z.string(),
29 |   files: z.array(
30 |     z.object({
31 |       content: z.string(),
32 |     }),
33 |   ),
34 | });
35 | 
36 | // Define schema for example component
37 | export const ExampleComponentSchema = z.object({
38 |   name: z.string(),
39 |   type: z.string(),
40 |   description: z.string(),
41 |   registryDependencies: z.array(z.string()),
42 | });
43 | 
44 | // Define schema for example detail response
45 | export const ExampleDetailSchema = z.object({
46 |   name: z.string(),
47 |   type: z.string(),
48 |   description: z.string(),
49 |   files: z.array(
50 |     z.object({
51 |       content: z.string(),
52 |     }),
53 |   ),
54 | });
55 | 
```

--------------------------------------------------------------------------------
/src/utils/api.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import {
 2 |   ComponentDetailSchema,
 3 |   ComponentSchema,
 4 |   ExampleComponentSchema,
 5 |   ExampleDetailSchema,
 6 | } from "./schemas.js";
 7 | 
 8 | // Function to fetch UI components
 9 | export async function fetchUIComponents() {
10 |   try {
11 |     const response = await fetch("https://magicui.design/registry.json");
12 |     if (!response.ok) {
13 |       throw new Error(
14 |         `Failed to fetch registry.json: ${response.statusText} (Status: ${response.status})`,
15 |       );
16 |     }
17 |     const data = await response.json();
18 | 
19 |     return data.items
20 |       .filter((item: any) => item.type === "registry:ui")
21 |       .map((item: any) => {
22 |         try {
23 |           return ComponentSchema.parse({
24 |             name: item.name,
25 |             type: item.type,
26 |             description: item.description,
27 |           });
28 |         } catch (parseError) {
29 |           return null;
30 |         }
31 |       });
32 |   } catch (error) {
33 |     return [];
34 |   }
35 | }
36 | 
37 | // Function to fetch individual component details
38 | export async function fetchComponentDetails(name: string) {
39 |   try {
40 |     const response = await fetch(`https://magicui.design/r/${name}`);
41 |     if (!response.ok) {
42 |       throw new Error(
43 |         `Failed to fetch component ${name}: ${response.statusText}`,
44 |       );
45 |     }
46 |     const data = await response.json();
47 |     return ComponentDetailSchema.parse(data);
48 |   } catch (error) {
49 |     console.error(`Error fetching component ${name}:`, error);
50 |     throw error;
51 |   }
52 | }
53 | 
54 | // Function to fetch example components
55 | export async function fetchExampleComponents() {
56 |   try {
57 |     const response = await fetch("https://magicui.design/registry.json");
58 |     const data = await response.json();
59 | 
60 |     return data.items
61 |       .filter((item: any) => item.type === "registry:example")
62 |       .map((item: any) => {
63 |         return ExampleComponentSchema.parse({
64 |           name: item.name,
65 |           type: item.type,
66 |           description: item.description,
67 |           registryDependencies: item.registryDependencies,
68 |         });
69 |       });
70 |   } catch (error) {
71 |     console.error("Error fetching MagicUI example components:", error);
72 |     return [];
73 |   }
74 | }
75 | 
76 | // Function to fetch details for a specific example
77 | export async function fetchExampleDetails(exampleName: string) {
78 |   try {
79 |     const response = await fetch(`https://magicui.design/r/${exampleName}`);
80 |     if (!response.ok) {
81 |       throw new Error(
82 |         `Failed to fetch example details for ${exampleName}: ${response.statusText}`,
83 |       );
84 |     }
85 |     const data = await response.json();
86 |     return ExampleDetailSchema.parse(data);
87 |   } catch (error) {
88 |     console.error(`Error fetching example details for ${exampleName}:`, error);
89 |     throw error;
90 |   }
91 | }
92 | 
```

--------------------------------------------------------------------------------
/src/server.ts:
--------------------------------------------------------------------------------

```typescript
  1 | #!/usr/bin/env node
  2 | 
  3 | import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
  4 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
  5 | import {
  6 |   IndividualComponentSchema,
  7 |   fetchComponentDetails,
  8 |   fetchExampleComponents,
  9 |   fetchExampleDetails,
 10 |   fetchUIComponents,
 11 | } from "./utils/index.js";
 12 | import { formatComponentName } from "./utils/formatters.js";
 13 | 
 14 | // Initialize the MCP Server
 15 | const server = new McpServer({
 16 |   name: "Magic UI MCP",
 17 |   version: "1.0.4",
 18 | });
 19 | 
 20 | // Register the main tool for getting all components
 21 | server.tool(
 22 |   "getUIComponents",
 23 |   "Provides a comprehensive list of all Magic UI components.",
 24 |   {},
 25 |   async () => {
 26 |     try {
 27 |       const uiComponents = await fetchUIComponents();
 28 | 
 29 |       return {
 30 |         content: [
 31 |           {
 32 |             type: "text",
 33 |             text: JSON.stringify(uiComponents, null, 2),
 34 |           },
 35 |         ],
 36 |       };
 37 |     } catch (error) {
 38 |       return {
 39 |         content: [
 40 |           {
 41 |             type: "text",
 42 |             text: "Failed to fetch MagicUI components",
 43 |           },
 44 |         ],
 45 |         isError: true,
 46 |       };
 47 |     }
 48 |   },
 49 | );
 50 | 
 51 | // Maps component names to their example implementations
 52 | function buildExampleComponentMap(
 53 |   allExampleComponents: Array<{
 54 |     name: string;
 55 |     registryDependencies?: string[];
 56 |   }>,
 57 | ): Map<string, string[]> {
 58 |   const exampleMap = new Map<string, string[]>();
 59 | 
 60 |   for (const example of allExampleComponents) {
 61 |     if (
 62 |       example.registryDependencies &&
 63 |       Array.isArray(example.registryDependencies)
 64 |     ) {
 65 |       for (const depUrl of example.registryDependencies) {
 66 |         if (typeof depUrl === "string" && depUrl.includes("magicui.design")) {
 67 |           const componentNameMatch = depUrl.match(/\/r\/([^\/]+)$/);
 68 |           if (componentNameMatch && componentNameMatch[1]) {
 69 |             const componentName = componentNameMatch[1];
 70 |             if (!exampleMap.has(componentName)) {
 71 |               exampleMap.set(componentName, []);
 72 |             }
 73 |             if (!exampleMap.get(componentName)?.includes(example.name)) {
 74 |               exampleMap.get(componentName)?.push(example.name);
 75 |             }
 76 |           }
 77 |         }
 78 |       }
 79 |     }
 80 |   }
 81 |   return exampleMap;
 82 | }
 83 | 
 84 | // Component category definitions
 85 | const componentCategories = {
 86 |   Layout: [
 87 |     "bento-grid",
 88 |     "dock",
 89 |     "file-tree",
 90 |     "grid-pattern",
 91 |     "interactive-grid-pattern",
 92 |     "dot-pattern",
 93 |   ],
 94 |   Media: [
 95 |     "hero-video-dialog",
 96 |     "terminal",
 97 |     "marquee",
 98 |     "script-copy-btn",
 99 |     "code-comparison",
100 |   ],
101 |   Motion: [
102 |     "blur-fade",
103 |     "scroll-progress",
104 |     "scroll-based-velocity",
105 |     "orbiting-circles",
106 |     "animated-circular-progress-bar",
107 |   ],
108 |   TextReveal: [
109 |     "text-animate",
110 |     "line-shadow-text",
111 |     "aurora-text",
112 |     "animated-shiny-text",
113 |     "animated-gradient-text",
114 |     "text-reveal",
115 |     "typing-animation",
116 |     "box-reveal",
117 |     "number-ticker",
118 |   ],
119 |   TextEffects: [
120 |     "word-rotate",
121 |     "flip-text",
122 |     "hyper-text",
123 |     "morphing-text",
124 |     "spinning-text",
125 |     "sparkles-text",
126 |   ],
127 |   Buttons: [
128 |     "rainbow-button",
129 |     "shimmer-button",
130 |     "shiny-button",
131 |     "interactive-hover-button",
132 |     "animated-subscribe-button",
133 |     "pulsating-button",
134 |     "ripple-button",
135 |   ],
136 |   Effects: [
137 |     "animated-beam",
138 |     "border-beam",
139 |     "shine-border",
140 |     "magic-card",
141 |     "meteors",
142 |     "neon-gradient-card",
143 |     "confetti",
144 |     "particles",
145 |     "cool-mode",
146 |     "scratch-to-reveal",
147 |   ],
148 |   Widgets: [
149 |     "animated-list",
150 |     "tweet-card",
151 |     "client-tweet-card",
152 |     "lens",
153 |     "pointer",
154 |     "avatar-circles",
155 |     "icon-cloud",
156 |     "globe",
157 |   ],
158 |   Backgrounds: [
159 |     "warp-background",
160 |     "flickering-grid",
161 |     "animated-grid-pattern",
162 |     "retro-grid",
163 |     "ripple",
164 |   ],
165 |   Devices: [
166 |     "safari",
167 |     "iphone-15-pro",
168 |     "android",
169 |   ],
170 | };
171 | 
172 | // Fetches detailed information about components in a specific category
173 | async function fetchComponentsByCategory(
174 |   categoryComponents: string[],
175 |   allComponents: any[],
176 |   exampleNamesByComponent: Map<string, string[]>,
177 | ) {
178 |   const componentResults = [];
179 | 
180 |   for (const componentName of categoryComponents) {
181 |     const component = allComponents.find((c) => c.name === componentName);
182 |     if (!component) continue;
183 | 
184 |     try {
185 |       const componentDetails = await fetchComponentDetails(componentName);
186 |       const componentContent = componentDetails.files[0]?.content;
187 | 
188 |       const relevantExampleNames =
189 |         exampleNamesByComponent.get(componentName) || [];
190 | 
191 |       // Generate installation instructions
192 |       const installInstructions = `Install the component using the same process as \
193 |       shadcn/ui. If you run into linter or dependency errors, make sure to install the \
194 |       component using these instructions. For example, with npm/npx: npx shadcn@latest add \
195 |       "https://magicui.design/r/${componentName}.json" (Rules: make sure the URL is wrapped in \
196 |       double quotes and use shadcn not shadcn-ui, or the command will fail). After installation, \ 
197 |       you can import the component like this: import { ${formatComponentName(component.name)} } from \
198 |       "@/components/ui/${componentName}";`;
199 |       
200 |       const disclaimerText = `The code below is for context only. It helps you understand \
201 |       the component's props, types, and behavior. To actually install and use the \
202 |       component, refer to the install instructions above. After installing, the component \
203 |       will be available for import via: import { ${formatComponentName(component.name)} } \
204 |       from "@/components/ui/${componentName}";`;
205 | 
206 |       const exampleDetailsList = await Promise.all(
207 |         relevantExampleNames.map((name) => fetchExampleDetails(name)),
208 |       );
209 | 
210 |       const formattedExamples = exampleDetailsList
211 |         .filter((details) => details !== null)
212 |         .map((details) => ({
213 |           name: details.name,
214 |           type: details.type,
215 |           description: details.description,
216 |           content: details.files[0]?.content,
217 |         }));
218 | 
219 |       const validatedComponent = IndividualComponentSchema.parse({
220 |         name: component.name,
221 |         type: component.type,
222 |         description: component.description,
223 |         install: installInstructions,
224 |         content: componentContent && disclaimerText + componentContent,
225 |         examples: formattedExamples,
226 |       });
227 | 
228 |       componentResults.push(validatedComponent);
229 |     } catch (error) {
230 |       console.error(`Error processing component ${componentName}:`, error);
231 |     }
232 |   }
233 | 
234 |   return componentResults;
235 | }
236 | 
237 | // Registers tools for each component category
238 | async function registerCategoryTools() {
239 |   const [components, allExampleComponents] = await Promise.all([
240 |     fetchUIComponents(),
241 |     fetchExampleComponents(),
242 |   ]);
243 | 
244 |   const exampleNamesByComponent =
245 |     buildExampleComponentMap(allExampleComponents);
246 | 
247 |   for (const [category, categoryComponents] of Object.entries(
248 |     componentCategories,
249 |   )) {
250 |     const componentNamesString = categoryComponents.join(", ");
251 | 
252 |     server.tool(
253 |       `get${category}`,
254 |       `Provides implementation details for ${componentNamesString} components.`,
255 |       {},
256 |       async () => {
257 |         try {
258 |           const categoryResults = await fetchComponentsByCategory(
259 |             categoryComponents,
260 |             components,
261 |             exampleNamesByComponent,
262 |           );
263 | 
264 |           return {
265 |             content: [
266 |               {
267 |                 type: "text",
268 |                 text: JSON.stringify(categoryResults, null, 2),
269 |               },
270 |             ],
271 |           };
272 |         } catch (error) {
273 |           let errorMessage = `Error processing ${category} components`;
274 |           if (error instanceof Error) {
275 |             errorMessage += `: ${error.message}`;
276 |           }
277 |           return {
278 |             content: [{ type: "text", text: errorMessage }],
279 |             isError: true,
280 |           };
281 |         }
282 |       },
283 |     );
284 |   }
285 | }
286 | 
287 | // Initialize category tools before starting the server
288 | registerCategoryTools()
289 |   .then(() => {
290 |     const transport = new StdioServerTransport();
291 |     server.connect(transport);
292 |   })
293 |   .catch((error) => {
294 |     console.error("Error registering category tools:", error);
295 |     const transport = new StdioServerTransport();
296 |     server.connect(transport);
297 |   });
```