mssql-mcp 2.0.2 → 2.1.1

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.
Files changed (3) hide show
  1. package/README.md +83 -36
  2. package/dist/index.js +198 -434
  3. package/package.json +4 -4
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # MS SQL Server MCP Server v2.0.2
1
+ # MS SQL Server MCP Server v2.1.1
2
2
 
3
- 🚀 **Smart Trust-Based Model Context Protocol (MCP) server** for Microsoft SQL Server with intelligent auto-connection and AI-friendly design.
3
+ 🚀 **Model Context Protocol (MCP) server** for Microsoft SQL Server - compatible with Claude Desktop, Cursor, Windsurf and VS Code.
4
4
 
5
5
  ## 🚀 Quick Start
6
6
 
@@ -24,6 +24,7 @@ npm install -g mssql-mcp
24
24
  "DB_DATABASE": "your-database",
25
25
  "DB_USER": "your-username",
26
26
  "DB_PASSWORD": "your-password",
27
+ "DB_ENCRYPT": "true",
27
28
  "DB_TRUST_SERVER_CERTIFICATE": "true"
28
29
  }
29
30
  }
@@ -43,6 +44,7 @@ npm install -g mssql-mcp
43
44
  "DB_DATABASE": "your-database",
44
45
  "DB_USER": "your-username",
45
46
  "DB_PASSWORD": "your-password",
47
+ "DB_ENCRYPT": "true",
46
48
  "DB_TRUST_SERVER_CERTIFICATE": "true"
47
49
  }
48
50
  }
@@ -50,63 +52,108 @@ npm install -g mssql-mcp
50
52
  }
