@neural-tools/cli 0.1.3 → 0.1.5

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.
@@ -1,112 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.generateCommand = generateCommand;
7
- const path_1 = __importDefault(require("path"));
8
- const os_1 = __importDefault(require("os"));
9
- const fs_extra_1 = __importDefault(require("fs-extra"));
10
- const core_1 = require("@neural-tools/core");
11
- const inquirer_1 = __importDefault(require("inquirer"));
12
- async function generateCommand(name, options) {
13
- core_1.logger.header(`Generating Claude Command: /${name}`);
14
- // Prompt for missing information
15
- let description = options.description;
16
- if (!description) {
17
- const answers = await inquirer_1.default.prompt([
18
- {
19
- type: 'input',
20
- name: 'description',
21
- message: 'Description of your command:',
22
- default: `Execute ${name}`
23
- }
24
- ]);
25
- description = answers.description;
26
- }
27
- // Determine output directory
28
- let outputDir;
29
- if (options.global) {
30
- outputDir = path_1.default.join(os_1.default.homedir(), '.claude', 'commands');
31
- }
32
- else {
33
- outputDir = path_1.default.resolve(options.output || './claude/commands');
34
- }
35
- const commandFile = path_1.default.join(outputDir, `${name}.md`);
36
- if (options.dryRun) {
37
- core_1.logger.info('Dry run mode - no files will be created');
38
- core_1.logger.section('Configuration', [
39
- `Name: /${name}`,
40
- `Description: ${description}`,
41
- `Output: ${commandFile}`,
42
- `Arguments: ${options.args?.join(', ') || 'none'}`,
43
- `Allowed Tools: ${options.tools?.join(', ') || 'all'}`,
44
- `Global: ${options.global ? 'Yes' : 'No'}`
45
- ]);
46
- return;
47
- }
48
- // Check if file already exists
49
- if (await fs_extra_1.default.pathExists(commandFile)) {
50
- const { overwrite } = await inquirer_1.default.prompt([
51
- {
52
- type: 'confirm',
53
- name: 'overwrite',
54
- message: `Command /${name} already exists. Overwrite?`,
55
- default: false
56
- }
57
- ]);
58
- if (!overwrite) {
59
- core_1.logger.warn('Cancelled');
60
- return;
61
- }
62
- }
63
- core_1.logger.startSpinner('Creating Claude command...');
64
- try {
65
- await fs_extra_1.default.ensureDir(outputDir);
66
- // Build frontmatter
67
- const frontmatter = ['---'];
68
- if (options.args && options.args.length > 0) {
69
- frontmatter.push(`argument-hint: ${options.args.join(' ')}`);
70
- }
71
- frontmatter.push(`description: ${description}`);
72
- if (options.tools && options.tools.length > 0) {
73
- frontmatter.push(`allowed-tools:`);
74
- options.tools.forEach(tool => {
75
- frontmatter.push(` - ${tool}`);
76
- });
77
- }
78
- frontmatter.push('---');
79
- frontmatter.push('');
80
- // Build command content
81
- const argsList = options.args || [];
82
- const argPlaceholders = argsList.map((arg, i) => `$${i + 1}`).join(' ');
83
- const argDescription = argsList.length > 0
84
- ? `\n\nArguments:\n${argsList.map((arg, i) => `- $${i + 1}: ${arg}`).join('\n')}`
85
- : '';
86
- const commandContent = `${frontmatter.join('\n')}# ${name} Command
87
-
88
- Execute the ${name} operation${argDescription ? ':' + argDescription : '.'}
89
-
90
- ${argPlaceholders ? `Using arguments: ${argPlaceholders}` : ''}
91
-
92
- Please proceed with the ${name} operation.
93
- `;
94
- await fs_extra_1.default.writeFile(commandFile, commandContent, 'utf-8');
95
- core_1.logger.succeedSpinner('Claude command created successfully!');
96
- core_1.logger.section('Next steps', [
97
- options.global
98
- ? `Command /${name} is now available globally in Claude Code`
99
- : `Add the command to your project by copying ${commandFile}`,
100
- '',
101
- 'Usage:',
102
- argsList.length > 0
103
- ? ` /${name} ${argsList.join(' ')}`
104
- : ` /${name}`
105
- ]);
106
- core_1.logger.success(`✨ Command "/${name}" ready to use!`);
107
- }
108
- catch (error) {
109
- core_1.logger.failSpinner('Failed to create command');
110
- throw error;
111
- }
112
- }
@@ -1,10 +0,0 @@
1
- interface GenerateMCPOptions {
2
- description?: string;
3
- output?: string;
4
- fastmcp?: boolean;
5
- cicd?: 'github' | 'harness' | 'none';
6
- deployment?: 'aws' | 'gcp' | 'none';
7
- dryRun?: boolean;
8
- }
9
- export declare function generateMCP(name: string, options: GenerateMCPOptions): Promise<void>;
10
- export {};
@@ -1,429 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.generateMCP = generateMCP;
7
- const path_1 = __importDefault(require("path"));
8
- const fs_extra_1 = __importDefault(require("fs-extra"));
9
- const core_1 = require("@neural-tools/core");
10
- const inquirer_1 = __importDefault(require("inquirer"));
11
- async function generateMCP(name, options) {
12
- core_1.logger.header(`Generating MCP: ${name}`);
13
- // Check license for cloud deployment
14
- if (options.deployment !== 'none') {
15
- await (0, core_1.requireFeature)('cloud-deployment', 'Cloud Deployment');
16
- }
17
- // Prompt for missing information
18
- let description = options.description;
19
- if (!description) {
20
- const answers = await inquirer_1.default.prompt([
21
- {
22
- type: 'input',
23
- name: 'description',
24
- message: 'Description of your MCP:',
25
- default: `${name} MCP server`
26
- }
27
- ]);
28
- description = answers.description;
29
- }
30
- const outputDir = path_1.default.resolve(options.output || './apps', name);
31
- if (options.dryRun) {
32
- core_1.logger.info('Dry run mode - no files will be created');
33
- core_1.logger.section('Configuration', [
34
- `Name: ${name}`,
35
- `Description: ${description}`,
36
- `Output: ${outputDir}`,
37
- `Template: ${options.fastmcp ? 'FastMCP' : 'Standard'}`,
38
- `CI/CD: ${options.cicd}`,
39
- `Deployment: ${options.deployment}`
40
- ]);
41
- return;
42
- }
43
- // Check if directory already exists
44
- if (await fs_extra_1.default.pathExists(outputDir)) {
45
- const { overwrite } = await inquirer_1.default.prompt([
46
- {
47
- type: 'confirm',
48
- name: 'overwrite',
49
- message: `Directory ${outputDir} already exists. Overwrite?`,
50
- default: false
51
- }
52
- ]);
53
- if (!overwrite) {
54
- core_1.logger.warn('Cancelled');
55
- return;
56
- }
57
- await fs_extra_1.default.remove(outputDir);
58
- }
59
- core_1.logger.startSpinner('Creating MCP structure...');
60
- try {
61
- // Create directory structure
62
- await fs_extra_1.default.ensureDir(outputDir);
63
- // Create pyproject.toml
64
- const pyprojectContent = `[project]
65
- name = "mcp-${name}"
66
- version = "0.1.0"
67
- description = "${description}"
68
- requires-python = ">=3.10"
69
- dependencies = [
70
- "fastmcp>=2.2.0",
71
- ]
72
-
73
- [project.optional-dependencies]
74
- dev = [
75
- "pytest>=7.0.0",
76
- "black>=23.0.0",
77
- "ruff>=0.1.0",
78
- ]
79
-
80
- [build-system]
81
- requires = ["hatchling"]
82
- build-backend = "hatchling.build"
83
-
84
- [tool.black]
85
- line-length = 100
86
-
87
- [tool.ruff]
88
- line-length = 100
89
- `;
90
- await fs_extra_1.default.writeFile(path_1.default.join(outputDir, 'pyproject.toml'), pyprojectContent, 'utf-8');
91
- // Create main server.py with FastMCP
92
- const serverContent = `"""
93
- ${name} MCP Server
94
-
95
- ${description}
96
- """
97
- from fastmcp import FastMCP
98
-
99
- mcp = FastMCP("${name}")
100
-
101
-
102
- @mcp.tool()
103
- def add_numbers(a: int, b: int) -> int:
104
- """Add two numbers together"""
105
- return a + b
106
-
107
-
108
- @mcp.tool()
109
- async def process_message(message: str) -> str:
110
- """Process a message and return the result"""
111
- return f"Processed: {message}"
112
-
113
-
114
- @mcp.resource("config://version")
115
- def get_version() -> str:
116
- """Get the current version of the MCP server"""
117
- return "0.1.0"
118
-
119
-
120
- @mcp.resource("example://data/{item_id}")
121
- async def get_item(item_id: str) -> str:
122
- """Get an item by ID"""
123
- return f"Item data for: {item_id}"
124
-
125
-
126
- @mcp.prompt()
127
- def review_code(code: str) -> str:
128
- """Generate a code review prompt"""
129
- return f"""Please review this code:
130
-
131
- \`\`\`python
132
- {code}
133
- \`\`\`
134
-
135
- Provide feedback on:
136
- 1. Code quality
137
- 2. Potential bugs
138
- 3. Performance improvements
139
- 4. Best practices
140
- """
141
-
142
-
143
- @mcp.prompt()
144
- def brainstorm_topic(topic: str) -> str:
145
- """Generate a brainstorming prompt"""
146
- return f"Let's brainstorm ideas about: {topic}"
147
-
148
-
149
- if __name__ == "__main__":
150
- mcp.run()
151
- `;
152
- await fs_extra_1.default.writeFile(path_1.default.join(outputDir, 'server.py'), serverContent, 'utf-8');
153
- // Create README
154
- const readmeContent = `# ${name} MCP Server
155
-
156
- ${description}
157
-
158
- ## Quick Start with Docker
159
-
160
- \`\`\`bash
161
- # Start the MCP server
162
- docker-compose up
163
-
164
- # In another terminal, test it
165
- docker-compose exec mcp python server.py
166
- \`\`\`
167
-
168
- ## Local Development
169
-
170
- ### Prerequisites
171
-
172
- - Python 3.10+
173
- - uv (recommended) or pip
174
-
175
- ### Installation
176
-
177
- \`\`\`bash
178
- # Using uv (recommended)
179
- uv pip install -e .
180
-
181
- # Or using pip
182
- pip install -e .
183
- \`\`\`
184
-
185
- ### Running the Server
186
-
187
- \`\`\`bash
188
- # Development mode with MCP Inspector
189
- fastmcp dev server.py
190
-
191
- # Direct execution
192
- python server.py
193
-
194
- # Install to Claude Desktop
195
- fastmcp install server.py
196
- \`\`\`
197
-
198
- ## Usage with Claude Code
199
-
200
- Add to your Claude Code settings (\`~/.config/claude/config.json\`):
201
-
202
- \`\`\`json
203
- {
204
- "mcpServers": {
205
- "${name}": {
206
- "command": "python",
207
- "args": ["/path/to/server.py"]
208
- }
209
- }
210
- }
211
- \`\`\`
212
-
213
- Or use the Docker container:
214
-
215
- \`\`\`json
216
- {
217
- "mcpServers": {
218
- "${name}": {
219
- "command": "docker",
220
- "args": ["run", "-i", "mcp-${name}"]
221
- }
222
- }
223
- }
224
- \`\`\`
225
-
226
- ## Features
227
-
228
- - **Tools**: Add numbers, process messages
229
- - **Resources**: Get version, retrieve items by ID
230
- - **Prompts**: Code review, brainstorming
231
-
232
- ## Project Structure
233
-
234
- \`\`\`
235
- .
236
- ├── server.py # Main MCP server
237
- ├── pyproject.toml # Python project configuration
238
- ├── Dockerfile # Docker image definition
239
- ├── docker-compose.yml # Local development setup
240
- └── README.md # This file
241
- \`\`\`
242
-
243
- ## Development
244
-
245
- ### Running Tests
246
-
247
- \`\`\`bash
248
- pytest
249
- \`\`\`
250
-
251
- ### Code Formatting
252
-
253
- \`\`\`bash
254
- black .
255
- ruff check .
256
- \`\`\`
257
-
258
- ## License
259
-
260
- MIT
261
- `;
262
- await fs_extra_1.default.writeFile(path_1.default.join(outputDir, 'README.md'), readmeContent, 'utf-8');
263
- // Create Dockerfile
264
- const dockerfileContent = `FROM python:3.11-slim
265
-
266
- WORKDIR /app
267
-
268
- # Install uv for faster dependency installation
269
- RUN pip install --no-cache-dir uv
270
-
271
- # Copy project files
272
- COPY pyproject.toml .
273
- COPY server.py .
274
-
275
- # Install dependencies
276
- RUN uv pip install --system --no-cache .
277
-
278
- # Run the MCP server
279
- CMD ["python", "server.py"]
280
- `;
281
- await fs_extra_1.default.writeFile(path_1.default.join(outputDir, 'Dockerfile'), dockerfileContent, 'utf-8');
282
- // Create docker-compose.yml
283
- const dockerComposeContent = `version: '3.8'
284
-
285
- services:
286
- mcp:
287
- build: .
288
- image: mcp-${name}
289
- container_name: ${name}-mcp
290
- stdin_open: true
291
- tty: true
292
- volumes:
293
- - .:/app
294
- environment:
295
- - PYTHONUNBUFFERED=1
296
- `;
297
- await fs_extra_1.default.writeFile(path_1.default.join(outputDir, 'docker-compose.yml'), dockerComposeContent, 'utf-8');
298
- // Create .dockerignore
299
- const dockerignoreContent = `__pycache__
300
- *.pyc
301
- *.pyo
302
- *.pyd
303
- .Python
304
- *.so
305
- *.egg
306
- *.egg-info
307
- dist
308
- build
309
- .pytest_cache
310
- .ruff_cache
311
- .venv
312
- venv
313
- .git
314
- .github
315
- README.md
316
- `;
317
- await fs_extra_1.default.writeFile(path_1.default.join(outputDir, '.dockerignore'), dockerignoreContent, 'utf-8');
318
- // Add CI/CD if requested
319
- if (options.cicd === 'github') {
320
- await fs_extra_1.default.ensureDir(path_1.default.join(outputDir, '.github', 'workflows'));
321
- const workflowContent = `name: Deploy MCP
322
-
323
- on:
324
- push:
325
- branches: [main]
326
- pull_request:
327
- branches: [main]
328
-
329
- jobs:
330
- build:
331
- runs-on: ubuntu-latest
332
- steps:
333
- - uses: actions/checkout@v4
334
- - uses: actions/setup-python@v5
335
- with:
336
- python-version: '3.11'
337
-
338
- - name: Install uv
339
- run: pip install uv
340
-
341
- - name: Install dependencies
342
- run: uv pip install --system -e ".[dev]"
343
-
344
- - name: Run tests
345
- run: pytest
346
-
347
- - name: Check code formatting
348
- run: |
349
- black --check .
350
- ruff check .
351
-
352
- docker:
353
- runs-on: ubuntu-latest
354
- needs: build
355
- steps:
356
- - uses: actions/checkout@v4
357
-
358
- - name: Build Docker image
359
- run: docker build -t mcp-${name}:latest .
360
-
361
- - name: Test Docker image
362
- run: docker run --rm mcp-${name}:latest python -c "import fastmcp; print('OK')"
363
-
364
- deploy:
365
- needs: [build, docker]
366
- runs-on: ubuntu-latest
367
- if: github.ref == 'refs/heads/main'
368
- steps:
369
- - uses: actions/checkout@v4
370
- ${options.deployment === 'aws' ? `
371
- - name: Configure AWS credentials
372
- uses: aws-actions/configure-aws-credentials@v4
373
- with:
374
- aws-access-key-id: \${{ secrets.AWS_ACCESS_KEY_ID }}
375
- aws-secret-access-key: \${{ secrets.AWS_SECRET_ACCESS_KEY }}
376
- aws-region: us-east-1
377
-
378
- - name: Login to Amazon ECR
379
- id: login-ecr
380
- uses: aws-actions/amazon-ecr-login@v2
381
-
382
- - name: Build and push Docker image
383
- env:
384
- ECR_REGISTRY: \${{ steps.login-ecr.outputs.registry }}
385
- ECR_REPOSITORY: mcp-${name}
386
- IMAGE_TAG: \${{ github.sha }}
387
- run: |
388
- docker build -t \$ECR_REGISTRY/\$ECR_REPOSITORY:\$IMAGE_TAG .
389
- docker push \$ECR_REGISTRY/\$ECR_REPOSITORY:\$IMAGE_TAG
390
- docker tag \$ECR_REGISTRY/\$ECR_REPOSITORY:\$IMAGE_TAG \$ECR_REGISTRY/\$ECR_REPOSITORY:latest
391
- docker push \$ECR_REGISTRY/\$ECR_REPOSITORY:latest
392
- ` : ''}${options.deployment === 'gcp' ? `
393
- - name: Authenticate to Google Cloud
394
- uses: google-github-actions/auth@v2
395
- with:
396
- credentials_json: \${{ secrets.GCP_CREDENTIALS }}
397
-
398
- - name: Set up Cloud SDK
399
- uses: google-github-actions/setup-gcloud@v2
400
-
401
- - name: Build and push Docker image
402
- run: |
403
- gcloud builds submit --tag gcr.io/\${{ secrets.GCP_PROJECT_ID }}/mcp-${name}:latest
404
- ` : ''}
405
- `;
406
- await fs_extra_1.default.writeFile(path_1.default.join(outputDir, '.github', 'workflows', 'deploy.yml'), workflowContent, 'utf-8');
407
- }
408
- core_1.logger.succeedSpinner('MCP created successfully!');
409
- core_1.logger.section('Next steps', [
410
- `1. cd ${outputDir}`,
411
- '2. docker-compose up # Start with Docker',
412
- '',
413
- 'Or for local development:',
414
- '2. uv pip install -e .',
415
- '3. python server.py',
416
- '',
417
- 'Or use MCP Inspector:',
418
- '2. uv pip install -e .',
419
- '3. fastmcp dev server.py',
420
- '',
421
- 'Add to Claude Code settings to use this MCP'
422
- ]);
423
- core_1.logger.success(`✨ MCP "${name}" ready to use!`);
424
- }
425
- catch (error) {
426
- core_1.logger.failSpinner('Failed to create MCP');
427
- throw error;
428
- }
429
- }
@@ -1,5 +0,0 @@
1
- interface LoginOptions {
2
- key?: string;
3
- }
4
- export declare function loginCommand(options: LoginOptions): Promise<void>;
5
- export {};
@@ -1,112 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.loginCommand = loginCommand;
7
- const core_1 = require("@neural-tools/core");
8
- const inquirer_1 = __importDefault(require("inquirer"));
9
- async function loginCommand(options) {
10
- core_1.logger.header('AI Toolkit License Management');
11
- let licenseKey = options.key;
12
- if (!licenseKey) {
13
- const answers = await inquirer_1.default.prompt([
14
- {
15
- type: 'input',
16
- name: 'licenseKey',
17
- message: 'Enter your license key:',
18
- validate: (input) => {
19
- if (!input || input.trim().length === 0) {
20
- return 'License key is required';
21
- }
22
- return true;
23
- }
24
- }
25
- ]);
26
- licenseKey = answers.licenseKey;
27
- }
28
- if (!licenseKey) {
29
- core_1.logger.error('License key is required');
30
- return;
31
- }
32
- core_1.logger.startSpinner('Validating license...');
33
- try {
34
- // TODO: Validate license key with backend API
35
- // For now, parse the key format: tier-email-signature
36
- const parts = licenseKey.split('-');
37
- if (parts.length < 2) {
38
- throw new Error('Invalid license key format');
39
- }
40
- const tier = parts[0];
41
- const email = parts[1];
42
- // Validate tier
43
- if (!Object.values(core_1.LicenseTier).includes(tier)) {
44
- throw new Error('Invalid license tier');
45
- }
46
- // Save license
47
- await core_1.licenseManager.saveLicense({
48
- tier,
49
- email,
50
- key: licenseKey,
51
- features: []
52
- });
53
- core_1.logger.succeedSpinner('License activated successfully!');
54
- const license = await core_1.licenseManager.loadLicense();
55
- core_1.logger.section('License Details', [
56
- `Tier: ${license.tier.toUpperCase()}`,
57
- `Email: ${license.email || 'N/A'}`,
58
- `Status: Active`
59
- ]);
60
- // Show available features based on tier
61
- const features = getFeaturesByTier(tier);
62
- core_1.logger.section('Available Features', features);
63
- if (tier === core_1.LicenseTier.FREE) {
64
- core_1.logger.newline();
65
- core_1.logger.info('Upgrade to Pro for advanced features:');
66
- core_1.logger.info('https://ai-toolkit.dev/pricing');
67
- }
68
- core_1.logger.success('✨ Ready to build!');
69
- }
70
- catch (error) {
71
- core_1.logger.failSpinner('License validation failed');
72
- core_1.logger.error(error.message || 'Invalid license key');
73
- core_1.logger.newline();
74
- core_1.logger.info('Get a license at: https://ai-toolkit.dev/pricing');
75
- core_1.logger.info('Or continue with free tier features');
76
- }
77
- }
78
- function getFeaturesByTier(tier) {
79
- const freeTier = [
80
- '✓ MCP generation',
81
- '✓ Claude commands',
82
- '✓ Basic templates',
83
- '✓ Local development'
84
- ];
85
- const proTier = [
86
- ...freeTier,
87
- '✓ Vector database integration',
88
- '✓ Semantic caching',
89
- '✓ Fine-tuning workflows',
90
- '✓ Cloud deployment (AWS/GCP)',
91
- '✓ Premium templates',
92
- '✓ GitHub automation'
93
- ];
94
- const enterpriseTier = [
95
- ...proTier,
96
- '✓ White-label support',
97
- '✓ Custom integrations',
98
- '✓ Priority support',
99
- '✓ SLA guarantee',
100
- '✓ Team collaboration features'
101
- ];
102
- switch (tier) {
103
- case core_1.LicenseTier.FREE:
104
- return freeTier;
105
- case core_1.LicenseTier.PRO:
106
- return proTier;
107
- case core_1.LicenseTier.ENTERPRISE:
108
- return enterpriseTier;
109
- default:
110
- return freeTier;
111
- }
112
- }
@@ -1 +0,0 @@
1
- export declare function statusCommand(): Promise<void>;