ai-react-animations 1.2.1 → 1.3.0

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/README.md CHANGED
@@ -136,23 +136,32 @@ import { FloatingLogin } from 'ai-react-animations';
136
136
 
137
137
  ## MCP Server (For AI Assistants)
138
138
 
139
- This package includes an MCP (Model Context Protocol) server that allows AI assistants like Claude to help users add animation components to their projects.
139
+ This package includes an MCP (Model Context Protocol) server that allows AI assistants like Claude, Cursor, and Windsurf to help users add animation components to their projects.
140
140
 
141
141
  ### Quick Setup
142
142
 
143
- Add to your `.mcp.json` file:
143
+ Run one command to configure MCP for your AI coding tool:
144
144
 
145
- ```json
146
- {
147
- "mcpServers": {
148
- "ai-react-animations": {
149
- "command": "npx",
150
- "args": ["tsx", "node_modules/ai-react-animations/mcp/server.ts"]
151
- }
152
- }
153
- }
145
+ ```bash
146
+ # Interactive mode - select your tool
147
+ npx ai-react-animations init
148
+
149
+ # Or specify directly
150
+ npx ai-react-animations init --client claude
151
+ npx ai-react-animations init --client cursor
152
+ npx ai-react-animations init --client windsurf
154
153
  ```
155
154
 
155
+ Then restart your AI tool to load the MCP server.
156
+
157
+ ### Supported AI Tools
158
+
159
+ | Tool | Config Location |
160
+ |------|-----------------|
161
+ | Claude Code | `~/.claude/claude_desktop_config.json` or `~/.mcp.json` |
162
+ | Cursor | `.cursor/mcp.json` or `~/.cursor/mcp.json` |
163
+ | Windsurf | `~/.codeium/windsurf/mcp_config.json` |
164
+
156
165
  ### Available MCP Tools
157
166
 
158
167
  | Tool | Description |
@@ -162,15 +171,22 @@ Add to your `.mcp.json` file:
162
171
  | `add_component` | Get instructions to add a component |
163
172
  | `get_install_command` | Get npm install command |
164
173
 
165
- ### Usage with Claude
174
+ ### Usage with AI Assistants
166
175
 
167
- Once configured, you can ask Claude:
176
+ Once configured, you can ask:
168
177
  - "List all animation components"
169
178
  - "Add the LoadingDots component to my project"
170
179
  - "Show me the PulseCircle component details"
171
180
  - "What dependencies do I need for FloatingLogin?"
172
181
 
173
- For detailed MCP setup instructions, see [MCP-GUIDE.md](./MCP-GUIDE.md).
182
+ ### CLI Commands
183
+
184
+ ```bash
185
+ npx ai-react-animations --help # Show help
186
+ npx ai-react-animations init # Interactive setup
187
+ npx ai-react-animations init --client X # Direct setup for client
188
+ npx ai-react-animations serve # Start MCP server manually
189
+ ```
174
190
 
175
191
  ---
176
192
 
@@ -0,0 +1,274 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
25
+
26
+ // mcp/cli.ts
27
+ var fs = __toESM(require("fs"));
28
+ var path = __toESM(require("path"));
29
+ var os = __toESM(require("os"));
30
+ var readline = __toESM(require("readline"));
31
+ var import_child_process = require("child_process");
32
+ var PACKAGE_NAME = "ai-react-animations";
33
+ var CLIENT_CONFIGS = {
34
+ claude: {
35
+ name: "Claude Code",
36
+ configPaths: [
37
+ path.join(os.homedir(), ".claude", "claude_desktop_config.json"),
38
+ path.join(os.homedir(), ".mcp.json")
39
+ ],
40
+ description: "Anthropic Claude Code CLI"
41
+ },
42
+ cursor: {
43
+ name: "Cursor",
44
+ configPaths: [
45
+ path.join(process.cwd(), ".cursor", "mcp.json"),
46
+ path.join(os.homedir(), ".cursor", "mcp.json")
47
+ ],
48
+ description: "Cursor AI Editor"
49
+ },
50
+ windsurf: {
51
+ name: "Windsurf",
52
+ configPaths: [
53
+ path.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json")
54
+ ],
55
+ description: "Codeium Windsurf Editor"
56
+ }
57
+ };
58
+ var colors = {
59
+ reset: "\x1B[0m",
60
+ bright: "\x1B[1m",
61
+ dim: "\x1B[2m",
62
+ green: "\x1B[32m",
63
+ yellow: "\x1B[33m",
64
+ blue: "\x1B[34m",
65
+ magenta: "\x1B[35m",
66
+ cyan: "\x1B[36m",
67
+ red: "\x1B[31m"
68
+ };
69
+ function log(message) {
70
+ console.log(message);
71
+ }
72
+ function success(message) {
73
+ console.log(`${colors.green}\u2713${colors.reset} ${message}`);
74
+ }
75
+ function info(message) {
76
+ console.log(`${colors.blue}\u2139${colors.reset} ${message}`);
77
+ }
78
+ function warn(message) {
79
+ console.log(`${colors.yellow}\u26A0${colors.reset} ${message}`);
80
+ }
81
+ function error(message) {
82
+ console.log(`${colors.red}\u2717${colors.reset} ${message}`);
83
+ }
84
+ function printBanner() {
85
+ console.log(`
86
+ ${colors.magenta}\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
87
+ \u2551 \u2551
88
+ \u2551 ${colors.bright}AI React Animations${colors.reset}${colors.magenta} \u2551
89
+ \u2551 ${colors.dim}MCP Server Configuration${colors.reset}${colors.magenta} \u2551
90
+ \u2551 \u2551
91
+ \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D${colors.reset}
92
+ `);
93
+ }
94
+ function getMcpConfig() {
95
+ return {
96
+ command: "npx",
97
+ args: ["-y", PACKAGE_NAME, "serve"]
98
+ };
99
+ }
100
+ function findExistingConfig(configPaths) {
101
+ for (const configPath of configPaths) {
102
+ if (fs.existsSync(configPath)) {
103
+ return configPath;
104
+ }
105
+ }
106
+ return null;
107
+ }
108
+ function ensureDirectoryExists(filePath) {
109
+ const dir = path.dirname(filePath);
110
+ if (!fs.existsSync(dir)) {
111
+ fs.mkdirSync(dir, { recursive: true });
112
+ }
113
+ }
114
+ function readJsonFile(filePath) {
115
+ try {
116
+ const content = fs.readFileSync(filePath, "utf-8");
117
+ return JSON.parse(content);
118
+ } catch {
119
+ return {};
120
+ }
121
+ }
122
+ function writeJsonFile(filePath, data) {
123
+ ensureDirectoryExists(filePath);
124
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n");
125
+ }
126
+ async function prompt(question) {
127
+ const rl = readline.createInterface({
128
+ input: process.stdin,
129
+ output: process.stdout
130
+ });
131
+ return new Promise((resolve) => {
132
+ rl.question(question, (answer) => {
133
+ rl.close();
134
+ resolve(answer.trim());
135
+ });
136
+ });
137
+ }
138
+ async function selectClient() {
139
+ log("\nSelect your AI coding tool:\n");
140
+ const clients = Object.entries(CLIENT_CONFIGS);
141
+ clients.forEach(([key, config], index2) => {
142
+ log(` ${colors.cyan}${index2 + 1}${colors.reset}) ${config.name} ${colors.dim}(${config.description})${colors.reset}`);
143
+ });
144
+ log("");
145
+ const answer = await prompt(`Enter choice (1-${clients.length}): `);
146
+ const index = parseInt(answer) - 1;
147
+ if (index >= 0 && index < clients.length) {
148
+ return clients[index][0];
149
+ }
150
+ error("Invalid selection. Please try again.");
151
+ return selectClient();
152
+ }
153
+ async function initMcp(clientKey) {
154
+ const client = CLIENT_CONFIGS[clientKey];
155
+ if (!client) {
156
+ error(`Unknown client: ${clientKey}`);
157
+ log(`
158
+ Supported clients: ${Object.keys(CLIENT_CONFIGS).join(", ")}`);
159
+ process.exit(1);
160
+ }
161
+ info(`Configuring MCP for ${colors.bright}${client.name}${colors.reset}...`);
162
+ log("");
163
+ let configPath = findExistingConfig(client.configPaths);
164
+ if (!configPath) {
165
+ configPath = client.configPaths[0];
166
+ info(`Creating new config at: ${colors.dim}${configPath}${colors.reset}`);
167
+ } else {
168
+ info(`Found existing config at: ${colors.dim}${configPath}${colors.reset}`);
169
+ }
170
+ const config = readJsonFile(configPath);
171
+ if (!config.mcpServers) {
172
+ config.mcpServers = {};
173
+ }
174
+ if (config.mcpServers[PACKAGE_NAME]) {
175
+ warn(`${PACKAGE_NAME} is already configured.`);
176
+ const answer = await prompt("Overwrite existing configuration? (y/N): ");
177
+ if (answer.toLowerCase() !== "y") {
178
+ info("Skipping configuration.");
179
+ return;
180
+ }
181
+ }
182
+ config.mcpServers[PACKAGE_NAME] = getMcpConfig();
183
+ writeJsonFile(configPath, config);
184
+ log("");
185
+ success(`Successfully configured ${colors.bright}${PACKAGE_NAME}${colors.reset} for ${client.name}!`);
186
+ log("");
187
+ log(`${colors.bright}Next steps:${colors.reset}`);
188
+ log("");
189
+ log(` 1. Restart ${client.name} to load the MCP server`);
190
+ log("");
191
+ log(` 2. Ask your AI assistant:`);
192
+ log(` ${colors.cyan}"List all animation components"${colors.reset}`);
193
+ log(` ${colors.cyan}"Add LoadingDots to my project"${colors.reset}`);
194
+ log(` ${colors.cyan}"Show me the AiCreating2 source code"${colors.reset}`);
195
+ log("");
196
+ log(`${colors.dim}Config location: ${configPath}${colors.reset}`);
197
+ log("");
198
+ }
199
+ function serveMcp() {
200
+ const serverPath = path.join(__dirname, "server.js");
201
+ if (!fs.existsSync(serverPath)) {
202
+ error("MCP server not found. Please reinstall the package.");
203
+ process.exit(1);
204
+ }
205
+ const child = (0, import_child_process.spawn)("node", [serverPath], {
206
+ stdio: "inherit",
207
+ env: process.env
208
+ });
209
+ child.on("error", (err) => {
210
+ error(`Failed to start MCP server: ${err.message}`);
211
+ process.exit(1);
212
+ });
213
+ child.on("exit", (code) => {
214
+ process.exit(code || 0);
215
+ });
216
+ }
217
+ function showHelp() {
218
+ printBanner();
219
+ log(`${colors.bright}Usage:${colors.reset}`);
220
+ log("");
221
+ log(` npx ${PACKAGE_NAME} init [--client <name>] Configure MCP for an AI tool`);
222
+ log(` npx ${PACKAGE_NAME} serve Start the MCP server`);
223
+ log(` npx ${PACKAGE_NAME} --help Show this help message`);
224
+ log("");
225
+ log(`${colors.bright}Supported clients:${colors.reset}`);
226
+ log("");
227
+ Object.entries(CLIENT_CONFIGS).forEach(([key, config]) => {
228
+ log(` ${colors.cyan}${key.padEnd(12)}${colors.reset} ${config.name} (${config.description})`);
229
+ });
230
+ log("");
231
+ log(`${colors.bright}Examples:${colors.reset}`);
232
+ log("");
233
+ log(` ${colors.dim}# Interactive mode - select your AI tool${colors.reset}`);
234
+ log(` npx ${PACKAGE_NAME} init`);
235
+ log("");
236
+ log(` ${colors.dim}# Direct configuration for Claude Code${colors.reset}`);
237
+ log(` npx ${PACKAGE_NAME} init --client claude`);
238
+ log("");
239
+ log(` ${colors.dim}# Direct configuration for Cursor${colors.reset}`);
240
+ log(` npx ${PACKAGE_NAME} init --client cursor`);
241
+ log("");
242
+ }
243
+ async function main() {
244
+ const args = process.argv.slice(2);
245
+ const command = args[0];
246
+ if (!command || command === "--help" || command === "-h") {
247
+ showHelp();
248
+ return;
249
+ }
250
+ if (command === "serve") {
251
+ serveMcp();
252
+ return;
253
+ }
254
+ if (command === "init") {
255
+ printBanner();
256
+ const clientIndex = args.indexOf("--client");
257
+ let clientKey;
258
+ if (clientIndex !== -1 && args[clientIndex + 1]) {
259
+ clientKey = args[clientIndex + 1].toLowerCase();
260
+ } else {
261
+ clientKey = await selectClient();
262
+ }
263
+ await initMcp(clientKey);
264
+ return;
265
+ }
266
+ error(`Unknown command: ${command}`);
267
+ log("");
268
+ log(`Run ${colors.cyan}npx ${PACKAGE_NAME} --help${colors.reset} for usage information.`);
269
+ process.exit(1);
270
+ }
271
+ main().catch((err) => {
272
+ error(err.message);
273
+ process.exit(1);
274
+ });
@@ -1,13 +1,32 @@
1
1
  #!/usr/bin/env node
