mssql-mcp 1.0.0

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 ADDED
@@ -0,0 +1,93 @@
1
+ # MS SQL Server MCP Server
2
+
3
+ Model Context Protocol (MCP) server for Microsoft SQL Server. Designed for use in IDEs like Claude Desktop, Cursor, Windsurf, and VS Code.
4
+
5
+ ## Features
6
+
7
+ - 🔗 **Database Connection Management**: Secure connection to MS SQL Server
8
+ - 📊 **SQL Query Execution**: Parameterized queries and DDL/DML operations
9
+ - 🗂️ **Schema Management**: Tables, views, stored procedures
10
+ - 📋 **Table Operations**: Structure inspection, data viewing, pagination
11
+ - ⚙️ **Stored Procedures**: Execute with parameters
12
+ - 🏢 **Database Listing**: All databases in the instance
13
+ - 🔒 **Security**: Environment variable support
14
+
15
+ ## IDE Configuration
16
+
17
+ This MCP server can be used in IDEs like Claude Desktop, Cursor, Windsurf, and VS Code.
18
+
19
+ ### Configuration Files
20
+
21
+ **For Claude Desktop**: `%APPDATA%\Claude\claude_desktop_config.json` (Windows) or `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)
22
+
23
+ **For VS Code-based IDEs**: `.vscode/mcp.json`
24
+
25
+ ### Basic Configuration
26
+
27
+ ```json
28
+ {
29
+ "mcpServers": {
30
+ "mssql": {
31
+ "command": "npx",
32
+ "args": ["-y", "mssql-mcp@latest"],
33
+ "env": {
34
+ "DB_SERVER": "your-server.com",
35
+ "DB_DATABASE": "your-database",
36
+ "DB_USER": "your-username",
37
+ "DB_PASSWORD": "your-password",
38
+ "DB_PORT": "1433",
39
+ "DB_TRUST_SERVER_CERTIFICATE": "true"
40
+ }
41
+ }
42
+ }
43
+ }
44
+ ```
45
+
46
+ > **Note**: Use `"servers"` instead of `"mcpServers"` in VS Code-based IDEs.
47
+
48
+ ### Platform Specific Settings
49
+
50
+ - **macOS/Linux**: Use the configuration above as is
51
+ - **Windows**: Use `"command": "cmd"` and `"args": ["/c", "npx", "-y", "mssql-mcp@latest"]`
52
+ - **WSL**: Use `"command": "wsl"` and `"args": ["npx", "-y", "mssql-mcp@latest"]`
53
+
54
+ ## Environment Variables
55
+
56
+ You can use the following environment variables:
57
+
58
+ - `DB_SERVER`: SQL Server address
59
+ - `DB_DATABASE`: Database name
60
+ - `DB_USER`: Username (leave empty for Windows Authentication)
61
+ - `DB_PASSWORD`: Password
62
+ - `DB_PORT`: Port number (default: 1433)
63
+ - `DB_TRUST_SERVER_CERTIFICATE`: SSL certificate trust (true/false)
64
+
65
+ ## Available Functions
66
+
67
+ This MCP server provides 9 database operations:
68
+
69
+ | Fonksiyon | Açıklama |
70
+ |-----------|----------|
71
+ | `connect_database` | SQL Server'a bağlantı kurar |
72
+ | `connection_status` | Bağlantı durumunu kontrol eder |
73
+ | `disconnect_database` | Bağlantıyı kapatır |
74
+ | `execute_query` | SQL sorgusu çalıştırır (SELECT, INSERT, UPDATE, DELETE) |
75
+ | `execute_procedure` | Stored procedure çalıştırır |
76
+ | `get_schema` | Veritabanı şemasını listeler (tablolar, views, procedures) |
77
+ | `describe_table` | Tablo yapısını detaylı gösterir |
78
+ | `list_databases` | Tüm veritabanlarını listeler |
79
+ | `get_table_data` | Tablo verilerini sayfalama ile getirir |
80
+
81
+ ## Güvenlik Notları
82
+
83
+ - Hassas bilgileri (şifreler) environment variable'lar ile yönetin
84
+ - Üretim ortamında güçlü şifreler kullanın
85
+ - SSL/TLS bağlantısı için sertifikaları doğrulayın
86
+ - SQL injection koruması için parametreli sorgular kullanın
87
+
88
+ ## GitHub Repository
89
+
90
+ Bu proje GitHub'da da mevcuttur:
91
+ - **Repository**: [BYMCS/mssql-mcp](https://github.com/BYMCS/mssql-mcp)
92
+ - **Issues**: Hata bildirimleri ve öneriler için
93
+ - **Releases**: Sürüm notları ve indirmeler
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,501 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import sql from "mssql";
5
+ import { z } from "zod";
6
+ import dotenv from "dotenv";
7
+ // Load environment variables
8
+ dotenv.config();
9
+ // Database connection configuration schema
10
+ const ConfigSchema = z.object({
11
+ server: z.string(),
12
+ database: z.string().optional(),
13
+ user: z.string().optional(),
14
+ password: z.string().optional(),
15
+ port: z.number().optional().default(1433),
16
+ trustServerCertificate: z.boolean().optional().default(true),
17
+ connectionTimeout: z.number().optional().default(30000),
18
+ requestTimeout: z.number().optional().default(30000),
19
+ });
20
+ class MSSQLMCPServer {
21
+ server;
22
+ pool = null;
23
+ config = null;
24
+ constructor() {
25
+ this.server = new McpServer({
26
+ name: "mssql-mcp-server",
27
+ version: "1.0.2",
28
+ });
29
+ this.setupTools();
30
+ this.setupResources();
31
+ }
32
+ setupTools() {
33
+ this.server.tool("connect_database", "Connect to MS SQL Server database", {
34
+ server: z.string().optional().describe("SQL Server instance name or IP address (uses DB_SERVER env var if not provided)"),
35
+ database: z.string().optional().describe("Database name (uses DB_DATABASE env var if not provided)"),
36
+ user: z.string().optional().describe("Username (uses DB_USER env var if not provided, leave empty for Windows auth)"),
37
+ password: z.string().optional().describe("Password (uses DB_PASSWORD env var if not provided)"),
38
+ port: z.number().optional().describe("Port number (uses DB_PORT env var or defaults to 1433)"),
39
+ trustServerCertificate: z.boolean().optional().describe("Trust server certificate (uses DB_TRUST_SERVER_CERTIFICATE env var or defaults to true)"),
40
+ }, async (args) => {
41
+ try {
42
+ // Use environment variables as defaults
43
+ const config = ConfigSchema.parse({
44
+ server: args.server || process.env.DB_SERVER,
45
+ database: args.database || process.env.DB_DATABASE,
46
+ user: args.user || process.env.DB_USER,
47
+ password: args.password || process.env.DB_PASSWORD,
48
+ port: args.port || (process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 1433),
49
+ trustServerCertificate: args.trustServerCertificate ?? (process.env.DB_TRUST_SERVER_CERTIFICATE === 'true'),
50
+ connectionTimeout: process.env.DB_CONNECTION_TIMEOUT ? parseInt(process.env.DB_CONNECTION_TIMEOUT) : 30000,
51
+ requestTimeout: process.env.DB_REQUEST_TIMEOUT ? parseInt(process.env.DB_REQUEST_TIMEOUT) : 30000,
52
+ });
53
+ if (!config.server) {
54
+ throw new Error("Server is required. Provide it as parameter or set DB_SERVER environment variable.");
55
+ }
56
+ await this.connect(config);
57
+ return {
58
+ content: [
59
+ {
60
+ type: "text",
61
+ text: `Successfully connected to SQL Server: ${config.server}${config.database ? ` (Database: ${config.database})` : ""}`,
62
+ },
63
+ ],
64
+ };
65
+ }
66
+ catch (error) {
67
+ return {
68
+ content: [
69
+ {
70
+ type: "text",
71
+ text: `Failed to connect: ${error instanceof Error ? error.message : String(error)}`,
72
+ },
73
+ ],
74
+ isError: true,
75
+ };
76
+ }
77
+ });
78
+ // Tool: Execute SQL query
79
+ this.server.tool("execute_query", "Execute a SQL query against the connected database", {
80
+ query: z.string().describe("SQL query to execute"),
81
+ parameters: z.record(z.any()).optional().describe("Query parameters (key-value pairs)"),
82
+ }, async ({ query, parameters }) => {
83
+ try {
84
+ if (!this.pool) {
85
+ throw new Error("No database connection. Please connect first using connect_database tool.");
86
+ }
87
+ const request = this.pool.request();
88
+ // Add parameters if provided
89
+ if (parameters) {
90
+ for (const [key, value] of Object.entries(parameters)) {
91
+ request.input(key, value);
92
+ }
93
+ }
94
+ const result = await request.query(query);
95
+ return {
96
+ content: [
97
+ {
98
+ type: "text",
99
+ text: JSON.stringify({
100
+ recordset: result.recordset,
101
+ rowsAffected: result.rowsAffected,
102
+ output: result.output,
103
+ }, null, 2),
104
+ },
105
+ ],
106
+ };
107
+ }
108
+ catch (error) {
109
+ return {
110
+ content: [
111
+ {
112
+ type: "text",
113
+ text: `Query execution failed: ${error instanceof Error ? error.message : String(error)}`,
114
+ },
115
+ ],
116
+ isError: true,
117
+ };
118
+ }
119
+ });
120
+ // Tool: Get database schema
121
+ this.server.tool("get_schema", "Get database schema information (tables, columns, etc.)", {
122
+ objectType: z.enum(["tables", "views", "procedures", "functions", "all"]).optional().default("tables"),
123
+ schemaName: z.string().optional().describe("Specific schema name to filter"),
124
+ }, async ({ objectType, schemaName }) => {
125
+ try {
126
+ if (!this.pool) {
127
+ throw new Error("No database connection. Please connect first.");
128
+ }
129
+ let query = "";
130
+ if (objectType === "tables" || objectType === "all") {
131
+ query += `
132
+ SELECT
133
+ TABLE_SCHEMA,
134
+ TABLE_NAME,
135
+ TABLE_TYPE,
136
+ 'table' as OBJECT_TYPE
137
+ FROM INFORMATION_SCHEMA.TABLES
138
+ ${schemaName ? `WHERE TABLE_SCHEMA = '${schemaName}'` : ""}
139
+ `;
140
+ }
141
+ if (objectType === "views" || objectType === "all") {
142
+ if (query)
143
+ query += " UNION ALL ";
144
+ query += `
145
+ SELECT
146
+ TABLE_SCHEMA,
147
+ TABLE_NAME,
148
+ 'VIEW' as TABLE_TYPE,
149
+ 'view' as OBJECT_TYPE
150
+ FROM INFORMATION_SCHEMA.VIEWS
151
+ ${schemaName ? `WHERE TABLE_SCHEMA = '${schemaName}'` : ""}
152
+ `;
153
+ }
154
+ if (objectType === "procedures" || objectType === "all") {
155
+ if (query)
156
+ query += " UNION ALL ";
157
+ query += `
158
+ SELECT
159
+ ROUTINE_SCHEMA as TABLE_SCHEMA,
160
+ ROUTINE_NAME as TABLE_NAME,
161
+ 'PROCEDURE' as TABLE_TYPE,
162
+ 'procedure' as OBJECT_TYPE
163
+ FROM INFORMATION_SCHEMA.ROUTINES
164
+ WHERE ROUTINE_TYPE = 'PROCEDURE'
165
+ ${schemaName ? `AND ROUTINE_SCHEMA = '${schemaName}'` : ""}
166
+ `;
167
+ }
168
+ if (objectType === "functions" || objectType === "all") {
169
+ if (query)
170
+ query += " UNION ALL ";
171
+ query += `
172
+ SELECT
173
+ ROUTINE_SCHEMA as TABLE_SCHEMA,
174
+ ROUTINE_NAME as TABLE_NAME,
175
+ 'FUNCTION' as TABLE_TYPE,
176
+ 'function' as OBJECT_TYPE
177
+ FROM INFORMATION_SCHEMA.ROUTINES
178
+ WHERE ROUTINE_TYPE = 'FUNCTION'
179
+ ${schemaName ? `AND ROUTINE_SCHEMA = '${schemaName}'` : ""}
180
+ `;
181
+ }
182
+ query += " ORDER BY TABLE_SCHEMA, TABLE_NAME";
183
+ const result = await this.pool.request().query(query);
184
+ return {
185
+ content: [
186
+ {
187
+ type: "text",
188
+ text: JSON.stringify(result.recordset, null, 2),
189
+ },
190
+ ],
191
+ };
192
+ }
193
+ catch (error) {
194
+ return {
195
+ content: [
196
+ {
197
+ type: "text",
198
+ text: `Schema query failed: ${error instanceof Error ? error.message : String(error)}`,
199
+ },
200
+ ],
201
+ isError: true,
202
+ };
203
+ }
204
+ });
205
+ // Tool: Get table structure
206
+ this.server.tool("describe_table", "Get detailed structure of a specific table", {
207
+ tableName: z.string().describe("Name of the table"),
208
+ schemaName: z.string().optional().default("dbo").describe("Schema name"),
209
+ }, async ({ tableName, schemaName }) => {
210
+ try {
211
+ if (!this.pool) {
212
+ throw new Error("No database connection. Please connect first.");
213
+ }
214
+ const query = `
215
+ SELECT
216
+ COLUMN_NAME,
217
+ DATA_TYPE,
218
+ CHARACTER_MAXIMUM_LENGTH,
219
+ NUMERIC_PRECISION,
220
+ NUMERIC_SCALE,
221
+ IS_NULLABLE,
222
+ COLUMN_DEFAULT,
223
+ ORDINAL_POSITION
224
+ FROM INFORMATION_SCHEMA.COLUMNS
225
+ WHERE TABLE_NAME = @tableName
226
+ AND TABLE_SCHEMA = @schemaName
227
+ ORDER BY ORDINAL_POSITION
228
+ `;
229
+ const result = await this.pool.request()
230
+ .input('tableName', sql.VarChar, tableName)
231
+ .input('schemaName', sql.VarChar, schemaName)
232
+ .query(query);
233
+ return {
234
+ content: [
235
+ {
236
+ type: "text",
237
+ text: JSON.stringify(result.recordset, null, 2),
238
+ },
239
+ ],
240
+ };
241
+ }
242
+ catch (error) {
243
+ return {
244
+ content: [
245
+ {
246
+ type: "text",
247
+ text: `Table description failed: ${error instanceof Error ? error.message : String(error)}`,
248
+ },
249
+ ],
250
+ isError: true,
251
+ };
252
+ }
253
+ });
254
+ // Tool: Get connection status
255
+ this.server.tool("connection_status", "Check current database connection status", {}, async () => {
256
+ const isConnected = this.pool?.connected || false;
257
+ const status = {
258
+ connected: isConnected,
259
+ server: this.config?.server || "Not configured",
260
+ database: this.config?.database || "Not specified",
261
+ };
262
+ return {
263
+ content: [
264
+ {
265
+ type: "text",
266
+ text: JSON.stringify(status, null, 2),
267
+ },
268
+ ],
269
+ };
270
+ });
271
+ // Tool: Disconnect from database
272
+ this.server.tool("disconnect_database", "Disconnect from the current database", {}, async () => {
273
+ try {
274
+ if (this.pool) {
275
+ await this.pool.close();
276
+ this.pool = null;
277
+ this.config = null;
278
+ }
279
+ return {
280
+ content: [
281
+ {
282
+ type: "text",
283
+ text: "Successfully disconnected from database",
284
+ },
285
+ ],
286
+ };
287
+ }
288
+ catch (error) {
289
+ return {
290
+ content: [
291
+ {
292
+ type: "text",
293
+ text: `Disconnect failed: ${error instanceof Error ? error.message : String(error)}`,
294
+ },
295
+ ],
296
+ isError: true,
297
+ };
298
+ }
299
+ });
300
+ // Tool: Get table data with pagination
301
+ this.server.tool("get_table_data", "Get data from a specific table with optional filtering and pagination", {
302
+ tableName: z.string().describe("Name of the table"),
303
+ schemaName: z.string().optional().default("dbo").describe("Schema name"),
304
+ limit: z.number().optional().default(100).describe("Maximum number of rows to return"),
305
+ offset: z.number().optional().default(0).describe("Number of rows to skip"),
306
+ whereClause: z.string().optional().describe("WHERE clause (without the WHERE keyword)"),
307
+ orderBy: z.string().optional().describe("ORDER BY clause (without the ORDER BY keyword)"),
308
+ }, async ({ tableName, schemaName, limit, offset, whereClause, orderBy }) => {
309
+ try {
310
+ if (!this.pool) {
311
+ throw new Error("No database connection. Please connect first.");
312
+ }
313
+ let query = `SELECT * FROM [${schemaName}].[${tableName}]`;
314
+ if (whereClause) {
315
+ query += ` WHERE ${whereClause}`;
316
+ }
317
+ if (orderBy) {
318
+ query += ` ORDER BY ${orderBy}`;
319
+ }
320
+ else {
321
+ // Default ordering for pagination
322
+ query += ` ORDER BY (SELECT NULL)`;
323
+ }
324
+ query += ` OFFSET ${offset} ROWS FETCH NEXT ${limit} ROWS ONLY`;
325
+ const result = await this.pool.request().query(query);
326
+ return {
327
+ content: [
328
+ {
329
+ type: "text",
330
+ text: JSON.stringify({
331
+ data: result.recordset,
332
+ rowCount: result.recordset.length,
333
+ offset: offset,
334
+ limit: limit,
335
+ }, null, 2),
336
+ },
337
+ ],
338
+ };
339
+ }
340
+ catch (error) {
341
+ return {
342
+ content: [
343
+ {
344
+ type: "text",
345
+ text: `Get table data failed: ${error instanceof Error ? error.message : String(error)}`,
346
+ },
347
+ ],
348
+ isError: true,
349
+ };
350
+ }
351
+ });
352
+ // Tool: Execute stored procedure
353
+ this.server.tool("execute_procedure", "Execute a stored procedure with parameters", {
354
+ procedureName: z.string().describe("Name of the stored procedure"),
355
+ schemaName: z.string().optional().default("dbo").describe("Schema name"),
356
+ parameters: z.record(z.any()).optional().describe("Procedure parameters (key-value pairs)"),
357
+ }, async ({ procedureName, schemaName, parameters }) => {
358
+ try {
359
+ if (!this.pool) {
360
+ throw new Error("No database connection. Please connect first.");
361
+ }
362
+ const request = this.pool.request();
363
+ // Add parameters if provided
364
+ if (parameters) {
365
+ for (const [key, value] of Object.entries(parameters)) {
366
+ request.input(key, value);
367
+ }
368
+ }
369
+ const result = await request.execute(`[${schemaName}].[${procedureName}]`);
370
+ return {
371
+ content: [
372
+ {
373
+ type: "text",
374
+ text: JSON.stringify({
375
+ recordsets: result.recordsets,
376
+ rowsAffected: result.rowsAffected,
377
+ output: result.output,
378
+ returnValue: result.returnValue,
379
+ }, null, 2),
380
+ },
381
+ ],
382
+ };
383
+ }
384
+ catch (error) {
385
+ return {
386
+ content: [
387
+ {
388
+ type: "text",
389
+ text: `Procedure execution failed: ${error instanceof Error ? error.message : String(error)}`,
390
+ },
391
+ ],
392
+ isError: true,
393
+ };
394
+ }
395
+ });
396
+ // Tool: Get database list
397
+ this.server.tool("list_databases", "List all databases on the connected SQL Server instance", {}, async () => {
398
+ try {
399
+ if (!this.pool) {
400
+ throw new Error("No database connection. Please connect first.");
401
+ }
402
+ const query = `
403
+ SELECT
404
+ name,
405
+ database_id,
406
+ create_date,
407
+ collation_name,
408
+ state_desc,
409
+ user_access_desc,
410
+ is_read_only,
411
+ is_auto_close_on,
412
+ is_auto_shrink_on,
413
+ recovery_model_desc
414
+ FROM sys.databases
415
+ ORDER BY name
416
+ `;
417
+ const result = await this.pool.request().query(query);
418
+ return {
419
+ content: [
420
+ {
421
+ type: "text",
422
+ text: JSON.stringify(result.recordset, null, 2),
423
+ },
424
+ ],
425
+ };
426
+ }
427
+ catch (error) {
428
+ return {
429
+ content: [
430
+ {
431
+ type: "text",
432
+ text: `List databases failed: ${error instanceof Error ? error.message : String(error)}`,
433
+ },
434
+ ],
435
+ isError: true,
436
+ };
437
+ }
438
+ });
439
+ }
440
+ setupResources() {
441
+ // Resource: Current connection info
442
+ this.server.resource("connection-info", "mssql://connection/info", async () => {
443
+ const info = {
444
+ connected: this.pool?.connected || false,
445
+ config: this.config ? {
446
+ server: this.config.server,
447
+ database: this.config.database,
448
+ port: this.config.port,
449
+ } : null,
450
+ };
451
+ return {
452
+ contents: [
453
+ {
454
+ uri: "mssql://connection/info",
455
+ text: JSON.stringify(info, null, 2),
456
+ mimeType: "application/json",
457
+ },
458
+ ],
459
+ };
460
+ });
461
+ }
462
+ async connect(config) {
463
+ // Close existing connection if any
464
+ if (this.pool) {
465
+ await this.pool.close();
466
+ }
467
+ // Create new connection pool
468
+ this.pool = new sql.ConnectionPool({
469
+ server: config.server,
470
+ database: config.database,
471
+ user: config.user,
472
+ password: config.password,
473
+ port: config.port,
474
+ options: {
475
+ trustServerCertificate: config.trustServerCertificate,
476
+ enableArithAbort: true,
477
+ },
478
+ connectionTimeout: config.connectionTimeout,
479
+ requestTimeout: config.requestTimeout,
480
+ });
481
+ await this.pool.connect();
482
+ this.config = config;
483
+ }
484
+ async run() {
485
+ const transport = new StdioServerTransport();
486
+ await this.server.connect(transport);
487
+ // Handle cleanup on exit
488
+ process.on('SIGINT', async () => {
489
+ if (this.pool) {
490
+ await this.pool.close();
491
+ }
492
+ process.exit(0);
493
+ });
494
+ }
495
+ }
496
+ // Start the server
497
+ const server = new MSSQLMCPServer();
498
+ server.run().catch((error) => {
499
+ console.error("Server failed to start:", error);
500
+ process.exit(1);
501
+ });
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "mssql-mcp",
3
+ "version": "1.0.0",
4
+ "description": "MCP Server for MS SQL Server integration with Claude Desktop, Cursor, Windsurf and VS Code",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "mssql-mcp-server": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist/**/*",
12
+ "README.md",
13
+ "package.json"
14
+ ],
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/BYMCS/mssql-mcp.git"
18
+ },
19
+ "homepage": "https://github.com/BYMCS/mssql-mcp#readme",
20
+ "bugs": {
21
+ "url": "https://github.com/BYMCS/mssql-mcp/issues"
22
+ },
23
+ "engines": {
24
+ "node": ">=18.0.0"
25
+ },
26
+ "scripts": {
27
+ "build": "tsc",
28
+ "dev": "tsc --watch",
29
+ "start": "node dist/index.js",
30
+ "clean": "rimraf dist",
31
+ "prepublishOnly": "npm run clean && npm run build",
32
+ "test": "echo \"No tests specified\" && exit 0"
33
+ },
34
+ "keywords": [
35
+ "mcp",
36
+ "mssql",
37
+ "sql-server",
38
+ "database",
39
+ "claude",
40
+ "cursor",
41
+ "windsurf",
42
+ "vscode",
43
+ "model-context-protocol"
44
+ ],
45
+ "author": "BYMCS <hello@bymcs.com>",
46
+ "license": "MIT",
47
+ "dependencies": {
48
+ "@modelcontextprotocol/sdk": "^1.12.1",
49
+ "mssql": "^11.0.1",
50
+ "zod": "^3.22.4",
51
+ "dotenv": "^16.3.1"
52
+ },
53
+ "devDependencies": {
54
+ "@types/node": "^20.0.0",
55
+ "@types/mssql": "^9.1.5",
56
+ "typescript": "^5.3.0",
57
+ "rimraf": "^5.0.0"
58
+ }
59
+ }