claudeunmask 1.0.22 → 1.0.23

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.js CHANGED
@@ -1,4 +1,4 @@
1
- /* v 1.0.22 */
1
+ /* v 1.0.23 */
2
2
  function getMessageEncoding(message) {
3
3
  return new TextEncoder().encode(message);
4
4
  }
@@ -61,7 +61,7 @@
61
61
  }
62
62
  return "";
63
63
  }
64
- async function decryptData(inData, decryptionKey) {
64
+ async function unmaskData(inData, decryptionKey) {
65
65
  var retVal = [];
66
66
  var enc = new TextEncoder();
67
67
  var [tmpPassword, salt, theIV] = decryptionKey.split("-");
package/index.min.js CHANGED
@@ -1 +1 @@
1
- function getMessageEncoding(e){return new TextEncoder().encode(e)}function getMessageDecoding(e){return new TextDecoder().decode(e)}function base64ToBytes(e){let t=atob(e),r=new Uint8Array(t.length);for(let n=0;n<t.length;n++)r[n]=t.charCodeAt(n);return r}function bytesToBase64(e){let t=String.fromCharCode(...e);return btoa(t)}async function deriveKeyFromPassword(e,t){let r=getMessageEncoding(e),n=await crypto.subtle.importKey("raw",r,"PBKDF2",!1,["deriveKey"]),a=await crypto.subtle.deriveKey({name:"PBKDF2",salt:t,iterations:1e5,hash:"SHA-256"},n,{name:"AES-GCM",length:256},!0,["encrypt","decrypt"]);return a}async function decryptThisData(e,t,r){try{let n=await crypto.subtle.decrypt({name:"AES-GCM",iv:r},t,e);return getMessageDecoding(new Uint8Array(n))}catch(a){return console.log("failed",t,e),"Failed to decrypt"}return""}async function decryptData(e,t){var r=[];new TextEncoder;var[n,a,s]=t.split("-");let o=n.slice(2);for(let i of e){var c={};for(let[l,d]of Object.entries(i))try{if("string"==typeof d&&d.includes("m$k_")){var y=base64ToBytes(i.secret_column.replace("m$k_",""));let u=await deriveKeyFromPassword(o,base64ToBytes(a));c[l]=await decryptThisData(y,u,base64ToBytes(s))}else c[l]=d}catch(f){c[l]="failed"}r.push(c)}return r}
1
+ function getMessageEncoding(e){return new TextEncoder().encode(e)}function getMessageDecoding(e){return new TextDecoder().decode(e)}function base64ToBytes(e){let t=atob(e),n=new Uint8Array(t.length);for(let r=0;r<t.length;r++)n[r]=t.charCodeAt(r);return n}function bytesToBase64(e){let t=String.fromCharCode(...e);return btoa(t)}async function deriveKeyFromPassword(e,t){let n=getMessageEncoding(e),r=await crypto.subtle.importKey("raw",n,"PBKDF2",!1,["deriveKey"]),a=await crypto.subtle.deriveKey({name:"PBKDF2",salt:t,iterations:1e5,hash:"SHA-256"},r,{name:"AES-GCM",length:256},!0,["encrypt","decrypt"]);return a}async function decryptThisData(e,t,n){try{let r=await crypto.subtle.decrypt({name:"AES-GCM",iv:n},t,e);return getMessageDecoding(new Uint8Array(r))}catch(a){return console.log("failed",t,e),"Failed to decrypt"}return""}async function unmaskData(e,t){var n=[];new TextEncoder;var[r,a,s]=t.split("-");let o=r.slice(2);for(let i of e){var c={};for(let[l,d]of Object.entries(i))try{if("string"==typeof d&&d.includes("m$k_")){var u=base64ToBytes(i.secret_column.replace("m$k_",""));let y=await deriveKeyFromPassword(o,base64ToBytes(a));c[l]=await decryptThisData(u,y,base64ToBytes(s))}else c[l]=d}catch(f){c[l]="failed"}n.push(c)}return n}
package/junk.js ADDED
@@ -0,0 +1,676 @@
1
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import {
4
+ CallToolRequestSchema,
5
+ ListToolsRequestSchema,
6
+ } from "@modelcontextprotocol/sdk/types.js";
7
+ import { DefaultAzureCredential } from "@azure/identity";
8
+ import { SqlManagementClient } from "@azure/arm-sql";
9
+ import sql from "mssql";
10
+ import * as fs from "fs";
11
+ import * as path from "path";
12
+
13
+ import { webcrypto } from 'crypto';
14
+ const subtle = webcrypto.subtle;
15
+
16
+ // Azure MCP Server
17
+ class AzureMCPServer {
18
+ private server: Server;
19
+ private credential: DefaultAzureCredential;
20
+ private subscriptionId: string;
21
+ private sqlPools: Map<string, sql.ConnectionPool>;
22
+
23
+ constructor() {
24
+ this.server = new Server(
25
+ {
26
+ name: "azure-mcp-server",
27
+ version: "1.0.0",
28
+ },
29
+ {
30
+ capabilities: {
31
+ tools: {},
32
+ },
33
+ }
34
+ );
35
+
36
+ // Get subscription ID from environment
37
+ this.subscriptionId = process.env.AZURE_SUBSCRIPTION_ID || "";
38
+ if (!this.subscriptionId) {
39
+ throw new Error("AZURE_SUBSCRIPTION_ID environment variable is required");
40
+ }
41
+
42
+ // Initialize Azure credential
43
+ this.credential = new DefaultAzureCredential();
44
+
45
+ // Initialize SQL connection pool cache
46
+ this.sqlPools = new Map();
47
+
48
+ this.setupHandlers();
49
+ }
50
+
51
+ private setupHandlers() {
52
+ // List available tools
53
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
54
+ tools: [
55
+ {
56
+ name: "list_resource_groups",
57
+ description: "List all resource groups in the Azure subscription",
58
+ inputSchema: {
59
+ type: "object",
60
+ properties: {},
61
+ },
62
+ },
63
+ {
64
+ name: "create_resource_group",
65
+ description: "Create a new resource group",
66
+ inputSchema: {
67
+ type: "object",
68
+ properties: {
69
+ name: { type: "string", description: "Resource group name" },
70
+ location: { type: "string", description: "Azure region (e.g., eastus, westus2)" },
71
+ },
72
+ required: ["name", "location"],
73
+ },
74
+ },
75
+ {
76
+ name: "list_storage_accounts",
77
+ description: "List all storage accounts in a resource group",
78
+ inputSchema: {
79
+ type: "object",
80
+ properties: {
81
+ resourceGroup: { type: "string", description: "Resource group name" },
82
+ },
83
+ required: ["resourceGroup"],
84
+ },
85
+ },
86
+ {
87
+ name: "create_storage_account",
88
+ description: "Create a new storage account",
89
+ inputSchema: {
90
+ type: "object",
91
+ properties: {
92
+ resourceGroup: { type: "string", description: "Resource group name" },
93
+ accountName: { type: "string", description: "Storage account name (lowercase, alphanumeric)" },
94
+ location: { type: "string", description: "Azure region" },
95
+ sku: { type: "string", description: "SKU name (e.g., Standard_LRS, Premium_LRS)", default: "Standard_LRS" },
96
+ },
97
+ required: ["resourceGroup", "accountName", "location"],
98
+ },
99
+ },
100
+ {
101
+ name: "list_vms",
102
+ description: "List all virtual machines in a resource group",
103
+ inputSchema: {
104
+ type: "object",
105
+ properties: {
106
+ resourceGroup: { type: "string", description: "Resource group name" },
107
+ },
108
+ required: ["resourceGroup"],
109
+ },
110
+ },
111
+ {
112
+ name: "get_vm_status",
113
+ description: "Get the power state of a virtual machine",
114
+ inputSchema: {
115
+ type: "object",
116
+ properties: {
117
+ resourceGroup: { type: "string", description: "Resource group name" },
118
+ vmName: { type: "string", description: "Virtual machine name" },
119
+ },
120
+ required: ["resourceGroup", "vmName"],
121
+ },
122
+ },
123
+ {
124
+ name: "list_blob_containers",
125
+ description: "List all blob containers in a storage account",
126
+ inputSchema: {
127
+ type: "object",
128
+ properties: {
129
+ accountName: { type: "string", description: "Storage account name" },
130
+ },
131
+ required: ["accountName"],
132
+ },
133
+ },
134
+ {
135
+ name: "upload_blob",
136
+ description: "Upload content to a blob in Azure Storage",
137
+ inputSchema: {
138
+ type: "object",
139
+ properties: {
140
+ accountName: { type: "string", description: "Storage account name" },
141
+ containerName: { type: "string", description: "Container name" },
142
+ blobName: { type: "string", description: "Blob name/path" },
143
+ content: { type: "string", description: "Content to upload" },
144
+ },
145
+ required: ["accountName", "containerName", "blobName", "content"],
146
+ },
147
+ },
148
+ {
149
+ name: "list_sql_servers",
150
+ description: "List all SQL servers in a resource group",
151
+ inputSchema: {
152
+ type: "object",
153
+ properties: {
154
+ resourceGroup: { type: "string", description: "Resource group name" },
155
+ },
156
+ required: ["resourceGroup"],
157
+ },
158
+ },
159
+ {
160
+ name: "list_databases",
161
+ description: "List all databases on a SQL server",
162
+ inputSchema: {
163
+ type: "object",
164
+ properties: {
165
+ resourceGroup: { type: "string", description: "Resource group name" },
166
+ serverName: { type: "string", description: "SQL server name" },
167
+ },
168
+ required: ["resourceGroup", "serverName"],
169
+ },
170
+ },
171
+ {
172
+ name: "execute_query",
173
+ description: "Execute a SQL query on an Azure SQL Database",
174
+ inputSchema: {
175
+ type: "object",
176
+ properties: {
177
+ server: { type: "string", description: "SQL server FQDN (e.g., myserver.database.windows.net)" },
178
+ database: { type: "string", description: "Database name" },
179
+ query: { type: "string", description: "SQL query to execute" },
180
+ username: { type: "string", description: "Username for audit logging (required)" },
181
+ password: { type: "string", description: "SQL password (optional, uses Azure AD if not provided)" },
182
+ },
183
+ required: ["server", "database", "query", "username"],
184
+ },
185
+ },
186
+ {
187
+ name: "execute_stored_procedure",
188
+ description: "Execute a stored procedure on an Azure SQL Database",
189
+ inputSchema: {
190
+ type: "object",
191
+ properties: {
192
+ server: { type: "string", description: "SQL server FQDN" },
193
+ database: { type: "string", description: "Database name" },
194
+ procedureName: { type: "string", description: "Stored procedure name" },
195
+ username: { type: "string", description: "Username for audit logging (required)" },
196
+ parameters: { type: "object", description: "Procedure parameters as key-value pairs" },
197
+ password: { type: "string", description: "SQL password (optional)" },
198
+ },
199
+ required: ["server", "database", "procedureName", "username"],
200
+ },
201
+ },
202
+ {
203
+ name: "get_database_info",
204
+ description: "Get detailed information about a specific database",
205
+ inputSchema: {
206
+ type: "object",
207
+ properties: {
208
+ resourceGroup: { type: "string", description: "Resource group name" },
209
+ serverName: { type: "string", description: "SQL server name" },
210
+ databaseName: { type: "string", description: "Database name" },
211
+ },
212
+ required: ["resourceGroup", "serverName", "databaseName"],
213
+ },
214
+ },
215
+ {
216
+ name: "get_version",
217
+ description: "Get the version of the Azure MCP Server",
218
+ inputSchema: {
219
+ type: "object",
220
+ properties: {},
221
+ },
222
+ },
223
+ ],
224
+ }));
225
+
226
+ // Handle tool calls
227
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
228
+ try {
229
+ switch (request.params.name) {
230
+ case "list_resource_groups":
231
+ return await this.listResourceGroups();
232
+
233
+ case "create_resource_group":
234
+ return await this.createResourceGroup(
235
+ request.params.arguments as { name: string; location: string }
236
+ );
237
+
238
+ case "list_storage_accounts":
239
+ return await this.listStorageAccounts(
240
+ request.params.arguments as { resourceGroup: string }
241
+ );
242
+
243
+ case "create_storage_account":
244
+ return await this.createStorageAccount(
245
+ request.params.arguments as { resourceGroup: string; accountName: string; location: string; sku?: string }
246
+ );
247
+
248
+ case "list_vms":
249
+ return await this.listVMs(
250
+ request.params.arguments as { resourceGroup: string }
251
+ );
252
+
253
+ case "get_vm_status":
254
+ return await this.getVMStatus(
255
+ request.params.arguments as { resourceGroup: string; vmName: string }
256
+ );
257
+
258
+ case "list_blob_containers":
259
+ return await this.listBlobContainers(
260
+ request.params.arguments as { accountName: string }
261
+ );
262
+
263
+ case "upload_blob":
264
+ return await this.uploadBlob(
265
+ request.params.arguments as { accountName: string; containerName: string; blobName: string; content: string }
266
+ );
267
+
268
+ case "list_sql_servers":
269
+ return await this.listSqlServers(
270
+ request.params.arguments as { resourceGroup: string }
271
+ );
272
+
273
+ case "list_databases":
274
+ return await this.listDatabases(
275
+ request.params.arguments as { resourceGroup: string; serverName: string }
276
+ );
277
+
278
+ case "execute_query":
279
+ return await this.executeQuery(
280
+ request.params.arguments as { server: string; database: string; query: string; username: string; password?: string }
281
+ );
282
+
283
+ case "execute_stored_procedure":
284
+ return await this.executeStoredProcedure(
285
+ request.params.arguments as { server: string; database: string; procedureName: string; username: string; parameters?: any; password?: string }
286
+ );
287
+
288
+ case "get_database_info":
289
+ return await this.getDatabaseInfo(
290
+ request.params.arguments as { resourceGroup: string; serverName: string; databaseName: string }
291
+ );
292
+
293
+ case "get_version":
294
+ return await this.getVersion();
295
+
296
+ default:
297
+ throw new Error(`Unknown tool: ${request.params.name}`);
298
+ }
299
+ } catch (error: any) {
300
+ return {
301
+ content: [
302
+ {
303
+ type: "text",
304
+ text: `Error: ${error.message}`,
305
+ },
306
+ ],
307
+ };
308
+ }
309
+ });
310
+ }
311
+
312
+ private async listSqlServers(args: { resourceGroup: string }) {
313
+ const client = new SqlManagementClient(this.credential, this.subscriptionId);
314
+ const servers = [];
315
+
316
+ for await (const server of client.servers.listByResourceGroup(args.resourceGroup)) {
317
+ servers.push({
318
+ name: server.name,
319
+ location: server.location,
320
+ fullyQualifiedDomainName: server.fullyQualifiedDomainName,
321
+ version: server.version,
322
+ administratorLogin: server.administratorLogin,
323
+ });
324
+ }
325
+
326
+ return {
327
+ content: [
328
+ {
329
+ type: "text",
330
+ text: JSON.stringify(servers, null, 2),
331
+ },
332
+ ],
333
+ };
334
+ }
335
+
336
+ private async listDatabases(args: { resourceGroup: string; serverName: string }) {
337
+ const client = new SqlManagementClient(this.credential, this.subscriptionId);
338
+ const databases = [];
339
+
340
+ for await (const db of client.databases.listByServer(args.resourceGroup, args.serverName)) {
341
+ databases.push({
342
+ name: db.name,
343
+ location: db.location,
344
+ status: db.status,
345
+ sku: db.sku,
346
+ maxSizeBytes: db.maxSizeBytes,
347
+ creationDate: db.creationDate,
348
+ });
349
+ }
350
+
351
+ return {
352
+ content: [
353
+ {
354
+ type: "text",
355
+ text: JSON.stringify(databases, null, 2),
356
+ },
357
+ ],
358
+ };
359
+ }
360
+
361
+ private async getDatabaseInfo(args: { resourceGroup: string; serverName: string; databaseName: string }) {
362
+ const client = new SqlManagementClient(this.credential, this.subscriptionId);
363
+
364
+ const database = await client.databases.get(
365
+ args.resourceGroup,
366
+ args.serverName,
367
+ args.databaseName
368
+ );
369
+
370
+ return {
371
+ content: [
372
+ {
373
+ type: "text",
374
+ text: JSON.stringify({
375
+ name: database.name,
376
+ location: database.location,
377
+ status: database.status,
378
+ sku: database.sku,
379
+ maxSizeBytes: database.maxSizeBytes,
380
+ collation: database.collation,
381
+ creationDate: database.creationDate,
382
+ earliestRestoreDate: database.earliestRestoreDate,
383
+ elasticPoolId: database.elasticPoolId,
384
+ kind: database.kind,
385
+ }, null, 2),
386
+ },
387
+ ],
388
+ };
389
+ }
390
+
391
+ private async getSqlPool(server: string, database: string, username: string, password?: string): Promise<sql.ConnectionPool> {
392
+ const poolKey = `${server}:${database}`;
393
+
394
+ // Return existing pool if available
395
+ if (this.sqlPools.has(poolKey)) {
396
+ const pool = this.sqlPools.get(poolKey)!;
397
+ if (pool.connected) {
398
+ return pool;
399
+ }
400
+ }
401
+
402
+ const DBusername = "pprappdevusermcp";
403
+ password = "ZuX?c5%+=6!c?}5z)n73"
404
+
405
+
406
+ // Create new connection pool
407
+ let config: sql.config;
408
+
409
+ // Use SQL auth if credentials provided, otherwise use Azure AD
410
+ if (DBusername && password) {
411
+ config = {
412
+ server: server,
413
+ database: database,
414
+ user: DBusername,
415
+ password: password,
416
+ options: {
417
+ encrypt: true,
418
+ trustServerCertificate: false,
419
+ },
420
+ pool: {
421
+ max: 10,
422
+ min: 0,
423
+ idleTimeoutMillis: 30000,
424
+ },
425
+ };
426
+ } else {
427
+ // Use Azure AD authentication with managed identity or DefaultAzureCredential
428
+ const token = await this.credential.getToken("https://database.windows.net/.default");
429
+ config = {
430
+ server: server,
431
+ database: database,
432
+ options: {
433
+ encrypt: true,
434
+ trustServerCertificate: false,
435
+ },
436
+ pool: {
437
+ max: 10,
438
+ min: 0,
439
+ idleTimeoutMillis: 30000,
440
+ },
441
+ authentication: {
442
+ type: 'azure-active-directory-access-token',
443
+ options: {
444
+ token: token.token,
445
+ },
446
+ } as any,
447
+ };
448
+ }
449
+
450
+ const pool = await sql.connect(config);
451
+ this.sqlPools.set(poolKey, pool);
452
+
453
+ return pool;
454
+ }
455
+
456
+ private async logRequest(queryString: string, server: string, username: string) {
457
+ const homeDir = process.env.USERPROFILE || process.env.HOME || '';
458
+ const logDir = path.join(homeDir, 'source', 'repos', 'mcp_server');
459
+
460
+ // Create directory if it doesn't exist
461
+ if (!fs.existsSync(logDir)) {
462
+ fs.mkdirSync(logDir, { recursive: true });
463
+ }
464
+
465
+ const logFile = path.join(logDir, 'sql_query_log.txt');
466
+ const logEntry = `[${new Date().toISOString()}] Server: ${server}\tUsername: ${username}\tQuery:\n ${queryString}\n`;
467
+ fs.appendFileSync(logFile, logEntry);
468
+
469
+ }
470
+
471
+ private getMessageEncoding(message: string): Uint8Array {
472
+ return new TextEncoder().encode(message);
473
+ }
474
+
475
+ private getMessageDecoding(message: Uint8Array): string {
476
+ return new TextDecoder().decode(message);
477
+ }
478
+
479
+ private bytesToBase64(bytes: Uint8Array): string {
480
+ const binary = String.fromCharCode(...bytes);
481
+ return btoa(binary);
482
+ }
483
+ private base64ToBytes(base64: string): Uint8Array {
484
+ const binary = atob(base64);
485
+ const bytes = new Uint8Array(binary.length);
486
+ for (let i = 0; i < binary.length; i++) {
487
+ bytes[i] = binary.charCodeAt(i);
488
+ }
489
+ return bytes;
490
+ }
491
+
492
+ private async deriveKeyFromPassword(password: string, salt: Uint8Array): Promise<CryptoKey> {
493
+ const pwUtf8 = this.getMessageEncoding(password);
494
+ // Use PBKDF2 for key derivation from a password
495
+
496
+ // importKey(format, keyData, algorithm, extractable, keyUsages)
497
+ const keyMaterial = await crypto.subtle.importKey(
498
+ 'raw',
499
+ pwUtf8 as BufferSource,
500
+ 'PBKDF2',
501
+ false,
502
+ ['deriveKey']
503
+ );
504
+
505
+ const derivedKey = await crypto.subtle.deriveKey(
506
+ {
507
+ name: 'PBKDF2',
508
+ salt: salt as BufferSource,
509
+ iterations: 100000, // High iterations make it more secure
510
+ hash: 'SHA-256',
511
+ },
512
+ keyMaterial,
513
+ { name: 'AES-GCM', length: 256 }, // Use AES-GCM for encryption
514
+ true, // Key can be extracted if needed
515
+ ['encrypt', 'decrypt']
516
+ );
517
+
518
+ return derivedKey;
519
+ }
520
+
521
+ private async encryptData(plaintext: string, key: CryptoKey, iv: BufferSource): Promise<{ ciphertext: string, iv: string }> {
522
+ const encoded = this.getMessageEncoding(plaintext);
523
+
524
+ const ciphertextBuffer = await crypto.subtle.encrypt(
525
+ { name: 'AES-GCM', iv},
526
+ key,
527
+ encoded as BufferSource
528
+ );
529
+ const cipherBase64 = this.bytesToBase64(new Uint8Array(ciphertextBuffer));
530
+ const ivBase64 = this.bytesToBase64(new Uint8Array(iv as ArrayBuffer));
531
+
532
+ return {
533
+ ciphertext: cipherBase64,
534
+ iv: ivBase64
535
+ };
536
+ }
537
+
538
+ private async findDataToEncrypt(theData: any[], secretKey: string, salt:Uint8Array, ivIn: BufferSource): Promise<any[]> {
539
+ const retVal: any[] = [];
540
+ const algorithm: string = 'SHA-256';
541
+
542
+ const server: string = "no server v1";
543
+ const username: string = "no username";
544
+
545
+ const encryptionKey = await this.deriveKeyFromPassword(secretKey, salt);
546
+
547
+ for (const curRow of theData) {
548
+ const retRow: any = {};
549
+
550
+ for (const [key, value] of Object.entries(curRow)) {
551
+ let newValue: string = <any>value;
552
+
553
+ if (typeof newValue === 'string' && newValue.startsWith("m$k_")) {
554
+ this.logRequest(`\t in encrypt -> encrypting ${JSON.stringify(newValue)}`, server, username);
555
+ var tmpValue: any = newValue.replace("m$k_", "");
556
+
557
+ const { ciphertext, iv } = await this.encryptData(tmpValue, encryptionKey, ivIn);
558
+ // newValue = "m$k_" + ciphertext + "-" + iv + "-" + this.bytesToBase64(salt) + "-" + this.bytesToBase64(ivIn as Uint8Array);
559
+ newValue = "m$k_" + ciphertext;
560
+ this.logRequest(`\tin encrypt -> result ${JSON.stringify(newValue)}`, server, username);
561
+ }
562
+
563
+ retRow[key] = newValue;
564
+ }
565
+
566
+ retVal.push(retRow);
567
+ }
568
+
569
+ return retVal;
570
+ }
571
+
572
+ private async executeQuery(args: { server: string; database: string; query: string; username: string; password?: string }) {
573
+ try {
574
+ const pool = await this.getSqlPool(args.server, args.database, args.username, args.password);
575
+
576
+ this.logRequest(args.query, args.server, args.username);
577
+
578
+ const result = await pool.request().query(args.query);
579
+ const resultCount = result.recordset ? result.recordset.length : 0;
580
+ this.logRequest(`\t-> Query returned ${JSON.stringify(result.recordset)} rows`, args.server, args.username);
581
+ const secretKey = this.bytesToBase64(crypto.getRandomValues(new Uint8Array(16)));
582
+ const salt = crypto.getRandomValues(new Uint8Array(16));
583
+ const ivIn = crypto.getRandomValues(new Uint8Array(16));
584
+
585
+ var retval: any = await this.findDataToEncrypt(result.recordset, secretKey, salt, ivIn);
586
+ const junkBits = new Date().getSeconds().toString(16).padStart(2, 'P');
587
+ const secretKey_modified = junkBits + secretKey;
588
+ this.logRequest(`\t-> encryption returned ${JSON.stringify(retval)}`, args.server, args.username);
589
+ return {
590
+ content: [
591
+ {
592
+ type: "text",
593
+ text: JSON.stringify({
594
+ rowsAffected: result.rowsAffected,
595
+ key: secretKey_modified + "-" + this.bytesToBase64(salt) + "-" + this.bytesToBase64(ivIn as Uint8Array),
596
+ recordset: retval,
597
+ }, null, 2),
598
+ },
599
+ ],
600
+ };
601
+ } catch (error: any) {
602
+ this.logRequest(`\t**** error occurred: ${error.message}`, args.server, args.username);
603
+ return {
604
+ content: [
605
+ {
606
+ type: "text",
607
+ text: `Query execution failed: ${error.message}`,
608
+ },
609
+ ],
610
+ };
611
+ }
612
+ }
613
+
614
+ private getVersion() {
615
+ return {
616
+ content: [
617
+ {
618
+ type: "text",
619
+ text: JSON.stringify({
620
+ version: "1.0.4",
621
+ name: "azure-mcp-server",
622
+ }, null, 2),
623
+ },
624
+ ],
625
+ };
626
+ }
627
+
628
+ private async executeStoredProcedure(args: { server: string; database: string; procedureName: string; username: string; parameters?: any; password?: string }) {
629
+ try {
630
+ const pool = await this.getSqlPool(args.server, args.database, args.username, args.password);
631
+ const request = pool.request();
632
+
633
+ // Add parameters if provided
634
+ if (args.parameters) {
635
+ for (const [key, value] of Object.entries(args.parameters)) {
636
+ request.input(key, value);
637
+ }
638
+ }
639
+
640
+ const result = await request.execute(args.procedureName);
641
+
642
+ return {
643
+ content: [
644
+ {
645
+ type: "text",
646
+ text: JSON.stringify({
647
+ rowsAffected: result.rowsAffected,
648
+ recordset: result.recordset,
649
+ recordsets: result.recordsets,
650
+ returnValue: result.returnValue,
651
+ }, null, 2),
652
+ },
653
+ ],
654
+ };
655
+ } catch (error: any) {
656
+ return {
657
+ content: [
658
+ {
659
+ type: "text",
660
+ text: `Stored procedure execution failed: ${error.message}`,
661
+ },
662
+ ],
663
+ };
664
+ }
665
+ }
666
+
667
+ async run() {
668
+ const transport = new StdioServerTransport();
669
+ await this.server.connect(transport);
670
+ console.error("Azure MCP Server running on stdio");
671
+ }
672
+ }
673
+
674
+ // Start the server
675
+ const server = new AzureMCPServer();
676
+ server.run().catch(console.error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudeunmask",
3
- "version": "1.0.22",
3
+ "version": "1.0.23",
4
4
  "description": "claude unmask test",
5
5
  "main": "index.js",
6
6
  "scripts": {