@bamboocss/mcp 1.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md ADDED
@@ -0,0 +1,16 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Segun Adebayo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
6
+ documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
7
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
8
+ persons to whom the Software is furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
11
+ Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
14
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
15
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/dist/index.js ADDED
@@ -0,0 +1,323 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ MCP_CLIENTS: () => MCP_CLIENTS,
34
+ createMcpServer: () => createMcpServer,
35
+ initMcpConfig: () => initMcpConfig,
36
+ startMcpServer: () => startMcpServer
37
+ });
38
+ module.exports = __toCommonJS(index_exports);
39
+
40
+ // src/server.ts
41
+ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
42
+ var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
43
+ var import_logger = require("@bamboocss/logger");
44
+ var import_node = require("@bamboocss/node");
45
+ var import_token_dictionary = require("@bamboocss/token-dictionary");
46
+ var import_path = require("path");
47
+ var z = __toESM(require("zod/v4"));
48
+ var tokenCategorySchema = z.enum(import_token_dictionary.TOKEN_CATEGORIES).optional().describe("Filter by token category");
49
+ var json = (data) => ({
50
+ content: [{ type: "text", text: JSON.stringify(data) }]
51
+ });
52
+ function createMcpServer(options) {
53
+ const { ctx } = options;
54
+ const server = new import_mcp.McpServer({
55
+ name: "@bamboocss/mcp",
56
+ version: "1.0.0"
57
+ });
58
+ const recipeNames = ctx.recipes.keys;
59
+ const patternNames = ctx.patterns.keys;
60
+ const recipeNameSchema = recipeNames.length ? z.enum(recipeNames).optional().describe("Filter by recipe name") : z.string().optional().describe("Filter by recipe name");
61
+ const patternNameSchema = patternNames.length ? z.enum(patternNames).optional().describe("Filter by pattern name") : z.string().optional().describe("Filter by pattern name");
62
+ server.registerTool(
63
+ "get_tokens",
64
+ {
65
+ description: "Get all design tokens with their values, CSS variables, and usage examples",
66
+ inputSchema: { category: tokenCategorySchema }
67
+ },
68
+ async ({ category }) => {
69
+ const spec = ctx.getSpecOfType("tokens");
70
+ const data = category ? spec.data.filter((group) => group.type === category) : spec.data;
71
+ return json({ type: spec.type, data });
72
+ }
73
+ );
74
+ server.registerTool(
75
+ "get_semantic_tokens",
76
+ {
77
+ description: "Get semantic tokens with their conditional values (responsive, color modes)",
78
+ inputSchema: { category: tokenCategorySchema }
79
+ },
80
+ async ({ category }) => {
81
+ const spec = ctx.getSpecOfType("semantic-tokens");
82
+ const data = category ? spec.data.filter((group) => group.type === category) : spec.data;
83
+ return json({ type: spec.type, data });
84
+ }
85
+ );
86
+ server.registerTool(
87
+ "get_recipes",
88
+ {
89
+ description: "Get component recipes with their variants, default values, and usage examples",
90
+ inputSchema: { name: recipeNameSchema }
91
+ },
92
+ async ({ name }) => {
93
+ const spec = ctx.getSpecOfType("recipes");
94
+ const data = name ? spec.data.filter((item) => item.name === name) : spec.data;
95
+ return json({ type: spec.type, data });
96
+ }
97
+ );
98
+ server.registerTool(
99
+ "get_patterns",
100
+ {
101
+ description: "Get layout patterns with their properties and usage examples",
102
+ inputSchema: { name: patternNameSchema }
103
+ },
104
+ async ({ name }) => {
105
+ const spec = ctx.getSpecOfType("patterns");
106
+ const data = name ? spec.data.filter((item) => item.name === name) : spec.data;
107
+ return json({ type: spec.type, data });
108
+ }
109
+ );
110
+ server.registerTool(
111
+ "get_conditions",
112
+ { description: "Get all conditions (breakpoints, pseudo-classes, color modes) and their CSS values" },
113
+ async () => json(ctx.getSpecOfType("conditions"))
114
+ );
115
+ server.registerTool(
116
+ "get_keyframes",
117
+ { description: "Get keyframe animations defined in the theme" },
118
+ async () => json(ctx.getSpecOfType("keyframes"))
119
+ );
120
+ server.registerTool(
121
+ "get_text_styles",
122
+ { description: "Get text style compositions for typography" },
123
+ async () => json(ctx.getSpecOfType("text-styles"))
124
+ );
125
+ server.registerTool(
126
+ "get_layer_styles",
127
+ { description: "Get layer style compositions for visual styling" },
128
+ async () => json(ctx.getSpecOfType("layer-styles"))
129
+ );
130
+ server.registerTool(
131
+ "get_animation_styles",
132
+ { description: "Get animation style compositions" },
133
+ async () => json(ctx.getSpecOfType("animation-styles"))
134
+ );
135
+ server.registerTool(
136
+ "get_color_palette",
137
+ { description: "Get the color palette with all color values" },
138
+ async () => json(ctx.getSpecOfType("color-palette"))
139
+ );
140
+ server.registerTool(
141
+ "get_config",
142
+ { description: "Get the resolved Bamboo CSS configuration including paths, JSX settings, and output options" },
143
+ async () => json(ctx.config)
144
+ );
145
+ server.registerTool(
146
+ "get_usage_report",
147
+ {
148
+ description: "Get a usage report of design tokens and recipes across the codebase. Shows which tokens/recipes are used, unused, or missing. Useful for auditing, cleanup, and identifying dead code.",
149
+ inputSchema: {
150
+ scope: z.enum(["all", "token", "recipe"]).optional().describe("Analysis scope: token, recipe, or all (default)")
151
+ }
152
+ },
153
+ async ({ scope }) => {
154
+ const result = (0, import_node.analyze)(ctx);
155
+ const includeTokens = !scope || scope === "all" || scope === "token";
156
+ const includeRecipes = !scope || scope === "all" || scope === "recipe";
157
+ const report = {};
158
+ if (includeTokens && !ctx.tokens.isEmpty) {
159
+ const tokenReport = result.getTokenReport();
160
+ report.tokens = tokenReport.report.getSummary();
161
+ }
162
+ if (includeRecipes && !ctx.recipes.isEmpty()) {
163
+ const recipeReport = result.getRecipeReport();
164
+ report.recipes = recipeReport.report;
165
+ }
166
+ return json(report);
167
+ }
168
+ );
169
+ return server;
170
+ }
171
+ async function startMcpServer(options = {}) {
172
+ const { cwd = process.cwd(), config: configPath, silent = false, transport } = options;
173
+ if (silent) {
174
+ import_logger.logger.level = "silent";
175
+ }
176
+ const resolvedCwd = (0, import_path.resolve)(cwd);
177
+ const resolvedConfigPath = configPath ? (0, import_path.resolve)(configPath) : void 0;
178
+ const ctx = await (0, import_node.loadConfigAndCreateContext)({
179
+ cwd: resolvedCwd,
180
+ configPath: resolvedConfigPath
181
+ });
182
+ const server = createMcpServer({ ctx });
183
+ const serverTransport = transport ?? new import_stdio.StdioServerTransport();
184
+ await server.connect(serverTransport);
185
+ console.error("Bamboo CSS MCP server started");
186
+ console.error(`Working directory: ${resolvedCwd}`);
187
+ if (resolvedConfigPath) {
188
+ console.error(`Config path: ${resolvedConfigPath}`);
189
+ }
190
+ return server;
191
+ }
192
+
193
+ // src/init.ts
194
+ var p = __toESM(require("@clack/prompts"));
195
+ var import_logger2 = require("@bamboocss/logger");
196
+ var import_fs = require("fs");
197
+ var import_path2 = require("path");
198
+
199
+ // src/clients.ts
200
+ var MCP_CLIENTS = {
201
+ claude: {
202
+ name: "claude",
203
+ label: "Claude (.mcp.json)",
204
+ configPath: ".mcp.json",
205
+ configKey: "mcpServers"
206
+ },
207
+ cursor: {
208
+ name: "cursor",
209
+ label: "Cursor (.cursor/mcp.json)",
210
+ configPath: ".cursor/mcp.json",
211
+ configKey: "mcpServers"
212
+ },
213
+ vscode: {
214
+ name: "vscode",
215
+ label: "VS Code (.vscode/mcp.json)",
216
+ configPath: ".vscode/mcp.json",
217
+ configKey: "servers"
218
+ },
219
+ windsurf: {
220
+ name: "windsurf",
221
+ label: "Windsurf (.windsurf/mcp.json)",
222
+ configPath: ".windsurf/mcp.json",
223
+ configKey: "mcpServers"
224
+ },
225
+ codex: {
226
+ name: "codex",
227
+ label: "Codex (.codex/mcp.json)",
228
+ configPath: ".codex/mcp.json",
229
+ configKey: "mcpServers"
230
+ }
231
+ };
232
+ var CLIENT_NAMES = Object.keys(MCP_CLIENTS);
233
+ function isValidClient(client) {
234
+ return CLIENT_NAMES.includes(client);
235
+ }
236
+ function getClientConfig(client) {
237
+ return MCP_CLIENTS[client];
238
+ }
239
+ function generateMcpConfig(clientConfig) {
240
+ const serverConfig = {
241
+ command: "npx",
242
+ args: ["bamboo", "mcp"]
243
+ };
244
+ return {
245
+ [clientConfig.configKey]: {
246
+ bamboo: serverConfig
247
+ }
248
+ };
249
+ }
250
+
251
+ // src/init.ts
252
+ async function initMcpConfig(options = {}) {
253
+ const { cwd = process.cwd() } = options;
254
+ let { clients } = options;
255
+ p.intro("Bamboo MCP Setup");
256
+ if (!clients || clients.length === 0) {
257
+ const selected = await p.multiselect({
258
+ message: "Select AI clients to configure:",
259
+ options: CLIENT_NAMES.map((client) => ({
260
+ value: client,
261
+ label: MCP_CLIENTS[client].label
262
+ })),
263
+ required: true
264
+ });
265
+ if (p.isCancel(selected)) {
266
+ p.cancel("Setup cancelled.");
267
+ process.exit(0);
268
+ }
269
+ clients = selected;
270
+ }
271
+ const validClients = clients.filter((client) => {
272
+ if (!isValidClient(client)) {
273
+ import_logger2.logger.warn("mcp:init", `Unknown client: ${client}`);
274
+ return false;
275
+ }
276
+ return true;
277
+ });
278
+ if (validClients.length === 0) {
279
+ p.cancel("No valid clients selected.");
280
+ process.exit(1);
281
+ }
282
+ const results = [];
283
+ for (const client of validClients) {
284
+ const clientConfig = getClientConfig(client);
285
+ const configPath = (0, import_path2.resolve)(cwd, clientConfig.configPath);
286
+ const configDir = (0, import_path2.dirname)(configPath);
287
+ if (!(0, import_fs.existsSync)(configDir)) {
288
+ (0, import_fs.mkdirSync)(configDir, { recursive: true });
289
+ }
290
+ const newConfig = generateMcpConfig(clientConfig);
291
+ let finalConfig = newConfig;
292
+ if ((0, import_fs.existsSync)(configPath)) {
293
+ try {
294
+ const existingContent = (0, import_fs.readFileSync)(configPath, "utf-8");
295
+ const existingConfig = JSON.parse(existingContent);
296
+ finalConfig = {
297
+ ...existingConfig,
298
+ [clientConfig.configKey]: {
299
+ ...existingConfig[clientConfig.configKey],
300
+ ...newConfig[clientConfig.configKey]
301
+ }
302
+ };
303
+ } catch {
304
+ }
305
+ }
306
+ (0, import_fs.writeFileSync)(configPath, JSON.stringify(finalConfig, null, 2));
307
+ results.push({
308
+ client,
309
+ path: clientConfig.configPath,
310
+ created: true
311
+ });
312
+ }
313
+ p.note(results.map((r) => `${r.client}: ${r.path}`).join("\n"), "Created MCP configurations");
314
+ p.outro("MCP setup complete! Your AI assistants can now use Bamboo CSS tools.");
315
+ return results;
316
+ }
317
+ // Annotate the CommonJS export names for ESM import in node:
318
+ 0 && (module.exports = {
319
+ MCP_CLIENTS,
320
+ createMcpServer,
321
+ initMcpConfig,
322
+ startMcpServer
323
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,283 @@
1
+ // src/server.ts
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { logger } from "@bamboocss/logger";
5
+ import { analyze, loadConfigAndCreateContext } from "@bamboocss/node";
6
+ import { TOKEN_CATEGORIES } from "@bamboocss/token-dictionary";
7
+ import { resolve } from "path";
8
+ import * as z from "zod/v4";
9
+ var tokenCategorySchema = z.enum(TOKEN_CATEGORIES).optional().describe("Filter by token category");
10
+ var json = (data) => ({
11
+ content: [{ type: "text", text: JSON.stringify(data) }]
12
+ });
13
+ function createMcpServer(options) {
14
+ const { ctx } = options;
15
+ const server = new McpServer({
16
+ name: "@bamboocss/mcp",
17
+ version: "1.0.0"
18
+ });
19
+ const recipeNames = ctx.recipes.keys;
20
+ const patternNames = ctx.patterns.keys;
21
+ const recipeNameSchema = recipeNames.length ? z.enum(recipeNames).optional().describe("Filter by recipe name") : z.string().optional().describe("Filter by recipe name");
22
+ const patternNameSchema = patternNames.length ? z.enum(patternNames).optional().describe("Filter by pattern name") : z.string().optional().describe("Filter by pattern name");
23
+ server.registerTool(
24
+ "get_tokens",
25
+ {
26
+ description: "Get all design tokens with their values, CSS variables, and usage examples",
27
+ inputSchema: { category: tokenCategorySchema }
28
+ },
29
+ async ({ category }) => {
30
+ const spec = ctx.getSpecOfType("tokens");
31
+ const data = category ? spec.data.filter((group) => group.type === category) : spec.data;
32
+ return json({ type: spec.type, data });
33
+ }
34
+ );
35
+ server.registerTool(
36
+ "get_semantic_tokens",
37
+ {
38
+ description: "Get semantic tokens with their conditional values (responsive, color modes)",
39
+ inputSchema: { category: tokenCategorySchema }
40
+ },
41
+ async ({ category }) => {
42
+ const spec = ctx.getSpecOfType("semantic-tokens");
43
+ const data = category ? spec.data.filter((group) => group.type === category) : spec.data;
44
+ return json({ type: spec.type, data });
45
+ }
46
+ );
47
+ server.registerTool(
48
+ "get_recipes",
49
+ {
50
+ description: "Get component recipes with their variants, default values, and usage examples",
51
+ inputSchema: { name: recipeNameSchema }
52
+ },
53
+ async ({ name }) => {
54
+ const spec = ctx.getSpecOfType("recipes");
55
+ const data = name ? spec.data.filter((item) => item.name === name) : spec.data;
56
+ return json({ type: spec.type, data });
57
+ }
58
+ );
59
+ server.registerTool(
60
+ "get_patterns",
61
+ {
62
+ description: "Get layout patterns with their properties and usage examples",
63
+ inputSchema: { name: patternNameSchema }
64
+ },
65
+ async ({ name }) => {
66
+ const spec = ctx.getSpecOfType("patterns");
67
+ const data = name ? spec.data.filter((item) => item.name === name) : spec.data;
68
+ return json({ type: spec.type, data });
69
+ }
70
+ );
71
+ server.registerTool(
72
+ "get_conditions",
73
+ { description: "Get all conditions (breakpoints, pseudo-classes, color modes) and their CSS values" },
74
+ async () => json(ctx.getSpecOfType("conditions"))
75
+ );
76
+ server.registerTool(
77
+ "get_keyframes",
78
+ { description: "Get keyframe animations defined in the theme" },
79
+ async () => json(ctx.getSpecOfType("keyframes"))
80
+ );
81
+ server.registerTool(
82
+ "get_text_styles",
83
+ { description: "Get text style compositions for typography" },
84
+ async () => json(ctx.getSpecOfType("text-styles"))
85
+ );
86
+ server.registerTool(
87
+ "get_layer_styles",
88
+ { description: "Get layer style compositions for visual styling" },
89
+ async () => json(ctx.getSpecOfType("layer-styles"))
90
+ );
91
+ server.registerTool(
92
+ "get_animation_styles",
93
+ { description: "Get animation style compositions" },
94
+ async () => json(ctx.getSpecOfType("animation-styles"))
95
+ );
96
+ server.registerTool(
97
+ "get_color_palette",
98
+ { description: "Get the color palette with all color values" },
99
+ async () => json(ctx.getSpecOfType("color-palette"))
100
+ );
101
+ server.registerTool(
102
+ "get_config",
103
+ { description: "Get the resolved Bamboo CSS configuration including paths, JSX settings, and output options" },
104
+ async () => json(ctx.config)
105
+ );
106
+ server.registerTool(
107
+ "get_usage_report",
108
+ {
109
+ description: "Get a usage report of design tokens and recipes across the codebase. Shows which tokens/recipes are used, unused, or missing. Useful for auditing, cleanup, and identifying dead code.",
110
+ inputSchema: {
111
+ scope: z.enum(["all", "token", "recipe"]).optional().describe("Analysis scope: token, recipe, or all (default)")
112
+ }
113
+ },
114
+ async ({ scope }) => {
115
+ const result = analyze(ctx);
116
+ const includeTokens = !scope || scope === "all" || scope === "token";
117
+ const includeRecipes = !scope || scope === "all" || scope === "recipe";
118
+ const report = {};
119
+ if (includeTokens && !ctx.tokens.isEmpty) {
120
+ const tokenReport = result.getTokenReport();
121
+ report.tokens = tokenReport.report.getSummary();
122
+ }
123
+ if (includeRecipes && !ctx.recipes.isEmpty()) {
124
+ const recipeReport = result.getRecipeReport();
125
+ report.recipes = recipeReport.report;
126
+ }
127
+ return json(report);
128
+ }
129
+ );
130
+ return server;
131
+ }
132
+ async function startMcpServer(options = {}) {
133
+ const { cwd = process.cwd(), config: configPath, silent = false, transport } = options;
134
+ if (silent) {
135
+ logger.level = "silent";
136
+ }
137
+ const resolvedCwd = resolve(cwd);
138
+ const resolvedConfigPath = configPath ? resolve(configPath) : void 0;
139
+ const ctx = await loadConfigAndCreateContext({
140
+ cwd: resolvedCwd,
141
+ configPath: resolvedConfigPath
142
+ });
143
+ const server = createMcpServer({ ctx });
144
+ const serverTransport = transport ?? new StdioServerTransport();
145
+ await server.connect(serverTransport);
146
+ console.error("Bamboo CSS MCP server started");
147
+ console.error(`Working directory: ${resolvedCwd}`);
148
+ if (resolvedConfigPath) {
149
+ console.error(`Config path: ${resolvedConfigPath}`);
150
+ }
151
+ return server;
152
+ }
153
+
154
+ // src/init.ts
155
+ import * as p from "@clack/prompts";
156
+ import { logger as logger2 } from "@bamboocss/logger";
157
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
158
+ import { dirname, resolve as resolve2 } from "path";
159
+
160
+ // src/clients.ts
161
+ var MCP_CLIENTS = {
162
+ claude: {
163
+ name: "claude",
164
+ label: "Claude (.mcp.json)",
165
+ configPath: ".mcp.json",
166
+ configKey: "mcpServers"
167
+ },
168
+ cursor: {
169
+ name: "cursor",
170
+ label: "Cursor (.cursor/mcp.json)",
171
+ configPath: ".cursor/mcp.json",
172
+ configKey: "mcpServers"
173
+ },
174
+ vscode: {
175
+ name: "vscode",
176
+ label: "VS Code (.vscode/mcp.json)",
177
+ configPath: ".vscode/mcp.json",
178
+ configKey: "servers"
179
+ },
180
+ windsurf: {
181
+ name: "windsurf",
182
+ label: "Windsurf (.windsurf/mcp.json)",
183
+ configPath: ".windsurf/mcp.json",
184
+ configKey: "mcpServers"
185
+ },
186
+ codex: {
187
+ name: "codex",
188
+ label: "Codex (.codex/mcp.json)",
189
+ configPath: ".codex/mcp.json",
190
+ configKey: "mcpServers"
191
+ }
192
+ };
193
+ var CLIENT_NAMES = Object.keys(MCP_CLIENTS);
194
+ function isValidClient(client) {
195
+ return CLIENT_NAMES.includes(client);
196
+ }
197
+ function getClientConfig(client) {
198
+ return MCP_CLIENTS[client];
199
+ }
200
+ function generateMcpConfig(clientConfig) {
201
+ const serverConfig = {
202
+ command: "npx",
203
+ args: ["bamboo", "mcp"]
204
+ };
205
+ return {
206
+ [clientConfig.configKey]: {
207
+ bamboo: serverConfig
208
+ }
209
+ };
210
+ }
211
+
212
+ // src/init.ts
213
+ async function initMcpConfig(options = {}) {
214
+ const { cwd = process.cwd() } = options;
215
+ let { clients } = options;
216
+ p.intro("Bamboo MCP Setup");
217
+ if (!clients || clients.length === 0) {
218
+ const selected = await p.multiselect({
219
+ message: "Select AI clients to configure:",
220
+ options: CLIENT_NAMES.map((client) => ({
221
+ value: client,
222
+ label: MCP_CLIENTS[client].label
223
+ })),
224
+ required: true
225
+ });
226
+ if (p.isCancel(selected)) {
227
+ p.cancel("Setup cancelled.");
228
+ process.exit(0);
229
+ }
230
+ clients = selected;
231
+ }
232
+ const validClients = clients.filter((client) => {
233
+ if (!isValidClient(client)) {
234
+ logger2.warn("mcp:init", `Unknown client: ${client}`);
235
+ return false;
236
+ }
237
+ return true;
238
+ });
239
+ if (validClients.length === 0) {
240
+ p.cancel("No valid clients selected.");
241
+ process.exit(1);
242
+ }
243
+ const results = [];
244
+ for (const client of validClients) {
245
+ const clientConfig = getClientConfig(client);
246
+ const configPath = resolve2(cwd, clientConfig.configPath);
247
+ const configDir = dirname(configPath);
248
+ if (!existsSync(configDir)) {
249
+ mkdirSync(configDir, { recursive: true });
250
+ }
251
+ const newConfig = generateMcpConfig(clientConfig);
252
+ let finalConfig = newConfig;
253
+ if (existsSync(configPath)) {
254
+ try {
255
+ const existingContent = readFileSync(configPath, "utf-8");
256
+ const existingConfig = JSON.parse(existingContent);
257
+ finalConfig = {
258
+ ...existingConfig,
259
+ [clientConfig.configKey]: {
260
+ ...existingConfig[clientConfig.configKey],
261
+ ...newConfig[clientConfig.configKey]
262
+ }
263
+ };
264
+ } catch {
265
+ }
266
+ }
267
+ writeFileSync(configPath, JSON.stringify(finalConfig, null, 2));
268
+ results.push({
269
+ client,
270
+ path: clientConfig.configPath,
271
+ created: true
272
+ });
273
+ }
274
+ p.note(results.map((r) => `${r.client}: ${r.path}`).join("\n"), "Created MCP configurations");
275
+ p.outro("MCP setup complete! Your AI assistants can now use Bamboo CSS tools.");
276
+ return results;
277
+ }
278
+ export {
279
+ MCP_CLIENTS,
280
+ createMcpServer,
281
+ initMcpConfig,
282
+ startMcpServer
283
+ };
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@bamboocss/mcp",
3
+ "version": "1.11.1",
4
+ "description": "MCP server for Bamboo CSS AI assistants",
5
+ "homepage": "https://bamboo-css.com",
6
+ "license": "MIT",
7
+ "author": "Segun Adebayo <joseshegs@gmail.com>",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/chakra-ui/bamboo.git",
11
+ "directory": "packages/mcp"
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "sideEffects": false,
17
+ "main": "dist/index.js",
18
+ "module": "dist/index.mjs",
19
+ "types": "dist/index.d.ts",
20
+ "exports": {
21
+ ".": {
22
+ "source": "./src/index.ts",
23
+ "types": "./dist/index.d.ts",
24
+ "require": "./dist/index.js",
25
+ "import": {
26
+ "types": "./dist/index.d.mts",
27
+ "default": "./dist/index.mjs"
28
+ }
29
+ },
30
+ "./package.json": "./package.json"
31
+ },
32
+ "publishConfig": {
33
+ "access": "public"
34
+ },
35
+ "dependencies": {
36
+ "@clack/prompts": "0.11.0",
37
+ "@modelcontextprotocol/sdk": "^1.29.0",
38
+ "zod": "^4.0.0",
39
+ "@bamboocss/logger": "1.11.1",
40
+ "@bamboocss/token-dictionary": "1.11.1",
41
+ "@bamboocss/node": "1.11.1",
42
+ "@bamboocss/types": "1.11.1"
43
+ },
44
+ "scripts": {
45
+ "build": "tsup src/index.ts --format=esm,cjs",
46
+ "build-fast": "tsup src/index.ts --format=esm,cjs",
47
+ "dev": "pnpm build-fast --watch"
48
+ }
49
+ }