2
- #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
3
25
 
4
26
  // mcp/server.ts
5
- import { Server } from "@modelcontextprotocol/sdk/server/index.js";
6
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
- import {
8
- CallToolRequestSchema,
9
- ListToolsRequestSchema
10
- } from "@modelcontextprotocol/sdk/types.js";
27
+ var import_server = require("@modelcontextprotocol/sdk/server/index.js");
28
+ var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
29
+ var import_types = require("@modelcontextprotocol/sdk/types.js");
11
30
 
12
31
  // mcp/registry.ts
13
32
  var components = [
@@ -844,8 +863,8 @@ function getCategories() {
844
863
  }
845
864
 
846
865
  // mcp/server.ts
847
- import * as path from "path";
848
- var server = new Server(
866
+ var path = __toESM(require("path"));
867
+ var server = new import_server.Server(
849
868
  {
850
869
  name: "ai-react-animations",
851
870
  version: "1.0.0"
@@ -856,7 +875,7 @@ var server = new Server(
856
875
  }
857
876
  }
858
877
  );
859
- server.setRequestHandler(ListToolsRequestSchema, async () => {
878
+ server.setRequestHandler(import_types.ListToolsRequestSchema, async () => {
860
879
  return {
861
880
  tools: [
862
881
  {
@@ -922,7 +941,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
922
941
  ]
923
942
  };
924
943
  });
925
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
944
+ server.setRequestHandler(import_types.CallToolRequestSchema, async (request) => {
926
945
  const { name, arguments: args } = request.params;
927
946
  switch (name) {
928
947
  case "list_components": {
@@ -1055,7 +1074,7 @@ Note: Make sure you have 'use client' directive if using Next.js App Router.
1055
1074
  }
1056
1075
  });
1057
1076
  async function main() {
1058
- const transport = new StdioServerTransport();
1077
+ const transport = new import_stdio.StdioServerTransport();
1059
1078
  await server.connect(transport);
1060
1079
  console.error("AI React Animations MCP Server running on stdio");
1061
1080
  }
package/mcp/cli.ts ADDED
@@ -0,0 +1,324 @@
1
+ /**
2
+ * AI React Animations - MCP CLI
3
+ *
4
+ * Initialize MCP configuration for different AI coding tools.
5
+ *
6
+ * Usage:
7
+ * npx ai-react-animations init --client claude
8
+ * npx ai-react-animations init --client cursor
9
+ * npx ai-react-animations init --client windsurf
10
+ */
11
+
12
+ import * as fs from 'fs';
13
+ import * as path from 'path';
14
+ import * as os from 'os';
15
+ import * as readline from 'readline';
16
+ import { spawn } from 'child_process';
17
+
18
+ const PACKAGE_NAME = 'ai-react-animations';
19
+
20
+ // Client configurations
21
+ const CLIENT_CONFIGS: Record<string, {
22
+ name: string;
23
+ configPaths: string[];
24
+ description: string;
25
+ }> = {
26
+ claude: {
27
+ name: 'Claude Code',
28
+ configPaths: [
29
+ path.join(os.homedir(), '.claude', 'claude_desktop_config.json'),
30
+ path.join(os.homedir(), '.mcp.json'),
31
+ ],
32
+ description: 'Anthropic Claude Code CLI',
33
+ },
34
+ cursor: {
35
+ name: 'Cursor',
36
+ configPaths: [
37
+ path.join(process.cwd(), '.cursor', 'mcp.json'),
38
+ path.join(os.homedir(), '.cursor', 'mcp.json'),
39
+ ],
40
+ description: 'Cursor AI Editor',
41
+ },
42
+ windsurf: {
43
+ name: 'Windsurf',
44
+ configPaths: [
45
+ path.join(os.homedir(), '.codeium', 'windsurf', 'mcp_config.json'),
46
+ ],
47
+ description: 'Codeium Windsurf Editor',
48
+ },
49
+ };
50
+
51
+ // Colors for terminal output
52
+ const colors = {
53
+ reset: '\x1b[0m',
54
+ bright: '\x1b[1m',
55
+ dim: '\x1b[2m',
56
+ green: '\x1b[32m',
57
+ yellow: '\x1b[33m',
58
+ blue: '\x1b[34m',
59
+ magenta: '\x1b[35m',
60
+ cyan: '\x1b[36m',
61
+ red: '\x1b[31m',
62
+ };
63
+
64
+ function log(message: string) {
65
+ console.log(message);
66
+ }
67
+
68
+ function success(message: string) {
69
+ console.log(`${colors.green}✓${colors.reset} ${message}`);
70
+ }
71
+
72
+ function info(message: string) {
73
+ console.log(`${colors.blue}ℹ${colors.reset} ${message}`);
74
+ }
75
+
76
+ function warn(message: string) {
77
+ console.log(`${colors.yellow}⚠${colors.reset} ${message}`);
78
+ }
79
+
80
+ function error(message: string) {
81
+ console.log(`${colors.red}✗${colors.reset} ${message}`);
82
+ }
83
+
84
+ function printBanner() {
85
+ console.log(`
86
+ ${colors.magenta}╔═══════════════════════════════════════════════════╗
87
+ ║ ║
88
+ ║ ${colors.bright}AI React Animations${colors.reset}${colors.magenta} ║
89
+ ║ ${colors.dim}MCP Server Configuration${colors.reset}${colors.magenta} ║
90
+ ║ ║
91
+ ╚═══════════════════════════════════════════════════╝${colors.reset}
92
+ `);
93
+ }
94
+
95
+ function getMcpConfig() {
96
+ return {
97
+ command: 'npx',
98
+ args: ['-y', PACKAGE_NAME, 'serve'],
99
+ };
100
+ }
101
+
102
+ function findExistingConfig(configPaths: string[]): string | null {
103
+ for (const configPath of configPaths) {
104
+ if (fs.existsSync(configPath)) {
105
+ return configPath;
106
+ }
107
+ }
108
+ return null;
109
+ }
110
+
111
+ function ensureDirectoryExists(filePath: string) {
112
+ const dir = path.dirname(filePath);
113
+ if (!fs.existsSync(dir)) {
114
+ fs.mkdirSync(dir, { recursive: true });
115
+ }
116
+ }
117
+
118
+ function readJsonFile(filePath: string): Record<string, any> {
119
+ try {
120
+ const content = fs.readFileSync(filePath, 'utf-8');
121
+ return JSON.parse(content);
122
+ } catch {
123
+ return {};
124
+ }
125
+ }
126
+
127
+ function writeJsonFile(filePath: string, data: Record<string, any>) {
128
+ ensureDirectoryExists(filePath);
129
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + '\n');
130
+ }
131
+
132
+ async function prompt(question: string): Promise<string> {
133
+ const rl = readline.createInterface({
134
+ input: process.stdin,
135
+ output: process.stdout,
136
+ });
137
+
138
+ return new Promise((resolve) => {
139
+ rl.question(question, (answer) => {
140
+ rl.close();
141
+ resolve(answer.trim());
142
+ });
143
+ });
144
+ }
145
+
146
+ async function selectClient(): Promise<string> {
147
+ log('\nSelect your AI coding tool:\n');
148
+
149
+ const clients = Object.entries(CLIENT_CONFIGS);
150
+ clients.forEach(([key, config], index) => {
151
+ log(` ${colors.cyan}${index + 1}${colors.reset}) ${config.name} ${colors.dim}(${config.description})${colors.reset}`);
152
+ });
153
+
154
+ log('');
155
+ const answer = await prompt(`Enter choice (1-${clients.length}): `);
156
+ const index = parseInt(answer) - 1;
157
+
158
+ if (index >= 0 && index < clients.length) {
159
+ return clients[index][0];
160
+ }
161
+
162
+ error('Invalid selection. Please try again.');
163
+ return selectClient();
164
+ }
165
+
166
+ async function initMcp(clientKey: string) {
167
+ const client = CLIENT_CONFIGS[clientKey];
168
+
169
+ if (!client) {
170
+ error(`Unknown client: ${clientKey}`);
171
+ log(`\nSupported clients: ${Object.keys(CLIENT_CONFIGS).join(', ')}`);
172
+ process.exit(1);
173
+ }
174
+
175
+ info(`Configuring MCP for ${colors.bright}${client.name}${colors.reset}...`);
176
+ log('');
177
+
178
+ // Find existing config or use first path
179
+ let configPath = findExistingConfig(client.configPaths);
180
+
181
+ if (!configPath) {
182
+ // Use the first config path as default
183
+ configPath = client.configPaths[0];
184
+ info(`Creating new config at: ${colors.dim}${configPath}${colors.reset}`);
185
+ } else {
186
+ info(`Found existing config at: ${colors.dim}${configPath}${colors.reset}`);
187
+ }
188
+
189
+ // Read existing config
190
+ const config = readJsonFile(configPath);
191
+
192
+ // Initialize mcpServers if not present
193
+ if (!config.mcpServers) {
194
+ config.mcpServers = {};
195
+ }
196
+
197
+ // Check if already configured
198
+ if (config.mcpServers[PACKAGE_NAME]) {
199
+ warn(`${PACKAGE_NAME} is already configured.`);
200
+ const answer = await prompt('Overwrite existing configuration? (y/N): ');
201
+ if (answer.toLowerCase() !== 'y') {
202
+ info('Skipping configuration.');
203
+ return;
204
+ }
205
+ }
206
+
207
+ // Add our MCP config
208
+ config.mcpServers[PACKAGE_NAME] = getMcpConfig();
209
+
210
+ // Write config
211
+ writeJsonFile(configPath, config);
212
+
213
+ log('');
214
+ success(`Successfully configured ${colors.bright}${PACKAGE_NAME}${colors.reset} for ${client.name}!`);
215
+ log('');
216
+
217
+ // Print next steps
218
+ log(`${colors.bright}Next steps:${colors.reset}`);
219
+ log('');
220
+ log(` 1. Restart ${client.name} to load the MCP server`);
221
+ log('');
222
+ log(` 2. Ask your AI assistant:`);
223
+ log(` ${colors.cyan}"List all animation components"${colors.reset}`);
224
+ log(` ${colors.cyan}"Add LoadingDots to my project"${colors.reset}`);
225
+ log(` ${colors.cyan}"Show me the AiCreating2 source code"${colors.reset}`);
226
+ log('');
227
+ log(`${colors.dim}Config location: ${configPath}${colors.reset}`);
228
+ log('');
229
+ }
230
+
231
+ function serveMcp() {
232
+ // Get the path to the server.js file
233
+ const serverPath = path.join(__dirname, 'server.js');
234
+
235
+ if (!fs.existsSync(serverPath)) {
236
+ error('MCP server not found. Please reinstall the package.');
237
+ process.exit(1);
238
+ }
239
+
240
+ // Run the server
241
+ const child = spawn('node', [serverPath], {
242
+ stdio: 'inherit',
243
+ env: process.env,
244
+ });
245
+
246
+ child.on('error', (err) => {
247
+ error(`Failed to start MCP server: ${err.message}`);
248
+ process.exit(1);
249
+ });
250
+
251
+ child.on('exit', (code) => {
252
+ process.exit(code || 0);
253
+ });
254
+ }
255
+
256
+ function showHelp() {
257
+ printBanner();
258
+
259
+ log(`${colors.bright}Usage:${colors.reset}`);
260
+ log('');
261
+ log(` npx ${PACKAGE_NAME} init [--client <name>] Configure MCP for an AI tool`);
262
+ log(` npx ${PACKAGE_NAME} serve Start the MCP server`);
263
+ log(` npx ${PACKAGE_NAME} --help Show this help message`);
264
+ log('');
265
+ log(`${colors.bright}Supported clients:${colors.reset}`);
266
+ log('');
267
+ Object.entries(CLIENT_CONFIGS).forEach(([key, config]) => {
268
+ log(` ${colors.cyan}${key.padEnd(12)}${colors.reset} ${config.name} (${config.description})`);
269
+ });
270
+ log('');
271
+ log(`${colors.bright}Examples:${colors.reset}`);
272
+ log('');
273
+ log(` ${colors.dim}# Interactive mode - select your AI tool${colors.reset}`);
274
+ log(` npx ${PACKAGE_NAME} init`);
275
+ log('');
276
+ log(` ${colors.dim}# Direct configuration for Claude Code${colors.reset}`);
277
+ log(` npx ${PACKAGE_NAME} init --client claude`);
278
+ log('');
279
+ log(` ${colors.dim}# Direct configuration for Cursor${colors.reset}`);
280
+ log(` npx ${PACKAGE_NAME} init --client cursor`);
281
+ log('');
282
+ }
283
+
284
+ async function main() {
285
+ const args = process.argv.slice(2);
286
+ const command = args[0];
287
+
288
+ if (!command || command === '--help' || command === '-h') {
289
+ showHelp();
290
+ return;
291
+ }
292
+
293
+ if (command === 'serve') {
294
+ serveMcp();
295
+ return;
296
+ }
297
+
298
+ if (command === 'init') {
299
+ printBanner();
300
+
301
+ // Check for --client flag
302
+ const clientIndex = args.indexOf('--client');
303
+ let clientKey: string;
304
+
305
+ if (clientIndex !== -1 && args[clientIndex + 1]) {
306
+ clientKey = args[clientIndex + 1].toLowerCase();
307
+ } else {
308
+ clientKey = await selectClient();
309
+ }
310
+
311
+ await initMcp(clientKey);
312
+ return;
313
+ }
314
+
315
+ error(`Unknown command: ${command}`);
316
+ log('');
317
+ log(`Run ${colors.cyan}npx ${PACKAGE_NAME} --help${colors.reset} for usage information.`);
318
+ process.exit(1);
319
+ }
320
+
321
+ main().catch((err) => {
322
+ error(err.message);
323
+ process.exit(1);
324
+ });
package/mcp/server.ts CHANGED
@@ -1,4 +1,3 @@
1
- #!/usr/bin/env node
2
1
  /**
3
2
  * AI React Animations - MCP Server
4
3
  *
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "ai-react-animations",
3
- "version": "1.2.1",
4
- "description": "Beautiful AI loading animation components for React/Next.js with MCP server support.",
3
+ "version": "1.3.0",
4
+ "description": "Beautiful AI loading animation components for React/Next.js with MCP server support for Claude, Cursor, and Windsurf.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",
8
8
  "bin": {
9
- "ai-react-animations-mcp": "./dist/mcp/server.js"
9
+ "ai-react-animations": "./dist/mcp/cli.js"
10
10
  },
11
11
  "exports": {
12
12
  ".": {
@@ -20,8 +20,6 @@
20
20
  "files": [
21
21
  "dist",
22
22
  "mcp",
23
- "mcp-config.json",
24
- "MCP-GUIDE.md",
25
23
  "README.md",
26
24
  "LICENSE"
27
25
  ],
@@ -30,8 +28,10 @@
30
28
  "build": "next build",
31
29
  "start": "next start",
32
30
  "build:lib": "node scripts/build.js",
33
- "build:mcp": "npx esbuild mcp/server.ts --bundle --platform=node --format=esm --outfile=dist/mcp/server.js --external:@modelcontextprotocol/sdk --banner:js='#!/usr/bin/env node'",
34
- "mcp": "node --experimental-specifier-resolution=node dist/mcp/server.js",
31
+ "build:mcp": "npm run build:mcp:server && npm run build:mcp:cli",
32
+ "build:mcp:server": "npx esbuild mcp/server.ts --bundle --platform=node --format=cjs --outfile=dist/mcp/server.js --external:@modelcontextprotocol/sdk --banner:js='#!/usr/bin/env node'",
33
+ "build:mcp:cli": "npx esbuild mcp/cli.ts --bundle --platform=node --format=cjs --outfile=dist/mcp/cli.js --banner:js='#!/usr/bin/env node'",
34
+ "mcp": "node dist/mcp/server.js",
35
35
  "mcp:dev": "npx tsx mcp/server.ts",
36
36
  "prepublishOnly": "npm run build:lib && npm run build:mcp"
37
37
  },
@@ -57,6 +57,7 @@
57
57
  "@radix-ui/react-scroll-area": "^1.2.10",
58
58
  "@radix-ui/react-separator": "^1.1.8",
59
59
  "@radix-ui/react-slot": "^1.2.4",
60
+ "@radix-ui/react-tabs": "^1.1.13",
60
61
  "@radix-ui/react-tooltip": "^1.2.8",
61
62
  "class-variance-authority": "^0.7.1",
62
63
  "clsx": "^2.1.1",
package/MCP-GUIDE.md DELETED
@@ -1,390 +0,0 @@
1
- # MCP Server Setup Guide
2
-
3
- This guide explains how to set up and use the AI React Animations MCP (Model Context Protocol) server with Claude Code or other AI assistants.
4
-
5
- ---
6
-
7
- ## Table of Contents
8
-
9
- 1. [What is MCP?](#what-is-mcp)
10
- 2. [Prerequisites](#prerequisites)
11
- 3. [Installation](#installation)
12
- 4. [Configuration](#configuration)
13
- 5. [Available Tools](#available-tools)
14
- 6. [Usage Examples](#usage-examples)
15
- 7. [Troubleshooting](#troubleshooting)
16
-
17
- ---
18
-
19
- ## What is MCP?
20
-
21
- MCP (Model Context Protocol) is a standard that allows AI assistants like Claude to interact with external tools and services. With the AI React Animations MCP server, you can ask Claude to:
22
-
23
- - List all available animation components
24
- - Get detailed information about any component
25
- - Add components to your project with proper source code
26
- - Get installation commands for dependencies
27
-
28
- ---
29
-
30
- ## Prerequisites
31
-
32
- Before setting up the MCP server, make sure you have:
33
-
34
- - **Node.js** version 18 or higher
35
- - **npm** (comes with Node.js)
36
- - **Claude Code** or another MCP-compatible AI assistant
37
-
38
- To check your Node.js version:
39
-
40
- ```bash
41
- node --version
42
- ```
43
-
44
- ---
45
-
46
- ## Installation
47
-
48
- ### Step 1: Install the package
49
-
50
- Open your terminal and run:
51
-
52
- ```bash
53
- npm install ai-react-animations
54
- ```
55
-
56
- This installs the animation components AND the MCP server.
57
-
58
- ### Step 2: Install tsx (TypeScript executor)
59
-
60
- The MCP server is written in TypeScript. Install tsx to run it:
61
-
62
- ```bash
63
- npm install -g tsx
64
- ```
65
-
66
- Or install it locally in your project:
67
-
68
- ```bash
69
- npm install tsx --save-dev
70
- ```
71
-
72
- ---
73
-
74
- ## Configuration
75
-
76
- ### Step 1: Find your MCP configuration file
77
-
78
- The MCP configuration file is named `.mcp.json` and is located in:
79
-
80
- - **macOS/Linux**: `~/.mcp.json` (your home directory)
81
- - **Windows**: `C:\Users\YourUsername\.mcp.json`
82
-
83
- If the file doesn't exist, create it.
84
-
85
- ### Step 2: Add the MCP server configuration
86
-
87
- Open `.mcp.json` in a text editor and add:
88
-
89
- ```json
90
- {
91
- "mcpServers": {
92
- "ai-react-animations": {
93
- "command": "npx",
94
- "args": ["tsx", "node_modules/ai-react-animations/mcp/server.ts"]
95
- }
96
- }
97
- }
98
- ```
99
-
100
- ### Step 3: If you already have other MCP servers
101
-
102
- Add the `ai-react-animations` entry to your existing `mcpServers` object:
103
-
104
- ```json
105
- {
106
- "mcpServers": {
107
- "your-existing-server": {
108
- "command": "...",
109
- "args": ["..."]
110
- },
111
- "ai-react-animations": {
112
- "command": "npx",
113
- "args": ["tsx", "node_modules/ai-react-animations/mcp/server.ts"]
114
- }
115
- }
116
- }
117
- ```
118
-
119
- ### Step 4: Restart Claude Code
120
-
121
- After saving the configuration:
122
-
123
- 1. Close Claude Code completely
124
- 2. Reopen Claude Code
125
- 3. The MCP server will now be available
126
-
127
- ---
128
-
129
- ## Available Tools
130
-
131
- The MCP server provides 4 tools:
132
-
133
- ### 1. `list_components`
134
-
135
- Lists all available animation components.
136
-
137
- **Parameters:**
138
- | Parameter | Type | Required | Description |
139
- |-----------|------|----------|-------------|
140
- | `category` | string | No | Filter by category: `all`, `loading`, `processing`, `creative`, `auth` |
141
-
142
- **Example response:**
143
- ```json
144
- {
145
- "total": 7,
146
- "categories": ["all", "loading", "processing", "creative", "auth"],
147
- "components": [
148
- {
149
- "name": "LoadingDots",
150
- "id": "loading-dots",
151
- "category": "loading",
152
- "description": "Simple, elegant bouncing dots animation."
153
- }
154
- ]
155
- }
156
- ```
157
-
158
- ---
159
-
160
- ### 2. `get_component`
161
-
162
- Gets detailed information about a specific component, including source code.
163
-
164
- **Parameters:**
165
- | Parameter | Type | Required | Description |
166
- |-----------|------|----------|-------------|
167
- | `name` | string | Yes | Component name or ID (e.g., `LoadingDots`, `loading-dots`) |
168
-
169
- **Example response:**
170
- ```json
171
- {
172
- "name": "LoadingDots",
173
- "id": "loading-dots",
174
- "description": "Simple, elegant bouncing dots animation.",
175
- "category": "loading",
176
- "dependencies": ["framer-motion"],
177
- "props": [...],
178
- "usage": "...",
179
- "source": "// Full component source code"
180
- }
181
- ```
182
-
183
- ---
184
-
185
- ### 3. `add_component`
186
-
187
- Gets instructions and source code to add a component to your project.
188
-
189
- **Parameters:**
190
- | Parameter | Type | Required | Description |
191
- |-----------|------|----------|-------------|
192
- | `name` | string | Yes | Component name or ID |
193
- | `directory` | string | No | Target directory (default: `./components`) |
194
-
195
- **Example response:**
196
- ```json
197
- {
198
- "success": true,
199
- "component": "LoadingDots",
200
- "filePath": "./components/LoadingDots.tsx",
201
- "source": "// Component source code",
202
- "dependencies": ["framer-motion"],
203
- "installCommand": "npm install framer-motion",
204
- "instructions": "1. Create the file..."
205
- }
206
- ```
207
-
208
- ---
209
-
210
- ### 4. `get_install_command`
211
-
212
- Gets the npm install command for a component's dependencies.
213
-
214
- **Parameters:**
215
- | Parameter | Type | Required | Description |
216
- |-----------|------|----------|-------------|
217
- | `name` | string | Yes | Component name or ID |
218
-
219
- **Example response:**
220
- ```
221
- npm install framer-motion
222
- ```
223
-
224
- ---
225
-
226
- ## Usage Examples
227
-
228
- Once the MCP server is configured, you can use natural language with Claude:
229
-
230
- ### Example 1: List all components
231
-
232
- **You say:**
233
- > "What animation components are available?"
234
-
235
- **Claude will:**
236
- 1. Call the `list_components` tool
237
- 2. Show you a list of all 7 components with descriptions
238
-
239
- ---
240
-
241
- ### Example 2: Get component details
242
-
243
- **You say:**
244
- > "Show me details about the PulseCircle component"
245
-
246
- **Claude will:**
247
- 1. Call `get_component` with `name: "PulseCircle"`
248
- 2. Show you the props, usage example, and description
249
-
250
- ---
251
-
252
- ### Example 3: Add a component to your project
253
-
254
- **You say:**
255
- > "Add the LoadingDots component to my project in the components folder"
256
-
257
- **Claude will:**
258
- 1. Call `add_component` with `name: "LoadingDots"` and `directory: "./components"`
259
- 2. Create the file `./components/LoadingDots.tsx` with the full source code
260
- 3. Tell you to run `npm install framer-motion`
261
-
262
- ---
263
-
264
- ### Example 4: Filter by category
265
-
266
- **You say:**
267
- > "Show me all loading animation components"
268
-
269
- **Claude will:**
270
- 1. Call `list_components` with `category: "loading"`
271
- 2. Show you only the loading-related components
272
-
273
- ---
274
-
275
- ### Example 5: Add multiple components
276
-
277
- **You say:**
278
- > "Add LoadingDots and PulseCircle to my components folder"
279
-
280
- **Claude will:**
281
- 1. Call `add_component` twice
282
- 2. Create both component files
283
- 3. Give you the combined install command
284
-
285
- ---
286
-
287
- ## Troubleshooting
288
-
289
- ### Problem: "MCP server not found"
290
-
291
- **Solution:**
292
- 1. Make sure you installed the package: `npm install ai-react-animations`
293
- 2. Check that `.mcp.json` is in the correct location
294
- 3. Restart Claude Code
295
-
296
- ---
297
-
298
- ### Problem: "tsx: command not found"
299
-
300
- **Solution:**
301
- Install tsx globally:
302
- ```bash
303
- npm install -g tsx
304
- ```
305
-
306
- ---
307
-
308
- ### Problem: "Cannot find module"
309
-
310
- **Solution:**
311
- Make sure you're in a directory where `node_modules/ai-react-animations` exists:
312
- ```bash
313
- ls node_modules/ai-react-animations
314
- ```
315
-
316
- If not, install the package:
317
- ```bash
318
- npm install ai-react-animations
319
- ```
320
-
321
- ---
322
-
323
- ### Problem: "Permission denied"
324
-
325
- **Solution (macOS/Linux):**
326
- ```bash
327
- chmod +x node_modules/ai-react-animations/mcp/server.ts
328
- ```
329
-
330
- ---
331
-
332
- ### Problem: MCP server doesn't respond
333
-
334
- **Solution:**
335
- 1. Test the server manually:
336
- ```bash
337
- echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | npx tsx node_modules/ai-react-animations/mcp/server.ts
338
- ```
339
-
340
- 2. You should see a JSON response with the tools list
341
-
342
- ---
343
-
344
- ## Component Categories
345
-
346
- | Category | Components | Use Case |
347
- |----------|-----------|----------|
348
- | **loading** | LoadingDots | Simple loading indicators |
349
- | **processing** | PulseCircle, DataProcessing | Progress and data flow |
350
- | **creative** | AiCreating, AiCreating2, CodeTyping | AI-themed animations |
351
- | **auth** | FloatingLogin | Authentication UI |
352
-
353
- ---
354
-
355
- ## Need Help?
356
-
357
- - **GitHub Issues**: [github.com/johnbekele/ai-react-animations/issues](https://github.com/johnbekele/ai-react-animations/issues)
358
- - **npm Package**: [npmjs.com/package/ai-react-animations](https://www.npmjs.com/package/ai-react-animations)
359
-
360
- ---
361
-
362
- ## Quick Reference Card
363
-
364
- ```
365
- ┌─────────────────────────────────────────────────────────┐
366
- │ AI React Animations - MCP Quick Reference │
367
- ├─────────────────────────────────────────────────────────┤
368
- │ │
369
- │ SETUP: │
370
- │ 1. npm install ai-react-animations │
371
- │ 2. Add to ~/.mcp.json │
372
- │ 3. Restart Claude Code │
373
- │ │
374
- │ ASK CLAUDE: │
375
- │ • "List animation components" │
376
- │ • "Add LoadingDots to my project" │
377
- │ • "Show me PulseCircle details" │
378
- │ • "What dependencies does FloatingLogin need?" │
379
- │ │
380
- │ COMPONENTS: │
381
- │ • LoadingDots - Bouncing dots │
382
- │ • PulseCircle - Progress circle │
383
- │ • CodeTyping - Code typing effect │
384
- │ • DataProcessing - Pipeline visualization │
385
- │ • AiCreating - Robot animation │
386
- │ • AiCreating2 - Brain animation │
387
- │ • FloatingLogin - Auth form │
388
- │ │
389
- └─────────────────────────────────────────────────────────┘
390
- ```
package/mcp-config.json DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "mcpServers": {
3
- "ai-react-animations": {
4
- "command": "npx",
5
- "args": ["ai-react-animations@latest", "mcp"]
6
- }
7
- }
8
- }