@supermodeltools/mcp-server 0.7.1 → 0.7.2
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 +71 -2
- package/dist/server.js +74 -11
- package/dist/tools/feature-request.js +84 -0
- package/dist/tools/find-call-sites.js +141 -0
- package/dist/tools/find-definition.js +161 -0
- package/dist/tools/report-bug.js +133 -0
- package/dist/tools/task-query-tools.js +81 -0
- package/dist/tools/trace-call-chain.js +179 -0
- package/dist/tools/trace-data-flow.js +233 -0
- package/dist/utils/github.js +253 -0
- package/package.json +2 -2
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared utilities for GitHub API interactions.
|
|
4
|
+
* Used by feedback tools (request_feature, report_bug) to create issues.
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.GITHUB_FETCH_TIMEOUT_MS = exports.GITHUB_API_URL = exports.GITHUB_REPO = void 0;
|
|
41
|
+
exports.validateGitHubToken = validateGitHubToken;
|
|
42
|
+
exports.validateRequiredString = validateRequiredString;
|
|
43
|
+
exports.validateOptionalString = validateOptionalString;
|
|
44
|
+
exports.validateLabels = validateLabels;
|
|
45
|
+
exports.classifyGitHubHttpError = classifyGitHubHttpError;
|
|
46
|
+
exports.createGitHubIssue = createGitHubIssue;
|
|
47
|
+
const types_1 = require("../types");
|
|
48
|
+
const logger = __importStar(require("./logger"));
|
|
49
|
+
exports.GITHUB_REPO = 'supermodeltools/mcp';
|
|
50
|
+
exports.GITHUB_API_URL = `https://api.github.com/repos/${exports.GITHUB_REPO}/issues`;
|
|
51
|
+
exports.GITHUB_FETCH_TIMEOUT_MS = 15_000;
|
|
52
|
+
/**
|
|
53
|
+
* Validate that GITHUB_TOKEN is set. Returns a StructuredError if not.
|
|
54
|
+
*/
|
|
55
|
+
function validateGitHubToken() {
|
|
56
|
+
if (!process.env.GITHUB_TOKEN) {
|
|
57
|
+
return {
|
|
58
|
+
type: 'authentication_error',
|
|
59
|
+
message: 'GITHUB_TOKEN environment variable is not set.',
|
|
60
|
+
code: 'MISSING_GITHUB_TOKEN',
|
|
61
|
+
recoverable: false,
|
|
62
|
+
suggestion: 'Set the GITHUB_TOKEN environment variable with a token that has repo scope, then restart the MCP server.',
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Validate a required string parameter.
|
|
69
|
+
* Returns a StructuredError if invalid, null if valid.
|
|
70
|
+
*/
|
|
71
|
+
function validateRequiredString(value, paramName, code, suggestion) {
|
|
72
|
+
if (!value || typeof value !== 'string') {
|
|
73
|
+
return {
|
|
74
|
+
type: 'validation_error',
|
|
75
|
+
message: `Missing or invalid "${paramName}" parameter. Must be a non-empty string.`,
|
|
76
|
+
code,
|
|
77
|
+
recoverable: false,
|
|
78
|
+
suggestion,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Validate an optional string parameter.
|
|
85
|
+
* Returns a StructuredError if present but invalid, null otherwise.
|
|
86
|
+
*/
|
|
87
|
+
function validateOptionalString(value, paramName, code, suggestion) {
|
|
88
|
+
if (value !== undefined && (typeof value !== 'string' || value === '')) {
|
|
89
|
+
return {
|
|
90
|
+
type: 'validation_error',
|
|
91
|
+
message: `Invalid "${paramName}" parameter. Must be a non-empty string if provided.`,
|
|
92
|
+
code,
|
|
93
|
+
recoverable: false,
|
|
94
|
+
suggestion,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Validate an optional labels array.
|
|
101
|
+
* Returns a StructuredError if invalid, null if valid.
|
|
102
|
+
*/
|
|
103
|
+
function validateLabels(labels) {
|
|
104
|
+
if (labels === undefined)
|
|
105
|
+
return null;
|
|
106
|
+
if (!Array.isArray(labels)) {
|
|
107
|
+
return {
|
|
108
|
+
type: 'validation_error',
|
|
109
|
+
message: 'Invalid "labels" parameter. Must be an array of strings.',
|
|
110
|
+
code: 'INVALID_LABELS',
|
|
111
|
+
recoverable: false,
|
|
112
|
+
suggestion: 'Provide labels as an array of strings, e.g. ["enhancement", "good first issue"].',
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
if (!labels.every((l) => typeof l === 'string')) {
|
|
116
|
+
return {
|
|
117
|
+
type: 'validation_error',
|
|
118
|
+
message: 'Invalid "labels" parameter. All items must be strings.',
|
|
119
|
+
code: 'INVALID_LABELS',
|
|
120
|
+
recoverable: false,
|
|
121
|
+
suggestion: 'Provide labels as an array of strings, e.g. ["enhancement", "good first issue"].',
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Classify a GitHub API HTTP error response into a StructuredError.
|
|
128
|
+
*/
|
|
129
|
+
function classifyGitHubHttpError(status, errorBody) {
|
|
130
|
+
switch (status) {
|
|
131
|
+
case 401:
|
|
132
|
+
return {
|
|
133
|
+
type: 'authentication_error',
|
|
134
|
+
message: 'GitHub token is invalid or expired.',
|
|
135
|
+
code: 'INVALID_GITHUB_TOKEN',
|
|
136
|
+
recoverable: false,
|
|
137
|
+
suggestion: 'Check that GITHUB_TOKEN is valid and has not expired.',
|
|
138
|
+
};
|
|
139
|
+
case 403:
|
|
140
|
+
return {
|
|
141
|
+
type: 'authorization_error',
|
|
142
|
+
message: 'GitHub token does not have permission to create issues.',
|
|
143
|
+
code: 'GITHUB_FORBIDDEN',
|
|
144
|
+
recoverable: false,
|
|
145
|
+
suggestion: 'Ensure the GITHUB_TOKEN has "repo" or "public_repo" scope.',
|
|
146
|
+
};
|
|
147
|
+
case 404:
|
|
148
|
+
return {
|
|
149
|
+
type: 'not_found_error',
|
|
150
|
+
message: `Repository ${exports.GITHUB_REPO} not found or not accessible.`,
|
|
151
|
+
code: 'REPO_NOT_FOUND',
|
|
152
|
+
recoverable: false,
|
|
153
|
+
suggestion: 'Check that the GitHub token has access to the repository.',
|
|
154
|
+
};
|
|
155
|
+
case 422:
|
|
156
|
+
return {
|
|
157
|
+
type: 'validation_error',
|
|
158
|
+
message: `GitHub rejected the issue: ${errorBody}`,
|
|
159
|
+
code: 'GITHUB_VALIDATION_ERROR',
|
|
160
|
+
recoverable: false,
|
|
161
|
+
suggestion: 'Check the title and description for invalid content.',
|
|
162
|
+
};
|
|
163
|
+
case 429:
|
|
164
|
+
return {
|
|
165
|
+
type: 'rate_limit_error',
|
|
166
|
+
message: 'GitHub API rate limit exceeded.',
|
|
167
|
+
code: 'GITHUB_RATE_LIMITED',
|
|
168
|
+
recoverable: true,
|
|
169
|
+
suggestion: 'Wait a few minutes and retry.',
|
|
170
|
+
};
|
|
171
|
+
default:
|
|
172
|
+
return {
|
|
173
|
+
type: 'internal_error',
|
|
174
|
+
message: `GitHub API returned HTTP ${status}: ${errorBody}`,
|
|
175
|
+
code: 'GITHUB_API_ERROR',
|
|
176
|
+
recoverable: status >= 500,
|
|
177
|
+
suggestion: status >= 500
|
|
178
|
+
? 'GitHub may be experiencing issues. Wait and retry.'
|
|
179
|
+
: 'Check the request parameters.',
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Create a GitHub issue via the API.
|
|
185
|
+
* Handles authentication, HTTP errors, and network failures.
|
|
186
|
+
*
|
|
187
|
+
* @param toolName - Name of the calling tool (for logging)
|
|
188
|
+
* @param payload - The issue title, body, and optional labels
|
|
189
|
+
* @param successMessage - Message to include in the success response
|
|
190
|
+
* @returns ToolCallResult with success data or structured error
|
|
191
|
+
*/
|
|
192
|
+
async function createGitHubIssue(toolName, payload, successMessage) {
|
|
193
|
+
const token = process.env.GITHUB_TOKEN;
|
|
194
|
+
// Token was already validated by the caller, but guard anyway
|
|
195
|
+
if (!token) {
|
|
196
|
+
return (0, types_1.asErrorResult)({
|
|
197
|
+
type: 'authentication_error',
|
|
198
|
+
message: 'GITHUB_TOKEN environment variable is not set.',
|
|
199
|
+
code: 'MISSING_GITHUB_TOKEN',
|
|
200
|
+
recoverable: false,
|
|
201
|
+
suggestion: 'Set the GITHUB_TOKEN environment variable with a token that has repo scope, then restart the MCP server.',
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
const body = {
|
|
205
|
+
title: payload.title,
|
|
206
|
+
body: payload.body,
|
|
207
|
+
};
|
|
208
|
+
if (payload.labels && payload.labels.length > 0) {
|
|
209
|
+
body.labels = payload.labels;
|
|
210
|
+
}
|
|
211
|
+
logger.debug(`[${toolName}] Creating issue:`, payload.title);
|
|
212
|
+
const controller = new AbortController();
|
|
213
|
+
const timeout = setTimeout(() => controller.abort(), exports.GITHUB_FETCH_TIMEOUT_MS);
|
|
214
|
+
try {
|
|
215
|
+
const response = await fetch(exports.GITHUB_API_URL, {
|
|
216
|
+
method: 'POST',
|
|
217
|
+
headers: {
|
|
218
|
+
'Authorization': `Bearer ${token}`,
|
|
219
|
+
'Accept': 'application/vnd.github+json',
|
|
220
|
+
'Content-Type': 'application/json',
|
|
221
|
+
'X-GitHub-Api-Version': '2022-11-28',
|
|
222
|
+
},
|
|
223
|
+
signal: controller.signal,
|
|
224
|
+
body: JSON.stringify(body),
|
|
225
|
+
});
|
|
226
|
+
if (!response.ok) {
|
|
227
|
+
const errorBody = await response.text();
|
|
228
|
+
logger.error(`[${toolName}] GitHub API error:`, response.status, errorBody);
|
|
229
|
+
return (0, types_1.asErrorResult)(classifyGitHubHttpError(response.status, errorBody));
|
|
230
|
+
}
|
|
231
|
+
const issue = await response.json();
|
|
232
|
+
logger.debug(`[${toolName}] Issue created:`, issue.html_url);
|
|
233
|
+
return (0, types_1.asTextContentResult)({
|
|
234
|
+
message: successMessage,
|
|
235
|
+
issue_url: issue.html_url,
|
|
236
|
+
issue_number: issue.number,
|
|
237
|
+
title: issue.title,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
logger.error(`[${toolName}] Network error:`, error.message);
|
|
242
|
+
return (0, types_1.asErrorResult)({
|
|
243
|
+
type: 'network_error',
|
|
244
|
+
message: `Failed to reach GitHub API: ${error.message}`,
|
|
245
|
+
code: 'GITHUB_NETWORK_ERROR',
|
|
246
|
+
recoverable: true,
|
|
247
|
+
suggestion: 'Check network connectivity and retry.',
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
finally {
|
|
251
|
+
clearTimeout(timeout);
|
|
252
|
+
}
|
|
253
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@supermodeltools/mcp-server",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"description": "MCP server for Supermodel API - code graph generation for AI agents",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
],
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@modelcontextprotocol/sdk": "^1.0.1",
|
|
41
|
-
"@supermodeltools/sdk": "0.7.
|
|
41
|
+
"@supermodeltools/sdk": "0.7.2",
|
|
42
42
|
"archiver": "^7.0.1",
|
|
43
43
|
"ignore": "^7.0.5",
|
|
44
44
|
"jq-web": "^0.6.2",
|