agentstudio 0.1.20 → 0.1.21
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/index.d.ts.map +1 -1
- package/index.js +5 -0
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/{AgentsPage-CKTz2ND6.js → AgentsPage-Nvg2xu6K.js} +2 -2
- package/public/assets/{Button-Dg6ni5Yl.js → Button-Co56C389.js} +1 -1
- package/public/assets/{ChatPage-DkO3kzY2.js → ChatPage-D6sol0ad.js} +5 -5
- package/public/assets/{CommandForm-CIfw9mVj.js → CommandForm-Bk7F_HU8.js} +1 -1
- package/public/assets/{CommandsPage-BgN0E41K.js → CommandsPage-DZHyOdKd.js} +1 -1
- package/public/assets/{DashboardPage-Duu6pBON.js → DashboardPage-29qC7Ev1.js} +2 -2
- package/public/assets/{FileBrowser-Bnm7ZyGT.js → FileBrowser-BYweUPH4.js} +4 -4
- package/public/assets/FileExplorer-DNYj6Tsx.js +1 -0
- package/public/assets/{GeneralSettingsPage-BJTiwSqP.js → GeneralSettingsPage-D9Xa7Nd8.js} +1 -1
- package/public/assets/LandingPage-CjnT-cvO.js +1 -0
- package/public/assets/{LoginPage-DCI_RABC.js → LoginPage-DcaGNCXH.js} +3 -3
- package/public/assets/McpAdminSettingsPage-DgR3E2Bd.js +7 -0
- package/public/assets/{McpPage-Dj4bE6a2.js → McpPage-CtWf1CoL.js} +1 -1
- package/public/assets/{MemorySettingsPage-v7kI6DEB.js → MemorySettingsPage-JTry4Ccp.js} +1 -1
- package/public/assets/PluginsPage-D-BHjQ3P.js +1 -0
- package/public/assets/{ProjectSelector-DKkhmVGz.js → ProjectSelector-DSXOjMQC.js} +1 -1
- package/public/assets/{ProjectsPage-6nGz1v6U.js → ProjectsPage-lLUk4-Xa.js} +5 -5
- package/public/assets/ScheduledTasksPage-5hPbd9Vs.js +1 -0
- package/public/assets/{SettingsLayout-stXQCl6u.js → SettingsLayout-DGJspXLp.js} +1 -1
- package/public/assets/SkillsPage-DBw0m7D2.js +18 -0
- package/public/assets/{SubagentForm-iYJ0l9vh.js → SubagentForm-BdUK1U4y.js} +1 -1
- package/public/assets/{SubagentsPage-ksh-LWAC.js → SubagentsPage-Dnq70IFd.js} +1 -1
- package/public/assets/{ToastTestPage-pxyInZeD.js → ToastTestPage-BfJQRFIm.js} +1 -1
- package/public/assets/{ToolsList-CWZLcBx2.js → ToolsList-Dl5F2fWk.js} +1 -1
- package/public/assets/UnifiedToolSelector-CNbPsiuq.js +1 -0
- package/public/assets/{VersionSettingsPage-ClLBqAIC.js → VersionSettingsPage-BfoCcham.js} +1 -1
- package/public/assets/{_basePickBy-Ce1_TuBk.js → _basePickBy-7C_e0Xv1.js} +1 -1
- package/public/assets/{_baseUniq-Dt6C4BgZ.js → _baseUniq-eGJNLBzx.js} +1 -1
- package/public/assets/{agents-C4aCwcCz.js → agents-ChrA1R0y.js} +1 -1
- package/public/assets/arc-CuA752eE.js +1 -0
- package/public/assets/{architectureDiagram-VXUJARFQ-rnurJGX4.js → architectureDiagram-VXUJARFQ-BnPYh1OW.js} +1 -1
- package/public/assets/{blockDiagram-VD42YOAC-CM33sjhb.js → blockDiagram-VD42YOAC-72nsMt_i.js} +1 -1
- package/public/assets/{c4Diagram-YG6GDRKO-B1tJjciL.js → c4Diagram-YG6GDRKO-BNJSAXcg.js} +1 -1
- package/public/assets/channel-CIunGC5m.js +1 -0
- package/public/assets/{chunk-4BX2VUAB-vbzk_8Ta.js → chunk-4BX2VUAB-RPxkCWhH.js} +1 -1
- package/public/assets/{chunk-55IACEB6-CNXjTgeK.js → chunk-55IACEB6-3ePDt0kp.js} +1 -1
- package/public/assets/{chunk-B4BG7PRW-CykotMKj.js → chunk-B4BG7PRW-CBg_BBfl.js} +1 -1
- package/public/assets/{chunk-DI55MBZ5-DbZodDrP.js → chunk-DI55MBZ5-DIh69TUJ.js} +1 -1
- package/public/assets/{chunk-FMBD7UC4-u0h-4JXb.js → chunk-FMBD7UC4-BbjwhyTe.js} +1 -1
- package/public/assets/{chunk-QN33PNHL-B7VLbRpC.js → chunk-QN33PNHL-BpH-o_YR.js} +1 -1
- package/public/assets/{chunk-QZHKN3VN-DfcZEdwM.js → chunk-QZHKN3VN-DYB7rh5Q.js} +1 -1
- package/public/assets/{chunk-TZMSLE5B-BP4O9iGm.js → chunk-TZMSLE5B-DPCYEVb3.js} +1 -1
- package/public/assets/classDiagram-2ON5EDUG-aUQHFsTA.js +1 -0
- package/public/assets/classDiagram-v2-WZHVMYZB-aUQHFsTA.js +1 -0
- package/public/assets/clone-Ckf7tA1V.js +1 -0
- package/public/assets/{cose-bilkent-S5V4N54A-CSV8iDOr.js → cose-bilkent-S5V4N54A-CnpfmL-Y.js} +1 -1
- package/public/assets/{dagre-6UL2VRFP-S5vHkFwY.js → dagre-6UL2VRFP-DR9x77Xf.js} +1 -1
- package/public/assets/{diagram-PSM6KHXK-Bl4NbJsm.js → diagram-PSM6KHXK-SONPsQNx.js} +1 -1
- package/public/assets/{diagram-QEK2KX5R-D-6ipdkt.js → diagram-QEK2KX5R-BKYFSfC1.js} +1 -1
- package/public/assets/{diagram-S2PKOQOG-DBuN3kfb.js → diagram-S2PKOQOG-CkM0APZj.js} +1 -1
- package/public/assets/{erDiagram-Q2GNP2WA-DEhlyUw1.js → erDiagram-Q2GNP2WA-BX1DpOGx.js} +1 -1
- package/public/assets/{flowDiagram-NV44I4VS-PsSk5-Xf.js → flowDiagram-NV44I4VS-HAAlzNbq.js} +1 -1
- package/public/assets/{ganttDiagram-LVOFAZNH-PfD-vtKp.js → ganttDiagram-LVOFAZNH-BqzWexqa.js} +1 -1
- package/public/assets/{gitGraphDiagram-NY62KEGX-CUq51Mt1.js → gitGraphDiagram-NY62KEGX-CIPmSp43.js} +1 -1
- package/public/assets/{graph-Bc5M3bvZ.js → graph-m515btDj.js} +1 -1
- package/public/assets/{index-ImPzdvfG.js → index-Bn3v3S9-.js} +47 -47
- package/public/assets/index-DWieeYj4.css +1 -0
- package/public/assets/infoDiagram-F6ZHWCRC-Pn4yNWrF.js +2 -0
- package/public/assets/{journeyDiagram-XKPGCS4Q-CTyau8Sh.js → journeyDiagram-XKPGCS4Q-BfzTomS0.js} +1 -1
- package/public/assets/{kanban-definition-3W4ZIXB7-2R3dHQq1.js → kanban-definition-3W4ZIXB7-Cgju7b-L.js} +1 -1
- package/public/assets/{layout-BCktuL_6.js → layout-BKQfQSxJ.js} +1 -1
- package/public/assets/{linear-lHuinZOC.js → linear-DigtLz3B.js} +1 -1
- package/public/assets/{mindmap-definition-VGOIOE7T-Dl8qR3zk.js → mindmap-definition-VGOIOE7T-qopraVFy.js} +1 -1
- package/public/assets/{pieDiagram-ADFJNKIX-Bqcukh_c.js → pieDiagram-ADFJNKIX-BcoaAI-L.js} +2 -2
- package/public/assets/{quadrantDiagram-AYHSOK5B-C_uML1JV.js → quadrantDiagram-AYHSOK5B-D-DwcoSd.js} +1 -1
- package/public/assets/{requirementDiagram-UZGBJVZJ-QUbH9ShO.js → requirementDiagram-UZGBJVZJ-DbQCpx77.js} +1 -1
- package/public/assets/{sankeyDiagram-TZEHDZUN-CEomXpQ1.js → sankeyDiagram-TZEHDZUN-BVk8387S.js} +1 -1
- package/public/assets/{sequenceDiagram-WL72ISMW-DNsDMjTd.js → sequenceDiagram-WL72ISMW-BdzICjxO.js} +1 -1
- package/public/assets/{stateDiagram-FKZM4ZOC-BA_Narwp.js → stateDiagram-FKZM4ZOC-CYY-uUvJ.js} +1 -1
- package/public/assets/stateDiagram-v2-4FDKWEC3-Dh2Kvomq.js +1 -0
- package/public/assets/{tabManager-CkNKjP4G.js → tabManager-B2LQO_Ll.js} +1 -1
- package/public/assets/{table-CSWCaVuS.js → table-D0L2RL5i.js} +1 -1
- package/public/assets/{timeline-definition-IT6M3QCI-DeEgHBeI.js → timeline-definition-IT6M3QCI-BAvjPYvX.js} +1 -1
- package/public/assets/{tools-C7xmF_rB.js → tools-IcPNZlPj.js} +1 -1
- package/public/assets/{treemap-KMMF4GRG-5HQSTjk6.js → treemap-KMMF4GRG-DtkpVA56.js} +1 -1
- package/public/assets/{ui-components-BNdpaz32.js → ui-components-D1St49qC.js} +129 -119
- package/public/assets/{useAgents-C9aEFOWD.js → useAgents-BnDTkOG8.js} +1 -1
- package/public/assets/{useClaudeVersions-CcFqpR2o.js → useClaudeVersions-CD59tFWM.js} +1 -1
- package/public/assets/{useCommands-BadxYHf2.js → useCommands-mvMu3mMD.js} +1 -1
- package/public/assets/{useProjects-Dgk7ldPq.js → useProjects-YXOjaOwL.js} +1 -1
- package/public/assets/{xychartDiagram-PRI3JC2R-C7BNHmgo.js → xychartDiagram-PRI3JC2R-ByBTDWE2.js} +1 -1
- package/public/index.html +5 -5
- package/routes/mcp.d.ts +23 -0
- package/routes/mcp.d.ts.map +1 -1
- package/routes/mcp.js +21 -18
- package/routes/mcp.js.map +1 -1
- package/routes/mcpAdmin.d.ts +16 -0
- package/routes/mcpAdmin.d.ts.map +1 -0
- package/routes/mcpAdmin.js +308 -0
- package/routes/mcpAdmin.js.map +1 -0
- package/routes/mcpAdminManagement.d.ts +17 -0
- package/routes/mcpAdminManagement.d.ts.map +1 -0
- package/routes/mcpAdminManagement.js +345 -0
- package/routes/mcpAdminManagement.js.map +1 -0
- package/services/mcpAdmin/__tests__/adminApiKeyService.test.d.ts +5 -0
- package/services/mcpAdmin/__tests__/adminApiKeyService.test.d.ts.map +1 -0
- package/services/mcpAdmin/__tests__/adminApiKeyService.test.js +289 -0
- package/services/mcpAdmin/__tests__/adminApiKeyService.test.js.map +1 -0
- package/services/mcpAdmin/__tests__/mcpAdminRoutes.test.d.ts +5 -0
- package/services/mcpAdmin/__tests__/mcpAdminRoutes.test.d.ts.map +1 -0
- package/services/mcpAdmin/__tests__/mcpAdminRoutes.test.js +345 -0
- package/services/mcpAdmin/__tests__/mcpAdminRoutes.test.js.map +1 -0
- package/services/mcpAdmin/__tests__/mcpAdminServer.test.d.ts +5 -0
- package/services/mcpAdmin/__tests__/mcpAdminServer.test.d.ts.map +1 -0
- package/services/mcpAdmin/__tests__/mcpAdminServer.test.js +453 -0
- package/services/mcpAdmin/__tests__/mcpAdminServer.test.js.map +1 -0
- package/services/mcpAdmin/__tests__/tools.test.d.ts +5 -0
- package/services/mcpAdmin/__tests__/tools.test.d.ts.map +1 -0
- package/services/mcpAdmin/__tests__/tools.test.js +371 -0
- package/services/mcpAdmin/__tests__/tools.test.js.map +1 -0
- package/services/mcpAdmin/adminApiKeyService.d.ts +61 -0
- package/services/mcpAdmin/adminApiKeyService.d.ts.map +1 -0
- package/services/mcpAdmin/adminApiKeyService.js +270 -0
- package/services/mcpAdmin/adminApiKeyService.js.map +1 -0
- package/services/mcpAdmin/index.d.ts +10 -0
- package/services/mcpAdmin/index.d.ts.map +1 -0
- package/services/mcpAdmin/index.js +43 -0
- package/services/mcpAdmin/index.js.map +1 -0
- package/services/mcpAdmin/mcpAdminServer.d.ts +76 -0
- package/services/mcpAdmin/mcpAdminServer.d.ts.map +1 -0
- package/services/mcpAdmin/mcpAdminServer.js +243 -0
- package/services/mcpAdmin/mcpAdminServer.js.map +1 -0
- package/services/mcpAdmin/tools/agentTools.d.ts +27 -0
- package/services/mcpAdmin/tools/agentTools.d.ts.map +1 -0
- package/services/mcpAdmin/tools/agentTools.js +359 -0
- package/services/mcpAdmin/tools/agentTools.js.map +1 -0
- package/services/mcpAdmin/tools/index.d.ts +15 -0
- package/services/mcpAdmin/tools/index.d.ts.map +1 -0
- package/services/mcpAdmin/tools/index.js +30 -0
- package/services/mcpAdmin/tools/index.js.map +1 -0
- package/services/mcpAdmin/tools/mcpServerTools.d.ts +27 -0
- package/services/mcpAdmin/tools/mcpServerTools.d.ts.map +1 -0
- package/services/mcpAdmin/tools/mcpServerTools.js +334 -0
- package/services/mcpAdmin/tools/mcpServerTools.js.map +1 -0
- package/services/mcpAdmin/tools/projectTools.d.ts +27 -0
- package/services/mcpAdmin/tools/projectTools.d.ts.map +1 -0
- package/services/mcpAdmin/tools/projectTools.js +353 -0
- package/services/mcpAdmin/tools/projectTools.js.map +1 -0
- package/services/mcpAdmin/tools/systemTools.d.ts +23 -0
- package/services/mcpAdmin/tools/systemTools.d.ts.map +1 -0
- package/services/mcpAdmin/tools/systemTools.js +241 -0
- package/services/mcpAdmin/tools/systemTools.js.map +1 -0
- package/services/mcpAdmin/types.d.ts +124 -0
- package/services/mcpAdmin/types.d.ts.map +1 -0
- package/services/mcpAdmin/types.js +18 -0
- package/services/mcpAdmin/types.js.map +1 -0
- package/public/assets/FileExplorer-Dy8ZFDtK.js +0 -1
- package/public/assets/LandingPage-CCqtSDce.js +0 -1
- package/public/assets/PluginsPage-CQ08px0h.js +0 -1
- package/public/assets/ScheduledTasksPage-Dv8qPeLY.js +0 -1
- package/public/assets/SkillsPage-DlQPlwG5.js +0 -18
- package/public/assets/UnifiedToolSelector-A2UIt1Xn.js +0 -1
- package/public/assets/arc-c63c3GDw.js +0 -1
- package/public/assets/channel-6fK1csbi.js +0 -1
- package/public/assets/classDiagram-2ON5EDUG-PrDkNsdA.js +0 -1
- package/public/assets/classDiagram-v2-WZHVMYZB-PrDkNsdA.js +0 -1
- package/public/assets/clone-CXX9AxT7.js +0 -1
- package/public/assets/index-TEVaBQiv.css +0 -1
- package/public/assets/infoDiagram-F6ZHWCRC-BTR1hJCm.js +0 -2
- package/public/assets/stateDiagram-v2-4FDKWEC3-Cy5am68v.js +0 -1
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Admin API Key Service
|
|
4
|
+
*
|
|
5
|
+
* Manages API keys for MCP Admin Server authentication.
|
|
6
|
+
* Keys are stored globally (not per-project) with permission-based access control.
|
|
7
|
+
*
|
|
8
|
+
* Storage: ~/.claude-agent/admin-api-keys.json
|
|
9
|
+
* Key Format: ask_{32-hex-chars}
|
|
10
|
+
*/
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.generateAdminApiKey = generateAdminApiKey;
|
|
16
|
+
exports.validateAdminApiKey = validateAdminApiKey;
|
|
17
|
+
exports.listAdminApiKeys = listAdminApiKeys;
|
|
18
|
+
exports.revokeAdminApiKey = revokeAdminApiKey;
|
|
19
|
+
exports.hasPermission = hasPermission;
|
|
20
|
+
exports.deleteAdminApiKey = deleteAdminApiKey;
|
|
21
|
+
exports.updateAdminApiKey = updateAdminApiKey;
|
|
22
|
+
exports.toggleAdminApiKey = toggleAdminApiKey;
|
|
23
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
24
|
+
const path_1 = __importDefault(require("path"));
|
|
25
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
26
|
+
const bcryptjs_1 = __importDefault(require("bcryptjs"));
|
|
27
|
+
const uuid_1 = require("uuid");
|
|
28
|
+
const proper_lockfile_1 = __importDefault(require("proper-lockfile"));
|
|
29
|
+
const SALT_ROUNDS = 10;
|
|
30
|
+
const KEY_PREFIX = 'ask_'; // Admin Server Key
|
|
31
|
+
// AES-256-GCM encryption key derived from a stable secret
|
|
32
|
+
const ENCRYPTION_KEY = crypto_1.default
|
|
33
|
+
.createHash('sha256')
|
|
34
|
+
.update(process.env.ADMIN_API_KEY_SECRET || 'agentstudio-admin-api-key-secret-v1')
|
|
35
|
+
.digest();
|
|
36
|
+
const LOCK_OPTIONS = {
|
|
37
|
+
retries: { retries: 5, minTimeout: 100, maxTimeout: 500 },
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Get path to admin API keys file
|
|
41
|
+
*/
|
|
42
|
+
function getAdminApiKeysPath() {
|
|
43
|
+
const homeDir = process.env.HOME || process.cwd();
|
|
44
|
+
return path_1.default.join(homeDir, '.claude-agent', 'admin-api-keys.json');
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Encrypt a plaintext API key using AES-256-GCM
|
|
48
|
+
*/
|
|
49
|
+
function encryptKey(plaintext) {
|
|
50
|
+
const iv = crypto_1.default.randomBytes(12);
|
|
51
|
+
const cipher = crypto_1.default.createCipheriv('aes-256-gcm', ENCRYPTION_KEY, iv);
|
|
52
|
+
let encrypted = cipher.update(plaintext, 'utf8', 'hex');
|
|
53
|
+
encrypted += cipher.final('hex');
|
|
54
|
+
const authTag = cipher.getAuthTag();
|
|
55
|
+
return `${iv.toString('hex')}:${authTag.toString('hex')}:${encrypted}`;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Decrypt an encrypted API key
|
|
59
|
+
*/
|
|
60
|
+
function decryptKey(encryptedData) {
|
|
61
|
+
try {
|
|
62
|
+
const [ivHex, authTagHex, encrypted] = encryptedData.split(':');
|
|
63
|
+
if (!ivHex || !authTagHex || !encrypted) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
const iv = Buffer.from(ivHex, 'hex');
|
|
67
|
+
const authTag = Buffer.from(authTagHex, 'hex');
|
|
68
|
+
const decipher = crypto_1.default.createDecipheriv('aes-256-gcm', ENCRYPTION_KEY, iv);
|
|
69
|
+
decipher.setAuthTag(authTag);
|
|
70
|
+
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
|
|
71
|
+
decrypted += decipher.final('utf8');
|
|
72
|
+
return decrypted;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Load admin API key registry
|
|
80
|
+
*/
|
|
81
|
+
async function loadRegistry() {
|
|
82
|
+
const filePath = getAdminApiKeysPath();
|
|
83
|
+
try {
|
|
84
|
+
const data = await promises_1.default.readFile(filePath, 'utf-8');
|
|
85
|
+
return JSON.parse(data);
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
if (error.code === 'ENOENT') {
|
|
89
|
+
return { version: '1.0.0', keys: [] };
|
|
90
|
+
}
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Save admin API key registry with file locking
|
|
96
|
+
*/
|
|
97
|
+
async function saveRegistry(registry) {
|
|
98
|
+
const filePath = getAdminApiKeysPath();
|
|
99
|
+
const dir = path_1.default.dirname(filePath);
|
|
100
|
+
// Ensure directory exists
|
|
101
|
+
await promises_1.default.mkdir(dir, { recursive: true });
|
|
102
|
+
// Check if file exists for lockfile
|
|
103
|
+
let fileExists = true;
|
|
104
|
+
try {
|
|
105
|
+
await promises_1.default.access(filePath);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
fileExists = false;
|
|
109
|
+
await promises_1.default.writeFile(filePath, JSON.stringify({ version: '1.0.0', keys: [] }, null, 2), 'utf-8');
|
|
110
|
+
}
|
|
111
|
+
const release = await proper_lockfile_1.default.lock(filePath, LOCK_OPTIONS);
|
|
112
|
+
try {
|
|
113
|
+
await promises_1.default.writeFile(filePath, JSON.stringify(registry, null, 2), 'utf-8');
|
|
114
|
+
}
|
|
115
|
+
finally {
|
|
116
|
+
await release();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Generate a new admin API key
|
|
121
|
+
* @param description - Human-readable description of the key
|
|
122
|
+
* @param permissions - Array of permission strings (default: ['admin:*'])
|
|
123
|
+
* @param allowedTools - Optional array of tool names this key can access. If undefined, all tools are accessible (based on permissions).
|
|
124
|
+
*/
|
|
125
|
+
async function generateAdminApiKey(description, permissions = ['admin:*'], allowedTools) {
|
|
126
|
+
const registry = await loadRegistry();
|
|
127
|
+
// Generate key: ask_{32-hex-chars}
|
|
128
|
+
const keyBytes = crypto_1.default.randomBytes(16);
|
|
129
|
+
const plainKey = `${KEY_PREFIX}${keyBytes.toString('hex')}`;
|
|
130
|
+
// Hash the key for storage
|
|
131
|
+
const keyHash = await bcryptjs_1.default.hash(plainKey, SALT_ROUNDS);
|
|
132
|
+
// Encrypt the key for display purposes
|
|
133
|
+
const encryptedKey = encryptKey(plainKey);
|
|
134
|
+
const keyData = {
|
|
135
|
+
id: (0, uuid_1.v4)(),
|
|
136
|
+
keyHash,
|
|
137
|
+
encryptedKey,
|
|
138
|
+
description,
|
|
139
|
+
createdAt: new Date().toISOString(),
|
|
140
|
+
permissions,
|
|
141
|
+
allowedTools: allowedTools && allowedTools.length > 0 ? allowedTools : undefined,
|
|
142
|
+
};
|
|
143
|
+
registry.keys.push(keyData);
|
|
144
|
+
await saveRegistry(registry);
|
|
145
|
+
return { key: plainKey, keyData };
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Validate an admin API key
|
|
149
|
+
*/
|
|
150
|
+
async function validateAdminApiKey(apiKey) {
|
|
151
|
+
if (!apiKey || !apiKey.startsWith(KEY_PREFIX)) {
|
|
152
|
+
return { valid: false };
|
|
153
|
+
}
|
|
154
|
+
const registry = await loadRegistry();
|
|
155
|
+
for (const keyData of registry.keys) {
|
|
156
|
+
// Skip revoked keys
|
|
157
|
+
if (keyData.revokedAt) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
// Compare key hash
|
|
161
|
+
const isMatch = await bcryptjs_1.default.compare(apiKey, keyData.keyHash);
|
|
162
|
+
if (isMatch) {
|
|
163
|
+
// Check if key is disabled
|
|
164
|
+
if (keyData.enabled === false) {
|
|
165
|
+
return { valid: false, disabled: true };
|
|
166
|
+
}
|
|
167
|
+
// Update last used timestamp
|
|
168
|
+
keyData.lastUsedAt = new Date().toISOString();
|
|
169
|
+
await saveRegistry(registry);
|
|
170
|
+
return {
|
|
171
|
+
valid: true,
|
|
172
|
+
keyId: keyData.id,
|
|
173
|
+
permissions: keyData.permissions,
|
|
174
|
+
allowedTools: keyData.allowedTools,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return { valid: false };
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* List all admin API keys (with decrypted keys for display)
|
|
182
|
+
*/
|
|
183
|
+
async function listAdminApiKeys() {
|
|
184
|
+
const registry = await loadRegistry();
|
|
185
|
+
return registry.keys.map((key) => ({
|
|
186
|
+
...key,
|
|
187
|
+
decryptedKey: decryptKey(key.encryptedKey) || undefined,
|
|
188
|
+
}));
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Revoke an admin API key
|
|
192
|
+
*/
|
|
193
|
+
async function revokeAdminApiKey(keyId) {
|
|
194
|
+
const registry = await loadRegistry();
|
|
195
|
+
const key = registry.keys.find((k) => k.id === keyId);
|
|
196
|
+
if (!key) {
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
key.revokedAt = new Date().toISOString();
|
|
200
|
+
await saveRegistry(registry);
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Check if a permission is granted
|
|
205
|
+
*/
|
|
206
|
+
function hasPermission(userPermissions, requiredPermission) {
|
|
207
|
+
// admin:* grants all permissions
|
|
208
|
+
if (userPermissions.includes('admin:*')) {
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
// Check for exact match
|
|
212
|
+
if (userPermissions.includes(requiredPermission)) {
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
// Check for wildcard (e.g., 'projects:write' implies 'projects:read')
|
|
216
|
+
const [category, action] = requiredPermission.split(':');
|
|
217
|
+
if (action === 'read' && userPermissions.includes(`${category}:write`)) {
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Delete an admin API key permanently
|
|
224
|
+
*/
|
|
225
|
+
async function deleteAdminApiKey(keyId) {
|
|
226
|
+
const registry = await loadRegistry();
|
|
227
|
+
const index = registry.keys.findIndex((k) => k.id === keyId);
|
|
228
|
+
if (index === -1) {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
registry.keys.splice(index, 1);
|
|
232
|
+
await saveRegistry(registry);
|
|
233
|
+
return true;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Update an admin API key
|
|
237
|
+
*/
|
|
238
|
+
async function updateAdminApiKey(keyId, updates) {
|
|
239
|
+
const registry = await loadRegistry();
|
|
240
|
+
const key = registry.keys.find((k) => k.id === keyId);
|
|
241
|
+
if (!key) {
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
// Apply updates
|
|
245
|
+
if (updates.description !== undefined) {
|
|
246
|
+
key.description = updates.description;
|
|
247
|
+
}
|
|
248
|
+
if (updates.allowedTools !== undefined) {
|
|
249
|
+
key.allowedTools = updates.allowedTools.length > 0 ? updates.allowedTools : undefined;
|
|
250
|
+
}
|
|
251
|
+
if (updates.enabled !== undefined) {
|
|
252
|
+
key.enabled = updates.enabled;
|
|
253
|
+
}
|
|
254
|
+
await saveRegistry(registry);
|
|
255
|
+
return key;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Toggle admin API key enabled status
|
|
259
|
+
*/
|
|
260
|
+
async function toggleAdminApiKey(keyId, enabled) {
|
|
261
|
+
const registry = await loadRegistry();
|
|
262
|
+
const key = registry.keys.find((k) => k.id === keyId);
|
|
263
|
+
if (!key) {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
key.enabled = enabled;
|
|
267
|
+
await saveRegistry(registry);
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=adminApiKeyService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adminApiKeyService.js","sourceRoot":"","sources":["../../../src/services/mcpAdmin/adminApiKeyService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Admin Server Module
|
|
3
|
+
*
|
|
4
|
+
* Provides management APIs via MCP HTTP Streamable protocol.
|
|
5
|
+
*/
|
|
6
|
+
export { McpAdminServer, getMcpAdminServer, resetMcpAdminServer } from './mcpAdminServer.js';
|
|
7
|
+
export { generateAdminApiKey, validateAdminApiKey, listAdminApiKeys, revokeAdminApiKey, deleteAdminApiKey, updateAdminApiKey, toggleAdminApiKey, hasPermission, } from './adminApiKeyService.js';
|
|
8
|
+
export { allTools, projectTools, agentTools, mcpServerTools, systemTools } from './tools/index.js';
|
|
9
|
+
export * from './types.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/mcpAdmin/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC7F,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,GACd,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACnG,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MCP Admin Server Module
|
|
4
|
+
*
|
|
5
|
+
* Provides management APIs via MCP HTTP Streamable protocol.
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
19
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.systemTools = exports.mcpServerTools = exports.agentTools = exports.projectTools = exports.allTools = exports.hasPermission = exports.toggleAdminApiKey = exports.updateAdminApiKey = exports.deleteAdminApiKey = exports.revokeAdminApiKey = exports.listAdminApiKeys = exports.validateAdminApiKey = exports.generateAdminApiKey = exports.resetMcpAdminServer = exports.getMcpAdminServer = exports.McpAdminServer = void 0;
|
|
23
|
+
var mcpAdminServer_js_1 = require("./mcpAdminServer.js");
|
|
24
|
+
Object.defineProperty(exports, "McpAdminServer", { enumerable: true, get: function () { return mcpAdminServer_js_1.McpAdminServer; } });
|
|
25
|
+
Object.defineProperty(exports, "getMcpAdminServer", { enumerable: true, get: function () { return mcpAdminServer_js_1.getMcpAdminServer; } });
|
|
26
|
+
Object.defineProperty(exports, "resetMcpAdminServer", { enumerable: true, get: function () { return mcpAdminServer_js_1.resetMcpAdminServer; } });
|
|
27
|
+
var adminApiKeyService_js_1 = require("./adminApiKeyService.js");
|
|
28
|
+
Object.defineProperty(exports, "generateAdminApiKey", { enumerable: true, get: function () { return adminApiKeyService_js_1.generateAdminApiKey; } });
|
|
29
|
+
Object.defineProperty(exports, "validateAdminApiKey", { enumerable: true, get: function () { return adminApiKeyService_js_1.validateAdminApiKey; } });
|
|
30
|
+
Object.defineProperty(exports, "listAdminApiKeys", { enumerable: true, get: function () { return adminApiKeyService_js_1.listAdminApiKeys; } });
|
|
31
|
+
Object.defineProperty(exports, "revokeAdminApiKey", { enumerable: true, get: function () { return adminApiKeyService_js_1.revokeAdminApiKey; } });
|
|
32
|
+
Object.defineProperty(exports, "deleteAdminApiKey", { enumerable: true, get: function () { return adminApiKeyService_js_1.deleteAdminApiKey; } });
|
|
33
|
+
Object.defineProperty(exports, "updateAdminApiKey", { enumerable: true, get: function () { return adminApiKeyService_js_1.updateAdminApiKey; } });
|
|
34
|
+
Object.defineProperty(exports, "toggleAdminApiKey", { enumerable: true, get: function () { return adminApiKeyService_js_1.toggleAdminApiKey; } });
|
|
35
|
+
Object.defineProperty(exports, "hasPermission", { enumerable: true, get: function () { return adminApiKeyService_js_1.hasPermission; } });
|
|
36
|
+
var index_js_1 = require("./tools/index.js");
|
|
37
|
+
Object.defineProperty(exports, "allTools", { enumerable: true, get: function () { return index_js_1.allTools; } });
|
|
38
|
+
Object.defineProperty(exports, "projectTools", { enumerable: true, get: function () { return index_js_1.projectTools; } });
|
|
39
|
+
Object.defineProperty(exports, "agentTools", { enumerable: true, get: function () { return index_js_1.agentTools; } });
|
|
40
|
+
Object.defineProperty(exports, "mcpServerTools", { enumerable: true, get: function () { return index_js_1.mcpServerTools; } });
|
|
41
|
+
Object.defineProperty(exports, "systemTools", { enumerable: true, get: function () { return index_js_1.systemTools; } });
|
|
42
|
+
__exportStar(require("./types.js"), exports);
|
|
43
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/mcpAdmin/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;;AAEH,yDAA6F;AAApF,mHAAA,cAAc,OAAA;AAAE,sHAAA,iBAAiB,OAAA;AAAE,wHAAA,mBAAmB,OAAA;AAC/D,iEASiC;AAR/B,4HAAA,mBAAmB,OAAA;AACnB,4HAAA,mBAAmB,OAAA;AACnB,yHAAA,gBAAgB,OAAA;AAChB,0HAAA,iBAAiB,OAAA;AACjB,0HAAA,iBAAiB,OAAA;AACjB,0HAAA,iBAAiB,OAAA;AACjB,0HAAA,iBAAiB,OAAA;AACjB,sHAAA,aAAa,OAAA;AAEf,6CAAmG;AAA1F,oGAAA,QAAQ,OAAA;AAAE,wGAAA,YAAY,OAAA;AAAE,sGAAA,UAAU,OAAA;AAAE,0GAAA,cAAc,OAAA;AAAE,uGAAA,WAAW,OAAA;AACxE,6CAA2B"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Admin Server
|
|
3
|
+
*
|
|
4
|
+
* Core MCP Server implementation for management APIs.
|
|
5
|
+
* Handles JSON-RPC 2.0 requests and dispatches to registered tools.
|
|
6
|
+
*
|
|
7
|
+
* Supports pure JSON responses (no SSE streaming) for stateless operation.
|
|
8
|
+
*/
|
|
9
|
+
import type { JsonRpcRequest, JsonRpcResponse, McpToolsListResult, ToolDefinition, ToolContext, AdminPermission } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* MCP Admin Server class
|
|
12
|
+
*
|
|
13
|
+
* Manages tool registration and handles MCP JSON-RPC requests.
|
|
14
|
+
*/
|
|
15
|
+
export declare class McpAdminServer {
|
|
16
|
+
private tools;
|
|
17
|
+
private initialized;
|
|
18
|
+
constructor();
|
|
19
|
+
/**
|
|
20
|
+
* Register a tool with the server
|
|
21
|
+
*/
|
|
22
|
+
registerTool(definition: ToolDefinition): void;
|
|
23
|
+
/**
|
|
24
|
+
* Register multiple tools at once
|
|
25
|
+
*/
|
|
26
|
+
registerTools(definitions: ToolDefinition[]): void;
|
|
27
|
+
/**
|
|
28
|
+
* Get all registered tools (filtered by permissions and allowedTools)
|
|
29
|
+
*/
|
|
30
|
+
getTools(permissions: AdminPermission[], allowedTools?: string[]): McpToolsListResult;
|
|
31
|
+
/**
|
|
32
|
+
* Handle a JSON-RPC request
|
|
33
|
+
*/
|
|
34
|
+
handleRequest(request: JsonRpcRequest, context: ToolContext): Promise<JsonRpcResponse>;
|
|
35
|
+
/**
|
|
36
|
+
* Handle initialize request
|
|
37
|
+
*/
|
|
38
|
+
private handleInitialize;
|
|
39
|
+
/**
|
|
40
|
+
* Handle tools/list request
|
|
41
|
+
*/
|
|
42
|
+
private handleToolsList;
|
|
43
|
+
/**
|
|
44
|
+
* Handle tools/call request
|
|
45
|
+
*/
|
|
46
|
+
private handleToolCall;
|
|
47
|
+
/**
|
|
48
|
+
* Create a success response
|
|
49
|
+
*/
|
|
50
|
+
private successResponse;
|
|
51
|
+
/**
|
|
52
|
+
* Create an error response
|
|
53
|
+
*/
|
|
54
|
+
private errorResponse;
|
|
55
|
+
/**
|
|
56
|
+
* Check if server is initialized
|
|
57
|
+
*/
|
|
58
|
+
isInitialized(): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Reset server state (for testing)
|
|
61
|
+
*/
|
|
62
|
+
reset(): void;
|
|
63
|
+
/**
|
|
64
|
+
* Get tool count
|
|
65
|
+
*/
|
|
66
|
+
getToolCount(): number;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get the MCP Admin Server singleton instance
|
|
70
|
+
*/
|
|
71
|
+
export declare function getMcpAdminServer(): McpAdminServer;
|
|
72
|
+
/**
|
|
73
|
+
* Reset the server instance (for testing)
|
|
74
|
+
*/
|
|
75
|
+
export declare function resetMcpAdminServer(): void;
|
|
76
|
+
//# sourceMappingURL=mcpAdminServer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcpAdminServer.d.ts","sourceRoot":"","sources":["../../../src/services/mcpAdmin/mcpAdminServer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EAIf,kBAAkB,EAGlB,cAAc,EACd,WAAW,EACX,eAAe,EAChB,MAAM,YAAY,CAAC;AAapB;;;;GAIG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAA0C;IACvD,OAAO,CAAC,WAAW,CAAkB;;IAMrC;;OAEG;IACH,YAAY,CAAC,UAAU,EAAE,cAAc,GAAG,IAAI;IAI9C;;OAEG;IACH,aAAa,CAAC,WAAW,EAAE,cAAc,EAAE,GAAG,IAAI;IAMlD;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,eAAe,EAAE,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,kBAAkB;IA0BrF;;OAEG;IACG,aAAa,CACjB,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,eAAe,CAAC;IAqC3B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAkBxB;;OAEG;IACH,OAAO,CAAC,eAAe;IAgBvB;;OAEG;YACW,cAAc;IAoE5B;;OAEG;IACH,OAAO,CAAC,eAAe;IAWvB;;OAEG;IACH,OAAO,CAAC,aAAa;IAWrB;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,YAAY,IAAI,MAAM;CAGvB;AAKD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,CAKlD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAK1C"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MCP Admin Server
|
|
4
|
+
*
|
|
5
|
+
* Core MCP Server implementation for management APIs.
|
|
6
|
+
* Handles JSON-RPC 2.0 requests and dispatches to registered tools.
|
|
7
|
+
*
|
|
8
|
+
* Supports pure JSON responses (no SSE streaming) for stateless operation.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.McpAdminServer = void 0;
|
|
12
|
+
exports.getMcpAdminServer = getMcpAdminServer;
|
|
13
|
+
exports.resetMcpAdminServer = resetMcpAdminServer;
|
|
14
|
+
const types_js_1 = require("./types.js");
|
|
15
|
+
const adminApiKeyService_js_1 = require("./adminApiKeyService.js");
|
|
16
|
+
// MCP Protocol version
|
|
17
|
+
const PROTOCOL_VERSION = '2024-11-05';
|
|
18
|
+
// Server info
|
|
19
|
+
const SERVER_INFO = {
|
|
20
|
+
name: 'agentstudio-admin',
|
|
21
|
+
version: '1.0.0',
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* MCP Admin Server class
|
|
25
|
+
*
|
|
26
|
+
* Manages tool registration and handles MCP JSON-RPC requests.
|
|
27
|
+
*/
|
|
28
|
+
class McpAdminServer {
|
|
29
|
+
tools = new Map();
|
|
30
|
+
initialized = false;
|
|
31
|
+
constructor() {
|
|
32
|
+
// Server starts uninitialized
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Register a tool with the server
|
|
36
|
+
*/
|
|
37
|
+
registerTool(definition) {
|
|
38
|
+
this.tools.set(definition.tool.name, definition);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Register multiple tools at once
|
|
42
|
+
*/
|
|
43
|
+
registerTools(definitions) {
|
|
44
|
+
for (const def of definitions) {
|
|
45
|
+
this.registerTool(def);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get all registered tools (filtered by permissions and allowedTools)
|
|
50
|
+
*/
|
|
51
|
+
getTools(permissions, allowedTools) {
|
|
52
|
+
const visibleTools = [];
|
|
53
|
+
for (const [, def] of this.tools) {
|
|
54
|
+
// Check if user has any of the required permissions
|
|
55
|
+
const hasAccess = def.requiredPermissions.some((perm) => (0, adminApiKeyService_js_1.hasPermission)(permissions, perm));
|
|
56
|
+
if (!hasAccess) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
// If allowedTools is specified, filter by it
|
|
60
|
+
if (allowedTools && allowedTools.length > 0) {
|
|
61
|
+
if (!allowedTools.includes(def.tool.name)) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
visibleTools.push(def.tool);
|
|
66
|
+
}
|
|
67
|
+
return { tools: visibleTools };
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Handle a JSON-RPC request
|
|
71
|
+
*/
|
|
72
|
+
async handleRequest(request, context) {
|
|
73
|
+
try {
|
|
74
|
+
// Validate JSON-RPC structure
|
|
75
|
+
if (request.jsonrpc !== '2.0') {
|
|
76
|
+
return this.errorResponse(request.id, types_js_1.JSON_RPC_ERRORS.INVALID_REQUEST);
|
|
77
|
+
}
|
|
78
|
+
// Route by method
|
|
79
|
+
switch (request.method) {
|
|
80
|
+
case 'initialize':
|
|
81
|
+
return this.handleInitialize(request);
|
|
82
|
+
case 'initialized':
|
|
83
|
+
// Client notification that initialization is complete
|
|
84
|
+
return this.successResponse(request.id, {});
|
|
85
|
+
case 'tools/list':
|
|
86
|
+
return this.handleToolsList(request, context);
|
|
87
|
+
case 'tools/call':
|
|
88
|
+
return this.handleToolCall(request, context);
|
|
89
|
+
case 'ping':
|
|
90
|
+
return this.successResponse(request.id, {});
|
|
91
|
+
default:
|
|
92
|
+
return this.errorResponse(request.id, types_js_1.JSON_RPC_ERRORS.METHOD_NOT_FOUND);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
console.error('[MCP Admin] Request handling error:', error);
|
|
97
|
+
return this.errorResponse(request.id, {
|
|
98
|
+
...types_js_1.JSON_RPC_ERRORS.INTERNAL_ERROR,
|
|
99
|
+
data: error instanceof Error ? error.message : String(error),
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Handle initialize request
|
|
105
|
+
*/
|
|
106
|
+
handleInitialize(request) {
|
|
107
|
+
const params = request.params;
|
|
108
|
+
console.info('[MCP Admin] Initialize request from:', params?.clientInfo?.name);
|
|
109
|
+
const result = {
|
|
110
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
111
|
+
capabilities: {
|
|
112
|
+
tools: {},
|
|
113
|
+
},
|
|
114
|
+
serverInfo: SERVER_INFO,
|
|
115
|
+
};
|
|
116
|
+
this.initialized = true;
|
|
117
|
+
return this.successResponse(request.id, result);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Handle tools/list request
|
|
121
|
+
*/
|
|
122
|
+
handleToolsList(request, context) {
|
|
123
|
+
const toolsList = this.getTools(context.permissions, context.allowedTools);
|
|
124
|
+
console.info('[MCP Admin] Tools list request, returning', toolsList.tools.length, 'tools', context.allowedTools ? `(filtered by ${context.allowedTools.length} allowed tools)` : '');
|
|
125
|
+
return this.successResponse(request.id, toolsList);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Handle tools/call request
|
|
129
|
+
*/
|
|
130
|
+
async handleToolCall(request, context) {
|
|
131
|
+
const params = request.params;
|
|
132
|
+
if (!params?.name) {
|
|
133
|
+
return this.errorResponse(request.id, {
|
|
134
|
+
...types_js_1.JSON_RPC_ERRORS.INVALID_PARAMS,
|
|
135
|
+
data: 'Tool name is required',
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
const toolDef = this.tools.get(params.name);
|
|
139
|
+
if (!toolDef) {
|
|
140
|
+
return this.errorResponse(request.id, {
|
|
141
|
+
...types_js_1.JSON_RPC_ERRORS.METHOD_NOT_FOUND,
|
|
142
|
+
data: `Tool not found: ${params.name}`,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
// Check permissions
|
|
146
|
+
const hasAccess = toolDef.requiredPermissions.some((perm) => (0, adminApiKeyService_js_1.hasPermission)(context.permissions, perm));
|
|
147
|
+
if (!hasAccess) {
|
|
148
|
+
return this.errorResponse(request.id, {
|
|
149
|
+
code: -32001,
|
|
150
|
+
message: 'Permission denied',
|
|
151
|
+
data: `Insufficient permissions for tool: ${params.name}`,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
// Check allowedTools filter
|
|
155
|
+
if (context.allowedTools && context.allowedTools.length > 0) {
|
|
156
|
+
if (!context.allowedTools.includes(params.name)) {
|
|
157
|
+
return this.errorResponse(request.id, {
|
|
158
|
+
code: -32002,
|
|
159
|
+
message: 'Tool not allowed',
|
|
160
|
+
data: `This API key does not have access to tool: ${params.name}`,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
console.info('[MCP Admin] Tool call:', params.name);
|
|
165
|
+
try {
|
|
166
|
+
const result = await toolDef.handler(params.arguments || {}, context);
|
|
167
|
+
return this.successResponse(request.id, result);
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
console.error('[MCP Admin] Tool execution error:', error);
|
|
171
|
+
const errorResult = {
|
|
172
|
+
content: [
|
|
173
|
+
{
|
|
174
|
+
type: 'text',
|
|
175
|
+
text: error instanceof Error ? error.message : String(error),
|
|
176
|
+
},
|
|
177
|
+
],
|
|
178
|
+
isError: true,
|
|
179
|
+
};
|
|
180
|
+
return this.successResponse(request.id, errorResult);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Create a success response
|
|
185
|
+
*/
|
|
186
|
+
successResponse(id, result) {
|
|
187
|
+
return {
|
|
188
|
+
jsonrpc: '2.0',
|
|
189
|
+
id,
|
|
190
|
+
result,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Create an error response
|
|
195
|
+
*/
|
|
196
|
+
errorResponse(id, error) {
|
|
197
|
+
return {
|
|
198
|
+
jsonrpc: '2.0',
|
|
199
|
+
id,
|
|
200
|
+
error,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Check if server is initialized
|
|
205
|
+
*/
|
|
206
|
+
isInitialized() {
|
|
207
|
+
return this.initialized;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Reset server state (for testing)
|
|
211
|
+
*/
|
|
212
|
+
reset() {
|
|
213
|
+
this.initialized = false;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Get tool count
|
|
217
|
+
*/
|
|
218
|
+
getToolCount() {
|
|
219
|
+
return this.tools.size;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
exports.McpAdminServer = McpAdminServer;
|
|
223
|
+
// Singleton instance
|
|
224
|
+
let serverInstance = null;
|
|
225
|
+
/**
|
|
226
|
+
* Get the MCP Admin Server singleton instance
|
|
227
|
+
*/
|
|
228
|
+
function getMcpAdminServer() {
|
|
229
|
+
if (!serverInstance) {
|
|
230
|
+
serverInstance = new McpAdminServer();
|
|
231
|
+
}
|
|
232
|
+
return serverInstance;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Reset the server instance (for testing)
|
|
236
|
+
*/
|
|
237
|
+
function resetMcpAdminServer() {
|
|
238
|
+
if (serverInstance) {
|
|
239
|
+
serverInstance.reset();
|
|
240
|
+
}
|
|
241
|
+
serverInstance = null;
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=mcpAdminServer.js.map
|