ai-react-animations 1.2.0 → 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 +170 -50
- package/dist/mcp/cli.js +274 -0
- package/dist/mcp/server.js +31 -12
- package/mcp/cli.ts +324 -0
- package/mcp/server.ts +0 -1
- package/package.json +8 -6
- package/mcp-config.json +0 -8
package/README.md
CHANGED
|
@@ -1,84 +1,204 @@
|
|
|
1
|
-
#
|
|
1
|
+
# AI React Animations
|
|
2
2
|
|
|
3
|
-
Beautiful AI loading animation components for React/Next.js.
|
|
3
|
+
Beautiful AI loading and animation components for React/Next.js. Production-ready components for AI interfaces with MCP (Model Context Protocol) server support.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/ai-react-animations)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- 7 production-ready animation components
|
|
11
|
+
- TypeScript support
|
|
12
|
+
- Framer Motion animations
|
|
13
|
+
- MCP Server for AI assistants (Claude, etc.)
|
|
14
|
+
- Customizable colors and sizes
|
|
15
|
+
- Dark/Light mode support
|
|
16
|
+
- Responsive design
|
|
4
17
|
|
|
5
18
|
## Installation
|
|
6
19
|
|
|
7
20
|
```bash
|
|
8
|
-
npm install ai-react-animations
|
|
21
|
+
npm install ai-react-animations framer-motion lucide-react
|
|
9
22
|
```
|
|
10
23
|
|
|
11
|
-
##
|
|
24
|
+
## Available Components
|
|
25
|
+
|
|
26
|
+
| Component | Category | Description |
|
|
27
|
+
|-----------|----------|-------------|
|
|
28
|
+
| `LoadingDots` | Loading | Simple bouncing dots animation |
|
|
29
|
+
| `PulseCircle` | Processing | Circular progress with pulse rings |
|
|
30
|
+
| `CodeTyping` | Creative | Code typing effect with syntax colors |
|
|
31
|
+
| `DataProcessing` | Processing | Data pipeline visualization |
|
|
32
|
+
| `AiCreating` | Creative | Multi-stage AI robot animation |
|
|
33
|
+
| `AiCreating2` | Creative | AI brain with rotating rings |
|
|
34
|
+
| `FloatingLogin` | Auth | Floating login form with OAuth |
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
12
37
|
|
|
13
38
|
```tsx
|
|
14
|
-
import
|
|
15
|
-
import 'ai-react-animations/styles.css';
|
|
39
|
+
import { LoadingDots } from 'ai-react-animations';
|
|
16
40
|
|
|
17
41
|
function MyComponent() {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return (
|
|
21
|
-
<AiCreating
|
|
22
|
-
isLoading={isLoading}
|
|
23
|
-
size="md"
|
|
24
|
-
onComplete={() => console.log('Done!')}
|
|
25
|
-
/>
|
|
26
|
-
);
|
|
42
|
+
return <LoadingDots size="md" color="#6366F1" />;
|
|
27
43
|
}
|
|
28
44
|
```
|
|
29
45
|
|
|
30
|
-
##
|
|
46
|
+
## Component Examples
|
|
47
|
+
|
|
48
|
+
### LoadingDots
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
import { LoadingDots } from 'ai-react-animations';
|
|
52
|
+
|
|
53
|
+
<LoadingDots size="md" color="#6366F1" />
|
|
54
|
+
```
|
|
31
55
|
|
|
56
|
+
**Props:**
|
|
32
57
|
| Prop | Type | Default | Description |
|
|
33
58
|
|------|------|---------|-------------|
|
|
34
|
-
| `
|
|
35
|
-
| `
|
|
36
|
-
| `onComplete` | `() => void` | - | Callback when animation completes |
|
|
59
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Size of the dots |
|
|
60
|
+
| `color` | `string` | `'#6366F1'` | Color of the dots |
|
|
37
61
|
|
|
38
|
-
|
|
62
|
+
### PulseCircle
|
|
39
63
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
- `md` - 240px height (default)
|
|
43
|
-
- `lg` - 340px height (for large displays)
|
|
44
|
-
- `full` - 100% height (fills container)
|
|
64
|
+
```tsx
|
|
65
|
+
import { PulseCircle } from 'ai-react-animations';
|
|
45
66
|
|
|
46
|
-
|
|
67
|
+
const [isActive, setIsActive] = useState(false);
|
|
47
68
|
|
|
48
|
-
|
|
69
|
+
<PulseCircle
|
|
70
|
+
isActive={isActive}
|
|
71
|
+
onComplete={() => setIsActive(false)}
|
|
72
|
+
/>
|
|
73
|
+
```
|
|
49
74
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
75
|
+
**Props:**
|
|
76
|
+
| Prop | Type | Default | Description |
|
|
77
|
+
|------|------|---------|-------------|
|
|
78
|
+
| `isActive` | `boolean` | required | Activates the animation |
|
|
79
|
+
| `progress` | `number` | - | External progress (0-100) |
|
|
80
|
+
| `onComplete` | `() => void` | - | Callback at 100% |
|
|
54
81
|
|
|
55
|
-
|
|
82
|
+
### AiCreating2
|
|
56
83
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
84
|
+
```tsx
|
|
85
|
+
import { AiCreating2 } from 'ai-react-animations';
|
|
86
|
+
|
|
87
|
+
<AiCreating2
|
|
88
|
+
isLoading={isLoading}
|
|
89
|
+
message="Creating your plan..."
|
|
90
|
+
primaryColor="#6366F1"
|
|
91
|
+
backgroundColor="#0f172a"
|
|
92
|
+
contained={true}
|
|
93
|
+
onComplete={() => setIsLoading(false)}
|
|
94
|
+
/>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Props:**
|
|
98
|
+
| Prop | Type | Default | Description |
|
|
99
|
+
|------|------|---------|-------------|
|
|
100
|
+
| `isLoading` | `boolean` | required | Controls visibility |
|
|
101
|
+
| `message` | `string` | `'AI is creating...'` | Main message |
|
|
102
|
+
| `subMessage` | `string` | - | Secondary text |
|
|
103
|
+
| `primaryColor` | `string` | `'#6366F1'` | Accent color |
|
|
104
|
+
| `backgroundColor` | `string` | `'#0f172a'` | Background color |
|
|
105
|
+
| `textColor` | `string` | `'#ffffff'` | Text color |
|
|
106
|
+
| `contained` | `boolean` | `false` | Render in container vs overlay |
|
|
107
|
+
| `onComplete` | `() => void` | - | Completion callback |
|
|
62
108
|
|
|
63
|
-
|
|
109
|
+
### FloatingLogin
|
|
64
110
|
|
|
65
111
|
```tsx
|
|
66
|
-
|
|
112
|
+
import { FloatingLogin } from 'ai-react-animations';
|
|
113
|
+
|
|
114
|
+
<FloatingLogin
|
|
115
|
+
mode="dark"
|
|
116
|
+
primaryColor="#6366F1"
|
|
117
|
+
floatIntensity={5}
|
|
118
|
+
onLogin={(data) => console.log(data)}
|
|
119
|
+
onGoogleLogin={() => signInWithGoogle()}
|
|
120
|
+
onAppleLogin={() => signInWithApple()}
|
|
121
|
+
/>
|
|
122
|
+
```
|
|
67
123
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
124
|
+
**Props:**
|
|
125
|
+
| Prop | Type | Default | Description |
|
|
126
|
+
|------|------|---------|-------------|
|
|
127
|
+
| `mode` | `'light' \| 'dark'` | `'light'` | Theme mode |
|
|
128
|
+
| `primaryColor` | `string` | `'#6366F1'` | Accent color |
|
|
129
|
+
| `floatingEnabled` | `boolean` | `true` | Enable floating animation |
|
|
130
|
+
| `floatIntensity` | `number` | `5` | Float intensity (1-10) |
|
|
131
|
+
| `onLogin` | `(data) => void` | - | Login callback |
|
|
132
|
+
| `onGoogleLogin` | `() => void` | - | Google OAuth callback |
|
|
133
|
+
| `onAppleLogin` | `() => void` | - | Apple Sign-In callback |
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## MCP Server (For AI Assistants)
|
|
138
|
+
|
|
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
|
+
|
|
141
|
+
### Quick Setup
|
|
142
|
+
|
|
143
|
+
Run one command to configure MCP for your AI coding tool:
|
|
144
|
+
|
|
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
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Then restart your AI tool to load the MCP server.
|
|
73
156
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
+
|
|
165
|
+
### Available MCP Tools
|
|
166
|
+
|
|
167
|
+
| Tool | Description |
|
|
168
|
+
|------|-------------|
|
|
169
|
+
| `list_components` | List all available components |
|
|
170
|
+
| `get_component` | Get component details and source code |
|
|
171
|
+
| `add_component` | Get instructions to add a component |
|
|
172
|
+
| `get_install_command` | Get npm install command |
|
|
173
|
+
|
|
174
|
+
### Usage with AI Assistants
|
|
175
|
+
|
|
176
|
+
Once configured, you can ask:
|
|
177
|
+
- "List all animation components"
|
|
178
|
+
- "Add the LoadingDots component to my project"
|
|
179
|
+
- "Show me the PulseCircle component details"
|
|
180
|
+
- "What dependencies do I need for FloatingLogin?"
|
|
181
|
+
|
|
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
|
|
80
189
|
```
|
|
81
190
|
|
|
191
|
+
---
|
|
192
|
+
|
|
82
193
|
## License
|
|
83
194
|
|
|
84
195
|
MIT
|
|
196
|
+
|
|
197
|
+
## Author
|
|
198
|
+
|
|
199
|
+
johnbekele
|
|
200
|
+
|
|
201
|
+
## Links
|
|
202
|
+
|
|
203
|
+
- [npm package](https://www.npmjs.com/package/ai-react-animations)
|
|
204
|
+
- [GitHub repository](https://github.com/johnbekele/ai-react-animations)
|
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
|
+
});
|
package/dist/mcp/server.js
CHANGED
|
@@ -1,13 +1,32 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
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
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-react-animations",
|
|
3
|
-
"version": "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
|
|
9
|
+
"ai-react-animations": "./dist/mcp/cli.js"
|
|
10
10
|
},
|
|
11
11
|
"exports": {
|
|
12
12
|
".": {
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
"files": [
|
|
21
21
|
"dist",
|
|
22
22
|
"mcp",
|
|
23
|
-
"mcp-config.json",
|
|
24
23
|
"README.md",
|
|
25
24
|
"LICENSE"
|
|
26
25
|
],
|
|
@@ -29,8 +28,10 @@
|
|
|
29
28
|
"build": "next build",
|
|
30
29
|
"start": "next start",
|
|
31
30
|
"build:lib": "node scripts/build.js",
|
|
32
|
-
"build:mcp": "
|
|
33
|
-
"mcp": "
|
|
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",
|
|
34
35
|
"mcp:dev": "npx tsx mcp/server.ts",
|
|
35
36
|
"prepublishOnly": "npm run build:lib && npm run build:mcp"
|
|
36
37
|
},
|
|
@@ -56,6 +57,7 @@
|
|
|
56
57
|
"@radix-ui/react-scroll-area": "^1.2.10",
|
|
57
58
|
"@radix-ui/react-separator": "^1.1.8",
|
|
58
59
|
"@radix-ui/react-slot": "^1.2.4",
|
|
60
|
+
"@radix-ui/react-tabs": "^1.1.13",
|
|
59
61
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
60
62
|
"class-variance-authority": "^0.7.1",
|
|
61
63
|
"clsx": "^2.1.1",
|