51
53
  ```
52
54
 
53
- > Replace with your actual database credentials. Server auto-connects using these.
55
+ > Replace with your actual database credentials.
54
56
 
55
57
  ## 🛠️ Available Tools
56
58
 
57
59
  | Tool | Description |
58
60
  |------|-------------|
61
+ | `connect_database` | Connect to database using environment variables |
62
+ | `disconnect_database` | Close current database connection |
63
+ | `connection_status` | Check connection state with pool info |
59
64
  | `execute_query` | Execute any SQL query with parameters |
60
65
  | `get_schema` | List database objects (tables, views, procedures) |
61
66
  | `describe_table` | Get detailed table structure |
62
67
  | `get_table_data` | Retrieve data with pagination |
63
68
  | `execute_procedure` | Execute stored procedures |
64
69
  | `list_databases` | List all databases |
65
- | `connection_status` | Check connection state |
66
- | `connect_database` | Manual connection (rarely needed) |
67
- | `disconnect_database` | Close connection |
68
- | `clear_cache` | Clear query cache |
69
-
70
- All tools auto-connect using environment variables.
71
70
 
72
71
  ## 🔧 Environment Variables
73
72
 
74
- | Variable | Required | Default |
75
- |----------|----------|---------|
76
- | `DB_SERVER` | ✅ | - |
77
- | `DB_DATABASE` | | - |
78
- | `DB_USER` | | - |
79
- | `DB_PASSWORD` | | - |
80
- | `DB_PORT` | ❌ | 1433 |
81
- | `DB_TRUST_SERVER_CERTIFICATE` | ❌ | true |
82
- | `DB_CONNECTION_TIMEOUT` | ❌ | 30000 |
83
- | `DB_REQUEST_TIMEOUT` | ❌ | 30000 |
84
-
85
- ## 🛡️ Security
86
-
87
- **✅ Supported:** All database operations (SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP)
73
+ | Variable | Required | Default | Description |
74
+ |----------|----------|---------|-------------|
75
+ | `DB_SERVER` | ✅ | - | SQL Server hostname |
76
+ | `DB_DATABASE` | | - | Database name |
77
+ | `DB_USER` | | - | Username |
78
+ | `DB_PASSWORD` | | - | Password |
79
+ | `DB_PORT` | ❌ | 1433 | SQL Server port |
80
+ | `DB_ENCRYPT` | ❌ | true | Enable TLS encryption (required for Azure SQL) |
81
+ | `DB_TRUST_SERVER_CERTIFICATE` | ❌ | false | Trust self-signed certificates |
82
+ | `DB_CONNECTION_TIMEOUT` | ❌ | 30000 | Connection timeout (ms) |
83
+ | `DB_REQUEST_TIMEOUT` | ❌ | 30000 | Request timeout (ms) |
84
+
85
+ ### Azure SQL Configuration
86
+ For Azure SQL Database, use these settings:
87
+ ```json
88
+ {
89
+ "DB_ENCRYPT": "true",
90
+ "DB_TRUST_SERVER_CERTIFICATE": "false"
91
+ }
92
+ ```
88
93
 
89
- **🚨 Blocked:** Server-level operations only (SHUTDOWN, XP_CMDSHELL, RECONFIGURE)
94
+ ### Local SQL Server (Self-signed cert)
95
+ For local development with self-signed certificates:
96
+ ```json
97
+ {
98
+ "DB_ENCRYPT": "true",
99
+ "DB_TRUST_SERVER_CERTIFICATE": "true"
100
+ }
101
+ ```
90
102
 
91
103
  ## 🏆 Features
92
104
 
93
- - ✅ **Auto-Connection**: Environment-based, no manual steps
105
+ - ✅ **MCP SDK 1.25.1**: Latest Model Context Protocol SDK
106
+ - ✅ **Azure SQL Compatible**: TLS encryption enabled by default
94
107
  - ✅ **Complete SQL Support**: All database operations
95
- - ✅ **No Rate Limiting**: Natural workflow
96
- - ✅ **Query Caching**: 5-minute TTL for SELECT queries
108
+ - ✅ **Parameterized Queries**: SQL injection protection
109
+ - ✅ **Connection Pooling**: Efficient resource management
97
110
  - ✅ **Performance Monitoring**: Execution time tracking
98
- - ✅ **Latest MCP SDK**: v1.20.2 with 2025 protocol
111
+
112
+ ## 📋 Usage Examples
113
+
114
+ ### Connect to Database
115
+ ```
116
+ Use the connect_database tool to establish a connection.
117
+ ```
118
+
119
+ ### Execute a Query
120
+ ```sql
121
+ SELECT TOP 10 * FROM Customers WHERE Country = @country
122
+ -- With parameters: { "country": "USA" }
123
+ ```
124
+
125
+ ### Get Table Schema
126
+ ```
127
+ Use describe_table with tableName: "Customers" to see column details.
128
+ ```
99
129
 
100
130
  ## 🔍 Troubleshooting
101
131
 
102
- **❌ Auto-connection failed**
103
- - Set all required environment variables
104
- - Verify server accessibility and credentials
105
- - Check network connectivity
132
+ **❌ Connection failed**
133
+ - Verify all required environment variables are set
134
+ - Check server accessibility and credentials
135
+ - Ensure network connectivity to SQL Server
136
+
137
+ **❌ SSL/Certificate errors**
138
+ - For Azure SQL: Set `DB_ENCRYPT=true` (default)
139
+ - For self-signed certs: Set `DB_TRUST_SERVER_CERTIFICATE=true`
140
+ - For local dev without encryption: Set `DB_ENCRYPT=false`
141
+
142
+ ## 📋 Version History
143
+
144
+ ### v2.1.1 - Latest
145
+ - ✅ Added `DB_ENCRYPT` environment variable (Issue #1)
146
+ - ✅ Azure SQL Database compatibility improved
147
+ - ✅ Encryption enabled by default (`DB_ENCRYPT=true`)
148
+ - ✅ Fixed `DB_TRUST_SERVER_CERTIFICATE` default to `false`
149
+
150
+ ### v2.1.0
151
+ - ✅ Updated to MCP SDK 1.25.1
152
+ - ✅ Migrated to `registerTool()` / `registerResource()` API
153
+ - ✅ Added tool titles for better UI display
106
154
 
107
- **❌ SQL Security Alert**
108
- - Only server operations are blocked
109
- - Database operations should work normally
155
+ ### v2.0.3
156
+ - Documentation improvements
110
157
 
111
158
  ## 📄 License
112
159
 
@@ -119,4 +166,4 @@ MIT License
119
166
 
120
167
  ---
121
168
 
122
- **🎉 v2.0.2: Smart auto-connection with complete SQL support**
169
+ **🎉 v2.1.1: Azure SQL compatibility with DB_ENCRYPT support**
package/dist/index.js CHANGED
@@ -13,156 +13,33 @@ const ConfigSchema = z.object({
13
13
  user: z.string().optional(),
14
14
  password: z.string().optional(),
15
15
  port: z.number().int().min(1).max(65535).optional().default(1433),
16
- trustServerCertificate: z.boolean().optional().default(true),
16
+ encrypt: z.boolean().optional().default(true),
17
+ trustServerCertificate: z.boolean().optional().default(false),
17
18
  connectionTimeout: z.number().int().min(1000).max(60000).optional().default(30000),
18
19
  requestTimeout: z.number().int().min(1000).max(300000).optional().default(30000),
19
20
  });
20
- // Enhanced error class for better error handling with MCP compliance
21
- class MCPServerError extends Error {
22
- code;
23
- details;
24
- category;
25
- constructor(message, code, details, category = 'SYSTEM') {
26
- super(message);
27
- this.code = code;
28
- this.details = details;
29
- this.category = category;
30
- this.name = 'MCPServerError';
31
- }
32
- toCallToolResult() {
33
- return {
34
- content: [{
35
- type: "text",
36
- text: `Error: ${this.message} (Code: ${this.code})`
37
- }],
38
- isError: true,
39
- _meta: {
40
- errorCategory: this.category,
41
- errorCode: this.code,
42
- timestamp: new Date().toISOString(),
43
- details: this.details
44
- }
45
- };
46
- }
47
- }
48
- // Query result cache for performance optimization
49
- class QueryCache {
50
- cache = new Map();
51
- defaultTTL = 300000; // 5 minutes
52
- set(key, data, ttl = this.defaultTTL) {
53
- this.cache.set(key, { data, timestamp: Date.now(), ttl });
54
- }
55
- get(key) {
56
- const item = this.cache.get(key);
57
- if (!item)
58
- return null;
59
- if (Date.now() - item.timestamp > item.ttl) {
60
- this.cache.delete(key);
61
- return null;
62
- }
63
- return item.data;
64
- }
65
- clear() {
66
- this.cache.clear();
67
- }
68
- cleanup() {
69
- const now = Date.now();
70
- for (const [key, item] of this.cache.entries()) {
71
- if (now - item.timestamp > item.ttl) {
72
- this.cache.delete(key);
73
- }
74
- }
75
- }
76
- }
77
- // No rate limiting - trust-based approach
78
- class RateLimiter {
79
- constructor() {
80
- // Silent - no console output for MCP protocol
81
- }
82
- checkLimit(clientId, operation) {
83
- // Always allow - user has provided credentials and is trusted
84
- return true;
85
- }
86
- }
87
21
  class MSSQLMCPServer {
88
22
  server;
89
23
  pool = null;
90
24
  config = null;
91
- queryCache = new QueryCache();
92
- rateLimiter = new RateLimiter();
93
- clientId = `client_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
94
25
  constructor() {
95
26
  this.server = new McpServer({
96
27
  name: "mssql-mcp-server",
97
- version: "2.0.2",
98
- instructions: "🚀 UNRESTRICTED SQL SERVER MCP SERVER v2.0.2 - TRUST-BASED!\n\n✨ FOR AI ASSISTANTS: COMPLETE FREEDOM!\n• All SQL operations allowed (SELECT, INSERT, UPDATE, DELETE, DROP, CREATE, etc.)\n• No rate limiting - unlimited operations\n• Auto-connects automatically with environment variables\n• Just use any tool directly (execute_query, get_schema, etc.)\n\n🔧 SETUP: Set DB_SERVER, DB_DATABASE, DB_USER, DB_PASSWORD environment variables\n\n🛡️ MINIMAL SECURITY: Only blocks server-level operations (SHUTDOWN, XP_CMDSHELL)\n⚡ FEATURES: Query caching, performance monitoring, dry-run validation",
28
+ version: "2.1.1",
99
29
  });
100
30
  this.setupTools();
101
31
  this.setupResources();
102
- // Set up periodic cache cleanup (every 5 minutes)
103
- setInterval(() => {
104
- this.queryCache.cleanup();
105
- }, 300000);
106
- }
107
- // Enhanced error handling method with MCP compliance
108
- handleToolError(error, toolName) {
109
- if (error instanceof MCPServerError) {
110
- console.error(`MCP Error [${error.code}] in ${toolName}: ${error.message}`, error.details);
111
- return error.toCallToolResult();
112
- }
113
- const errorMessage = error instanceof Error ? error.message : String(error);
114
- console.error(`Tool error in ${toolName}:`, errorMessage);
115
- return {
116
- content: [{
117
- type: "text",
118
- text: `Error: ${errorMessage}`
119
- }],
120
- isError: true,
121
- _meta: {
122
- errorCategory: 'EXECUTION',
123
- toolName,
124
- timestamp: new Date().toISOString()
125
- }
126
- };
127
- }
128
- // Helper method to generate cache keys
129
- generateCacheKey(operation, params) {
130
- return `${operation}_${JSON.stringify(params)}`;
131
- }
132
- // Trust-based SQL validation - only block truly dangerous system operations
133
- validateSQLSecurity(query, context = { operation: 'unknown' }) {
134
- // User has already provided database credentials and connection
135
- // Only block operations that could compromise the database server itself
136
- const criticalSystemPatterns = [
137
- { pattern: /\b(SHUTDOWN|KILL)\b/i, category: 'SERVER_CONTROL' },
138
- { pattern: /\b(XP_CMDSHELL|SP_OACREATE|SP_OAMETHOD)\b/i, category: 'SYSTEM_EXEC' },
139
- { pattern: /\b(RECONFIGURE|DISK\s+INIT)\b/i, category: 'SERVER_CONFIG' }
140
- ];
141
- for (const { pattern, category } of criticalSystemPatterns) {
142
- if (pattern.test(query)) {
143
- throw new MCPServerError(`System-level operation not allowed: ${category}`, "SYSTEM_OPERATION_BLOCKED", {
144
- pattern: pattern.source,
145
- category,
146
- query: query.substring(0, 100) + (query.length > 100 ? '...' : ''),
147
- context,
148
- note: "This operation could affect the database server itself"
149
- }, 'SECURITY');
150
- }
151
- }
152
32
  }
