@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.
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +360 -80
- package/dist/cli.mjs +364 -0
- package/dist/index.d.mts +45 -0
- package/dist/index.d.ts +45 -6
- package/dist/index.js +363 -15
- package/dist/index.mjs +363 -0
- package/package.json +18 -5
- package/dist/commands/deploy.d.ts +0 -7
- package/dist/commands/deploy.js +0 -96
- package/dist/commands/generate-agent.d.ts +0 -10
- package/dist/commands/generate-agent.js +0 -126
- package/dist/commands/generate-command.d.ts +0 -10
- package/dist/commands/generate-command.js +0 -112
- package/dist/commands/generate-mcp.d.ts +0 -10
- package/dist/commands/generate-mcp.js +0 -429
- package/dist/commands/login.d.ts +0 -5
- package/dist/commands/login.js +0 -112
- package/dist/commands/status.d.ts +0 -1
- package/dist/commands/status.js +0 -64
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import p from"path";import u from"fs-extra";import{logger as d,requireFeature as M}from"@neural-tools/core";import R from"inquirer";async function O(e,t){d.header(`Generating MCP: ${e}`),t.deployment!=="none"&&await M("cloud-deployment","Cloud Deployment");let r=t.description;r||(r=(await R.prompt([{type:"input",name:"description",message:"Description of your MCP:",default:`${e} MCP server`}])).description);let n=p.resolve(t.output||"./apps",e);if(t.dryRun){d.info("Dry run mode - no files will be created"),d.section("Configuration",[`Name: ${e}`,`Description: ${r}`,`Output: ${n}`,`Template: ${t.fastmcp?"FastMCP":"Standard"}`,`CI/CD: ${t.cicd}`,`Deployment: ${t.deployment}`]);return}if(await u.pathExists(n)){let{overwrite:i}=await R.prompt([{type:"confirm",name:"overwrite",message:`Directory ${n} already exists. Overwrite?`,default:!1}]);if(!i){d.warn("Cancelled");return}await u.remove(n)}d.startSpinner("Creating MCP structure...");try{await u.ensureDir(n);let i=`[project]
|
|
2
|
+
name = "mcp-${e}"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "${r}"
|
|
5
|
+
requires-python = ">=3.10"
|
|
6
|
+
dependencies = [
|
|
7
|
+
"fastmcp>=2.2.0",
|
|
8
|
+
]
|
|
9
|
+
|
|
10
|
+
[project.optional-dependencies]
|
|
11
|
+
dev = [
|
|
12
|
+
"pytest>=7.0.0",
|
|
13
|
+
"black>=23.0.0",
|
|
14
|
+
"ruff>=0.1.0",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[build-system]
|
|
18
|
+
requires = ["hatchling"]
|
|
19
|
+
build-backend = "hatchling.build"
|
|
20
|
+
|
|
21
|
+
[tool.black]
|
|
22
|
+
line-length = 100
|
|
23
|
+
|
|
24
|
+
[tool.ruff]
|
|
25
|
+
line-length = 100
|
|
26
|
+
`;await u.writeFile(p.join(n,"pyproject.toml"),i,"utf-8");let o=`"""
|
|
27
|
+
${e} MCP Server
|
|
28
|
+
|
|
29
|
+
${r}
|
|
30
|
+
"""
|
|
31
|
+
from fastmcp import FastMCP
|
|
32
|
+
|
|
33
|
+
mcp = FastMCP("${e}")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@mcp.tool()
|
|
37
|
+
def add_numbers(a: int, b: int) -> int:
|
|
38
|
+
"""Add two numbers together"""
|
|
39
|
+
return a + b
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@mcp.tool()
|
|
43
|
+
async def process_message(message: str) -> str:
|
|
44
|
+
"""Process a message and return the result"""
|
|
45
|
+
return f"Processed: {message}"
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@mcp.resource("config://version")
|
|
49
|
+
def get_version() -> str:
|
|
50
|
+
"""Get the current version of the MCP server"""
|
|
51
|
+
return "0.1.0"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@mcp.resource("example://data/{item_id}")
|
|
55
|
+
async def get_item(item_id: str) -> str:
|
|
56
|
+
"""Get an item by ID"""
|
|
57
|
+
return f"Item data for: {item_id}"
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@mcp.prompt()
|
|
61
|
+
def review_code(code: str) -> str:
|
|
62
|
+
"""Generate a code review prompt"""
|
|
63
|
+
return f"""Please review this code:
|
|
64
|
+
|
|
65
|
+
\`\`\`python
|
|
66
|
+
{code}
|
|
67
|
+
\`\`\`
|
|
68
|
+
|
|
69
|
+
Provide feedback on:
|
|
70
|
+
1. Code quality
|
|
71
|
+
2. Potential bugs
|
|
72
|
+
3. Performance improvements
|
|
73
|
+
4. Best practices
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@mcp.prompt()
|
|
78
|
+
def brainstorm_topic(topic: str) -> str:
|
|
79
|
+
"""Generate a brainstorming prompt"""
|
|
80
|
+
return f"Let's brainstorm ideas about: {topic}"
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
if __name__ == "__main__":
|
|
84
|
+
mcp.run()
|
|
85
|
+
`;await u.writeFile(p.join(n,"server.py"),o,"utf-8");let s=`# ${e} MCP Server
|
|
86
|
+
|
|
87
|
+
${r}
|
|
88
|
+
|
|
89
|
+
## Quick Start with Docker
|
|
90
|
+
|
|
91
|
+
\`\`\`bash
|
|
92
|
+
# Start the MCP server
|
|
93
|
+
docker-compose up
|
|
94
|
+
|
|
95
|
+
# In another terminal, test it
|
|
96
|
+
docker-compose exec mcp python server.py
|
|
97
|
+
\`\`\`
|
|
98
|
+
|
|
99
|
+
## Local Development
|
|
100
|
+
|
|
101
|
+
### Prerequisites
|
|
102
|
+
|
|
103
|
+
- Python 3.10+
|
|
104
|
+
- uv (recommended) or pip
|
|
105
|
+
|
|
106
|
+
### Installation
|
|
107
|
+
|
|
108
|
+
\`\`\`bash
|
|
109
|
+
# Using uv (recommended)
|
|
110
|
+
uv pip install -e .
|
|
111
|
+
|
|
112
|
+
# Or using pip
|
|
113
|
+
pip install -e .
|
|
114
|
+
\`\`\`
|
|
115
|
+
|
|
116
|
+
### Running the Server
|
|
117
|
+
|
|
118
|
+
\`\`\`bash
|
|
119
|
+
# Development mode with MCP Inspector
|
|
120
|
+
fastmcp dev server.py
|
|
121
|
+
|
|
122
|
+
# Direct execution
|
|
123
|
+
python server.py
|
|
124
|
+
|
|
125
|
+
# Install to Claude Desktop
|
|
126
|
+
fastmcp install server.py
|
|
127
|
+
\`\`\`
|
|
128
|
+
|
|
129
|
+
## Usage with Claude Code
|
|
130
|
+
|
|
131
|
+
Add to your Claude Code settings (\`~/.config/claude/config.json\`):
|
|
132
|
+
|
|
133
|
+
\`\`\`json
|
|
134
|
+
{
|
|
135
|
+
"mcpServers": {
|
|
136
|
+
"${e}": {
|
|
137
|
+
"command": "python",
|
|
138
|
+
"args": ["/path/to/server.py"]
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
\`\`\`
|
|
143
|
+
|
|
144
|
+
Or use the Docker container:
|
|
145
|
+
|
|
146
|
+
\`\`\`json
|
|
147
|
+
{
|
|
148
|
+
"mcpServers": {
|
|
149
|
+
"${e}": {
|
|
150
|
+
"command": "docker",
|
|
151
|
+
"args": ["run", "-i", "mcp-${e}"]
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
\`\`\`
|
|
156
|
+
|
|
157
|
+
## Features
|
|
158
|
+
|
|
159
|
+
- **Tools**: Add numbers, process messages
|
|
160
|
+
- **Resources**: Get version, retrieve items by ID
|
|
161
|
+
- **Prompts**: Code review, brainstorming
|
|
162
|
+
|
|
163
|
+
## Project Structure
|
|
164
|
+
|
|
165
|
+
\`\`\`
|
|
166
|
+
.
|
|
167
|
+
\u251C\u2500\u2500 server.py # Main MCP server
|
|
168
|
+
\u251C\u2500\u2500 pyproject.toml # Python project configuration
|
|
169
|
+
\u251C\u2500\u2500 Dockerfile # Docker image definition
|
|
170
|
+
\u251C\u2500\u2500 docker-compose.yml # Local development setup
|
|
171
|
+
\u2514\u2500\u2500 README.md # This file
|
|
172
|
+
\`\`\`
|
|
173
|
+
|
|
174
|
+
## Development
|
|
175
|
+
|
|
176
|
+
### Running Tests
|
|
177
|
+
|
|
178
|
+
\`\`\`bash
|
|
179
|
+
pytest
|
|
180
|
+
\`\`\`
|
|
181
|
+
|
|
182
|
+
### Code Formatting
|
|
183
|
+
|
|
184
|
+
\`\`\`bash
|
|
185
|
+
black .
|
|
186
|
+
ruff check .
|
|
187
|
+
\`\`\`
|
|
188
|
+
|
|
189
|
+
## License
|
|
190
|
+
|
|
191
|
+
MIT
|
|
192
|
+
`;await u.writeFile(p.join(n,"README.md"),s,"utf-8"),await u.writeFile(p.join(n,"Dockerfile"),`FROM python:3.11-slim
|
|
193
|
+
|
|
194
|
+
WORKDIR /app
|
|
195
|
+
|
|
196
|
+
# Install uv for faster dependency installation
|
|
197
|
+
RUN pip install --no-cache-dir uv
|
|
198
|
+
|
|
199
|
+
# Copy project files
|
|
200
|
+
COPY pyproject.toml .
|
|
201
|
+
COPY server.py .
|
|
202
|
+
|
|
203
|
+
# Install dependencies
|
|
204
|
+
RUN uv pip install --system --no-cache .
|
|
205
|
+
|
|
206
|
+
# Run the MCP server
|
|
207
|
+
CMD ["python", "server.py"]
|
|
208
|
+
`,"utf-8");let f=`version: '3.8'
|
|
209
|
+
|
|
210
|
+
services:
|
|
211
|
+
mcp:
|
|
212
|
+
build: .
|
|
213
|
+
image: mcp-${e}
|
|
214
|
+
container_name: ${e}-mcp
|
|
215
|
+
stdin_open: true
|
|
216
|
+
tty: true
|
|
217
|
+
volumes:
|
|
218
|
+
- .:/app
|
|
219
|
+
environment:
|
|
220
|
+
- PYTHONUNBUFFERED=1
|
|
221
|
+
`;if(await u.writeFile(p.join(n,"docker-compose.yml"),f,"utf-8"),await u.writeFile(p.join(n,".dockerignore"),`__pycache__
|
|
222
|
+
*.pyc
|
|
223
|
+
*.pyo
|
|
224
|
+
*.pyd
|
|
225
|
+
.Python
|
|
226
|
+
*.so
|
|
227
|
+
*.egg
|
|
228
|
+
*.egg-info
|
|
229
|
+
dist
|
|
230
|
+
build
|
|
231
|
+
.pytest_cache
|
|
232
|
+
.ruff_cache
|
|
233
|
+
.venv
|
|
234
|
+
venv
|
|
235
|
+
.git
|
|
236
|
+
.github
|
|
237
|
+
README.md
|
|
238
|
+
`,"utf-8"),t.cicd==="github"){await u.ensureDir(p.join(n,".github","workflows"));let y=`name: Deploy MCP
|
|
239
|
+
|
|
240
|
+
on:
|
|
241
|
+
push:
|
|
242
|
+
branches: [main]
|
|
243
|
+
pull_request:
|
|
244
|
+
branches: [main]
|
|
245
|
+
|
|
246
|
+
jobs:
|
|
247
|
+
build:
|
|
248
|
+
runs-on: ubuntu-latest
|
|
249
|
+
steps:
|
|
250
|
+
- uses: actions/checkout@v4
|
|
251
|
+
- uses: actions/setup-python@v5
|
|
252
|
+
with:
|
|
253
|
+
python-version: '3.11'
|
|
254
|
+
|
|
255
|
+
- name: Install uv
|
|
256
|
+
run: pip install uv
|
|
257
|
+
|
|
258
|
+
- name: Install dependencies
|
|
259
|
+
run: uv pip install --system -e ".[dev]"
|
|
260
|
+
|
|
261
|
+
- name: Run tests
|
|
262
|
+
run: pytest
|
|
263
|
+
|
|
264
|
+
- name: Check code formatting
|
|
265
|
+
run: |
|
|
266
|
+
black --check .
|
|
267
|
+
ruff check .
|
|
268
|
+
|
|
269
|
+
docker:
|
|
270
|
+
runs-on: ubuntu-latest
|
|
271
|
+
needs: build
|
|
272
|
+
steps:
|
|
273
|
+
- uses: actions/checkout@v4
|
|
274
|
+
|
|
275
|
+
- name: Build Docker image
|
|
276
|
+
run: docker build -t mcp-${e}:latest .
|
|
277
|
+
|
|
278
|
+
- name: Test Docker image
|
|
279
|
+
run: docker run --rm mcp-${e}:latest python -c "import fastmcp; print('OK')"
|
|
280
|
+
|
|
281
|
+
deploy:
|
|
282
|
+
needs: [build, docker]
|
|
283
|
+
runs-on: ubuntu-latest
|
|
284
|
+
if: github.ref == 'refs/heads/main'
|
|
285
|
+
steps:
|
|
286
|
+
- uses: actions/checkout@v4
|
|
287
|
+
${t.deployment==="aws"?`
|
|
288
|
+
- name: Configure AWS credentials
|
|
289
|
+
uses: aws-actions/configure-aws-credentials@v4
|
|
290
|
+
with:
|
|
291
|
+
aws-access-key-id: \${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
292
|
+
aws-secret-access-key: \${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
293
|
+
aws-region: us-east-1
|
|
294
|
+
|
|
295
|
+
- name: Login to Amazon ECR
|
|
296
|
+
id: login-ecr
|
|
297
|
+
uses: aws-actions/amazon-ecr-login@v2
|
|
298
|
+
|
|
299
|
+
- name: Build and push Docker image
|
|
300
|
+
env:
|
|
301
|
+
ECR_REGISTRY: \${{ steps.login-ecr.outputs.registry }}
|
|
302
|
+
ECR_REPOSITORY: mcp-${e}
|
|
303
|
+
IMAGE_TAG: \${{ github.sha }}
|
|
304
|
+
run: |
|
|
305
|
+
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
|
|
306
|
+
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
|
|
307
|
+
docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:latest
|
|
308
|
+
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
|
|
309
|
+
`:""}${t.deployment==="gcp"?`
|
|
310
|
+
- name: Authenticate to Google Cloud
|
|
311
|
+
uses: google-github-actions/auth@v2
|
|
312
|
+
with:
|
|
313
|
+
credentials_json: \${{ secrets.GCP_CREDENTIALS }}
|
|
314
|
+
|
|
315
|
+
- name: Set up Cloud SDK
|
|
316
|
+
uses: google-github-actions/setup-gcloud@v2
|
|
317
|
+
|
|
318
|
+
- name: Build and push Docker image
|
|
319
|
+
run: |
|
|
320
|
+
gcloud builds submit --tag gcr.io/\${{ secrets.GCP_PROJECT_ID }}/mcp-${e}:latest
|
|
321
|
+
`:""}
|
|
322
|
+
`;await u.writeFile(p.join(n,".github","workflows","deploy.yml"),y,"utf-8")}d.succeedSpinner("MCP created successfully!"),d.section("Next steps",[`1. cd ${n}`,"2. docker-compose up # Start with Docker","","Or for local development:","2. uv pip install -e .","3. python server.py","","Or use MCP Inspector:","2. uv pip install -e .","3. fastmcp dev server.py","","Add to Claude Code settings to use this MCP"]),d.success(`\u2728 MCP "${e}" ready to use!`)}catch(i){throw d.failSpinner("Failed to create MCP"),i}}import b from"path";import G from"os";import k from"fs-extra";import{logger as m}from"@neural-tools/core";import D from"inquirer";async function I(e,t){m.header(`Generating Claude Command: /${e}`);let r=t.description;r||(r=(await D.prompt([{type:"input",name:"description",message:"Description of your command:",default:`Execute ${e}`}])).description);let n;t.global?n=b.join(G.homedir(),".claude","commands"):n=b.resolve(t.output||"./claude/commands");let i=b.join(n,`${e}.md`);if(t.dryRun){m.info("Dry run mode - no files will be created"),m.section("Configuration",[`Name: /${e}`,`Description: ${r}`,`Output: ${i}`,`Arguments: ${t.args?.join(", ")||"none"}`,`Allowed Tools: ${t.tools?.join(", ")||"all"}`,`Global: ${t.global?"Yes":"No"}`]);return}if(await k.pathExists(i)){let{overwrite:o}=await D.prompt([{type:"confirm",name:"overwrite",message:`Command /${e} already exists. Overwrite?`,default:!1}]);if(!o){m.warn("Cancelled");return}}m.startSpinner("Creating Claude command...");try{await k.ensureDir(n);let o=["---"];t.args&&t.args.length>0&&o.push(`argument-hint: ${t.args.join(" ")}`),o.push(`description: ${r}`),t.tools&&t.tools.length>0&&(o.push("allowed-tools:"),t.tools.forEach(y=>{o.push(` - ${y}`)})),o.push("---"),o.push("");let s=t.args||[],w=s.map((y,$)=>`$${$+1}`).join(" "),f=s.length>0?`
|
|
323
|
+
|
|
324
|
+
Arguments:
|
|
325
|
+
${s.map((y,$)=>`- $${$+1}: ${y}`).join(`
|
|
326
|
+
`)}`:"",S=`${o.join(`
|
|
327
|
+
`)}# ${e} Command
|
|
328
|
+
|
|
329
|
+
Execute the ${e} operation${f?":"+f:"."}
|
|
330
|
+
|
|
331
|
+
${w?`Using arguments: ${w}`:""}
|
|
332
|
+
|
|
333
|
+
Please proceed with the ${e} operation.
|
|
334
|
+
`;await k.writeFile(i,S,"utf-8"),m.succeedSpinner("Claude command created successfully!"),m.section("Next steps",[t.global?`Command /${e} is now available globally in Claude Code`:`Add the command to your project by copying ${i}`,"","Usage:",s.length>0?` /${e} ${s.join(" ")}`:` /${e}`]),m.success(`\u2728 Command "/${e}" ready to use!`)}catch(o){throw m.failSpinner("Failed to create command"),o}}import P from"path";import F from"os";import E from"fs-extra";import{logger as g}from"@neural-tools/core";import A from"inquirer";async function j(e,t){g.header(`Generating Claude Agent: ${e}`);let r=t.description;r||(r=(await A.prompt([{type:"input",name:"description",message:"Description of your agent:",default:`${e} specialized agent`}])).description);let n;t.global?n=P.join(F.homedir(),".claude","agents"):n=P.resolve(t.output||"./claude/agents");let i=P.join(n,`${e}.md`),o=t.model||"sonnet";if(t.dryRun){g.info("Dry run mode - no files will be created"),g.section("Configuration",[`Name: ${e}`,`Description: ${r}`,`Output: ${i}`,`Model: ${o}`,`Tools: ${t.tools?.join(", ")||"all"}`,`Global: ${t.global?"Yes":"No"}`]);return}if(await E.pathExists(i)){let{overwrite:s}=await A.prompt([{type:"confirm",name:"overwrite",message:`Agent ${e} already exists. Overwrite?`,default:!1}]);if(!s){g.warn("Cancelled");return}}g.startSpinner("Creating Claude agent...");try{await E.ensureDir(n);let s=["---"];s.push(`model: claude-${o}-4-5`),t.tools&&t.tools.length>0&&(s.push("tools:"),t.tools.forEach(f=>{s.push(` - ${f}`)})),s.push("---"),s.push("");let w=`${s.join(`
|
|
335
|
+
`)}# ${e} Agent
|
|
336
|
+
|
|
337
|
+
${r}
|
|
338
|
+
|
|
339
|
+
## Role
|
|
340
|
+
|
|
341
|
+
You are a specialized agent for ${e} tasks. Your primary responsibilities include:
|
|
342
|
+
|
|
343
|
+
- [Responsibility 1]
|
|
344
|
+
- [Responsibility 2]
|
|
345
|
+
- [Responsibility 3]
|
|
346
|
+
|
|
347
|
+
## Guidelines
|
|
348
|
+
|
|
349
|
+
When performing ${e} tasks:
|
|
350
|
+
|
|
351
|
+
1. [Guideline 1]
|
|
352
|
+
2. [Guideline 2]
|
|
353
|
+
3. [Guideline 3]
|
|
354
|
+
|
|
355
|
+
## Output Format
|
|
356
|
+
|
|
357
|
+
Provide clear, structured responses that:
|
|
358
|
+
- [Output requirement 1]
|
|
359
|
+
- [Output requirement 2]
|
|
360
|
+
- [Output requirement 3]
|
|
361
|
+
|
|
362
|
+
Focus on ${e} and deliver actionable results.
|
|
363
|
+
`;await E.writeFile(i,w,"utf-8"),g.succeedSpinner("Claude agent created successfully!"),g.section("Next steps",[t.global?`Agent ${e} is now available globally in Claude Code`:`Add the agent to your project by copying ${i}`,"","Customize the agent by editing:",` ${i}`,"","Use the agent via the Task tool in Claude Code"]),g.success(`\u2728 Agent "${e}" ready to use!`)}catch(s){throw g.failSpinner("Failed to create agent"),s}}import{logger as a,requireFeature as x}from"@neural-tools/core";import{execa as L}from"execa";import Y from"path";import N from"fs-extra";async function q(e,t){a.header(`Deploying MCP: ${e}`),await x("cloud-deployment","Cloud Deployment");let r=t.platform||"aws",n=t.env||"dev";a.info(`Platform: ${r}`),a.info(`Environment: ${n}`);let i=Y.resolve("./apps",e);if(!await N.pathExists(i))throw new Error(`MCP "${e}" not found at ${i}`);a.startSpinner("Building MCP...");try{await L("npm",["run","build"],{cwd:i,stdio:"pipe"}),a.succeedSpinner("MCP built successfully"),r==="aws"?await U(e,i,t):r==="gcp"&&await W(e,i,t),a.success(`\u2728 MCP "${e}" deployed successfully!`)}catch(o){throw a.failSpinner("Deployment failed"),o}}async function U(e,t,r){a.startSpinner("Deploying to AWS Lambda..."),a.updateSpinner("Packaging Lambda function..."),await new Promise(n=>setTimeout(n,1e3)),a.updateSpinner("Uploading to S3..."),await new Promise(n=>setTimeout(n,1e3)),a.updateSpinner("Creating/updating Lambda function..."),await new Promise(n=>setTimeout(n,1e3)),a.succeedSpinner("Deployed to AWS Lambda"),a.section("Deployment Info",[`Function: ${e}-${r.env}`,`Region: ${r.region||"us-east-1"}`,`Environment: ${r.env}`,"","Configure in Claude Code:",JSON.stringify({mcpServers:{[e]:{command:"aws",args:["lambda","invoke","--function-name",`${e}-${r.env}`,"--payload","stdin","--output","stdout"]}}},null,2)])}async function W(e,t,r){a.startSpinner("Deploying to Google Cloud Functions..."),a.updateSpinner("Packaging function..."),await new Promise(n=>setTimeout(n,1e3)),a.updateSpinner("Uploading to Cloud Storage..."),await new Promise(n=>setTimeout(n,1e3)),a.updateSpinner("Deploying Cloud Function..."),await new Promise(n=>setTimeout(n,1e3)),a.succeedSpinner("Deployed to Google Cloud Functions"),a.section("Deployment Info",[`Function: ${e}-${r.env}`,`Region: ${r.region||"us-central1"}`,`Environment: ${r.env}`])}import{logger as c,licenseManager as T,LicenseTier as v}from"@neural-tools/core";import B from"inquirer";async function K(e){c.header("AI Toolkit License Management");let t=e.key;if(t||(t=(await B.prompt([{type:"input",name:"licenseKey",message:"Enter your license key:",validate:n=>!n||n.trim().length===0?"License key is required":!0}])).licenseKey),!t){c.error("License key is required");return}c.startSpinner("Validating license...");try{let r=t.split("-");if(r.length<2)throw new Error("Invalid license key format");let n=r[0],i=r[1];if(!Object.values(v).includes(n))throw new Error("Invalid license tier");await T.saveLicense({tier:n,email:i,key:t,features:[]}),c.succeedSpinner("License activated successfully!");let o=await T.loadLicense();c.section("License Details",[`Tier: ${o.tier.toUpperCase()}`,`Email: ${o.email||"N/A"}`,"Status: Active"]);let s=z(n);c.section("Available Features",s),n===v.FREE&&(c.newline(),c.info("Upgrade to Pro for advanced features:"),c.info("https://ai-toolkit.dev/pricing")),c.success("\u2728 Ready to build!")}catch(r){c.failSpinner("License validation failed"),c.error(r.message||"Invalid license key"),c.newline(),c.info("Get a license at: https://ai-toolkit.dev/pricing"),c.info("Or continue with free tier features")}}function z(e){let t=["\u2713 MCP generation","\u2713 Claude commands","\u2713 Basic templates","\u2713 Local development"],r=[...t,"\u2713 Vector database integration","\u2713 Semantic caching","\u2713 Fine-tuning workflows","\u2713 Cloud deployment (AWS/GCP)","\u2713 Premium templates","\u2713 GitHub automation"],n=[...r,"\u2713 White-label support","\u2713 Custom integrations","\u2713 Priority support","\u2713 SLA guarantee","\u2713 Team collaboration features"];switch(e){case v.FREE:return t;case v.PRO:return r;case v.ENTERPRISE:return n;default:return t}}import{logger as l,licenseManager as _,LicenseTier as V}from"@neural-tools/core";async function H(){l.header("AI Toolkit Status");try{let e=await _.loadLicense();l.section("License Information",[`Tier: ${e.tier.toUpperCase()}`,`Email: ${e.email||"N/A"}`,`Status: ${e.expiresAt?J(e.expiresAt):"Active"}`]);let t=[{name:"MCP Generation",key:"mcp-generation"},{name:"Claude Commands",key:"claude-commands"},{name:"Vector Database",key:"vector-db"},{name:"Semantic Cache",key:"semantic-cache"},{name:"Fine-tuning",key:"fine-tuning"},{name:"Cloud Deployment",key:"cloud-deployment"},{name:"GitHub Automation",key:"github-automation"}],r=await Promise.all(t.map(async n=>`${await _.checkFeature(n.key)?"\u2713":"\u2717"} ${n.name}`));l.section("Feature Availability",r),e.tier===V.FREE&&(l.newline(),l.info("Unlock more features with Pro or Enterprise:"),l.info("https://ai-toolkit.dev/pricing")),l.newline(),l.section("Quick Start",["Generate an MCP server:"," ai-toolkit generate mcp github","","Generate a Claude command:"," ai-toolkit generate command search-kb","","View all commands:"," ai-toolkit --help"])}catch{l.error("Failed to load license information"),l.newline(),l.info('Run "ai-toolkit login" to activate your license'),l.info("Or continue with free tier features")}}function J(e){let t=new Date(e),r=new Date;if(t<r)return"Expired";let n=Math.ceil((t.getTime()-r.getTime())/(1e3*60*60*24));return n<=30?`Active (expires in ${n} days)`:"Active"}export{q as deployMCP,j as generateAgent,I as generateCommand,O as generateMCP,K as loginCommand,H as statusCommand};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neural-tools/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "CLI for Neural Tools - Generate MCPs, Claude commands, and AI workflows",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -13,9 +13,22 @@
|
|
|
13
13
|
},
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|
|
16
|
-
"url": "https://github.com/
|
|
16
|
+
"url": "https://github.com/MacLeanLuke/neural-tools.git",
|
|
17
17
|
"directory": "packages/cli"
|
|
18
18
|
},
|
|
19
|
+
"homepage": "https://neural-tools.com/docs/cli.html",
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/MacLeanLuke/neural-tools/issues"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"cli",
|
|
25
|
+
"neural-tools",
|
|
26
|
+
"mcp",
|
|
27
|
+
"claude",
|
|
28
|
+
"ai-tools",
|
|
29
|
+
"code-generation",
|
|
30
|
+
"developer-tools"
|
|
31
|
+
],
|
|
19
32
|
"dependencies": {
|
|
20
33
|
"commander": "^12.0.0",
|
|
21
34
|
"inquirer": "^9.2.12",
|
|
@@ -23,7 +36,7 @@
|
|
|
23
36
|
"fs-extra": "^11.2.0",
|
|
24
37
|
"globby": "^14.0.0",
|
|
25
38
|
"picocolors": "^1.0.0",
|
|
26
|
-
"@neural-tools/core": "0.1.
|
|
39
|
+
"@neural-tools/core": "0.1.5"
|
|
27
40
|
},
|
|
28
41
|
"devDependencies": {
|
|
29
42
|
"@types/fs-extra": "^11.0.4",
|
|
@@ -35,8 +48,8 @@
|
|
|
35
48
|
"dist"
|
|
36
49
|
],
|
|
37
50
|
"scripts": {
|
|
38
|
-
"build": "
|
|
39
|
-
"dev": "
|
|
51
|
+
"build": "tsup && chmod +x dist/cli.js",
|
|
52
|
+
"dev": "tsup --watch",
|
|
40
53
|
"clean": "rm -rf dist",
|
|
41
54
|
"test": "echo 'Tests coming soon'"
|
|
42
55
|
}
|
package/dist/commands/deploy.js
DELETED
|
@@ -1,96 +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.deployMCP = deployMCP;
|
|
7
|
-
const core_1 = require("@neural-tools/core");
|
|
8
|
-
const execa_1 = require("execa");
|
|
9
|
-
const path_1 = __importDefault(require("path"));
|
|
10
|
-
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
11
|
-
async function deployMCP(name, options) {
|
|
12
|
-
core_1.logger.header(`Deploying MCP: ${name}`);
|
|
13
|
-
// Check license for cloud deployment
|
|
14
|
-
await (0, core_1.requireFeature)('cloud-deployment', 'Cloud Deployment');
|
|
15
|
-
const platform = options.platform || 'aws';
|
|
16
|
-
const env = options.env || 'dev';
|
|
17
|
-
core_1.logger.info(`Platform: ${platform}`);
|
|
18
|
-
core_1.logger.info(`Environment: ${env}`);
|
|
19
|
-
// Find MCP directory
|
|
20
|
-
const mcpDir = path_1.default.resolve('./apps', name);
|
|
21
|
-
if (!await fs_extra_1.default.pathExists(mcpDir)) {
|
|
22
|
-
throw new Error(`MCP "${name}" not found at ${mcpDir}`);
|
|
23
|
-
}
|
|
24
|
-
core_1.logger.startSpinner('Building MCP...');
|
|
25
|
-
try {
|
|
26
|
-
// Build the MCP
|
|
27
|
-
await (0, execa_1.execa)('npm', ['run', 'build'], { cwd: mcpDir, stdio: 'pipe' });
|
|
28
|
-
core_1.logger.succeedSpinner('MCP built successfully');
|
|
29
|
-
if (platform === 'aws') {
|
|
30
|
-
await deployToAWS(name, mcpDir, options);
|
|
31
|
-
}
|
|
32
|
-
else if (platform === 'gcp') {
|
|
33
|
-
await deployToGCP(name, mcpDir, options);
|
|
34
|
-
}
|
|
35
|
-
core_1.logger.success(`✨ MCP "${name}" deployed successfully!`);
|
|
36
|
-
}
|
|
37
|
-
catch (error) {
|
|
38
|
-
core_1.logger.failSpinner('Deployment failed');
|
|
39
|
-
throw error;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
async function deployToAWS(name, mcpDir, options) {
|
|
43
|
-
core_1.logger.startSpinner('Deploying to AWS Lambda...');
|
|
44
|
-
// TODO: Implement AWS Lambda deployment
|
|
45
|
-
// This would use AWS CDK or SAM to deploy
|
|
46
|
-
// For now, just a placeholder
|
|
47
|
-
core_1.logger.updateSpinner('Packaging Lambda function...');
|
|
48
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
49
|
-
core_1.logger.updateSpinner('Uploading to S3...');
|
|
50
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
51
|
-
core_1.logger.updateSpinner('Creating/updating Lambda function...');
|
|
52
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
53
|
-
core_1.logger.succeedSpinner('Deployed to AWS Lambda');
|
|
54
|
-
core_1.logger.section('Deployment Info', [
|
|
55
|
-
`Function: ${name}-${options.env}`,
|
|
56
|
-
`Region: ${options.region || 'us-east-1'}`,
|
|
57
|
-
`Environment: ${options.env}`,
|
|
58
|
-
'',
|
|
59
|
-
'Configure in Claude Code:',
|
|
60
|
-
JSON.stringify({
|
|
61
|
-
mcpServers: {
|
|
62
|
-
[name]: {
|
|
63
|
-
command: 'aws',
|
|
64
|
-
args: [
|
|
65
|
-
'lambda',
|
|
66
|
-
'invoke',
|
|
67
|
-
'--function-name',
|
|
68
|
-
`${name}-${options.env}`,
|
|
69
|
-
'--payload',
|
|
70
|
-
'stdin',
|
|
71
|
-
'--output',
|
|
72
|
-
'stdout'
|
|
73
|
-
]
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}, null, 2)
|
|
77
|
-
]);
|
|
78
|
-
}
|
|
79
|
-
async function deployToGCP(name, mcpDir, options) {
|
|
80
|
-
core_1.logger.startSpinner('Deploying to Google Cloud Functions...');
|
|
81
|
-
// TODO: Implement GCP Cloud Functions deployment
|
|
82
|
-
// This would use gcloud CLI or Terraform
|
|
83
|
-
// For now, just a placeholder
|
|
84
|
-
core_1.logger.updateSpinner('Packaging function...');
|
|
85
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
86
|
-
core_1.logger.updateSpinner('Uploading to Cloud Storage...');
|
|
87
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
88
|
-
core_1.logger.updateSpinner('Deploying Cloud Function...');
|
|
89
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
90
|
-
core_1.logger.succeedSpinner('Deployed to Google Cloud Functions');
|
|
91
|
-
core_1.logger.section('Deployment Info', [
|
|
92
|
-
`Function: ${name}-${options.env}`,
|
|
93
|
-
`Region: ${options.region || 'us-central1'}`,
|
|
94
|
-
`Environment: ${options.env}`
|
|
95
|
-
]);
|
|
96
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
interface GenerateAgentOptions {
|
|
2
|
-
description?: string;
|
|
3
|
-
output?: string;
|
|
4
|
-
model?: 'sonnet' | 'opus' | 'haiku';
|
|
5
|
-
tools?: string[];
|
|
6
|
-
global?: boolean;
|
|
7
|
-
dryRun?: boolean;
|
|
8
|
-
}
|
|
9
|
-
export declare function generateAgent(name: string, options: GenerateAgentOptions): Promise<void>;
|
|
10
|
-
export {};
|
|
@@ -1,126 +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.generateAgent = generateAgent;
|
|
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 generateAgent(name, options) {
|
|
13
|
-
core_1.logger.header(`Generating Claude Agent: ${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 agent:',
|
|
22
|
-
default: `${name} specialized agent`
|
|
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', 'agents');
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
outputDir = path_1.default.resolve(options.output || './claude/agents');
|
|
34
|
-
}
|
|
35
|
-
const agentFile = path_1.default.join(outputDir, `${name}.md`);
|
|
36
|
-
const model = options.model || 'sonnet';
|
|
37
|
-
if (options.dryRun) {
|
|
38
|
-
core_1.logger.info('Dry run mode - no files will be created');
|
|
39
|
-
core_1.logger.section('Configuration', [
|
|
40
|
-
`Name: ${name}`,
|
|
41
|
-
`Description: ${description}`,
|
|
42
|
-
`Output: ${agentFile}`,
|
|
43
|
-
`Model: ${model}`,
|
|
44
|
-
`Tools: ${options.tools?.join(', ') || 'all'}`,
|
|
45
|
-
`Global: ${options.global ? 'Yes' : 'No'}`
|
|
46
|
-
]);
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
// Check if file already exists
|
|
50
|
-
if (await fs_extra_1.default.pathExists(agentFile)) {
|
|
51
|
-
const { overwrite } = await inquirer_1.default.prompt([
|
|
52
|
-
{
|
|
53
|
-
type: 'confirm',
|
|
54
|
-
name: 'overwrite',
|
|
55
|
-
message: `Agent ${name} already exists. Overwrite?`,
|
|
56
|
-
default: false
|
|
57
|
-
}
|
|
58
|
-
]);
|
|
59
|
-
if (!overwrite) {
|
|
60
|
-
core_1.logger.warn('Cancelled');
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
core_1.logger.startSpinner('Creating Claude agent...');
|
|
65
|
-
try {
|
|
66
|
-
await fs_extra_1.default.ensureDir(outputDir);
|
|
67
|
-
// Build frontmatter
|
|
68
|
-
const frontmatter = ['---'];
|
|
69
|
-
frontmatter.push(`model: claude-${model}-4-5`);
|
|
70
|
-
if (options.tools && options.tools.length > 0) {
|
|
71
|
-
frontmatter.push(`tools:`);
|
|
72
|
-
options.tools.forEach(tool => {
|
|
73
|
-
frontmatter.push(` - ${tool}`);
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
frontmatter.push('---');
|
|
77
|
-
frontmatter.push('');
|
|
78
|
-
// Build agent content
|
|
79
|
-
const agentContent = `${frontmatter.join('\n')}# ${name} Agent
|
|
80
|
-
|
|
81
|
-
${description}
|
|
82
|
-
|
|
83
|
-
## Role
|
|
84
|
-
|
|
85
|
-
You are a specialized agent for ${name} tasks. Your primary responsibilities include:
|
|
86
|
-
|
|
87
|
-
- [Responsibility 1]
|
|
88
|
-
- [Responsibility 2]
|
|
89
|
-
- [Responsibility 3]
|
|
90
|
-
|
|
91
|
-
## Guidelines
|
|
92
|
-
|
|
93
|
-
When performing ${name} tasks:
|
|
94
|
-
|
|
95
|
-
1. [Guideline 1]
|
|
96
|
-
2. [Guideline 2]
|
|
97
|
-
3. [Guideline 3]
|
|
98
|
-
|
|
99
|
-
## Output Format
|
|
100
|
-
|
|
101
|
-
Provide clear, structured responses that:
|
|
102
|
-
- [Output requirement 1]
|
|
103
|
-
- [Output requirement 2]
|
|
104
|
-
- [Output requirement 3]
|
|
105
|
-
|
|
106
|
-
Focus on ${name} and deliver actionable results.
|
|
107
|
-
`;
|
|
108
|
-
await fs_extra_1.default.writeFile(agentFile, agentContent, 'utf-8');
|
|
109
|
-
core_1.logger.succeedSpinner('Claude agent created successfully!');
|
|
110
|
-
core_1.logger.section('Next steps', [
|
|
111
|
-
options.global
|
|
112
|
-
? `Agent ${name} is now available globally in Claude Code`
|
|
113
|
-
: `Add the agent to your project by copying ${agentFile}`,
|
|
114
|
-
'',
|
|
115
|
-
'Customize the agent by editing:',
|
|
116
|
-
` ${agentFile}`,
|
|
117
|
-
'',
|
|
118
|
-
'Use the agent via the Task tool in Claude Code'
|
|
119
|
-
]);
|
|
120
|
-
core_1.logger.success(`✨ Agent "${name}" ready to use!`);
|
|
121
|
-
}
|
|
122
|
-
catch (error) {
|
|
123
|
-
core_1.logger.failSpinner('Failed to create agent');
|
|
124
|
-
throw error;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
interface GenerateCommandOptions {
|
|
2
|
-
description?: string;
|
|
3
|
-
output?: string;
|
|
4
|
-
args?: string[];
|
|
5
|
-
tools?: string[];
|
|
6
|
-
global?: boolean;
|
|
7
|
-
dryRun?: boolean;
|
|
8
|
-
}
|
|
9
|
-
export declare function generateCommand(name: string, options: GenerateCommandOptions): Promise<void>;
|
|
10
|
-
export {};
|