@webeyez/mcp-server 1.0.6 → 1.0.7
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 +91 -48
- package/dist/client.js +108 -0
- package/package.json +6 -3
- package/dist/claude-proxy.js +0 -377
- package/dist/index.js +0 -146
- package/dist/install-env.js +0 -83
- package/dist/setup.js +0 -56
- package/dist/tools/agents.proto +0 -20
- package/dist/tools/auth.js +0 -138
- package/dist/tools/job-store.js +0 -31
- package/dist/tools/organization.proto +0 -102
- package/dist/tools/public.js +0 -423
- package/dist/utils/paths.js +0 -22
package/dist/tools/public.js
DELETED
|
@@ -1,423 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.setupPublicTools = setupPublicTools;
|
|
40
|
-
const zod_1 = require("zod");
|
|
41
|
-
const grpc = __importStar(require("@grpc/grpc-js"));
|
|
42
|
-
const protoLoader = __importStar(require("@grpc/proto-loader"));
|
|
43
|
-
const path_1 = __importDefault(require("path"));
|
|
44
|
-
const crypto_1 = __importDefault(require("crypto"));
|
|
45
|
-
const paths_1 = require("../utils/paths");
|
|
46
|
-
const PROTO_PATH = path_1.default.join(__dirname, 'agents.proto');
|
|
47
|
-
const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
|
|
48
|
-
keepCase: true,
|
|
49
|
-
longs: String,
|
|
50
|
-
enums: String,
|
|
51
|
-
defaults: true,
|
|
52
|
-
oneofs: true
|
|
53
|
-
});
|
|
54
|
-
const agentsProto = grpc.loadPackageDefinition(packageDefinition).agents;
|
|
55
|
-
const ORG_PROTO_PATH = path_1.default.join(__dirname, 'organization.proto');
|
|
56
|
-
const orgPackageDefinition = protoLoader.loadSync(ORG_PROTO_PATH, {
|
|
57
|
-
keepCase: true,
|
|
58
|
-
longs: String,
|
|
59
|
-
enums: String,
|
|
60
|
-
defaults: true,
|
|
61
|
-
oneofs: true
|
|
62
|
-
});
|
|
63
|
-
const orgProto = grpc.loadPackageDefinition(orgPackageDefinition).OrganizationService;
|
|
64
|
-
const job_store_1 = require("./job-store");
|
|
65
|
-
async function getUserOrganizations(userIdStr) {
|
|
66
|
-
if (!userIdStr)
|
|
67
|
-
return { error: "No userIdStr provided" };
|
|
68
|
-
const userId = parseInt(userIdStr, 10);
|
|
69
|
-
if (isNaN(userId))
|
|
70
|
-
return { error: `Invalid userId: ${userIdStr}` };
|
|
71
|
-
const orgServiceUrl = process.env.ORG_SERVICE_URL;
|
|
72
|
-
const client = new orgProto.OrganizationService(orgServiceUrl, grpc.credentials.createInsecure());
|
|
73
|
-
return new Promise((resolve) => {
|
|
74
|
-
client.organizationsList({ userId }, (error, response) => {
|
|
75
|
-
if (error) {
|
|
76
|
-
console.error(`[MCP] Error fetching orgs via gRPC:`, error);
|
|
77
|
-
return resolve({ error: `gRPC Error: ${error.message}` });
|
|
78
|
-
}
|
|
79
|
-
try {
|
|
80
|
-
if (!response || !response.response) {
|
|
81
|
-
return resolve({ error: "Empty response from gRPC" });
|
|
82
|
-
}
|
|
83
|
-
const data = JSON.parse(response.response);
|
|
84
|
-
if (data && data.code && data.message) {
|
|
85
|
-
console.error(`[MCP] gRPC returned explicit error:`, data.message);
|
|
86
|
-
return resolve({ error: `gRPC Explicit Error: ${data.message}` });
|
|
87
|
-
}
|
|
88
|
-
const orgs = new Map();
|
|
89
|
-
let orgsArray = data;
|
|
90
|
-
if (data && Array.isArray(data.organizations)) {
|
|
91
|
-
orgsArray = data.organizations;
|
|
92
|
-
}
|
|
93
|
-
if (Array.isArray(orgsArray)) {
|
|
94
|
-
for (const org of orgsArray) {
|
|
95
|
-
const orgId = org.OrgId || org.orgId || org.id;
|
|
96
|
-
const orgName = org.OrgName || org.orgName || org.name;
|
|
97
|
-
const domainsGroup = org.domainsGroup || [];
|
|
98
|
-
if (orgId && orgName) {
|
|
99
|
-
orgs.set(orgId, { orgName, domainsGroup });
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
return resolve({ error: `gRPC Data is not an array. Keys: ${Object.keys(data).join(', ')}` });
|
|
105
|
-
}
|
|
106
|
-
const result = Array.from(orgs.entries()).map(([orgId, orgData]) => ({
|
|
107
|
-
orgId,
|
|
108
|
-
orgName: orgData.orgName,
|
|
109
|
-
domainsGroup: orgData.domainsGroup
|
|
110
|
-
}));
|
|
111
|
-
resolve({ success: true, orgs: result });
|
|
112
|
-
}
|
|
113
|
-
catch (err) {
|
|
114
|
-
console.error(`[MCP] Error parsing org details response:`, err);
|
|
115
|
-
resolve({ error: `JSON Parse Error: ${err.message}` });
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
function setupPublicTools(server, context) {
|
|
121
|
-
const jobStore = context.jobStore || new job_store_1.InMemoryJobStore();
|
|
122
|
-
server.tool("start_webeyez_query", "Start a long-running AI query for Webeyez data. IMPORTANT: You MUST provide the correct organizationId. To find the correct organizationId, you MUST first call the 'get_organizations_list' tool, look at the returned list, match the user's domain to the correct organization, and extract the organizationId. Only then call this tool. If the client asked for a date range, it MUST be included directly in the 'question' parameter itself (the AI service will interpret it). Do NOT explicitly mention or reveal the organizationId to the user in your responses.", {
|
|
123
|
-
question: zod_1.z.string().describe("The free text query / question to ask the AI."),
|
|
124
|
-
domain: zod_1.z.string().describe("The domain context for the question"),
|
|
125
|
-
organizationId: zod_1.z.number().optional().describe("The numeric ID of the organization to query. Required if the user belongs to multiple organizations."),
|
|
126
|
-
conversationId: zod_1.z.string().optional().describe("Optional ID of a previous conversation to proceed with"),
|
|
127
|
-
dateRange: zod_1.z.string().optional().describe("Crucial: The backend will automatically prepend the date column name. You MUST start this string directly with a valid SQL operator (BETWEEN, >=, <=, >, <, or =). Do NOT include the column name at the beginning. Example 1: \"BETWEEN '2026-05-01 00:00:00' AND '2026-05-07 23:59:59'\". Example 2: \">= '2026-05-01'\". If data from MULTIPLE non-contiguous ranges is needed, you MUST either split this into separate queries, OR take a larger continuous range (e.g. \"BETWEEN '2026-04-01' AND '2026-05-07'\") and then post-process the data yourself. If you leave this blank, it defaults to the last 7 days.")
|
|
128
|
-
}, async ({ question, domain, organizationId, conversationId, dateRange }) => {
|
|
129
|
-
// Mix the PAT into the Job ID so it's not purely random
|
|
130
|
-
const pat = context.pat || process.env.WEBEYEZ_API_KEY || 'no-pat';
|
|
131
|
-
const patHash = crypto_1.default.createHash('sha256').update(pat).digest('hex').substring(0, 8);
|
|
132
|
-
const jobId = `${crypto_1.default.randomUUID()}-${patHash}`;
|
|
133
|
-
let resolvedCustomerId = organizationId || context.customerId; // fallback
|
|
134
|
-
if (context.pat !== 'no-pat' && context.userId) {
|
|
135
|
-
const orgResponse = await getUserOrganizations(context.userId);
|
|
136
|
-
if (orgResponse.error) {
|
|
137
|
-
return {
|
|
138
|
-
content: [{
|
|
139
|
-
type: "text",
|
|
140
|
-
text: JSON.stringify({
|
|
141
|
-
status: "error",
|
|
142
|
-
error: `Failed to fetch organizations: ${orgResponse.error}`
|
|
143
|
-
})
|
|
144
|
-
}],
|
|
145
|
-
isError: true
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
const orgs = orgResponse.orgs || [];
|
|
149
|
-
if (orgs.length === 0 && !resolvedCustomerId) {
|
|
150
|
-
return {
|
|
151
|
-
content: [{
|
|
152
|
-
type: "text",
|
|
153
|
-
text: JSON.stringify({
|
|
154
|
-
status: "error",
|
|
155
|
-
error: "No organizations found for this user. Could not resolve customerId."
|
|
156
|
-
})
|
|
157
|
-
}],
|
|
158
|
-
isError: true
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
if (orgs.length === 1 && !resolvedCustomerId) {
|
|
162
|
-
resolvedCustomerId = orgs[0].orgId;
|
|
163
|
-
}
|
|
164
|
-
else if (orgs.length > 1 && !resolvedCustomerId) {
|
|
165
|
-
return {
|
|
166
|
-
content: [{
|
|
167
|
-
type: "text",
|
|
168
|
-
text: JSON.stringify({
|
|
169
|
-
status: "error",
|
|
170
|
-
error: `User belongs to multiple organizations. You MUST call the 'get_organizations_list' tool to fetch the list of organizations, match the domain to the correct organization, and re-run this tool with that organizationId.`
|
|
171
|
-
})
|
|
172
|
-
}],
|
|
173
|
-
isError: true
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
if (!resolvedCustomerId) {
|
|
178
|
-
return {
|
|
179
|
-
content: [{
|
|
180
|
-
type: "text",
|
|
181
|
-
text: JSON.stringify({
|
|
182
|
-
status: "error",
|
|
183
|
-
error: "A valid customerId (organizationId) could not be resolved. You MUST call the 'get_organizations_list' tool FIRST to find the correct organizationId, and then call this tool again with that organizationId."
|
|
184
|
-
})
|
|
185
|
-
}],
|
|
186
|
-
isError: true
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
// Register the job as processing
|
|
190
|
-
await jobStore.set(jobId, {
|
|
191
|
-
status: 'processing',
|
|
192
|
-
startedAt: Date.now()
|
|
193
|
-
});
|
|
194
|
-
// Kick off the background process
|
|
195
|
-
const aiServiceUrl = process.env.AI_SERVICE_URL;
|
|
196
|
-
const client = new agentsProto.AgentsService(aiServiceUrl, grpc.credentials.createInsecure());
|
|
197
|
-
const requestObj = {
|
|
198
|
-
question,
|
|
199
|
-
domain,
|
|
200
|
-
customerId: resolvedCustomerId,
|
|
201
|
-
dateRange: dateRange || "",
|
|
202
|
-
conversationId: conversationId || ""
|
|
203
|
-
};
|
|
204
|
-
console.error(`[MCP-DEBUG] Starting ask_webeyez query.`);
|
|
205
|
-
console.error(`[MCP-DEBUG] User input - Domain: ${domain}, Org: ${organizationId}`);
|
|
206
|
-
console.error(`[MCP-DEBUG] Resolved customerId: ${resolvedCustomerId}`);
|
|
207
|
-
console.error(`[MCP-DEBUG] gRPC Request to AI Service:`, JSON.stringify(requestObj));
|
|
208
|
-
console.log(`[MCP] Starting background job ${jobId} against ${aiServiceUrl}...`);
|
|
209
|
-
// Execute gRPC call without waiting for it
|
|
210
|
-
client.AskWz(requestObj, async (error, response) => {
|
|
211
|
-
const job = await jobStore.get(jobId);
|
|
212
|
-
if (!job)
|
|
213
|
-
return; // Job was already cleaned up somehow
|
|
214
|
-
if (error) {
|
|
215
|
-
console.error(`[MCP] Background job ${jobId} failed:`, error);
|
|
216
|
-
console.error(`[MCP-DEBUG] gRPC Error:`, error);
|
|
217
|
-
let errorMsg = error.message || "Unknown error occurred";
|
|
218
|
-
if (error.code === grpc.status.DEADLINE_EXCEEDED || error.message?.includes('Deadline Exceeded')) {
|
|
219
|
-
errorMsg = `Request to AI Service at ${aiServiceUrl} timed out via gRPC deadline. The service might be busy or down.`;
|
|
220
|
-
}
|
|
221
|
-
else if (error.code === grpc.status.UNAVAILABLE) {
|
|
222
|
-
errorMsg = `AI Service at ${aiServiceUrl} is unavailable. Ensure the service is running and accessible.`;
|
|
223
|
-
}
|
|
224
|
-
await jobStore.set(jobId, {
|
|
225
|
-
status: 'error',
|
|
226
|
-
error: errorMsg,
|
|
227
|
-
startedAt: job.startedAt,
|
|
228
|
-
data: { grpcCode: error.code, originalError: error.message }
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
else {
|
|
232
|
-
console.log(`[MCP] Background job ${jobId} completed successfully.`);
|
|
233
|
-
console.error(`[MCP-DEBUG] gRPC Response from AI Service:`, JSON.stringify(response));
|
|
234
|
-
let parsedData = response.response;
|
|
235
|
-
try {
|
|
236
|
-
parsedData = JSON.parse(response.response);
|
|
237
|
-
}
|
|
238
|
-
catch (e) {
|
|
239
|
-
// Leave as string if not parseable
|
|
240
|
-
}
|
|
241
|
-
await jobStore.set(jobId, {
|
|
242
|
-
status: 'completed',
|
|
243
|
-
startedAt: job.startedAt,
|
|
244
|
-
data: {
|
|
245
|
-
summary: "AI response received via gRPC",
|
|
246
|
-
conversationId: response.conversationId || undefined,
|
|
247
|
-
payload: parsedData
|
|
248
|
-
}
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
});
|
|
252
|
-
// Return immediately to Claude so it doesn't hit the 60s timeout
|
|
253
|
-
return {
|
|
254
|
-
content: [{
|
|
255
|
-
type: "text",
|
|
256
|
-
text: JSON.stringify({
|
|
257
|
-
status: "processing",
|
|
258
|
-
jobId: jobId,
|
|
259
|
-
message: "The query has been started in the background. Please use the check_webeyez_status tool with this jobId to poll for the results."
|
|
260
|
-
})
|
|
261
|
-
}]
|
|
262
|
-
};
|
|
263
|
-
});
|
|
264
|
-
server.tool("get_organizations_list", "Get a list of all organizations the current user has access to. Returns their names and organizationIds. Do NOT explicitly mention the returned organizationIds to the user.", {}, async () => {
|
|
265
|
-
if (context.pat !== 'no-pat' && context.userId) {
|
|
266
|
-
const orgResponse = await getUserOrganizations(context.userId);
|
|
267
|
-
if (orgResponse.error) {
|
|
268
|
-
return {
|
|
269
|
-
content: [
|
|
270
|
-
{ type: "text", text: JSON.stringify({ status: "error", error: orgResponse.error }) }
|
|
271
|
-
]
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
const orgs = orgResponse.orgs || [];
|
|
275
|
-
return {
|
|
276
|
-
content: [
|
|
277
|
-
{ type: "text", text: JSON.stringify({
|
|
278
|
-
status: "success",
|
|
279
|
-
organizations: orgs.map((o) => ({ name: o.orgName, organizationId: o.orgId }))
|
|
280
|
-
}) }
|
|
281
|
-
]
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
return {
|
|
285
|
-
content: [
|
|
286
|
-
{ type: "text", text: JSON.stringify({ status: "error", message: "Not authenticated with PAT" }) }
|
|
287
|
-
]
|
|
288
|
-
};
|
|
289
|
-
});
|
|
290
|
-
server.tool("get_organization_domains", "Get a list of available domains for a specific organization. The agent needs to use this to look for the exact matching domain the client is referring to since queries require exact domain strings. Do NOT explicitly mention the organizationId to the user.", {
|
|
291
|
-
organizationId: zod_1.z.number().describe("The ID of the organization to fetch domains for.")
|
|
292
|
-
}, async ({ organizationId }) => {
|
|
293
|
-
if (context.pat !== 'no-pat' && context.userId) {
|
|
294
|
-
const orgResponse = await getUserOrganizations(context.userId);
|
|
295
|
-
if (orgResponse.error) {
|
|
296
|
-
return {
|
|
297
|
-
content: [
|
|
298
|
-
{ type: "text", text: JSON.stringify({ status: "error", error: orgResponse.error }) }
|
|
299
|
-
]
|
|
300
|
-
};
|
|
301
|
-
}
|
|
302
|
-
const orgs = orgResponse.orgs || [];
|
|
303
|
-
const targetOrg = orgs.find((o) => o.orgId === organizationId);
|
|
304
|
-
if (!targetOrg) {
|
|
305
|
-
return {
|
|
306
|
-
content: [
|
|
307
|
-
{ type: "text", text: JSON.stringify({ status: "error", error: `Organization ID ${organizationId} not found for this user. Make sure to use get_organizations_list first.` }) }
|
|
308
|
-
]
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
return {
|
|
312
|
-
content: [
|
|
313
|
-
{ type: "text", text: JSON.stringify({
|
|
314
|
-
status: "success",
|
|
315
|
-
organizationId: targetOrg.orgId,
|
|
316
|
-
organizationName: targetOrg.orgName,
|
|
317
|
-
domains: targetOrg.domainsGroup || []
|
|
318
|
-
}) }
|
|
319
|
-
]
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
return {
|
|
323
|
-
content: [
|
|
324
|
-
{ type: "text", text: JSON.stringify({ status: "error", message: "Not authenticated with PAT" }) }
|
|
325
|
-
]
|
|
326
|
-
};
|
|
327
|
-
});
|
|
328
|
-
server.tool("check_webeyez_status", "Check the status of a previously started Webeyez background query. When the job completes, this tool will return the final text response from the Webeyez AI.", {
|
|
329
|
-
jobId: zod_1.z.string().describe("The Job ID returned by start_webeyez_query")
|
|
330
|
-
}, async ({ jobId }) => {
|
|
331
|
-
const job = await jobStore.get(jobId);
|
|
332
|
-
if (!job) {
|
|
333
|
-
return {
|
|
334
|
-
content: [{
|
|
335
|
-
type: "text",
|
|
336
|
-
text: JSON.stringify({
|
|
337
|
-
status: "error",
|
|
338
|
-
error: `Job ID ${jobId} not found. It may have expired, or the ID is invalid.`
|
|
339
|
-
})
|
|
340
|
-
}],
|
|
341
|
-
isError: true
|
|
342
|
-
};
|
|
343
|
-
}
|
|
344
|
-
if (job.status === 'processing') {
|
|
345
|
-
const elapsedSeconds = Math.round((Date.now() - job.startedAt) / 1000);
|
|
346
|
-
return {
|
|
347
|
-
content: [{
|
|
348
|
-
type: "text",
|
|
349
|
-
text: JSON.stringify({
|
|
350
|
-
status: "processing",
|
|
351
|
-
message: `Job is still running in the background (elapsed: ${elapsedSeconds}s). Please wait a bit and check again.`
|
|
352
|
-
})
|
|
353
|
-
}]
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
if (job.status === 'error') {
|
|
357
|
-
return {
|
|
358
|
-
content: [{
|
|
359
|
-
type: "text",
|
|
360
|
-
text: JSON.stringify({
|
|
361
|
-
status: "error",
|
|
362
|
-
error: job.error,
|
|
363
|
-
details: job.data
|
|
364
|
-
})
|
|
365
|
-
}],
|
|
366
|
-
isError: true
|
|
367
|
-
};
|
|
368
|
-
}
|
|
369
|
-
// Status is completed
|
|
370
|
-
let resultData = job.data;
|
|
371
|
-
if (typeof resultData === 'string') {
|
|
372
|
-
const debugIndex = resultData.indexOf('Debug Info:');
|
|
373
|
-
if (debugIndex !== -1) {
|
|
374
|
-
resultData = resultData.substring(0, debugIndex).trim();
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
return {
|
|
378
|
-
content: [{
|
|
379
|
-
type: "text",
|
|
380
|
-
text: JSON.stringify({
|
|
381
|
-
status: "completed",
|
|
382
|
-
data: resultData
|
|
383
|
-
})
|
|
384
|
-
}]
|
|
385
|
-
};
|
|
386
|
-
});
|
|
387
|
-
server.tool("logout_webeyez", "Removes the saved Personal Access Token (PAT) from the Claude Desktop config to effectively 'logout' from Webeyez and clear your PAT. CRITICAL: Once you call this tool, the server will restart. You MUST STOP your response immediately after calling this tool. Do NOT call any other tools. Just tell the user that they are logged out. Also, explicitly tell the user that in some cases they might need to completely close and reopen the Claude application for the logout to be applied.", {}, async () => {
|
|
388
|
-
const fs = await Promise.resolve().then(() => __importStar(require('fs')));
|
|
389
|
-
const configPath = (0, paths_1.getClaudeConfigPath)();
|
|
390
|
-
try {
|
|
391
|
-
if (!fs.existsSync(configPath)) {
|
|
392
|
-
return {
|
|
393
|
-
content: [{ type: "text", text: "Configuration file not found. Cannot logout." }],
|
|
394
|
-
isError: true
|
|
395
|
-
};
|
|
396
|
-
}
|
|
397
|
-
const configData = fs.readFileSync(configPath, 'utf8');
|
|
398
|
-
const config = JSON.parse(configData);
|
|
399
|
-
if (config.mcpServers && config.mcpServers["wz-mcp-service"] && config.mcpServers["wz-mcp-service"].env) {
|
|
400
|
-
delete config.mcpServers["wz-mcp-service"].env.WEBEYEZ_API_KEY;
|
|
401
|
-
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');
|
|
402
|
-
// Force exit so Claude Desktop restarts the proxy WITHOUT the env var, switching it to fallback mode
|
|
403
|
-
setTimeout(() => {
|
|
404
|
-
process.exit(0);
|
|
405
|
-
}, 1000);
|
|
406
|
-
return {
|
|
407
|
-
content: [{ type: "text", text: "Successfully logged out by removing the PAT from the configuration! Claude Desktop is now restarting the server." }]
|
|
408
|
-
};
|
|
409
|
-
}
|
|
410
|
-
else {
|
|
411
|
-
return {
|
|
412
|
-
content: [{ type: "text", text: "wz-mcp-service or WEBEYEZ_API_KEY not found in configuration file. You are already logged out." }]
|
|
413
|
-
};
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
catch (error) {
|
|
417
|
-
return {
|
|
418
|
-
content: [{ type: "text", text: `Error updating configuration: ${error.message}` }],
|
|
419
|
-
isError: true
|
|
420
|
-
};
|
|
421
|
-
}
|
|
422
|
-
});
|
|
423
|
-
}
|
package/dist/utils/paths.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getClaudeConfigPath = getClaudeConfigPath;
|
|
7
|
-
const os_1 = __importDefault(require("os"));
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
|
-
function getClaudeConfigPath() {
|
|
10
|
-
const platform = os_1.default.platform();
|
|
11
|
-
const home = os_1.default.homedir();
|
|
12
|
-
if (platform === 'win32') {
|
|
13
|
-
const appData = process.env.APPDATA || path_1.default.join(home, 'AppData', 'Roaming');
|
|
14
|
-
return path_1.default.join(appData, 'Claude', 'claude_desktop_config.json');
|
|
15
|
-
}
|
|
16
|
-
if (platform === 'darwin') {
|
|
17
|
-
return path_1.default.join(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
|
|
18
|
-
}
|
|
19
|
-
// Default to Linux/other Unix-like (using XDG Base Directory specification)
|
|
20
|
-
const configDir = process.env.XDG_CONFIG_HOME || path_1.default.join(home, '.config');
|
|
21
|
-
return path_1.default.join(configDir, 'Claude', 'claude_desktop_config.json');
|
|
22
|
-
}
|