@elliotding/ai-agent-mcp 0.1.4 → 0.1.6
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/ai-resource-telemetry.json +19 -1
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +3 -4
- package/dist/api/client.js.map +1 -1
- package/dist/auth/token-validator.d.ts.map +1 -1
- package/dist/auth/token-validator.js +1 -3
- package/dist/auth/token-validator.js.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/prompts/manager.d.ts.map +1 -1
- package/dist/prompts/manager.js +2 -3
- package/dist/prompts/manager.js.map +1 -1
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/http.js +2 -3
- package/dist/server/http.js.map +1 -1
- package/dist/telemetry/manager.d.ts +4 -2
- package/dist/telemetry/manager.d.ts.map +1 -1
- package/dist/telemetry/manager.js +6 -7
- package/dist/telemetry/manager.js.map +1 -1
- package/dist/tools/sync-resources.d.ts.map +1 -1
- package/dist/tools/sync-resources.js +148 -332
- package/dist/tools/sync-resources.js.map +1 -1
- package/dist/tools/uninstall-resource.d.ts.map +1 -1
- package/dist/tools/uninstall-resource.js +66 -150
- package/dist/tools/uninstall-resource.js.map +1 -1
- package/dist/types/tools.d.ts +53 -0
- package/dist/types/tools.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/api/client.ts +3 -4
- package/src/auth/token-validator.ts +1 -3
- package/src/config/index.ts +4 -4
- package/src/index.ts +3 -3
- package/src/prompts/manager.ts +2 -3
- package/src/server/http.ts +2 -3
- package/src/telemetry/manager.ts +6 -6
- package/src/tools/sync-resources.ts +162 -380
- package/src/tools/uninstall-resource.ts +70 -162
- package/src/types/tools.ts +74 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uninstall-resource.d.ts","sourceRoot":"","sources":["../../src/tools/uninstall-resource.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"uninstall-resource.d.ts","sourceRoot":"","sources":["../../src/tools/uninstall-resource.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,KAAK,EAA2B,uBAAuB,EAAe,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAIhH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC,CAoKrG;AAGD,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;CA2BjC,CAAC"}
|
|
@@ -43,7 +43,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
43
43
|
exports.uninstallResourceTool = void 0;
|
|
44
44
|
exports.uninstallResource = uninstallResource;
|
|
45
45
|
const fs = __importStar(require("fs/promises"));
|
|
46
|
-
const fsSync = __importStar(require("fs"));
|
|
47
46
|
const path = __importStar(require("path"));
|
|
48
47
|
const logger_1 = require("../utils/logger");
|
|
49
48
|
const manager_1 = require("../filesystem/manager");
|
|
@@ -51,102 +50,6 @@ const client_1 = require("../api/client");
|
|
|
51
50
|
const cursor_paths_js_1 = require("../utils/cursor-paths.js");
|
|
52
51
|
const errors_1 = require("../types/errors");
|
|
53
52
|
const index_js_1 = require("../prompts/index.js");
|
|
54
|
-
/**
|
|
55
|
-
* Find installed resource files/directories by pattern.
|
|
56
|
-
* - File-based types (rule, command): scan for matching .md/.mdc files
|
|
57
|
-
* - Directory-based types (skill, mcp): scan for matching subdirectories
|
|
58
|
-
*/
|
|
59
|
-
async function findInstalledResources(pattern) {
|
|
60
|
-
const results = [];
|
|
61
|
-
const FILE_TYPES = ['rule', 'command'];
|
|
62
|
-
const DIR_TYPES = ['skill', 'mcp'];
|
|
63
|
-
// Scan file-based types
|
|
64
|
-
for (const type of FILE_TYPES) {
|
|
65
|
-
let typePath;
|
|
66
|
-
try {
|
|
67
|
-
typePath = (0, cursor_paths_js_1.getCursorTypeDir)(type);
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
continue;
|
|
71
|
-
}
|
|
72
|
-
try {
|
|
73
|
-
// listFiles returns relative names; build absolute paths here
|
|
74
|
-
const relNames = await manager_1.filesystemManager.listFiles(typePath, /\.(md|mdc)$/);
|
|
75
|
-
for (const relName of relNames) {
|
|
76
|
-
const absPath = path.join(typePath, relName);
|
|
77
|
-
const baseName = path.basename(relName).replace(/\.(md|mdc)$/, '');
|
|
78
|
-
if (baseName === pattern || baseName.includes(pattern) || relName.includes(pattern)) {
|
|
79
|
-
results.push({ id: baseName, name: baseName, path: absPath, isDirectory: false });
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
catch {
|
|
84
|
-
logger_1.logger.debug({ type, typePath: typePath }, 'Cursor resource type directory not found, skipping');
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
// Scan directory-based types
|
|
88
|
-
for (const type of DIR_TYPES) {
|
|
89
|
-
let typePath;
|
|
90
|
-
try {
|
|
91
|
-
typePath = (0, cursor_paths_js_1.getCursorTypeDir)(type);
|
|
92
|
-
}
|
|
93
|
-
catch {
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
try {
|
|
97
|
-
const entries = await fs.readdir(typePath, { withFileTypes: true });
|
|
98
|
-
for (const entry of entries) {
|
|
99
|
-
if (!entry.isDirectory())
|
|
100
|
-
continue;
|
|
101
|
-
if (entry.name === pattern || entry.name.includes(pattern)) {
|
|
102
|
-
results.push({
|
|
103
|
-
id: entry.name,
|
|
104
|
-
name: entry.name,
|
|
105
|
-
path: path.join(typePath, entry.name),
|
|
106
|
-
isDirectory: true,
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
catch {
|
|
112
|
-
logger_1.logger.debug({ type, typePath: typePath }, 'Cursor resource type directory not found, skipping');
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
return results;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Remove the mcpServers entry whose key matches `serverName` from ~/.cursor/mcp.json.
|
|
119
|
-
* Writes back atomically. No-op if the file or entry does not exist.
|
|
120
|
-
*/
|
|
121
|
-
async function removeMcpJsonEntry(serverName) {
|
|
122
|
-
const mcpJsonPath = path.join((0, cursor_paths_js_1.getCursorRootDir)(), 'mcp.json');
|
|
123
|
-
if (!fsSync.existsSync(mcpJsonPath))
|
|
124
|
-
return false;
|
|
125
|
-
try {
|
|
126
|
-
const raw = await fs.readFile(mcpJsonPath, 'utf-8');
|
|
127
|
-
const config = JSON.parse(raw);
|
|
128
|
-
if (!config.mcpServers)
|
|
129
|
-
return false;
|
|
130
|
-
// Case-insensitive search for the server entry
|
|
131
|
-
const matchedKey = Object.keys(config.mcpServers).find(k => k === serverName || k.toLowerCase() === serverName.toLowerCase());
|
|
132
|
-
if (!matchedKey)
|
|
133
|
-
return false;
|
|
134
|
-
delete config.mcpServers[matchedKey];
|
|
135
|
-
const tempPath = `${mcpJsonPath}.tmp`;
|
|
136
|
-
await fs.writeFile(tempPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
137
|
-
await fs.rename(tempPath, mcpJsonPath);
|
|
138
|
-
logger_1.logger.info({ serverName: matchedKey, mcpJsonPath }, 'Removed mcpServers entry from mcp.json');
|
|
139
|
-
return true;
|
|
140
|
-
}
|
|
141
|
-
catch (error) {
|
|
142
|
-
logger_1.logger.warn({ serverName, mcpJsonPath, error }, 'Failed to update mcp.json');
|
|
143
|
-
return false;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
/** Recursively delete a directory and all its contents. */
|
|
147
|
-
async function removeDirectory(dirPath) {
|
|
148
|
-
await fs.rm(dirPath, { recursive: true, force: true });
|
|
149
|
-
}
|
|
150
53
|
async function uninstallResource(params) {
|
|
151
54
|
const startTime = Date.now();
|
|
152
55
|
const typedParams = params;
|
|
@@ -156,7 +59,6 @@ async function uninstallResource(params) {
|
|
|
156
59
|
const removeFromAccount = typedParams.remove_from_account || false;
|
|
157
60
|
const removedResources = [];
|
|
158
61
|
let subscriptionRemoved = false;
|
|
159
|
-
let mcpJsonCleaned = false;
|
|
160
62
|
// ── Command / Skill: unregister MCP Prompt + delete cache ─────────────
|
|
161
63
|
// Match registered prompt names that contain the pattern.
|
|
162
64
|
const matchedPromptNames = index_js_1.promptManager.promptNames().filter((name) => name === pattern || name.includes(pattern));
|
|
@@ -205,70 +107,80 @@ async function uninstallResource(params) {
|
|
|
205
107
|
(0, logger_1.logToolCall)('uninstall_resource', 'user-id', params, duration);
|
|
206
108
|
return { success: true, data: result };
|
|
207
109
|
}
|
|
208
|
-
// ── Rule / MCP:
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}
|
|
226
|
-
else {
|
|
227
|
-
// File-based resource (rule / command): remove single file
|
|
228
|
-
await manager_1.filesystemManager.deleteResource(resource.path);
|
|
229
|
-
logger_1.logger.debug({ resourceId: resource.id, path: resource.path }, 'Resource file deleted');
|
|
230
|
-
}
|
|
231
|
-
removedResources.push({ id: resource.id, name: resource.name, path: resource.path });
|
|
232
|
-
// Remove from server subscription if requested
|
|
233
|
-
if (removeFromAccount) {
|
|
234
|
-
try {
|
|
235
|
-
await client_1.apiClient.unsubscribe(resource.id);
|
|
236
|
-
subscriptionRemoved = true;
|
|
237
|
-
logger_1.logger.debug({ resourceId: resource.id }, 'Resource unsubscribed from account');
|
|
238
|
-
}
|
|
239
|
-
catch (error) {
|
|
240
|
-
logger_1.logger.warn({ resourceId: resource.id, error }, 'Failed to unsubscribe resource from account');
|
|
241
|
-
}
|
|
110
|
+
// ── Rule / MCP: return LocalAction instructions for the AI to execute ────
|
|
111
|
+
// The MCP server may be running remotely; we must NOT touch the server's
|
|
112
|
+
// own filesystem. Instead we return delete/remove instructions so the AI
|
|
113
|
+
// Agent performs them on the user's LOCAL machine.
|
|
114
|
+
logger_1.logger.debug({ pattern }, 'Building local uninstall actions for Rule/MCP resource...');
|
|
115
|
+
const localActions = [];
|
|
116
|
+
const mcpJsonPath = path.join((0, cursor_paths_js_1.getCursorRootDir)(), 'mcp.json');
|
|
117
|
+
// Rule: delete matching .md/.mdc files from ~/.cursor/rules/
|
|
118
|
+
try {
|
|
119
|
+
const rulesDir = (0, cursor_paths_js_1.getCursorTypeDir)('rule');
|
|
120
|
+
const ruleFiles = await manager_1.filesystemManager.listFiles(rulesDir, /\.(md|mdc)$/);
|
|
121
|
+
for (const relName of ruleFiles) {
|
|
122
|
+
const baseName = path.basename(relName).replace(/\.(md|mdc)$/, '');
|
|
123
|
+
if (baseName === pattern || baseName.includes(pattern) || relName.includes(pattern)) {
|
|
124
|
+
const absPath = path.join(rulesDir, relName);
|
|
125
|
+
localActions.push({ action: 'delete_file', path: absPath });
|
|
126
|
+
removedResources.push({ id: baseName, name: baseName, path: absPath });
|
|
242
127
|
}
|
|
243
128
|
}
|
|
244
|
-
|
|
245
|
-
|
|
129
|
+
}
|
|
130
|
+
catch { /* rules dir may not exist */ }
|
|
131
|
+
// MCP: delete install directory + remove mcp.json entry
|
|
132
|
+
try {
|
|
133
|
+
const mcpDir = (0, cursor_paths_js_1.getCursorTypeDir)('mcp');
|
|
134
|
+
const entries = await fs.readdir(mcpDir, { withFileTypes: true });
|
|
135
|
+
for (const entry of entries) {
|
|
136
|
+
if (!entry.isDirectory())
|
|
137
|
+
continue;
|
|
138
|
+
if (entry.name === pattern || entry.name.includes(pattern)) {
|
|
139
|
+
const dirPath = path.join(mcpDir, entry.name);
|
|
140
|
+
localActions.push({ action: 'delete_file', path: dirPath, recursive: true });
|
|
141
|
+
localActions.push({ action: 'remove_mcp_json_entry', mcp_json_path: mcpJsonPath, server_name: entry.name });
|
|
142
|
+
removedResources.push({ id: entry.name, name: entry.name, path: dirPath });
|
|
143
|
+
}
|
|
246
144
|
}
|
|
247
145
|
}
|
|
248
|
-
|
|
249
|
-
|
|
146
|
+
catch { /* mcp-servers dir may not exist */ }
|
|
147
|
+
// Also check Remote-URL MCPs whose entry is only in mcp.json (no local dir).
|
|
148
|
+
// The pattern might match a server name in mcp.json directly.
|
|
149
|
+
if (localActions.filter(a => a.action === 'remove_mcp_json_entry').length === 0) {
|
|
150
|
+
// Add a conditional remove action — the AI will check if the key exists.
|
|
151
|
+
localActions.push({
|
|
152
|
+
action: 'remove_mcp_json_entry',
|
|
153
|
+
mcp_json_path: mcpJsonPath,
|
|
154
|
+
server_name: pattern,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
if (removedResources.length === 0 && localActions.length === 0) {
|
|
158
|
+
throw (0, errors_1.createValidationError)(pattern, 'resource_id_or_name', 'No installed Rule or MCP resources found matching pattern. Use search_resources to find available resources');
|
|
159
|
+
}
|
|
160
|
+
// Remove from server subscription if requested
|
|
161
|
+
if (removeFromAccount) {
|
|
250
162
|
try {
|
|
251
|
-
|
|
252
|
-
|
|
163
|
+
await client_1.apiClient.unsubscribe(pattern);
|
|
164
|
+
subscriptionRemoved = true;
|
|
253
165
|
}
|
|
254
|
-
catch {
|
|
255
|
-
|
|
166
|
+
catch (err) {
|
|
167
|
+
logger_1.logger.warn({ pattern, err }, 'Failed to unsubscribe resource from account');
|
|
256
168
|
}
|
|
257
169
|
}
|
|
258
|
-
const messageParts = [
|
|
259
|
-
`Successfully uninstalled ${removedResources.length} resource${removedResources.length > 1 ? 's' : ''}.`,
|
|
260
|
-
mcpJsonCleaned ? 'MCP server entry removed from ~/.cursor/mcp.json.' : null,
|
|
261
|
-
subscriptionRemoved ? 'Subscription removed from account.' : null,
|
|
262
|
-
];
|
|
263
170
|
const result = {
|
|
264
171
|
success: true,
|
|
265
172
|
removed_resources: removedResources,
|
|
266
173
|
subscription_removed: subscriptionRemoved,
|
|
267
|
-
message:
|
|
174
|
+
message: [
|
|
175
|
+
`Prepared ${localActions.length} local uninstall action(s) for ${removedResources.length} resource(s).`,
|
|
176
|
+
'Execute every action in local_actions_required on the user\'s local machine.',
|
|
177
|
+
subscriptionRemoved ? 'Subscription removed from account.' : null,
|
|
178
|
+
].filter(Boolean).join(' '),
|
|
179
|
+
local_actions_required: localActions,
|
|
268
180
|
};
|
|
269
181
|
const duration = Date.now() - startTime;
|
|
270
182
|
(0, logger_1.logToolCall)('uninstall_resource', 'user-id', params, duration);
|
|
271
|
-
logger_1.logger.info({ pattern,
|
|
183
|
+
logger_1.logger.info({ pattern, actionCount: localActions.length, subscriptionRemoved, duration }, 'uninstall_resource completed');
|
|
272
184
|
return { success: true, data: result };
|
|
273
185
|
}
|
|
274
186
|
catch (error) {
|
|
@@ -285,9 +197,13 @@ async function uninstallResource(params) {
|
|
|
285
197
|
// Tool definition for registry
|
|
286
198
|
exports.uninstallResourceTool = {
|
|
287
199
|
name: 'uninstall_resource',
|
|
288
|
-
description: 'Uninstall a resource from the local machine. ' +
|
|
289
|
-
'
|
|
290
|
-
'
|
|
200
|
+
description: 'Uninstall a Rule or MCP resource from the user\'s local machine. ' +
|
|
201
|
+
'Returns `local_actions_required` — an ordered list of delete_file and ' +
|
|
202
|
+
'remove_mcp_json_entry actions that the AI Agent MUST execute on the USER\'S LOCAL MACHINE. ' +
|
|
203
|
+
'For delete_file actions: delete the file or directory at the given path. ' +
|
|
204
|
+
'For remove_mcp_json_entry actions: read ~/.cursor/mcp.json, delete the matching ' +
|
|
205
|
+
'mcpServers key, then write the file back. ' +
|
|
206
|
+
'Command and Skill resources are handled by unregistering their MCP Prompt (no local files). ' +
|
|
291
207
|
'Set remove_from_account: true to also cancel the server-side subscription.',
|
|
292
208
|
inputSchema: {
|
|
293
209
|
type: 'object',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uninstall-resource.js","sourceRoot":"","sources":["../../src/tools/uninstall-resource.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"uninstall-resource.js","sourceRoot":"","sources":["../../src/tools/uninstall-resource.ts"],"names":[],"mappings":"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"}
|
package/dist/types/tools.d.ts
CHANGED
|
@@ -2,6 +2,43 @@
|
|
|
2
2
|
* MCP Tool Types
|
|
3
3
|
*/
|
|
4
4
|
import type { MCPToolSchema } from './mcp';
|
|
5
|
+
export interface WriteFileAction {
|
|
6
|
+
action: 'write_file';
|
|
7
|
+
/** Absolute path on the user's local machine (may start with ~). */
|
|
8
|
+
path: string;
|
|
9
|
+
/** UTF-8 file content to write. */
|
|
10
|
+
content: string;
|
|
11
|
+
}
|
|
12
|
+
export interface DeleteFileAction {
|
|
13
|
+
action: 'delete_file';
|
|
14
|
+
/** Absolute path on the user's local machine (may start with ~). */
|
|
15
|
+
path: string;
|
|
16
|
+
/** When true, recursively delete a directory. */
|
|
17
|
+
recursive?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface MergeMcpJsonAction {
|
|
20
|
+
action: 'merge_mcp_json';
|
|
21
|
+
/** Absolute path to the user's mcp.json file. */
|
|
22
|
+
mcp_json_path: string;
|
|
23
|
+
/** Key under mcpServers to add or update. */
|
|
24
|
+
server_name: string;
|
|
25
|
+
/** The MCP server entry object to merge in. */
|
|
26
|
+
entry: Record<string, unknown>;
|
|
27
|
+
/** env keys that are currently empty and must be filled by the user. */
|
|
28
|
+
missing_env?: string[];
|
|
29
|
+
/** Human-readable hint when manual env configuration is required. */
|
|
30
|
+
setup_hint?: string;
|
|
31
|
+
/** Path to a local setup/readme doc if one exists in the install dir. */
|
|
32
|
+
setup_doc?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface RemoveMcpJsonEntryAction {
|
|
35
|
+
action: 'remove_mcp_json_entry';
|
|
36
|
+
/** Absolute path to the user's mcp.json file. */
|
|
37
|
+
mcp_json_path: string;
|
|
38
|
+
/** Key under mcpServers to remove. */
|
|
39
|
+
server_name: string;
|
|
40
|
+
}
|
|
41
|
+
export type LocalAction = WriteFileAction | DeleteFileAction | MergeMcpJsonAction | RemoveMcpJsonEntryAction;
|
|
5
42
|
export type ToolHandler = (params: unknown) => Promise<ToolResult>;
|
|
6
43
|
export interface ToolDefinition {
|
|
7
44
|
name: string;
|
|
@@ -63,8 +100,18 @@ export interface SyncResourcesResult {
|
|
|
63
100
|
/**
|
|
64
101
|
* MCP servers that were installed/updated but require manual configuration
|
|
65
102
|
* before they can be used. Present only when at least one server needs setup.
|
|
103
|
+
* @deprecated use local_actions_required MergeMcpJsonAction.missing_env instead
|
|
66
104
|
*/
|
|
67
105
|
pending_setup?: McpSetupItem[];
|
|
106
|
+
/**
|
|
107
|
+
* Ordered list of file-system and mcp.json operations the AI Agent must
|
|
108
|
+
* execute on the user's LOCAL machine after receiving this response.
|
|
109
|
+
* Present only when at least one Rule or MCP resource was synced.
|
|
110
|
+
*
|
|
111
|
+
* The AI MUST execute every action in order before reporting success to the
|
|
112
|
+
* user. See LocalAction type variants for details.
|
|
113
|
+
*/
|
|
114
|
+
local_actions_required?: LocalAction[];
|
|
68
115
|
}
|
|
69
116
|
export interface ManageSubscriptionParams {
|
|
70
117
|
action: 'subscribe' | 'unsubscribe' | 'list' | 'batch_subscribe' | 'batch_unsubscribe';
|
|
@@ -158,5 +205,11 @@ export interface UninstallResourceResult {
|
|
|
158
205
|
}>;
|
|
159
206
|
subscription_removed: boolean;
|
|
160
207
|
message: string;
|
|
208
|
+
/**
|
|
209
|
+
* Ordered list of file-system and mcp.json operations the AI Agent must
|
|
210
|
+
* execute on the user's LOCAL machine after receiving this response.
|
|
211
|
+
* Present only for Rule and local-executable MCP resources.
|
|
212
|
+
*/
|
|
213
|
+
local_actions_required?: LocalAction[];
|
|
161
214
|
}
|
|
162
215
|
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/types/tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/types/tools.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/api/client.ts
CHANGED
|
@@ -26,16 +26,15 @@ class APIClient {
|
|
|
26
26
|
// Request interceptor for authentication and logging.
|
|
27
27
|
// Every request MUST carry a per-request Authorization header supplied by
|
|
28
28
|
// the caller via authConfig(userToken). If none is present the request is
|
|
29
|
-
// rejected immediately
|
|
30
|
-
//
|
|
29
|
+
// rejected immediately — the token must come from the authenticated SSE
|
|
30
|
+
// connection, not from environment variables.
|
|
31
31
|
this.client.interceptors.request.use(
|
|
32
32
|
(requestConfig) => {
|
|
33
33
|
if (!requestConfig.headers.Authorization) {
|
|
34
34
|
return Promise.reject(
|
|
35
35
|
new Error(
|
|
36
36
|
'Authorization token is missing. ' +
|
|
37
|
-
'Ensure the MCP server is connected via SSE with a valid Bearer token in the Authorization header.
|
|
38
|
-
'Check that your mcp.json has the correct "headers": {"Authorization": "Bearer <token>"} configured.'
|
|
37
|
+
'Ensure the MCP server is connected via SSE with a valid Bearer token in the Authorization header.'
|
|
39
38
|
)
|
|
40
39
|
);
|
|
41
40
|
}
|
|
@@ -111,9 +111,7 @@ export async function verifyTokenViaAPI(token: string): Promise<TokenPayload | n
|
|
|
111
111
|
'Calling CSP API /user/permissions to validate token'
|
|
112
112
|
);
|
|
113
113
|
|
|
114
|
-
// Call CSP API to validate token
|
|
115
|
-
// Note: apiClient already adds Authorization header with CSP_API_TOKEN
|
|
116
|
-
// But for SSE connection, we might use a different token from the client
|
|
114
|
+
// Call CSP API to validate the token presented in the SSE Authorization header.
|
|
117
115
|
const response = await apiClient.get<PermissionsResponse>(
|
|
118
116
|
'/csp/api/user/permissions',
|
|
119
117
|
{
|
package/src/config/index.ts
CHANGED
|
@@ -62,10 +62,10 @@ export interface Config {
|
|
|
62
62
|
// CSP API
|
|
63
63
|
csp: {
|
|
64
64
|
apiBaseUrl: string;
|
|
65
|
-
// NOTE: No apiToken here. The user token
|
|
66
|
-
//
|
|
67
|
-
// receives it via the user_token argument
|
|
68
|
-
//
|
|
65
|
+
// NOTE: No apiToken here. The user token is established during the first MCP
|
|
66
|
+
// connection (SSE Authorization header), validated, then cached per-session.
|
|
67
|
+
// Each tool call receives it via the injected user_token argument.
|
|
68
|
+
// Storing a static token in config would break multi-user scenarios.
|
|
69
69
|
timeout: number;
|
|
70
70
|
};
|
|
71
71
|
|
package/src/index.ts
CHANGED
|
@@ -54,10 +54,10 @@ async function main() {
|
|
|
54
54
|
// Start log cleanup scheduler
|
|
55
55
|
const cleanupTimer = startLogCleanupSchedule();
|
|
56
56
|
|
|
57
|
-
// Wire up telemetry reporting (inject API client to avoid circular import)
|
|
57
|
+
// Wire up telemetry reporting (inject API client to avoid circular import).
|
|
58
|
+
// Tokens are sourced exclusively from authenticated SSE connections via setUserToken().
|
|
58
59
|
telemetry.configure(
|
|
59
|
-
(payload, token) => apiClient.reportTelemetry(payload, token)
|
|
60
|
-
() => process.env.CSP_API_TOKEN
|
|
60
|
+
(payload, token) => apiClient.reportTelemetry(payload, token)
|
|
61
61
|
);
|
|
62
62
|
|
|
63
63
|
try {
|
package/src/prompts/manager.ts
CHANGED
|
@@ -150,9 +150,8 @@ export class PromptManager {
|
|
|
150
150
|
: undefined;
|
|
151
151
|
|
|
152
152
|
// Fire-and-forget telemetry recording attributed to the calling user.
|
|
153
|
-
// userToken is captured from the SSE connection at handler-install time
|
|
154
|
-
|
|
155
|
-
const effectiveToken = userToken ?? process.env.CSP_API_TOKEN ?? '';
|
|
153
|
+
// userToken is captured from the SSE connection at handler-install time.
|
|
154
|
+
const effectiveToken = userToken ?? '';
|
|
156
155
|
if (effectiveToken) {
|
|
157
156
|
telemetry
|
|
158
157
|
.recordInvocation(meta.resource_id, meta.resource_type, meta.resource_name, effectiveToken, jiraId)
|
package/src/server/http.ts
CHANGED
|
@@ -262,9 +262,8 @@ export class HTTPServer {
|
|
|
262
262
|
return;
|
|
263
263
|
}
|
|
264
264
|
|
|
265
|
-
//
|
|
266
|
-
//
|
|
267
|
-
// the token through the Authorization header, not via mcp.json env injection).
|
|
265
|
+
// Register the authenticated token so flush() can report telemetry for this user.
|
|
266
|
+
// The token comes from the SSE Authorization header and is the single source of truth.
|
|
268
267
|
telemetry.setUserToken(token);
|
|
269
268
|
|
|
270
269
|
try {
|
package/src/telemetry/manager.ts
CHANGED
|
@@ -104,7 +104,6 @@ export class TelemetryManager {
|
|
|
104
104
|
private clientVersion: string;
|
|
105
105
|
private timer: ReturnType<typeof setInterval> | null = null;
|
|
106
106
|
private reportFn: ReportFn | null = null;
|
|
107
|
-
private userTokenFn: (() => string | undefined) | null = null;
|
|
108
107
|
/** Tracks all tokens seen from active SSE connections for multi-user flush. */
|
|
109
108
|
private activeTokens: Set<string> = new Set();
|
|
110
109
|
/** Simple mutex: true while a file write is in progress. */
|
|
@@ -129,10 +128,12 @@ export class TelemetryManager {
|
|
|
129
128
|
* Configure the function used to send telemetry to the server.
|
|
130
129
|
* Called during server initialisation to inject the API client without
|
|
131
130
|
* creating a circular dependency.
|
|
131
|
+
*
|
|
132
|
+
* All user tokens must arrive via setUserToken() from authenticated SSE
|
|
133
|
+
* connections — no environment variable fallback.
|
|
132
134
|
*/
|
|
133
|
-
configure(reportFn: ReportFn
|
|
135
|
+
configure(reportFn: ReportFn): void {
|
|
134
136
|
this.reportFn = reportFn;
|
|
135
|
-
this.userTokenFn = userTokenFn;
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
/**
|
|
@@ -236,10 +237,9 @@ export class TelemetryManager {
|
|
|
236
237
|
async flush(): Promise<void> {
|
|
237
238
|
if (!this.reportFn) return;
|
|
238
239
|
|
|
239
|
-
//
|
|
240
|
+
// Only flush tokens from authenticated SSE connections.
|
|
241
|
+
// No environment variable fallback — tokens must arrive via setUserToken().
|
|
240
242
|
const tokens = new Set(this.activeTokens);
|
|
241
|
-
const envToken = this.userTokenFn?.();
|
|
242
|
-
if (envToken) tokens.add(envToken);
|
|
243
243
|
|
|
244
244
|
if (tokens.size === 0) return;
|
|
245
245
|
|