# Directory Structure
```
├── .gitignore
├── .husky
│ └── commit-msg
├── .npmignore
├── .npmrc
├── commitlint.config.mjs
├── LICENSE
├── package.json
├── pnpm-lock.yaml
├── public
│ └── logo.svg
├── README.md
├── src
│ ├── lib
│ │ ├── categories.ts
│ │ └── config.ts
│ ├── server.ts
│ └── utils
│ ├── api.ts
│ ├── formatters.ts
│ ├── index.ts
│ └── schemas.ts
└── tsconfig.json
```
# Files
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
```
tag-version-prefix="v"
message="chore(release): %s"
```
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
```
.DS_Store
dist/
node_modules/
tsconfig.tsbuildinfo
.husky/_
.env
.env.*
```
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
```
# Source files
src/
tsconfig.json
tsconfig.tsbuildinfo
# Development files
.git/
.gitignore
.DS_Store
# Node modules and lock files
node_modules/
pnpm-lock.yaml
yarn.lock
package-lock.json
# Development and testing
*.log
coverage/
.nyc_output/
.env
.env.local
.env.*.local
# IDE files
.vscode/
.idea/
*.swp
*.swo
# Build artifacts (keep only what's in "files" array)
# Everything else will be excluded by default since we specified "files": ["dist"]
```
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
```markdown
<!-- PROJECT LOGO -->
<br />
<div align="center">
<a href="https://github.com/stackzero-labs/ui">
<img src="public/logo.svg" alt="Logo" width="80" height="80">
</a>
<h3 align="center">@stackzero-labs/mcp</h3>
<p align="center">
Official MCP (Model Context Protocol) server for stackzero-labs/ui.
<br />
<a href="https://ui.stackzero.co"><strong>Official Docs »</strong></a>
<br />
<br />
<a href="https://ui.stackzero.co/get-started">Get started</a>
·
<a href="https://github.com/stackzero-labs/mcp/issues/new?labels=bug&template=bug-report---.md">Report Bug</a>
·
<a href="https://github.com/stackzero-labs/mcp/issues/new?labels=enhancement&template=feature-request---.md">Request Feature</a>
</p>
</div>
## Overview
This package allows you to run a model context server for stackzero-labs/ui components, enabling you to use the MCP protocol with your applications.
## 1-click install in Cursor
[](https://cursor.com/install-mcp?name=%40stackzero-labs%2Fmcp&config=eyJjb21tYW5kIjoibnB4IC15IEBzdGFja3plcm8tbGFicy9tY3BAbGF0ZXN0In0%3D)
## Installation
```bash
npm install @stackzero-labs/mcp
```
## Usage
### As a standalone server
```bash
npx @stackzero-labs/mcp
```
### In Claude Desktop
Add to your Claude Desktop configuration:
```json
{
"mcpServers": {
"@stackzero-labs/mcp": {
"command": "npx",
"args": ["-y", "@stackzero-labs/mcp@latest"]
}
}
}
```
### In Cursor (manual setup)
Go to Cursor settings, select `MCP`. Add to your Cursor configuration:
```json
{
"mcpServers": {
"@stackzero-labs/mcp": {
"command": "npx",
"args": ["-y", "@stackzero-labs/mcp@latest"]
}
}
}
```
### Development
```bash
# Install dependencies
pnpm install
# Build the project
pnpm build
# Run in development mode
pnpm dev
# Inspect the MCP server
pnpm inspect
```
## License
See [LICENSE](LICENSE) for details.
```
--------------------------------------------------------------------------------
/src/utils/index.ts:
--------------------------------------------------------------------------------
```typescript
export * from "./api.js";
export * from "./formatters.js";
export * from "./schemas.js";
```
--------------------------------------------------------------------------------
/src/lib/config.ts:
--------------------------------------------------------------------------------
```typescript
/**
* General configuration for MCP service
*/
export const mcpConfig = {
projectName: "@stackzero-labs/ui",
baseUrl: "https://ui.stackzero.co",
registryUrl: "https://ui.stackzero.co/r",
registryFileUrl: "https://ui.stackzero.co/registry.json",
};
```
--------------------------------------------------------------------------------
/src/utils/formatters.ts:
--------------------------------------------------------------------------------
```typescript
/**
* Formats a component name by converting it from kebab-case to PascalCase.
* @param componentName
* @returns
*/
export function formatComponentName(componentName: string): string {
return componentName
.split("-")
.map((part) => {
return part.charAt(0).toUpperCase() + part.slice(1);
})
.join("");
}
```
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
```json
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "node",
"outDir": "dist",
"rootDir": "src",
"sourceMap": true,
"declaration": true,
"strict": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
```
--------------------------------------------------------------------------------
/public/logo.svg:
--------------------------------------------------------------------------------
```
<svg width="217" height="216" viewBox="0 0 217 216" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1134_83)">
<path d="M91.8543 167.855C112.307 173.221 135.092 167.808 151.24 151.659C167.389 135.511 172.803 112.726 167.437 92.2731L91.8543 167.855Z" fill="#00FF9D"/>
<path d="M158.581 74.1351C156.455 71.0144 154.008 68.047 151.241 65.2791C127.387 41.426 88.714 41.426 64.8609 65.2791C41.0078 89.1322 41.0078 127.806 64.8609 151.659C67.6288 154.427 70.5962 156.873 73.7169 158.999L158.581 74.1351Z" fill="#8940FF"/>
</g>
<defs>
<clipPath id="clip0_1134_83">
<rect width="152.699" height="152.699" fill="white" transform="translate(108.051 215.949) rotate(-135)"/>
</clipPath>
</defs>
</svg>
```
--------------------------------------------------------------------------------
/commitlint.config.mjs:
--------------------------------------------------------------------------------
```
const Configuration = {
extends: ["@commitlint/config-conventional"],
rules: {
"type-enum": [
2,
"always",
[
"feat", // A new feature
"fix", // A bug fix
"docs", // Documentation only changes
"style", // Changes that do not affect the meaning of the code
"refactor", // A code change that neither fixes a bug nor adds a feature
"perf", // A code change that improves performance
"test", // Adding missing tests or correcting existing tests
"chore", // Changes to the build process or auxiliary tools
"ci", // Changes to CI configuration files and scripts
"build", // Changes that affect the build system or external dependencies
"revert", // Reverts a previous commit
],
],
"type-case": [2, "always", "lower-case"],
"type-empty": [2, "never"],
"scope-case": [2, "always", "lower-case"],
"subject-case": [
2,
"never",
["sentence-case", "start-case", "pascal-case", "upper-case"],
],
"subject-empty": [2, "never"],
"subject-full-stop": [2, "never", "."],
"header-max-length": [2, "always", 100],
"body-leading-blank": [1, "always"],
"body-max-line-length": [2, "always", 100],
"footer-leading-blank": [1, "always"],
"footer-max-line-length": [2, "always", 100],
},
};
export default Configuration;
```
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
```json
{
"name": "@stackzero-labs/mcp",
"version": "0.4.0",
"author": "@stackzero-labs",
"keywords": [
"mcp",
"model-context-protocol",
"ai",
"claude",
"server"
],
"license": "MIT",
"description": "MCP (Model Context Protocol) server for stackzero-labs/ui",
"homepage": "https://ui.stackzero.co",
"repository": {
"type": "git",
"url": "git+https://github.com/stackzero-labs/mcp.git"
},
"bugs": {
"url": "https://github.com/stackzero-labs/mcp/issues"
},
"scripts": {
"build": "tsup src/server.ts --format esm,cjs --dts --out-dir dist",
"build:old": "tsc && shx chmod +x dist/*.js",
"start": "node dist/server.js",
"dev": "tsx watch src/server.ts",
"inspect": "mcp-inspector node dist/server.js",
"prepublishOnly": "pnpm run build",
"prepare": "husky"
},
"type": "module",
"main": "./dist/server.js",
"module": "./dist/server.js",
"types": "./dist/server.d.ts",
"bin": {
"mcp": "./dist/server.js"
},
"files": [
"dist"
],
"dependencies": {
"@modelcontextprotocol/sdk": "^1.12.3",
"zod": "^3.25.64"
},
"devDependencies": {
"@commitlint/cli": "^19.8.1",
"@commitlint/config-conventional": "^19.8.1",
"@modelcontextprotocol/inspector": "^0.14.2",
"@types/node": "^22.14.1",
"husky": "^9.1.7",
"shx": "^0.4.0",
"tsup": "^8.5.0",
"tsx": "^4.20.3",
"typescript": "^5.8.3"
}
}
```
--------------------------------------------------------------------------------
/src/utils/schemas.ts:
--------------------------------------------------------------------------------
```typescript
import { z } from "zod";
import { registry } from "zod/dist/types/v4";
export const ComponentSchema = z.object({
name: z.string(),
type: z.string(),
description: z.string().optional(),
});
export const BlockSchema = ComponentSchema.extend({
name: z.string(),
type: z.string(),
description: z.string().optional(),
});
const ExampleSchema = z.object({
name: z.string(),
type: z.string(),
description: z.string(),
content: z.string(),
});
export const IndividualComponentSchema = ComponentSchema.extend({
install: z.string(),
content: z.string(),
examples: z.array(ExampleSchema),
});
export const IndividualBlockSchema = BlockSchema.extend({
install: z.string(),
content: z.string(),
examples: z.array(ExampleSchema),
});
export const ComponentDetailSchema = z.object({
name: z.string(),
type: z.string(),
files: z.array(
z.object({
content: z.string(),
})
),
});
export const BlockDetailSchema = z.object({
name: z.string(),
type: z.string(),
registryDependencies: z.array(z.string()),
files: z.array(
z.object({
content: z.string(),
})
),
});
export const ExampleComponentSchema = z.object({
name: z.string(),
type: z.string(),
description: z.string().optional(),
registryDependencies: z.array(z.string()),
});
export const ExampleDetailSchema = z.object({
name: z.string(),
type: z.string(),
description: z.string(),
files: z.array(
z.object({
content: z.string(),
})
),
});
```
--------------------------------------------------------------------------------
/src/lib/categories.ts:
--------------------------------------------------------------------------------
```typescript
// Component category definitions
export const componentCategories = {
Ratings: [
"star-rating-basic",
"star-rating-fractions",
"upvote-rating-basic",
"upvote-rating-animated",
"face-rating-basic",
"face-rating-gradient",
],
Images: ["image-viewer-basic", "image-viewer-motion", "image-carousel-basic"],
Products: [
"price-format-basic",
"price-format-sale",
"quantity-input-basic",
"variant-color-selector-basic",
"variant-selector-basic",
"variant-selector-images",
"variant-selector-multiple",
],
Inputs: ["input-icon", "phone-number-input-basic"],
};
export const blocksCategories = {
Addresses: ["address-01-block", "address-02-block"],
Banners: [
"banner-01-block",
"banner-02-block",
"banner-03-block",
"banner-04-block",
"banner-05-block",
"banner-06-block",
"banner-07-block",
"banner-08-block",
"banner-09-block",
"banner-10-block",
"banner-11-block",
"banner-12-block",
],
ProductCards: [
"product-card-01-block",
"product-card-02-block",
"product-card-03-block",
"product-card-04-block",
"product-card-05-block",
"product-card-06-block",
"product-card-07-block",
"product-card-08-block",
"product-card-09-block",
"product-card-10-block",
"product-card-11-block",
"product-card-12-block",
"product-card-13-block",
],
ProductVariants: [
"product-variant-01-block",
"product-variant-02-block",
"product-variant-03-block",
"product-variant-04-block",
"product-variant-05-block",
],
Reviews: [
"review-01-block",
"review-02-block",
"review-03-block",
"review-04-block",
"review-05-block",
"review-06-block",
"review-07-block",
"review-08-block",
"review-09-block",
"review-10-block",
],
Carts: ["cart-01-block"],
};
```
--------------------------------------------------------------------------------
/src/utils/api.ts:
--------------------------------------------------------------------------------
```typescript
import { mcpConfig } from "../lib/config.js";
import {
BlockDetailSchema,
BlockSchema,
ComponentDetailSchema,
ComponentSchema,
ExampleComponentSchema,
ExampleDetailSchema,
} from "./schemas.js";
/**
* Fetches all UI components from the registry.
* @returns An array of components with their details.
*/
export async function fetchUIComponents() {
try {
const response = await fetch(mcpConfig.registryFileUrl);
if (!response.ok) {
throw new Error(
`Failed to fetch registry.json: ${response.statusText} - Status: ${response.status}`
);
}
const data = await response.json();
return data.registry
.filter((item: any) => item.type === "registry:component")
.map((item: any) => {
try {
return ComponentSchema.parse({
name: item.name,
type: item.type,
description: item.description,
});
} catch (parseError) {
return null;
}
});
} catch (error) {
return [];
}
}
/**
* Fetches all UI blocks from the registry.
* @returns An array of UI blocks.
*/
export async function fetchUIBlocks() {
try {
const response = await fetch(mcpConfig.registryFileUrl);
if (!response.ok) {
throw new Error(
`Failed to fetch registry.json: ${response.statusText} - Status: ${response.status}`
);
}
const data = await response.json();
return data.registry
.filter((item: any) => item.type === "registry:block")
.map((item: any) => {
try {
return BlockSchema.parse({
name: item.name,
type: item.type,
description: item.description,
});
} catch (parseError) {
return null;
}
});
} catch (error) {
return [];
}
}
/**
* Fetches details for a specific component from the registry.
* @param componentName The name of the component.
* @returns The details of the component.
*/
export async function fetchComponentDetails(componentName: string) {
try {
const response = await fetch(
`${mcpConfig.registryUrl}/${componentName}.json`
);
if (!response.ok) {
throw new Error(
`Failed to fetch component ${componentName}: ${response.statusText}`
);
}
const data = await response.json();
return ComponentDetailSchema.parse(data);
} catch (error) {
console.error(`Error fetching component ${componentName}:`, error);
throw error;
}
}
/**
* Fetches details for a specific component from the registry.
* @param componentName The name of the component.
* @returns The details of the component.
*/
export async function fetchBlockDetails(blockName: string) {
try {
const response = await fetch(`${mcpConfig.registryUrl}/${blockName}.json`);
if (!response.ok) {
throw new Error(
`Failed to fetch block ${blockName}: ${response.statusText}`
);
}
const data = await response.json();
return BlockDetailSchema.parse(data);
} catch (error) {
console.error(`Error fetching block ${blockName}:`, error);
throw error;
}
}
/**
* Fetches example components from the registry.
* @returns An array of example components.
*/
export async function fetchExampleComponents() {
try {
const response = await fetch(mcpConfig.registryFileUrl);
const data = await response.json();
return data.registry
.filter((item: any) => item.type === "registry:example")
.map((item: any) => {
return ExampleComponentSchema.parse({
name: item.name,
type: item.type,
description: item.description,
registryDependencies: item.registryDependencies,
});
});
} catch (error) {
console.error("Error fetching example components:", error);
return [];
}
}
/**
* Fetches details for a specific example component.
* @param exampleName The name of the example component.
* @returns The details of the example component.
*/
export async function fetchExampleDetails(exampleName: string) {
try {
const response = await fetch(`${mcpConfig.registryUrl}/${exampleName}`);
if (!response.ok) {
throw new Error(
`Failed to fetch example details for ${exampleName}: ${response.statusText}`
);
}
const data = await response.json();
return ExampleDetailSchema.parse(data);
} catch (error) {
console.error(`Error fetching example details for ${exampleName}:`, error);
throw error;
}
}
```
--------------------------------------------------------------------------------
/src/server.ts:
--------------------------------------------------------------------------------
```typescript
#!/usr/bin/env node
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
IndividualComponentSchema,
fetchComponentDetails,
fetchBlockDetails,
fetchExampleComponents,
fetchExampleDetails,
fetchUIBlocks,
fetchUIComponents,
IndividualBlockSchema,
} from "./utils/index.js";
import { formatComponentName } from "./utils/formatters.js";
import { blocksCategories, componentCategories } from "./lib/categories.js";
// Initialize the MCP Server
const server = new McpServer({
name: "@stackzero-labs/mcp",
version: "0.2.0",
});
// Register the main tool for getting all components
server.tool(
"getUIComponents",
"Provides a comprehensive list of all stackzero-labs/ui components.",
{},
async () => {
try {
const uiComponents = await fetchUIComponents();
return {
content: [
{
type: "text",
text: JSON.stringify(uiComponents, null, 2),
},
],
};
} catch (error) {
return {
content: [
{
type: "text",
text: "Failed to fetch stackzero-labs/ui components",
},
],
isError: true,
};
}
}
);
// Register the main tool for getting all blocks
server.tool(
"getUIBlocks",
"Provides a comprehensive list of all stackzero-labs/ui blocks.",
{},
async () => {
try {
const uiBlocks = await fetchUIBlocks();
return {
content: [
{
type: "text",
text: JSON.stringify(uiBlocks, null, 2),
},
],
};
} catch (error) {
return {
content: [
{
type: "text",
text: "Failed to fetch stackzero-labs/ui blocks",
},
],
};
}
}
);
/**
* Creates a registry mapping component names to their example implementations.
* @param exampleComponentList - The list of example components to process.
* @returns A map where each key is a component name and the value is an array of example names.
*/
function createComponentExampleRegistry(
exampleComponentList: Array<{
name: string;
registryDependencies?: string[];
}>
): Map<string, string[]> {
const componentRegistry = new Map<string, string[]>();
for (const exampleItem of exampleComponentList) {
if (
exampleItem.registryDependencies &&
Array.isArray(exampleItem.registryDependencies)
) {
for (const dependencyUrl of exampleItem.registryDependencies) {
if (
typeof dependencyUrl === "string" &&
dependencyUrl.includes("stackzero.co")
) {
const nameExtraction = dependencyUrl.match(/\/r\/([^\/]+)$/);
if (nameExtraction && nameExtraction[1]) {
const extractedComponentName = nameExtraction[1];
if (!componentRegistry.has(extractedComponentName)) {
componentRegistry.set(extractedComponentName, []);
}
if (
!componentRegistry
.get(extractedComponentName)
?.includes(exampleItem.name)
) {
componentRegistry
.get(extractedComponentName)
?.push(exampleItem.name);
}
}
}
}
}
}
return componentRegistry;
}
/**
* Fetches components and blocks by category, processing each category's components and blocks.
* @param categoryComponents - The list of component names in the category.
* @param categoryBlocks - The list of block names in the category.
* @returns An object containing the processed components and blocks.
*/
async function fetchComponentsByCategory(
categoryComponents: string[],
allComponents: any[],
exampleNamesByComponent: Map<string, string[]>
) {
const componentResults = [];
for (const componentName of categoryComponents) {
const component = allComponents.find((c) => c.name === componentName);
if (!component) continue;
try {
const componentDetails = await fetchComponentDetails(componentName);
const componentContent = componentDetails.files[0]?.content;
const relevantExampleNames =
exampleNamesByComponent.get(componentName) || [];
// Generate installation instructions
const installInstructions = `You can install the component/blocks using \
shadcn/ui CLI. For example, with npx: npx shadcn@latest add \
"https://ui.stackzero.co/r/${componentName}.json" (Rules: make sure the URL is wrapped in \
double quotes. Once installed, \
you can import the component like this: import { ${formatComponentName(
component.name
)} } from \
"@/components/ui/${componentName}";`;
const disclaimerText = `The code below is for context only. It helps you understand
the component's props, types, and behavior. After installing, the component
will be available for import via: import { ${formatComponentName(
component.name
)} } \
from "@/components/ui/${componentName}";`;
const exampleDetailsList = await Promise.all(
relevantExampleNames.map((name) => fetchExampleDetails(name))
);
const formattedExamples = exampleDetailsList
.filter((details) => details !== null)
.map((details) => ({
name: details.name,
type: details.type,
description: details.description,
content: details.files[0]?.content,
}));
const validatedComponent = IndividualComponentSchema.parse({
name: component.name,
type: component.type,
description: component.description,
install: installInstructions,
content: componentContent && disclaimerText + componentContent,
examples: formattedExamples,
});
componentResults.push(validatedComponent);
} catch (error) {
console.error(`Error processing component ${componentName}:`, error);
}
}
return componentResults;
}
/**
* Fetches blocks by category, processing each block in the category.
* @param categoryBlocks - The list of block names in the category.
* @param allBlocks - The complete list of blocks to search from.
* @returns An array of processed blocks.
*/
async function fetchBlocksByCategory(
categoryBlocks: string[],
allBlocks: any[]
) {
const blockResults = [];
for (const blockName of categoryBlocks) {
const block = allBlocks.find((b) => b.name === blockName);
if (!block) continue;
try {
const blockDetails = await fetchBlockDetails(blockName);
const blockContent = blockDetails.files[0]?.content;
// Generate installation instructions
const installInstructions = `You can install the blocks using \
shadcn/ui CLI. For example, with npx: npx shadcn@latest add \
"https://ui.stackzero.co/r/${blockName}.json" (Rules: make sure the URL is wrapped in \
double quotes. Once installed, \
you can import the block like this: import { ${formatComponentName(
block.name
)} } from \
"@/components/ui/${blockName}";`;
const disclaimerText = `The code below is for context only. It helps you understand
the block's props, types, and behavior. After installing, the block
will be available for import via: import { ${formatComponentName(
block.name
)} } \
from "@/components/ui/${blockName}";`;
const validatedBlock = IndividualBlockSchema.parse({
name: block.name,
type: block.type,
description: block.description,
install: installInstructions,
content: blockContent && disclaimerText + blockContent,
examples: [], // Blocks typically don't have examples, but can be added if needed
});
blockResults.push(validatedBlock);
} catch (error) {
console.error(`Error processing block ${blockName}:`, error);
}
}
return blockResults;
}
// Registers tools for each component category
async function registerComponentsCategoryTools() {
const [components, allExampleComponents] = await Promise.all([
fetchUIComponents(),
fetchExampleComponents(),
]);
const exampleNamesByComponent =
createComponentExampleRegistry(allExampleComponents);
// console.error(
// "🔍 Found example names by component:",
// exampleNamesByComponent
// );
for (const [category, categoryComponents] of Object.entries(
componentCategories
)) {
const componentNamesString = categoryComponents.join(", ");
server.tool(
`get${category}`,
`Provides implementation details for ${componentNamesString} components.`,
{},
async () => {
try {
const categoryResults = await fetchComponentsByCategory(
categoryComponents,
components,
exampleNamesByComponent
);
return {
content: [
{
type: "text",
text: JSON.stringify(categoryResults, null, 2),
},
],
};
} catch (error) {
let errorMessage = `Error processing ${category} components`;
if (error instanceof Error) {
errorMessage += `: ${error.message}`;
}
return {
content: [{ type: "text", text: errorMessage }],
isError: true,
};
}
}
);
}
}
async function registerBlocksCategoryTools() {
const [blocks] = await Promise.all([fetchUIBlocks()]);
// console.error(
// "🔍 Found example names by component:",
// exampleNamesByComponent
// );
for (const [category, categoryBlocks] of Object.entries(blocksCategories)) {
const blockNamesString = categoryBlocks.join(", ");
server.tool(
`get${category}`,
`Provides implementation details for ${blockNamesString} blocks.`,
{},
async () => {
try {
const categoryResults = await fetchBlocksByCategory(
categoryBlocks,
blocks
);
return {
content: [
{
type: "text",
text: JSON.stringify(categoryResults, null, 2),
},
],
};
} catch (error) {
let errorMessage = `Error processing ${category} blocks`;
if (error instanceof Error) {
errorMessage += `: ${error.message}`;
}
return {
content: [{ type: "text", text: errorMessage }],
isError: true,
};
}
}
);
}
}
// Start the MCP server
async function startServer() {
try {
// Initialize category tools first
await registerComponentsCategoryTools();
await registerBlocksCategoryTools();
// Connect to stdio transport
const transport = new StdioServerTransport();
await server.connect(transport);
} catch (error) {
console.error("❌ Error starting MCP server:", error);
// Try to start server anyway with basic functionality
try {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("⚠️ MCP server started with limited functionality");
} catch (connectionError) {
console.error("❌ Failed to connect to transport:", connectionError);
process.exit(1);
}
}
}
// Start the server
startServer();
```