ai-react-animations 1.2.1 → 1.3.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/README.md +30 -14
- package/dist/mcp/cli.js +274 -0
- package/dist/mcp/server.js +19386 -9
- package/mcp/cli.ts +324 -0
- package/mcp/server.ts +0 -1
- package/package.json +8 -7
- package/MCP-GUIDE.md +0 -390
- package/mcp-config.json +0 -8
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
|
-
|
|
143
|
+
Run one command to configure MCP for your AI coding tool:
|
|
144
144
|
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
|
174
|
+
### Usage with AI Assistants
|
|
166
175
|
|
|
167
|
-
Once configured, you can ask
|
|
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
|
-
|
|
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
|
|
package/dist/mcp/cli.js
ADDED
|
@@ -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
|
+
});
|