@jvittechs/jai1-mcp 1.0.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 +181 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +436 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# @jvittechs/jai1-mcp
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) proxy for connecting IDE AI agents to Jai1 developer tools.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package provides a stdio MCP server that proxies requests to the remote Jai1 MCP Server. It allows AI agents in Cursor, Windsurf, and other MCP-compatible IDEs to access powerful developer tools:
|
|
8
|
+
|
|
9
|
+
- **Feature Planning** - Get structured development plans with requirements and task breakdowns
|
|
10
|
+
- **Code Review** - Quality analysis with best practices suggestions
|
|
11
|
+
- **Security Audit** - Vulnerability detection and security recommendations
|
|
12
|
+
- **Commit Messages** - Generate Conventional Commits formatted messages
|
|
13
|
+
- **Tech Stack Suggestions** - Get technology recommendations for your project
|
|
14
|
+
- **Technical Research** - Research topics with structured summaries
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install -g @jvittechs/jai1-mcp
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or use directly with npx (recommended):
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx @jvittechs/jai1-mcp
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Configuration
|
|
29
|
+
|
|
30
|
+
### Required Environment Variables
|
|
31
|
+
|
|
32
|
+
| Variable | Description |
|
|
33
|
+
|----------|-------------|
|
|
34
|
+
| `JAI1_ACCESS_KEY` | Your Jai1 access key (required) |
|
|
35
|
+
|
|
36
|
+
### Optional Environment Variables
|
|
37
|
+
|
|
38
|
+
| Variable | Default | Description |
|
|
39
|
+
|----------|---------|-------------|
|
|
40
|
+
| `JAI1_MCP_SERVER_URL` | `https://mcp.jai1.jv-it.net` | MCP server URL |
|
|
41
|
+
| `JAI1_MCP_TIMEOUT` | `60000` | Request timeout in milliseconds |
|
|
42
|
+
| `JAI1_MCP_DEBUG` | `false` | Enable debug logging |
|
|
43
|
+
|
|
44
|
+
## IDE Setup
|
|
45
|
+
|
|
46
|
+
### Cursor IDE
|
|
47
|
+
|
|
48
|
+
Add to your Cursor MCP configuration (`~/.cursor/mcp.json` or project `.cursor/mcp.json`):
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"mcpServers": {
|
|
53
|
+
"jai1": {
|
|
54
|
+
"command": "npx",
|
|
55
|
+
"args": ["@jvittechs/jai1-mcp"],
|
|
56
|
+
"env": {
|
|
57
|
+
"JAI1_ACCESS_KEY": "your_access_key_here"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Windsurf IDE
|
|
65
|
+
|
|
66
|
+
Add to your Windsurf MCP configuration:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"mcpServers": {
|
|
71
|
+
"jai1": {
|
|
72
|
+
"command": "npx",
|
|
73
|
+
"args": ["@jvittechs/jai1-mcp"],
|
|
74
|
+
"env": {
|
|
75
|
+
"JAI1_ACCESS_KEY": "your_access_key_here"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Claude Desktop
|
|
83
|
+
|
|
84
|
+
Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"mcpServers": {
|
|
89
|
+
"jai1": {
|
|
90
|
+
"command": "npx",
|
|
91
|
+
"args": ["@jvittechs/jai1-mcp"],
|
|
92
|
+
"env": {
|
|
93
|
+
"JAI1_ACCESS_KEY": "your_access_key_here"
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Available Tools
|
|
101
|
+
|
|
102
|
+
Once connected, the following tools are available to your AI agent:
|
|
103
|
+
|
|
104
|
+
### `jai1_plan_feature`
|
|
105
|
+
|
|
106
|
+
Create a structured development plan for a feature.
|
|
107
|
+
|
|
108
|
+
**Input:**
|
|
109
|
+
- `feature_description` (required): Description of the feature
|
|
110
|
+
- `codebase_context`: Current codebase context
|
|
111
|
+
- `tech_stack`: Tech stack being used
|
|
112
|
+
- `constraints`: Any constraints to consider
|
|
113
|
+
|
|
114
|
+
### `jai1_suggest_techstack`
|
|
115
|
+
|
|
116
|
+
Get tech stack recommendations based on requirements.
|
|
117
|
+
|
|
118
|
+
**Input:**
|
|
119
|
+
- `requirements` (required): Project requirements and goals
|
|
120
|
+
- `project_type`: Type of project (web app, mobile, API, etc.)
|
|
121
|
+
- `constraints`: Budget, team skills, timeline
|
|
122
|
+
- `preferences`: Technology preferences
|
|
123
|
+
|
|
124
|
+
### `jai1_research`
|
|
125
|
+
|
|
126
|
+
Research a technical topic.
|
|
127
|
+
|
|
128
|
+
**Input:**
|
|
129
|
+
- `topic` (required): The topic to research
|
|
130
|
+
- `context`: Context for the research
|
|
131
|
+
- `depth`: One of "brief", "standard", "deep"
|
|
132
|
+
|
|
133
|
+
### `jai1_review_code`
|
|
134
|
+
|
|
135
|
+
Review code for quality and best practices.
|
|
136
|
+
|
|
137
|
+
**Input:**
|
|
138
|
+
- `code` (required): The code or diff to review
|
|
139
|
+
- `language`: Programming language
|
|
140
|
+
- `scope`: Areas to focus on
|
|
141
|
+
- `project_guidelines`: Project-specific guidelines
|
|
142
|
+
|
|
143
|
+
### `jai1_review_security`
|
|
144
|
+
|
|
145
|
+
Audit code for security vulnerabilities.
|
|
146
|
+
|
|
147
|
+
**Input:**
|
|
148
|
+
- `code` (required): The code or diff to audit
|
|
149
|
+
- `language`: Programming language
|
|
150
|
+
- `context`: Context about the code
|
|
151
|
+
|
|
152
|
+
### `jai1_generate_commit`
|
|
153
|
+
|
|
154
|
+
Generate a commit message from a git diff.
|
|
155
|
+
|
|
156
|
+
**Input:**
|
|
157
|
+
- `diff` (required): Git diff content
|
|
158
|
+
- `files_changed`: List of files changed
|
|
159
|
+
|
|
160
|
+
## Error Codes
|
|
161
|
+
|
|
162
|
+
| Code | Description |
|
|
163
|
+
|------|-------------|
|
|
164
|
+
| `ERR-MCP-001` | Invalid access key |
|
|
165
|
+
| `ERR-MCP-002` | Request timeout |
|
|
166
|
+
| `ERR-MCP-003` | Tool not found |
|
|
167
|
+
| `ERR-MCP-004` | Server error |
|
|
168
|
+
| `ERR-MCP-005` | Network error |
|
|
169
|
+
|
|
170
|
+
## Getting an Access Key
|
|
171
|
+
|
|
172
|
+
To get a JAI1_ACCESS_KEY, please contact the Jai1 team or use the jai1-cli:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
# Login to get your access key
|
|
176
|
+
jai1 auth login
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## License
|
|
180
|
+
|
|
181
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
5
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
|
+
import {
|
|
7
|
+
CallToolRequestSchema,
|
|
8
|
+
ListToolsRequestSchema
|
|
9
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
10
|
+
|
|
11
|
+
// src/config.ts
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
var ConfigSchema = z.object({
|
|
14
|
+
/** MCP Server URL */
|
|
15
|
+
serverUrl: z.string().url().default("https://mcp.jai1.jv-it.net"),
|
|
16
|
+
/** JAI1 Access Key for authentication */
|
|
17
|
+
accessKey: z.string().min(1, "Access key is required"),
|
|
18
|
+
/** Request timeout in milliseconds */
|
|
19
|
+
timeout: z.number().positive().default(6e4),
|
|
20
|
+
/** Enable debug logging */
|
|
21
|
+
debug: z.boolean().default(false)
|
|
22
|
+
});
|
|
23
|
+
function loadConfig() {
|
|
24
|
+
const rawConfig = {
|
|
25
|
+
serverUrl: process.env.JAI1_MCP_SERVER_URL || process.env.MCP_SERVER_URL,
|
|
26
|
+
accessKey: process.env.JAI1_ACCESS_KEY,
|
|
27
|
+
timeout: process.env.JAI1_MCP_TIMEOUT ? parseInt(process.env.JAI1_MCP_TIMEOUT, 10) : void 0,
|
|
28
|
+
debug: process.env.JAI1_MCP_DEBUG === "true" || process.env.DEBUG === "true"
|
|
29
|
+
};
|
|
30
|
+
const result = ConfigSchema.safeParse(rawConfig);
|
|
31
|
+
if (!result.success) {
|
|
32
|
+
const errors = result.error.errors.map((e) => ` - ${e.path.join(".")}: ${e.message}`).join("\n");
|
|
33
|
+
throw new Error(
|
|
34
|
+
`Invalid MCP proxy configuration:
|
|
35
|
+
${errors}
|
|
36
|
+
|
|
37
|
+
Required environment variables:
|
|
38
|
+
JAI1_ACCESS_KEY - Your Jai1 access key
|
|
39
|
+
|
|
40
|
+
Optional environment variables:
|
|
41
|
+
JAI1_MCP_SERVER_URL - MCP server URL (default: https://mcp.jai1.jv-it.net)
|
|
42
|
+
JAI1_MCP_TIMEOUT - Request timeout in ms (default: 60000)
|
|
43
|
+
JAI1_MCP_DEBUG - Enable debug logging (default: false)`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
return result.data;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/proxy.ts
|
|
50
|
+
var ProxyError = class extends Error {
|
|
51
|
+
constructor(message, code, statusCode) {
|
|
52
|
+
super(message);
|
|
53
|
+
this.code = code;
|
|
54
|
+
this.statusCode = statusCode;
|
|
55
|
+
this.name = "ProxyError";
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
var MCPProxy = class {
|
|
59
|
+
config;
|
|
60
|
+
debug;
|
|
61
|
+
constructor(config) {
|
|
62
|
+
this.config = config;
|
|
63
|
+
this.debug = config.debug ? (...args) => console.error("[MCP-PROXY]", ...args) : () => {
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Call a tool on the remote MCP server
|
|
68
|
+
*/
|
|
69
|
+
async callTool(toolName, args) {
|
|
70
|
+
const url = `${this.config.serverUrl}/api/agents/tools/${toolName}/execute`;
|
|
71
|
+
this.debug(`Calling tool: ${toolName}`, { url, args });
|
|
72
|
+
const controller = new AbortController();
|
|
73
|
+
const timeoutId = setTimeout(
|
|
74
|
+
() => controller.abort(),
|
|
75
|
+
this.config.timeout
|
|
76
|
+
);
|
|
77
|
+
try {
|
|
78
|
+
const response = await fetch(url, {
|
|
79
|
+
method: "POST",
|
|
80
|
+
headers: {
|
|
81
|
+
"Content-Type": "application/json",
|
|
82
|
+
Authorization: `Bearer ${this.config.accessKey}`
|
|
83
|
+
},
|
|
84
|
+
body: JSON.stringify(args),
|
|
85
|
+
signal: controller.signal
|
|
86
|
+
});
|
|
87
|
+
clearTimeout(timeoutId);
|
|
88
|
+
if (!response.ok) {
|
|
89
|
+
const errorBody = await response.text();
|
|
90
|
+
this.debug(`Tool error response:`, { status: response.status, body: errorBody });
|
|
91
|
+
if (response.status === 401) {
|
|
92
|
+
throw new ProxyError(
|
|
93
|
+
"Invalid JAI1_ACCESS_KEY",
|
|
94
|
+
"ERR-MCP-001",
|
|
95
|
+
401
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
if (response.status === 404) {
|
|
99
|
+
throw new ProxyError(
|
|
100
|
+
`Tool not found: ${toolName}`,
|
|
101
|
+
"ERR-MCP-003",
|
|
102
|
+
404
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
throw new ProxyError(
|
|
106
|
+
`Server error: ${errorBody}`,
|
|
107
|
+
"ERR-MCP-004",
|
|
108
|
+
response.status
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
const result = await response.json();
|
|
112
|
+
this.debug(`Tool response:`, { toolName, result });
|
|
113
|
+
return result;
|
|
114
|
+
} catch (error) {
|
|
115
|
+
clearTimeout(timeoutId);
|
|
116
|
+
if (error instanceof ProxyError) {
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
120
|
+
throw new ProxyError(
|
|
121
|
+
`Request timeout after ${this.config.timeout}ms`,
|
|
122
|
+
"ERR-MCP-002",
|
|
123
|
+
504
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
throw new ProxyError(
|
|
127
|
+
`Network error: ${error instanceof Error ? error.message : String(error)}`,
|
|
128
|
+
"ERR-MCP-005"
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* List available tools from the MCP server
|
|
134
|
+
*/
|
|
135
|
+
async listTools() {
|
|
136
|
+
const url = `${this.config.serverUrl}/api/mcp/tools`;
|
|
137
|
+
this.debug(`Listing tools from: ${url}`);
|
|
138
|
+
const controller = new AbortController();
|
|
139
|
+
const timeoutId = setTimeout(
|
|
140
|
+
() => controller.abort(),
|
|
141
|
+
this.config.timeout
|
|
142
|
+
);
|
|
143
|
+
try {
|
|
144
|
+
const response = await fetch(url, {
|
|
145
|
+
method: "GET",
|
|
146
|
+
headers: {
|
|
147
|
+
Authorization: `Bearer ${this.config.accessKey}`
|
|
148
|
+
},
|
|
149
|
+
signal: controller.signal
|
|
150
|
+
});
|
|
151
|
+
clearTimeout(timeoutId);
|
|
152
|
+
if (!response.ok) {
|
|
153
|
+
if (response.status === 401) {
|
|
154
|
+
throw new ProxyError(
|
|
155
|
+
"Invalid JAI1_ACCESS_KEY",
|
|
156
|
+
"ERR-MCP-001",
|
|
157
|
+
401
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
throw new ProxyError(
|
|
161
|
+
`Failed to list tools: ${response.statusText}`,
|
|
162
|
+
"ERR-MCP-004",
|
|
163
|
+
response.status
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
const data = await response.json();
|
|
167
|
+
this.debug(`Available tools:`, data);
|
|
168
|
+
return data.tools || [];
|
|
169
|
+
} catch (error) {
|
|
170
|
+
clearTimeout(timeoutId);
|
|
171
|
+
if (error instanceof ProxyError) {
|
|
172
|
+
throw error;
|
|
173
|
+
}
|
|
174
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
175
|
+
throw new ProxyError(
|
|
176
|
+
`Request timeout after ${this.config.timeout}ms`,
|
|
177
|
+
"ERR-MCP-002",
|
|
178
|
+
504
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
throw new ProxyError(
|
|
182
|
+
`Network error: ${error instanceof Error ? error.message : String(error)}`,
|
|
183
|
+
"ERR-MCP-005"
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Health check for the MCP server
|
|
189
|
+
*/
|
|
190
|
+
async healthCheck() {
|
|
191
|
+
const url = `${this.config.serverUrl}/health`;
|
|
192
|
+
this.debug(`Health check: ${url}`);
|
|
193
|
+
try {
|
|
194
|
+
const response = await fetch(url, {
|
|
195
|
+
method: "GET",
|
|
196
|
+
signal: AbortSignal.timeout(5e3)
|
|
197
|
+
});
|
|
198
|
+
return response.ok;
|
|
199
|
+
} catch {
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
// src/index.ts
|
|
206
|
+
var TOOLS = [
|
|
207
|
+
{
|
|
208
|
+
name: "jai1_plan_feature",
|
|
209
|
+
description: "Create a structured development plan for a feature. Returns requirements, design approach, and task breakdown.",
|
|
210
|
+
inputSchema: {
|
|
211
|
+
type: "object",
|
|
212
|
+
properties: {
|
|
213
|
+
feature_description: {
|
|
214
|
+
type: "string",
|
|
215
|
+
description: "Description of the feature to plan"
|
|
216
|
+
},
|
|
217
|
+
codebase_context: {
|
|
218
|
+
type: "string",
|
|
219
|
+
description: "Current codebase context (tech stack, patterns, relevant code)"
|
|
220
|
+
},
|
|
221
|
+
tech_stack: {
|
|
222
|
+
type: "string",
|
|
223
|
+
description: "Tech stack being used"
|
|
224
|
+
},
|
|
225
|
+
constraints: {
|
|
226
|
+
type: "string",
|
|
227
|
+
description: "Any constraints or requirements to consider"
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
required: ["feature_description"]
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
name: "jai1_suggest_techstack",
|
|
235
|
+
description: "Get tech stack recommendations based on project requirements. Returns recommended technologies with justification.",
|
|
236
|
+
inputSchema: {
|
|
237
|
+
type: "object",
|
|
238
|
+
properties: {
|
|
239
|
+
requirements: {
|
|
240
|
+
type: "string",
|
|
241
|
+
description: "Project requirements and goals"
|
|
242
|
+
},
|
|
243
|
+
project_type: {
|
|
244
|
+
type: "string",
|
|
245
|
+
description: "Type of project (web app, mobile, API, CLI, etc.)"
|
|
246
|
+
},
|
|
247
|
+
constraints: {
|
|
248
|
+
type: "string",
|
|
249
|
+
description: "Constraints (budget, team skills, timeline)"
|
|
250
|
+
},
|
|
251
|
+
preferences: {
|
|
252
|
+
type: "string",
|
|
253
|
+
description: "Any technology preferences or existing stack"
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
required: ["requirements"]
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
name: "jai1_research",
|
|
261
|
+
description: "Research a technical topic. Returns structured summary with key concepts, best practices, and resources.",
|
|
262
|
+
inputSchema: {
|
|
263
|
+
type: "object",
|
|
264
|
+
properties: {
|
|
265
|
+
topic: {
|
|
266
|
+
type: "string",
|
|
267
|
+
description: "The topic to research"
|
|
268
|
+
},
|
|
269
|
+
context: {
|
|
270
|
+
type: "string",
|
|
271
|
+
description: "Context for the research (project, use case)"
|
|
272
|
+
},
|
|
273
|
+
depth: {
|
|
274
|
+
type: "string",
|
|
275
|
+
enum: ["brief", "standard", "deep"],
|
|
276
|
+
description: "Depth of research: brief (overview), standard (detailed), deep (comprehensive)"
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
required: ["topic"]
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
name: "jai1_review_code",
|
|
284
|
+
description: "Review code for quality, maintainability, and best practices. Returns quality checklist and improvement suggestions.",
|
|
285
|
+
inputSchema: {
|
|
286
|
+
type: "object",
|
|
287
|
+
properties: {
|
|
288
|
+
code: {
|
|
289
|
+
type: "string",
|
|
290
|
+
description: "The code or diff to review"
|
|
291
|
+
},
|
|
292
|
+
language: {
|
|
293
|
+
type: "string",
|
|
294
|
+
description: "Programming language"
|
|
295
|
+
},
|
|
296
|
+
scope: {
|
|
297
|
+
type: "string",
|
|
298
|
+
description: "Specific areas to focus on (e.g., 'error handling', 'performance')"
|
|
299
|
+
},
|
|
300
|
+
project_guidelines: {
|
|
301
|
+
type: "string",
|
|
302
|
+
description: "Project-specific guidelines to check"
|
|
303
|
+
}
|
|
304
|
+
},
|
|
305
|
+
required: ["code"]
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
name: "jai1_review_security",
|
|
310
|
+
description: "Audit code for security vulnerabilities. Returns security checklist and vulnerability report.",
|
|
311
|
+
inputSchema: {
|
|
312
|
+
type: "object",
|
|
313
|
+
properties: {
|
|
314
|
+
code: {
|
|
315
|
+
type: "string",
|
|
316
|
+
description: "The code or diff to audit"
|
|
317
|
+
},
|
|
318
|
+
language: {
|
|
319
|
+
type: "string",
|
|
320
|
+
description: "Programming language"
|
|
321
|
+
},
|
|
322
|
+
context: {
|
|
323
|
+
type: "string",
|
|
324
|
+
description: "Context about the code (e.g., 'authentication endpoint', 'file upload handler')"
|
|
325
|
+
}
|
|
326
|
+
},
|
|
327
|
+
required: ["code"]
|
|
328
|
+
}
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
name: "jai1_generate_commit",
|
|
332
|
+
description: "Generate a commit message from a git diff. Returns Conventional Commits formatted message.",
|
|
333
|
+
inputSchema: {
|
|
334
|
+
type: "object",
|
|
335
|
+
properties: {
|
|
336
|
+
diff: {
|
|
337
|
+
type: "string",
|
|
338
|
+
description: "Git diff content"
|
|
339
|
+
},
|
|
340
|
+
files_changed: {
|
|
341
|
+
type: "string",
|
|
342
|
+
description: "List of files changed with status"
|
|
343
|
+
}
|
|
344
|
+
},
|
|
345
|
+
required: ["diff"]
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
];
|
|
349
|
+
async function main() {
|
|
350
|
+
let config;
|
|
351
|
+
try {
|
|
352
|
+
config = loadConfig();
|
|
353
|
+
} catch (error) {
|
|
354
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
355
|
+
process.exit(1);
|
|
356
|
+
}
|
|
357
|
+
const proxy = new MCPProxy(config);
|
|
358
|
+
const isHealthy = await proxy.healthCheck();
|
|
359
|
+
if (!isHealthy) {
|
|
360
|
+
console.error(
|
|
361
|
+
`Warning: Cannot reach MCP server at ${config.serverUrl}. Requests may fail.`
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
const server = new Server(
|
|
365
|
+
{
|
|
366
|
+
name: "jai1-mcp",
|
|
367
|
+
version: "1.0.0"
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
capabilities: {
|
|
371
|
+
tools: {}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
);
|
|
375
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
376
|
+
return { tools: TOOLS };
|
|
377
|
+
});
|
|
378
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
379
|
+
const { name, arguments: args } = request.params;
|
|
380
|
+
const tool = TOOLS.find((t) => t.name === name);
|
|
381
|
+
if (!tool) {
|
|
382
|
+
return {
|
|
383
|
+
content: [
|
|
384
|
+
{
|
|
385
|
+
type: "text",
|
|
386
|
+
text: `Error: Unknown tool '${name}'. Available tools: ${TOOLS.map((t) => t.name).join(", ")}`
|
|
387
|
+
}
|
|
388
|
+
],
|
|
389
|
+
isError: true
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
try {
|
|
393
|
+
const result = await proxy.callTool(name, args);
|
|
394
|
+
if (typeof result === "string") {
|
|
395
|
+
return {
|
|
396
|
+
content: [{ type: "text", text: result }]
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
if (typeof result === "object" && result !== null) {
|
|
400
|
+
const data = result.result ?? result;
|
|
401
|
+
return {
|
|
402
|
+
content: [
|
|
403
|
+
{
|
|
404
|
+
type: "text",
|
|
405
|
+
text: typeof data === "string" ? data : JSON.stringify(data, null, 2)
|
|
406
|
+
}
|
|
407
|
+
]
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
return {
|
|
411
|
+
content: [{ type: "text", text: String(result) }]
|
|
412
|
+
};
|
|
413
|
+
} catch (error) {
|
|
414
|
+
const message = error instanceof ProxyError ? `[${error.code}] ${error.message}` : `Error: ${error instanceof Error ? error.message : String(error)}`;
|
|
415
|
+
return {
|
|
416
|
+
content: [{ type: "text", text: message }],
|
|
417
|
+
isError: true
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
const transport = new StdioServerTransport();
|
|
422
|
+
await server.connect(transport);
|
|
423
|
+
process.on("SIGINT", async () => {
|
|
424
|
+
await server.close();
|
|
425
|
+
process.exit(0);
|
|
426
|
+
});
|
|
427
|
+
process.on("SIGTERM", async () => {
|
|
428
|
+
await server.close();
|
|
429
|
+
process.exit(0);
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
main().catch((error) => {
|
|
433
|
+
console.error("Fatal error:", error);
|
|
434
|
+
process.exit(1);
|
|
435
|
+
});
|
|
436
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/proxy.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { z } from \"zod\";\n\nimport { loadConfig } from \"./config.js\";\nimport { MCPProxy, ProxyError } from \"./proxy.js\";\n\n/**\n * Jai1 MCP Proxy Server\n * \n * This is a stdio MCP server that acts as a proxy to the remote Jai1 MCP Server.\n * It allows IDE AI agents (Cursor, Windsurf) to access Jai1 developer tools.\n * \n * Usage:\n * JAI1_ACCESS_KEY=your_key npx @jvittechs/jai1-mcp\n * \n * Or in Cursor MCP config:\n * {\n * \"mcpServers\": {\n * \"jai1\": {\n * \"command\": \"npx\",\n * \"args\": [\"@jvittechs/jai1-mcp\"],\n * \"env\": {\n * \"JAI1_ACCESS_KEY\": \"your_key\"\n * }\n * }\n * }\n * }\n */\n\n// Tool definitions matching the mcp-server tools\nconst TOOLS = [\n {\n name: \"jai1_plan_feature\",\n description:\n \"Create a structured development plan for a feature. Returns requirements, design approach, and task breakdown.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n feature_description: {\n type: \"string\",\n description: \"Description of the feature to plan\",\n },\n codebase_context: {\n type: \"string\",\n description:\n \"Current codebase context (tech stack, patterns, relevant code)\",\n },\n tech_stack: {\n type: \"string\",\n description: \"Tech stack being used\",\n },\n constraints: {\n type: \"string\",\n description: \"Any constraints or requirements to consider\",\n },\n },\n required: [\"feature_description\"],\n },\n },\n {\n name: \"jai1_suggest_techstack\",\n description:\n \"Get tech stack recommendations based on project requirements. Returns recommended technologies with justification.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n requirements: {\n type: \"string\",\n description: \"Project requirements and goals\",\n },\n project_type: {\n type: \"string\",\n description: \"Type of project (web app, mobile, API, CLI, etc.)\",\n },\n constraints: {\n type: \"string\",\n description: \"Constraints (budget, team skills, timeline)\",\n },\n preferences: {\n type: \"string\",\n description: \"Any technology preferences or existing stack\",\n },\n },\n required: [\"requirements\"],\n },\n },\n {\n name: \"jai1_research\",\n description:\n \"Research a technical topic. Returns structured summary with key concepts, best practices, and resources.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n topic: {\n type: \"string\",\n description: \"The topic to research\",\n },\n context: {\n type: \"string\",\n description: \"Context for the research (project, use case)\",\n },\n depth: {\n type: \"string\",\n enum: [\"brief\", \"standard\", \"deep\"],\n description:\n \"Depth of research: brief (overview), standard (detailed), deep (comprehensive)\",\n },\n },\n required: [\"topic\"],\n },\n },\n {\n name: \"jai1_review_code\",\n description:\n \"Review code for quality, maintainability, and best practices. Returns quality checklist and improvement suggestions.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n code: {\n type: \"string\",\n description: \"The code or diff to review\",\n },\n language: {\n type: \"string\",\n description: \"Programming language\",\n },\n scope: {\n type: \"string\",\n description:\n \"Specific areas to focus on (e.g., 'error handling', 'performance')\",\n },\n project_guidelines: {\n type: \"string\",\n description: \"Project-specific guidelines to check\",\n },\n },\n required: [\"code\"],\n },\n },\n {\n name: \"jai1_review_security\",\n description:\n \"Audit code for security vulnerabilities. Returns security checklist and vulnerability report.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n code: {\n type: \"string\",\n description: \"The code or diff to audit\",\n },\n language: {\n type: \"string\",\n description: \"Programming language\",\n },\n context: {\n type: \"string\",\n description:\n \"Context about the code (e.g., 'authentication endpoint', 'file upload handler')\",\n },\n },\n required: [\"code\"],\n },\n },\n {\n name: \"jai1_generate_commit\",\n description:\n \"Generate a commit message from a git diff. Returns Conventional Commits formatted message.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n diff: {\n type: \"string\",\n description: \"Git diff content\",\n },\n files_changed: {\n type: \"string\",\n description: \"List of files changed with status\",\n },\n },\n required: [\"diff\"],\n },\n },\n];\n\nasync function main() {\n // Load configuration\n let config;\n try {\n config = loadConfig();\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n\n const proxy = new MCPProxy(config);\n\n // Verify server is reachable\n const isHealthy = await proxy.healthCheck();\n if (!isHealthy) {\n console.error(\n `Warning: Cannot reach MCP server at ${config.serverUrl}. ` +\n `Requests may fail.`\n );\n }\n\n // Create MCP server\n const server = new Server(\n {\n name: \"jai1-mcp\",\n version: \"1.0.0\",\n },\n {\n capabilities: {\n tools: {},\n },\n }\n );\n\n // Handle tool listing\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n return { tools: TOOLS };\n });\n\n // Handle tool execution\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n // Validate tool exists\n const tool = TOOLS.find((t) => t.name === name);\n if (!tool) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Error: Unknown tool '${name}'. Available tools: ${TOOLS.map((t) => t.name).join(\", \")}`,\n },\n ],\n isError: true,\n };\n }\n\n try {\n // Call the remote MCP server\n const result = await proxy.callTool(name, args as Record<string, unknown>);\n\n // Handle different response types\n if (typeof result === \"string\") {\n return {\n content: [{ type: \"text\" as const, text: result }],\n };\n }\n\n if (typeof result === \"object\" && result !== null) {\n // If result has a 'result' property, extract it\n const data = (result as Record<string, unknown>).result ?? result;\n return {\n content: [\n {\n type: \"text\" as const,\n text: typeof data === \"string\" ? data : JSON.stringify(data, null, 2),\n },\n ],\n };\n }\n\n return {\n content: [{ type: \"text\" as const, text: String(result) }],\n };\n } catch (error) {\n const message =\n error instanceof ProxyError\n ? `[${error.code}] ${error.message}`\n : `Error: ${error instanceof Error ? error.message : String(error)}`;\n\n return {\n content: [{ type: \"text\" as const, text: message }],\n isError: true,\n };\n }\n });\n\n // Connect via stdio\n const transport = new StdioServerTransport();\n await server.connect(transport);\n\n // Handle graceful shutdown\n process.on(\"SIGINT\", async () => {\n await server.close();\n process.exit(0);\n });\n\n process.on(\"SIGTERM\", async () => {\n await server.close();\n process.exit(0);\n });\n}\n\nmain().catch((error) => {\n console.error(\"Fatal error:\", error);\n process.exit(1);\n});\n","import { z } from \"zod\";\n\n/**\n * Configuration schema for the MCP proxy\n */\nconst ConfigSchema = z.object({\n /** MCP Server URL */\n serverUrl: z\n .string()\n .url()\n .default(\"https://mcp.jai1.jv-it.net\"),\n\n /** JAI1 Access Key for authentication */\n accessKey: z.string().min(1, \"Access key is required\"),\n\n /** Request timeout in milliseconds */\n timeout: z.number().positive().default(60000),\n\n /** Enable debug logging */\n debug: z.boolean().default(false),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n\n/**\n * Load configuration from environment variables\n */\nexport function loadConfig(): Config {\n const rawConfig = {\n serverUrl: process.env.JAI1_MCP_SERVER_URL || process.env.MCP_SERVER_URL,\n accessKey: process.env.JAI1_ACCESS_KEY,\n timeout: process.env.JAI1_MCP_TIMEOUT\n ? parseInt(process.env.JAI1_MCP_TIMEOUT, 10)\n : undefined,\n debug:\n process.env.JAI1_MCP_DEBUG === \"true\" ||\n process.env.DEBUG === \"true\",\n };\n\n const result = ConfigSchema.safeParse(rawConfig);\n\n if (!result.success) {\n const errors = result.error.errors\n .map((e) => ` - ${e.path.join(\".\")}: ${e.message}`)\n .join(\"\\n\");\n throw new Error(\n `Invalid MCP proxy configuration:\\n${errors}\\n\\n` +\n `Required environment variables:\\n` +\n ` JAI1_ACCESS_KEY - Your Jai1 access key\\n\\n` +\n `Optional environment variables:\\n` +\n ` JAI1_MCP_SERVER_URL - MCP server URL (default: https://mcp.jai1.jv-it.net)\\n` +\n ` JAI1_MCP_TIMEOUT - Request timeout in ms (default: 60000)\\n` +\n ` JAI1_MCP_DEBUG - Enable debug logging (default: false)`\n );\n }\n\n return result.data;\n}\n\n/**\n * Default config for documentation purposes\n */\nexport const DEFAULT_CONFIG = {\n serverUrl: \"https://mcp.jai1.jv-it.net\",\n timeout: 60000,\n debug: false,\n} as const;\n","import type { Config } from \"./config.js\";\n\n/**\n * Error class for proxy-related errors\n */\nexport class ProxyError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly statusCode?: number\n ) {\n super(message);\n this.name = \"ProxyError\";\n }\n}\n\n/**\n * HTTP client for proxying requests to the MCP server\n */\nexport class MCPProxy {\n private config: Config;\n private debug: (...args: unknown[]) => void;\n\n constructor(config: Config) {\n this.config = config;\n this.debug = config.debug\n ? (...args: unknown[]) => console.error(\"[MCP-PROXY]\", ...args)\n : () => { };\n }\n\n /**\n * Call a tool on the remote MCP server\n */\n async callTool(\n toolName: string,\n args: Record<string, unknown>\n ): Promise<unknown> {\n const url = `${this.config.serverUrl}/api/agents/tools/${toolName}/execute`;\n this.debug(`Calling tool: ${toolName}`, { url, args });\n\n const controller = new AbortController();\n const timeoutId = setTimeout(\n () => controller.abort(),\n this.config.timeout\n );\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.config.accessKey}`,\n },\n body: JSON.stringify(args),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorBody = await response.text();\n this.debug(`Tool error response:`, { status: response.status, body: errorBody });\n\n if (response.status === 401) {\n throw new ProxyError(\n \"Invalid JAI1_ACCESS_KEY\",\n \"ERR-MCP-001\",\n 401\n );\n }\n if (response.status === 404) {\n throw new ProxyError(\n `Tool not found: ${toolName}`,\n \"ERR-MCP-003\",\n 404\n );\n }\n throw new ProxyError(\n `Server error: ${errorBody}`,\n \"ERR-MCP-004\",\n response.status\n );\n }\n\n const result = await response.json();\n this.debug(`Tool response:`, { toolName, result });\n return result;\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof ProxyError) {\n throw error;\n }\n\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new ProxyError(\n `Request timeout after ${this.config.timeout}ms`,\n \"ERR-MCP-002\",\n 504\n );\n }\n\n throw new ProxyError(\n `Network error: ${error instanceof Error ? error.message : String(error)}`,\n \"ERR-MCP-005\"\n );\n }\n }\n\n /**\n * List available tools from the MCP server\n */\n async listTools(): Promise<ToolInfo[]> {\n const url = `${this.config.serverUrl}/api/mcp/tools`;\n this.debug(`Listing tools from: ${url}`);\n\n const controller = new AbortController();\n const timeoutId = setTimeout(\n () => controller.abort(),\n this.config.timeout\n );\n\n try {\n const response = await fetch(url, {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${this.config.accessKey}`,\n },\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new ProxyError(\n \"Invalid JAI1_ACCESS_KEY\",\n \"ERR-MCP-001\",\n 401\n );\n }\n throw new ProxyError(\n `Failed to list tools: ${response.statusText}`,\n \"ERR-MCP-004\",\n response.status\n );\n }\n\n const data = await response.json();\n this.debug(`Available tools:`, data);\n return data.tools || [];\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof ProxyError) {\n throw error;\n }\n\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new ProxyError(\n `Request timeout after ${this.config.timeout}ms`,\n \"ERR-MCP-002\",\n 504\n );\n }\n\n throw new ProxyError(\n `Network error: ${error instanceof Error ? error.message : String(error)}`,\n \"ERR-MCP-005\"\n );\n }\n }\n\n /**\n * Health check for the MCP server\n */\n async healthCheck(): Promise<boolean> {\n const url = `${this.config.serverUrl}/health`;\n this.debug(`Health check: ${url}`);\n\n try {\n const response = await fetch(url, {\n method: \"GET\",\n signal: AbortSignal.timeout(5000),\n });\n return response.ok;\n } catch {\n return false;\n }\n }\n}\n\n/**\n * Tool information returned from the server\n */\nexport interface ToolInfo {\n name: string;\n description: string;\n inputSchema: {\n type: string;\n properties: Record<string, unknown>;\n required?: string[];\n };\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jvittechs/jai1-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP stdio proxy for Jai1 MCP Server - connects IDE AI agents to Jai1 developer tools",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"jai1-mcp": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"exports": {
|
|
10
|
+
".": "./dist/index.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=20"
|
|
18
|
+
},
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"author": "JVIT <dev@jvit.com>",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/jvittechs/jai1-framework.git",
|
|
24
|
+
"directory": "packages/mcp"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://github.com/jvittechs/jai1-framework/tree/main/packages/mcp#readme",
|
|
27
|
+
"keywords": [
|
|
28
|
+
"jai1",
|
|
29
|
+
"mcp",
|
|
30
|
+
"model-context-protocol",
|
|
31
|
+
"ai",
|
|
32
|
+
"cursor",
|
|
33
|
+
"windsurf",
|
|
34
|
+
"developer-tools"
|
|
35
|
+
],
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsup src/index.ts --format esm --target node22 --out-dir dist --sourcemap --dts",
|
|
38
|
+
"dev": "tsx src/index.ts",
|
|
39
|
+
"lint": "eslint .",
|
|
40
|
+
"test": "vitest run",
|
|
41
|
+
"smart-publish": "node scripts/smart-publish.js"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
45
|
+
"zod": "^3.23.8"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/node": "^22.19.2",
|
|
49
|
+
"tsup": "^8.1.0",
|
|
50
|
+
"tsx": "^4.21.0",
|
|
51
|
+
"typescript": "^5.9.3",
|
|
52
|
+
"vitest": "^2.1.4"
|
|
53
|
+
}
|
|
54
|
+
}
|