153
33
  setupTools() {
154
- // Tool: Connect to database with enhanced security validation and MCP annotations
155
- this.server.tool("connect_database", "Connect to MS SQL Server database with security validation using environment variables", {}, {
156
- title: "Connect to Database",
157
- description: "Establishes secure connection to MS SQL Server using environment variables only",
158
- annotations: {
159
- destructiveHint: false,
160
- idempotentHint: true,
161
- readOnlyHint: true
162
- }
163
- }, async (extra) => {
34
+ // Tool: Connect to database with enhanced security validation (only uses environment variables)
35
+ this.server.registerTool("connect_database", {
36
+ title: "Connect Database",
37
+ description: "Connect to MS SQL Server database with security validation (uses only environment variables for security)",
38
+ inputSchema: {
39
+ // No parameters - only environment variables will be used for security
40
+ },
41
+ }, async () => {
164
42
  try {
165
- // No rate limiting - user is trusted
166
43
  // SECURITY: Only use environment variables, ignore all user parameters
167
44
  const config = ConfigSchema.parse({
168
45
  server: process.env.DB_SERVER,
@@ -170,129 +47,53 @@ class MSSQLMCPServer {
170
47
  user: process.env.DB_USER,
171
48
  password: process.env.DB_PASSWORD,
172
49
  port: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 1433,
50
+ encrypt: process.env.DB_ENCRYPT !== 'false', // Default true for Azure SQL compatibility
173
51
  trustServerCertificate: process.env.DB_TRUST_SERVER_CERTIFICATE === 'true',
174
52
  connectionTimeout: process.env.DB_CONNECTION_TIMEOUT ? parseInt(process.env.DB_CONNECTION_TIMEOUT) : 30000,
175
53
  requestTimeout: process.env.DB_REQUEST_TIMEOUT ? parseInt(process.env.DB_REQUEST_TIMEOUT) : 30000,
176
54
  });
177
55
  if (!config.server) {
178
- throw new MCPServerError("Server is required. Set DB_SERVER environment variable.", "SERVER_REQUIRED", undefined, 'VALIDATION');
56
+ throw new Error("Server is required. Provide it as parameter or set DB_SERVER environment variable.");
179
57
  }
180
- const startTime = Date.now();
181
58
  await this.connect(config);
182
- const connectionTime = Date.now() - startTime;
183
59
  return {
184
- content: [{
60
+ content: [
61
+ {
185
62
  type: "text",
186
- text: `✅ Successfully connected to SQL Server: ${config.server}${config.database ? ` (Database: ${config.database})` : ""} in ${connectionTime}ms`
187
- }],
188
- _meta: {
189
- connectionTime: `${connectionTime}ms`,
190
- server: config.server,
191
- database: config.database,
192
- port: config.port,
193
- sslEnabled: !config.trustServerCertificate,
194
- timestamp: new Date().toISOString()
195
- }
63
+ text: `✅ Successfully connected to SQL Server: ${config.server}${config.database ? ` (Database: ${config.database})` : ""}`,
64
+ },
65
+ ],
196
66
  };
197
67
  }
198
68
  catch (error) {
199
- return this.handleToolError(error, 'connect_database');
69
+ const errorMessage = error instanceof Error ? error.message : String(error);
70
+ console.error("❌ Database connection failed:", errorMessage);
71
+ return {
72
+ content: [
73
+ {
74
+ type: "text",
75
+ text: `❌ Failed to connect: ${errorMessage}`,
76
+ },
77
+ ],
78
+ isError: true,
79
+ };
200
80
  }
201
81
  });
202
- // Tool: Execute SQL query with enhanced security, caching, and MCP annotations
203
- this.server.tool("execute_query", "Execute SQL queries directly - auto-connects if needed. No manual connection required when environment variables are set.", {
204
- query: z.string().min(1, "Query cannot be empty").describe("SQL query to execute (parameters recommended for user input)"),
205
- parameters: z.record(z.any()).optional().describe("Query parameters for security (key-value pairs)"),
206
- useCache: z.boolean().optional().default(true).describe("Enable result caching for SELECT queries"),
207
- dryRun: z.boolean().optional().default(false).describe("Validate query without execution"),
208
- }, {
209
- title: "Execute SQL Query",
210
- description: "Executes SQL queries with comprehensive security validation and performance optimization",
211
- annotations: {
212
- destructiveHint: false,
213
- idempotentHint: true,
214
- readOnlyHint: true
215
- }
216
- }, async ({ query, parameters, useCache, dryRun }, extra) => {
82
+ // Tool: Execute SQL query with enhanced security
83
+ this.server.registerTool("execute_query", {
84
+ title: "Execute Query",
85
+ description: "Execute a SQL query against the connected database with security validation",
86
+ inputSchema: {
87
+ query: z.string().min(1, "Query cannot be empty").describe("SQL query to execute"),
88
+ parameters: z.record(z.any()).optional().describe("Query parameters (key-value pairs) - always use parameters for user input"),
89
+ },
90
+ }, async ({ query, parameters }) => {
217
91
  try {
218
- // No rate limiting - user is trusted
219
- // Auto-connection logic for better AI experience
220
92
  if (!this.pool) {
221
- console.error("Auto-connecting...");
222
- try {
223
- // Try to auto-connect using environment variables
224
- const config = ConfigSchema.parse({
225
- server: process.env.DB_SERVER,
226
- database: process.env.DB_DATABASE,
227
- user: process.env.DB_USER,
228
- password: process.env.DB_PASSWORD,
229
- port: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 1433,
230
- trustServerCertificate: process.env.DB_TRUST_SERVER_CERTIFICATE === 'true',
231
- connectionTimeout: process.env.DB_CONNECTION_TIMEOUT ? parseInt(process.env.DB_CONNECTION_TIMEOUT) : 30000,
232
- requestTimeout: process.env.DB_REQUEST_TIMEOUT ? parseInt(process.env.DB_REQUEST_TIMEOUT) : 30000,
233
- });
234
- if (!config.server) {
235
- throw new MCPServerError("❌ Auto-connection failed: DB_SERVER environment variable not set. Please set database connection environment variables or use connect_database tool first.", "AUTO_CONNECTION_FAILED", {
236
- requiredEnvVars: ['DB_SERVER', 'DB_DATABASE', 'DB_USER', 'DB_PASSWORD'],
237
- suggestion: "Use connect_database tool manually or set environment variables"
238
- }, 'CONNECTION');
239
- }
240
- await this.connect(config);
241
- console.error("Auto-connected");
242
- }
243
- catch (autoConnectError) {
244
- throw new MCPServerError("❌ No database connection available and auto-connection failed. Please use connect_database tool first or check your environment variables.", "NO_CONNECTION_AUTO_FAILED", {
245
- autoConnectError: autoConnectError instanceof Error ? autoConnectError.message : String(autoConnectError),
246
- suggestion: "1. Use connect_database tool first, OR\n2. Set environment variables: DB_SERVER, DB_DATABASE, DB_USER, DB_PASSWORD"
247
- }, 'CONNECTION');
248
- }
249
- }
250
- // Enhanced security validation with context
251
- this.validateSQLSecurity(query, { operation: 'execute_query', userProvided: true });
252
- // Check cache for SELECT queries
253
- const queryType = query.trim().toUpperCase().split(/\s+/)[0];
254
- const isSelectQuery = queryType === 'SELECT';
255
- let cacheKey = null;
256
- if (isSelectQuery && useCache && !dryRun) {
257
- cacheKey = this.generateCacheKey('execute_query', { query, parameters });
258
- const cachedResult = this.queryCache.get(cacheKey);
259
- if (cachedResult) {
260
- return {
261
- content: [{
262
- type: "text",
263
- text: JSON.stringify({
264
- ...cachedResult,
265
- fromCache: true,
266
- executionTime: "0ms (cached)",
267
- cacheHit: true
268
- }, null, 2)
269
- }],
270
- _meta: {
271
- cached: true,
272
- cacheKey,
273
- timestamp: new Date().toISOString()
274
- }
275
- };
276
- }
277
- }
278
- // Dry run validation
279
- if (dryRun) {
280
- return {
281
- content: [{
282
- type: "text",
283
- text: `✅ Query validation passed:\n• Query type: ${queryType}\n• Parameters: ${parameters ? Object.keys(parameters).length : 0}\n• Estimated complexity: ${query.length > 200 ? 'High' : 'Low'}\n• Security: ✓ Passed\n• Ready for execution`
284
- }],
285
- _meta: {
286
- dryRun: true,
287
- queryType,
288
- parameterCount: parameters ? Object.keys(parameters).length : 0,
289
- validationPassed: true,
290
- timestamp: new Date().toISOString()
291
- }
292
- };
93
+ throw new Error("No database connection. Please connect first using connect_database tool.");
293
94
  }
294
95
  const request = this.pool.request();
295
- // Add parameters with type safety
96
+ // Add parameters if provided (recommended for security)
296
97
  if (parameters) {
297
98
  for (const [key, value] of Object.entries(parameters)) {
298
99
  request.input(key, value);
@@ -301,190 +102,139 @@ class MSSQLMCPServer {
301
102
  const startTime = Date.now();
302
103
  const result = await request.query(query);
303
104
  const executionTime = Date.now() - startTime;
304
- const response = {
305
- recordset: result.recordset,
306
- rowsAffected: result.rowsAffected,
307
- output: result.output,
308
- executionTime: `${executionTime}ms`,
309
- parametersUsed: parameters ? Object.keys(parameters).length : 0,
310
- fromCache: false,
311
- queryType,
312
- rowCount: result.recordset.length
313
- };
314
- // Cache SELECT query results
315
- if (isSelectQuery && useCache && cacheKey) {
316
- this.queryCache.set(cacheKey, response);
317
- }
318
105
  return {
319
- content: [{
106
+ content: [
107
+ {
320
108
  type: "text",
321
- text: JSON.stringify(response, null, 2)
322
- }],
323
- _meta: {
324
- executionTime: `${executionTime}ms`,
325
- queryType,
326
- rowCount: result.recordset.length,
327
- parametersUsed: parameters ? Object.keys(parameters).length : 0,
328
- cached: false,
329
- timestamp: new Date().toISOString()
330
- }
109
+ text: JSON.stringify({
110
+ recordset: result.recordset,
111
+ rowsAffected: result.rowsAffected,
112
+ output: result.output,
113
+ executionTime: `${executionTime}ms`,
114
+ parametersUsed: parameters ? Object.keys(parameters).length : 0,
115
+ }, null, 2),
116
+ },
117
+ ],
331
118
  };
332
119
  }
333
120
  catch (error) {
334
- return this.handleToolError(error, 'execute_query');
121
+ const errorMessage = error instanceof Error ? error.message : String(error);
122
+ console.error("❌ Query execution failed:", errorMessage);
123
+ return {
124
+ content: [
125
+ {
126
+ type: "text",
127
+ text: `❌ Query execution failed: ${errorMessage}`,
128
+ },
129
+ ],
130
+ isError: true,
131
+ };
335
132
  }
336
133
  });
337
- // Tool: Get database schema with enhanced filtering and MCP annotations
338
- this.server.tool("get_schema", "Explore database schema - auto-connects if needed. No manual connection required when environment variables are set.", {
339
- objectType: z.enum(["tables", "views", "procedures", "functions", "all"]).optional().default("tables").describe("Type of objects to list"),
340
- schemaName: z.string().optional().describe("Filter by specific schema name"),
341
- includeMetadata: z.boolean().optional().default(true).describe("Include detailed metadata"),
342
- }, {
343
- title: "Get Database Schema",
344
- description: "Retrieves comprehensive database schema information with filtering options",
345
- annotations: {
346
- destructiveHint: false,
347
- idempotentHint: true,
348
- readOnlyHint: true
349
- }
350
- }, async ({ objectType, schemaName, includeMetadata }, extra) => {
134
+ // Tool: Get database schema
135
+ this.server.registerTool("get_schema", {
136
+ title: "Get Schema",
137
+ description: "Get database schema information (tables, columns, etc.)",
138
+ inputSchema: {
139
+ objectType: z.enum(["tables", "views", "procedures", "functions", "all"]).optional().default("tables"),
140
+ schemaName: z.string().optional().describe("Specific schema name to filter"),
141
+ },
142
+ }, async ({ objectType, schemaName }) => {
351
143
  try {
352
- // Auto-connection logic for seamless AI experience
353
144
  if (!this.pool) {
354
- try {
355
- const config = ConfigSchema.parse({
356
- server: process.env.DB_SERVER,
357
- database: process.env.DB_DATABASE,
358
- user: process.env.DB_USER,
359
- password: process.env.DB_PASSWORD,
360
- port: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 1433,
361
- trustServerCertificate: process.env.DB_TRUST_SERVER_CERTIFICATE === 'true',
362
- connectionTimeout: process.env.DB_CONNECTION_TIMEOUT ? parseInt(process.env.DB_CONNECTION_TIMEOUT) : 30000,
363
- requestTimeout: process.env.DB_REQUEST_TIMEOUT ? parseInt(process.env.DB_REQUEST_TIMEOUT) : 30000,
364
- });
365
- if (config.server) {
366
- await this.connect(config);
367
- }
368
- else {
369
- throw new MCPServerError("Database connection required. Set environment variables or use connect_database tool.", "NO_CONNECTION", { requiredEnvVars: ['DB_SERVER', 'DB_DATABASE', 'DB_USER', 'DB_PASSWORD'] }, 'CONNECTION');
370
- }
371
- }
372
- catch (error) {
373
- throw new MCPServerError("Database connection required. Use connect_database tool or set environment variables.", "NO_CONNECTION_AUTO_FAILED", undefined, 'CONNECTION');
374
- }
145
+ throw new Error("No database connection. Please connect first.");
375
146
  }
376
147
  let query = "";
377
- const startTime = Date.now();
378
148
  if (objectType === "tables" || objectType === "all") {
379
- query += includeMetadata ? `
380
- SELECT
381
- TABLE_SCHEMA,
382
- TABLE_NAME,
383
- TABLE_TYPE,
384
- 'table' as OBJECT_TYPE,
385
- (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS c
386
- WHERE c.TABLE_NAME = t.TABLE_NAME AND c.TABLE_SCHEMA = t.TABLE_SCHEMA) as COLUMN_COUNT
387
- FROM INFORMATION_SCHEMA.TABLES t
388
- ${schemaName ? `WHERE TABLE_SCHEMA = @schemaName` : ""}
389
- ` : `
390
- SELECT
149
+ query += `
150
+ SELECT
391
151
  TABLE_SCHEMA,
392
152
  TABLE_NAME,
393
153
  TABLE_TYPE,
394
154
  'table' as OBJECT_TYPE
395
155
  FROM INFORMATION_SCHEMA.TABLES
396
- ${schemaName ? `WHERE TABLE_SCHEMA = @schemaName` : ""}
156
+ ${schemaName ? `WHERE TABLE_SCHEMA = '${schemaName}'` : ""}
397
157
  `;
398
158
  }
399
159
  if (objectType === "views" || objectType === "all") {
400
160
  if (query)
401
161
  query += " UNION ALL ";
402
162
  query += `
403
- SELECT
163
+ SELECT
404
164
  TABLE_SCHEMA,
405
165
  TABLE_NAME,
406
166
  'VIEW' as TABLE_TYPE,
407
167
  'view' as OBJECT_TYPE
408
- ${includeMetadata ? ", (SELECT COUNT(*) FROM INFORMATION_SCHEMA.VIEW_COLUMNS v WHERE v.TABLE_NAME = TABLE_NAME AND v.TABLE_SCHEMA = TABLE_SCHEMA) as COLUMN_COUNT" : ""}
409
168
  FROM INFORMATION_SCHEMA.VIEWS
410
- ${schemaName ? `WHERE TABLE_SCHEMA = @schemaName` : ""}
169
+ ${schemaName ? `WHERE TABLE_SCHEMA = '${schemaName}'` : ""}
411
170
  `;
412
171
  }
413
172
  if (objectType === "procedures" || objectType === "all") {
414
173
  if (query)
415
174
  query += " UNION ALL ";
416
175
  query += `
417
- SELECT
176
+ SELECT
418
177
  ROUTINE_SCHEMA as TABLE_SCHEMA,
419
178
  ROUTINE_NAME as TABLE_NAME,
420
179
  'PROCEDURE' as TABLE_TYPE,
421
180
  'procedure' as OBJECT_TYPE
422
- ${includeMetadata ? ", (SELECT COUNT(*) FROM INFORMATION_SCHEMA.PARAMETERS p WHERE p.SPECIFIC_NAME = ROUTINE_NAME AND p.SPECIFIC_SCHEMA = ROUTINE_SCHEMA) as PARAMETER_COUNT" : ""}
423
181
  FROM INFORMATION_SCHEMA.ROUTINES
424
182
  WHERE ROUTINE_TYPE = 'PROCEDURE'
425
- ${schemaName ? `AND ROUTINE_SCHEMA = @schemaName` : ""}
183
+ ${schemaName ? `AND ROUTINE_SCHEMA = '${schemaName}'` : ""}
426
184
  `;
427
185
  }
428
186
  if (objectType === "functions" || objectType === "all") {
429
187
  if (query)
430
188
  query += " UNION ALL ";
431
189
  query += `
432
- SELECT
190
+ SELECT
433
191
  ROUTINE_SCHEMA as TABLE_SCHEMA,
434
192
  ROUTINE_NAME as TABLE_NAME,
435
193
  'FUNCTION' as TABLE_TYPE,
436
194
  'function' as OBJECT_TYPE
437
- ${includeMetadata ? ", (SELECT COUNT(*) FROM INFORMATION_SCHEMA.PARAMETERS p WHERE p.SPECIFIC_NAME = ROUTINE_NAME AND p.SPECIFIC_SCHEMA = ROUTINE_SCHEMA) as PARAMETER_COUNT" : ""}
438
195
  FROM INFORMATION_SCHEMA.ROUTINES
439
196
  WHERE ROUTINE_TYPE = 'FUNCTION'
440
- ${schemaName ? `AND ROUTINE_SCHEMA = @schemaName` : ""}
197
+ ${schemaName ? `AND ROUTINE_SCHEMA = '${schemaName}'` : ""}
441
198
  `;
442
199
  }
443
200
  query += " ORDER BY TABLE_SCHEMA, TABLE_NAME";
444
- const request = this.pool.request();
445
- if (schemaName) {
446
- request.input('schemaName', schemaName);
447
- }
448
- const result = await request.query(query);
449
- const executionTime = Date.now() - startTime;
201
+ const result = await this.pool.request().query(query);
450
202
  return {
451
- content: [{
203
+ content: [
204
+ {
452
205
  type: "text",
453
- text: JSON.stringify({
454
- objects: result.recordset,
455
- metadata: {
456
- objectType,
457
- schemaName: schemaName || 'all',
458
- count: result.recordset.length,
459
- executionTime: `${executionTime}ms`,
460
- includeMetadata
461
- }
462
- }, null, 2)
463
- }],
464
- _meta: {
465
- objectType,
466
- count: result.recordset.length,
467
- executionTime: `${executionTime}ms`,
468
- schemaFiltered: !!schemaName,
469
- timestamp: new Date().toISOString()
470
- }
206
+ text: JSON.stringify(result.recordset, null, 2),
207
+ },
208
+ ],
471
209
  };
472
210
  }
473
211
  catch (error) {
474
- return this.handleToolError(error, 'get_schema');
212
+ return {
213
+ content: [
214
+ {
215
+ type: "text",
216
+ text: `Schema query failed: ${error instanceof Error ? error.message : String(error)}`,
217
+ },
218
+ ],
219
+ isError: true,
220
+ };
475
221
  }
476
222
  });
477
223
  // Tool: Get table structure
478
- this.server.tool("describe_table", "Get table structure - auto-connects if needed. No manual connection required when environment variables are set.", {
479
- tableName: z.string().describe("Name of the table"),
480
- schemaName: z.string().optional().default("dbo").describe("Schema name"),
224
+ this.server.registerTool("describe_table", {
225
+ title: "Describe Table",
226
+ description: "Get detailed structure of a specific table",
227
+ inputSchema: {
228
+ tableName: z.string().describe("Name of the table"),
229
+ schemaName: z.string().optional().default("dbo").describe("Schema name"),
230
+ },
481
231
  }, async ({ tableName, schemaName }) => {
482
232
  try {
483
233
  if (!this.pool) {
484
- throw new MCPServerError("No database connection. Please connect first.", "NO_CONNECTION");
234
+ throw new Error("No database connection. Please connect first.");
485
235
  }
486
236
  const query = `
487
- SELECT
237
+ SELECT
488
238
  COLUMN_NAME,
489
239
  DATA_TYPE,
490
240
  CHARACTER_MAXIMUM_LENGTH,
@@ -494,7 +244,7 @@ class MSSQLMCPServer {
494
244
  COLUMN_DEFAULT,
495
245
  ORDINAL_POSITION
496
246
  FROM INFORMATION_SCHEMA.COLUMNS
497
- WHERE TABLE_NAME = @tableName
247
+ WHERE TABLE_NAME = @tableName
498
248
  AND TABLE_SCHEMA = @schemaName
499
249
  ORDER BY ORDINAL_POSITION
500
250
  `;
@@ -512,11 +262,23 @@ class MSSQLMCPServer {
512
262
  };
513
263
  }
514
264
  catch (error) {
515
- return this.handleToolError(error);
265
+ return {
266
+ content: [
267
+ {
268
+ type: "text",
269
+ text: `Table description failed: ${error instanceof Error ? error.message : String(error)}`,
270
+ },
271
+ ],
272
+ isError: true,
273
+ };
516
274
  }
517
275
  });
518
276
  // Tool: Get enhanced connection status
519
- this.server.tool("connection_status", "Check current database connection status with detailed information", {}, async () => {
277
+ this.server.registerTool("connection_status", {
278
+ title: "Connection Status",
279
+ description: "Check current database connection status with detailed information",
280
+ inputSchema: {},
281
+ }, async () => {
520
282
  const isConnected = this.pool?.connected || false;
521
283
  const status = {
522
284
  connected: isConnected,
@@ -526,12 +288,6 @@ class MSSQLMCPServer {
526
288
  connectionTime: isConnected ? new Date().toISOString() : null,
527
289
  securityFeatures: {
528
290
  sqlInjectionProtection: "Enabled",
529
- rateLimiting: "Enabled",
530
- caching: "Enabled"
531
- },
532
- cacheStats: {
533
- cacheSize: this.queryCache['cache'].size,
534
- clientInfo: this.clientId
535
291
  },
536
292
  poolInfo: this.pool ? {
537
293
  size: this.pool.size,
@@ -550,48 +306,63 @@ class MSSQLMCPServer {
550
306
  };
551
307
  });
552
308
  // Tool: Disconnect from database
553
- this.server.tool("disconnect_database", "Disconnect from the current database", {}, async () => {
309
+ this.server.registerTool("disconnect_database", {
310
+ title: "Disconnect Database",
311
+ description: "Disconnect from the current database",
312
+ inputSchema: {},
313
+ }, async () => {
554
314
  try {
555
315
  if (this.pool) {
556
316
  await this.pool.close();
557
317
  this.pool = null;
558
318
  this.config = null;
559
- this.queryCache.clear(); // Clear cache on disconnect
560
319
  }
561
320
  return {
562
321
  content: [
563
322
  {
564
323
  type: "text",
565
- text: "Successfully disconnected from database and cleared cache",
324
+ text: "Successfully disconnected from database",
566
325
  },
567
326
  ],
568
327
  };
569
328
  }
570
329
  catch (error) {
571
- return this.handleToolError(error);
330
+ return {
331
+ content: [
332
+ {
333
+ type: "text",
334
+ text: `Disconnect failed: ${error instanceof Error ? error.message : String(error)}`,
335
+ },
336
+ ],
337
+ isError: true,
338
+ };
572
339
  }
573
340
  });
574
341
  // Tool: Get table data with enhanced security and validation
575
- this.server.tool("get_table_data", "Get data from a specific table with optional filtering, pagination and input validation", {
576
- tableName: z.string().min(1).regex(/^[a-zA-Z0-9_]+$/, "Table name can only contain letters, numbers, and underscores").describe("Name of the table"),
577
- schemaName: z.string().regex(/^[a-zA-Z0-9_]+$/, "Schema name can only contain letters, numbers, and underscores").optional().default("dbo").describe("Schema name"),
578
- limit: z.number().int().min(1).max(10000).optional().default(100).describe("Maximum number of rows to return (1-10000)"),
579
- offset: z.number().int().min(0).optional().default(0).describe("Number of rows to skip"),
580
- whereClause: z.string().optional().describe("WHERE clause (without the WHERE keyword) - use parameters for values"),
581
- orderBy: z.string().optional().describe("ORDER BY clause (without the ORDER BY keyword)"),
582
- parameters: z.record(z.any()).optional().describe("Parameters for WHERE clause"),
342
+ this.server.registerTool("get_table_data", {
343
+ title: "Get Table Data",
344
+ description: "Get data from a specific table with optional filtering, pagination and input validation",
345
+ inputSchema: {
346
+ tableName: z.string().min(1).regex(/^[a-zA-Z0-9_]+$/, "Table name can only contain letters, numbers, and underscores").describe("Name of the table"),
347
+ schemaName: z.string().regex(/^[a-zA-Z0-9_]+$/, "Schema name can only contain letters, numbers, and underscores").optional().default("dbo").describe("Schema name"),
348
+ limit: z.number().int().min(1).max(10000).optional().default(100).describe("Maximum number of rows to return (1-10000)"),
349
+ offset: z.number().int().min(0).optional().default(0).describe("Number of rows to skip"),
350
+ whereClause: z.string().optional().describe("WHERE clause (without the WHERE keyword) - use parameters for values"),
351
+ orderBy: z.string().optional().describe("ORDER BY clause (without the ORDER BY keyword)"),
352
+ parameters: z.record(z.any()).optional().describe("Parameters for WHERE clause"),
353
+ },
583
354
  }, async ({ tableName, schemaName, limit, offset, whereClause, orderBy, parameters }) => {
584
355
  try {
585
356
  if (!this.pool) {
586
- throw new MCPServerError("No database connection. Please connect first.", "NO_CONNECTION");
357
+ throw new Error("No database connection. Please connect first.");
587
358
  }
588
359
  // Security: Validate table and schema names to prevent SQL injection
589
360
  const tableNamePattern = /^[a-zA-Z0-9_]+$/;
590
361
  if (!tableNamePattern.test(tableName)) {
591
- throw new MCPServerError("Invalid table name. Only letters, numbers, and underscores are allowed.", "INVALID_TABLE_NAME");
362
+ throw new Error("Invalid table name. Only letters, numbers, and underscores are allowed.");
592
363
  }
593
364
  if (!tableNamePattern.test(schemaName)) {
594
- throw new MCPServerError("Invalid schema name. Only letters, numbers, and underscores are allowed.", "INVALID_SCHEMA_NAME");
365
+ throw new Error("Invalid schema name. Only letters, numbers, and underscores are allowed.");
595
366
  }
596
367
  // Build query using parameterized approach
597
368
  let query = `SELECT * FROM [${schemaName}].[${tableName}]`;
@@ -607,9 +378,10 @@ class MSSQLMCPServer {
607
378
  }
608
379
  if (orderBy) {
609
380
  // Validate ORDER BY clause for basic security
610
- const orderByPattern = /^([\[\]a-zA-Z0-9_.]+(\s+(ASC|DESC))?)(\s*,\s*[\[\]a-zA-Z0-9_.]+(\s+(ASC|DESC))?)*$/i;
381
+ // Allow dotted identifiers, bracketed identifiers, commas, spaces and optional ASC/DESC per column
382
+ const orderByPattern = /^([\[\]a-zA-Z0-9_.]+(\s+(ASC|DESC))?)((\s*,\s*)[\[\]a-zA-Z0-9_.]+(\s+(ASC|DESC))?)*$/i;
611
383
  if (!orderByPattern.test(orderBy)) {
612
- throw new MCPServerError("Invalid ORDER BY clause. Only column names, commas, spaces, ASC, and DESC are allowed.", "INVALID_ORDER_BY");
384
+ throw new Error("Invalid ORDER BY clause. Only column names, commas, spaces, ASC, and DESC are allowed.");
613
385
  }
614
386
  query += ` ORDER BY ${orderBy}`;
615
387
  }
@@ -642,18 +414,32 @@ class MSSQLMCPServer {
642
414
  };
643
415
  }
644
416
  catch (error) {
645
- return this.handleToolError(error);
417
+ const errorMessage = error instanceof Error ? error.message : String(error);
418
+ console.error("❌ Get table data failed:", errorMessage);
419
+ return {
420
+ content: [
421
+ {
422
+ type: "text",
423
+ text: `❌ Get table data failed: ${errorMessage}`,
424
+ },
425
+ ],
426
+ isError: true,
427
+ };
646
428
  }
647
429
  });
648
430
  // Tool: Execute stored procedure
649
- this.server.tool("execute_procedure", "Execute a stored procedure with parameters", {
650
- procedureName: z.string().describe("Name of the stored procedure"),
651
- schemaName: z.string().optional().default("dbo").describe("Schema name"),
652
- parameters: z.record(z.any()).optional().describe("Procedure parameters (key-value pairs)"),
431
+ this.server.registerTool("execute_procedure", {
432
+ title: "Execute Procedure",
433
+ description: "Execute a stored procedure with parameters",
434
+ inputSchema: {
435
+ procedureName: z.string().describe("Name of the stored procedure"),
436
+ schemaName: z.string().optional().default("dbo").describe("Schema name"),
437
+ parameters: z.record(z.any()).optional().describe("Procedure parameters (key-value pairs)"),
438
+ },
653
439
  }, async ({ procedureName, schemaName, parameters }) => {
654
440
  try {
655
441
  if (!this.pool) {
656
- throw new MCPServerError("No database connection. Please connect first.", "NO_CONNECTION");
442
+ throw new Error("No database connection. Please connect first.");
657
443
  }
658
444
  const request = this.pool.request();
659
445
  // Add parameters if provided
@@ -678,17 +464,29 @@ class MSSQLMCPServer {
678
464
  };
679
465
  }
680
466
  catch (error) {
681
- return this.handleToolError(error);
467
+ return {
468
+ content: [
469
+ {
470
+ type: "text",
471
+ text: `Procedure execution failed: ${error instanceof Error ? error.message : String(error)}`,
472
+ },
473
+ ],
474
+ isError: true,
475
+ };
682
476
  }
683
477
  });
684
478
  // Tool: Get database list
685
- this.server.tool("list_databases", "List all databases on the connected SQL Server instance", {}, async () => {
479
+ this.server.registerTool("list_databases", {
480
+ title: "List Databases",
481
+ description: "List all databases on the connected SQL Server instance",
482
+ inputSchema: {},
483
+ }, async () => {
686
484
  try {
687
485
  if (!this.pool) {
688
- throw new MCPServerError("No database connection. Please connect first.", "NO_CONNECTION");
486
+ throw new Error("No database connection. Please connect first.");
689
487
  }
690
488
  const query = `
691
- SELECT
489
+ SELECT
692
490
  name,
693
491
  database_id,
694
492
  create_date,
@@ -713,35 +511,25 @@ class MSSQLMCPServer {
713
511
  };
714
512
  }
715
513
  catch (error) {
716
- return this.handleToolError(error);
717
- }
718
- });
719
- // Tool: Clear query cache
720
- this.server.tool("clear_cache", "Clear the query result cache", {}, async () => {
721
- try {
722
- const cacheSize = this.queryCache['cache'].size;
723
- this.queryCache.clear();
724
514
  return {
725
515
  content: [
726
516
  {
727
517
  type: "text",
728
- text: JSON.stringify({
729
- message: "Query cache cleared successfully",
730
- clearedEntries: cacheSize,
731
- timestamp: new Date().toISOString()
732
- }, null, 2),
518
+ text: `List databases failed: ${error instanceof Error ? error.message : String(error)}`,
733
519
  },
734
520
  ],
521
+ isError: true,
735
522
  };
736
523
  }
737
- catch (error) {
738
- return this.handleToolError(error);
739
- }
740
524
  });
741
525
  }
742
526
  setupResources() {
743
527
  // Resource: Current connection info
744
- this.server.resource("connection-info", "mssql://connection/info", async () => {
528
+ this.server.registerResource("connection-info", "mssql://connection/info", {
529
+ title: "Connection Info",
530
+ description: "Current MSSQL connection information",
531
+ mimeType: "application/json",
532
+ }, async () => {
745
533
  const info = {
746
534
  connected: this.pool?.connected || false,
747
535
  config: this.config ? {
@@ -749,14 +537,6 @@ class MSSQLMCPServer {
749
537
  database: this.config.database,
750
538
  port: this.config.port,
751
539
  } : null,
752
- cacheStats: {
753
- cacheSize: this.queryCache['cache'].size,
754
- lastCleanup: new Date().toISOString()
755
- },
756
- clientInfo: {
757
- clientId: this.clientId,
758
- rateLimitsEnabled: true
759
- }
760
540
  };
761
541
  return {
762
542
  contents: [
@@ -768,22 +548,6 @@ class MSSQLMCPServer {
768
548
  ],
769
549
  };
770
550
  });
771
- // Dynamic resource for query results cache status
772
- this.server.resource("cache-status", "mssql://cache/status", async () => {
773
- const status = {
774
- cacheSize: this.queryCache['cache'].size,
775
- rateLimiting: "DISABLED - Trust-based approach",
776
- clientId: this.clientId,
777
- timestamp: new Date().toISOString()
778
- };
779
- return {
780
- contents: [{
781
- uri: "mssql://cache/status",
782
- text: JSON.stringify(status, null, 2),
783
- mimeType: "application/json"
784
- }]
785
- };
786
- });
787
551
  }
788
552
  async connect(config) {
789
553
  try {
@@ -801,9 +565,9 @@ class MSSQLMCPServer {
801
565
  password: config.password,
802
566
  port: config.port,
803
567
  options: {
568
+ encrypt: config.encrypt,
804
569
  trustServerCertificate: config.trustServerCertificate,
805
570
  enableArithAbort: true,
806
- encrypt: !config.trustServerCertificate, // Enable encryption when not trusting server certificate
807
571
  },
808
572
  connectionTimeout: config.connectionTimeout,
809
573
  requestTimeout: config.requestTimeout,
@@ -871,7 +635,7 @@ class MSSQLMCPServer {
871
635
  console.error('Unhandled Rejection:', reason);
872
636
  shutdown('unhandledRejection');
873
637
  });
874
- console.error("MSSQL MCP Server v2.0.2 starting...");
638
+ console.error("MSSQL MCP Server v2.1.1 starting...");
875
639
  await this.server.connect(transport);
876
640
  console.error("Server ready");
877
641
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mssql-mcp",
3
- "version": "2.0.2",
3
+ "version": "2.1.1",
4
4
  "description": "MCP Server for MS SQL Server integration with Claude Desktop, Cursor, Windsurf and VS Code",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -45,10 +45,10 @@
45
45
  "author": "BYMCS <hello@bymcs.com>",
46
46
  "license": "MIT",
47
47
  "dependencies": {
48
- "@modelcontextprotocol/sdk": "^1.20.2",
48
+ "@modelcontextprotocol/sdk": "^1.25.1",
49
49
  "dotenv": "^16.3.1",
50
50
  "mssql": "^11.0.1",
51
- "zod": "^3.22.4"
51
+ "zod": "^3.25.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/mssql": "^9.1.7",
@@ -56,4 +56,4 @@
56
56
  "rimraf": "^5.0.0",
57
57
  "typescript": "^5.3.0"
58
58
  }
59
- }
59
+ }