@connorbritain/mssql-mcp-server 0.1.1 → 0.2.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 +12 -15
- package/dist/audit/AuditLogger.d.ts +13 -1
- package/dist/audit/AuditLogger.d.ts.map +1 -1
- package/dist/audit/AuditLogger.js +57 -3
- package/dist/audit/AuditLogger.js.map +1 -1
- package/dist/config/EnvironmentManager.d.ts +34 -1
- package/dist/config/EnvironmentManager.d.ts.map +1 -1
- package/dist/config/EnvironmentManager.js +117 -1
- package/dist/config/EnvironmentManager.js.map +1 -1
- package/dist/index.js +95 -4
- package/dist/index.js.map +1 -1
- package/dist/tools/DescribeTableTool.d.ts +15 -3
- package/dist/tools/DescribeTableTool.d.ts.map +1 -1
- package/dist/tools/DescribeTableTool.js +79 -5
- package/dist/tools/DescribeTableTool.js.map +1 -1
- package/dist/tools/ListDatabasesTool.d.ts +27 -0
- package/dist/tools/ListDatabasesTool.d.ts.map +1 -0
- package/dist/tools/ListDatabasesTool.js +109 -0
- package/dist/tools/ListDatabasesTool.js.map +1 -0
- package/dist/tools/ListEnvironmentsTool.d.ts +49 -0
- package/dist/tools/ListEnvironmentsTool.d.ts.map +1 -0
- package/dist/tools/ListEnvironmentsTool.js +73 -0
- package/dist/tools/ListEnvironmentsTool.js.map +1 -0
- package/dist/tools/ListTableTool.d.ts +8 -2
- package/dist/tools/ListTableTool.d.ts.map +1 -1
- package/dist/tools/ListTableTool.js +52 -10
- package/dist/tools/ListTableTool.js.map +1 -1
- package/dist/tools/ReadDataTool.d.ts +5 -2
- package/dist/tools/ReadDataTool.d.ts.map +1 -1
- package/dist/tools/ReadDataTool.js +54 -18
- package/dist/tools/ReadDataTool.js.map +1 -1
- package/dist/tools/ValidateEnvironmentConfigTool.d.ts +37 -0
- package/dist/tools/ValidateEnvironmentConfigTool.d.ts.map +1 -0
- package/dist/tools/ValidateEnvironmentConfigTool.js +230 -0
- package/dist/tools/ValidateEnvironmentConfigTool.js.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
# @connorbritain/mssql-mcp-server
|
|
2
2
|
|
|
3
|
-
Model Context Protocol server for SQL Server.
|
|
3
|
+
Model Context Protocol server for SQL Server. Enterprise-ready schema discovery, profiling, and safe data operations.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Multi-environment support** - Define named database environments (prod, staging, dev) with per-environment policies
|
|
8
|
+
- **Governance controls** - `allowedTools`, `deniedTools`, `allowedSchemas`, `deniedSchemas`, `requireApproval`
|
|
9
|
+
- **Server-level access** - Query across multiple databases on a single SQL Server instance
|
|
10
|
+
- **Audit logging** - JSON Lines logs with session IDs, auto-redaction of sensitive data
|
|
11
|
+
- **Secret management** - `${secret:NAME}` placeholders resolve from environment variables
|
|
12
|
+
- **Safe by default** - `READONLY` mode, preview/confirm for mutations, automatic row limits
|
|
4
13
|
|
|
5
14
|
## Install
|
|
6
15
|
|
|
@@ -10,13 +19,7 @@ npm install -g @connorbritain/mssql-mcp-server@latest
|
|
|
10
19
|
npx @connorbritain/mssql-mcp-server@latest
|
|
11
20
|
```
|
|
12
21
|
|
|
13
|
-
##
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
mssql-mcp-server
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
The entrypoint expects env vars:
|
|
22
|
+
## Quick Start
|
|
20
23
|
|
|
21
24
|
| Variable | Required | Notes |
|
|
22
25
|
| --- | --- | --- |
|
|
@@ -24,14 +27,8 @@ The entrypoint expects env vars:
|
|
|
24
27
|
| `DATABASE_NAME` | ✅ | Database to target |
|
|
25
28
|
| `SQL_AUTH_MODE` | | `sql`, `windows`, or `aad` (default `aad`) |
|
|
26
29
|
| `SQL_USERNAME`/`SQL_PASSWORD` | | Required for `sql`/`windows` modes |
|
|
27
|
-
| `SQL_DOMAIN` | | Optional for NTLM |
|
|
28
|
-
| `SQL_PORT` | | Defaults to `1433` |
|
|
29
|
-
| `TRUST_SERVER_CERTIFICATE` | | Set `true` for dev/self-signed |
|
|
30
|
-
| `CONNECTION_TIMEOUT` | | Seconds, default `30` |
|
|
31
30
|
| `READONLY` | | `true` disables write tools |
|
|
32
|
-
| `
|
|
33
|
-
| `PROFILE_SAMPLE_RETURN_LIMIT` | | Max sample rows returned (default `10`) |
|
|
34
|
-
| `SEARCH_SCHEMA_DEFAULT_LIMIT` | | Default pagination size for `search_schema` (default `50`) |
|
|
31
|
+
| `ENVIRONMENTS_CONFIG_PATH` | | Path to multi-environment JSON config |
|
|
35
32
|
|
|
36
33
|
## Example MCP config
|
|
37
34
|
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
export type AuditLevel = "none" | "basic" | "verbose";
|
|
1
2
|
export interface AuditLogEntry {
|
|
2
3
|
timestamp: string;
|
|
3
4
|
toolName: string;
|
|
5
|
+
environment?: string;
|
|
4
6
|
arguments?: Record<string, any>;
|
|
5
7
|
result?: {
|
|
6
8
|
success: boolean;
|
|
7
9
|
recordCount?: number;
|
|
8
10
|
error?: string;
|
|
11
|
+
data?: any;
|
|
9
12
|
};
|
|
10
13
|
durationMs?: number;
|
|
11
14
|
sessionId?: string;
|
|
@@ -19,7 +22,16 @@ export declare class AuditLogger {
|
|
|
19
22
|
private ensureLogDirectory;
|
|
20
23
|
private redactArguments;
|
|
21
24
|
log(entry: AuditLogEntry): void;
|
|
22
|
-
logToolInvocation(toolName: string, args: any, result: any, durationMs: number,
|
|
25
|
+
logToolInvocation(toolName: string, args: any, result: any, durationMs: number, options?: {
|
|
26
|
+
sessionId?: string;
|
|
27
|
+
userId?: string;
|
|
28
|
+
environment?: string;
|
|
29
|
+
auditLevel?: AuditLevel;
|
|
30
|
+
}): void;
|
|
31
|
+
/**
|
|
32
|
+
* Truncate result data for verbose logging to prevent huge log entries
|
|
33
|
+
*/
|
|
34
|
+
private truncateResultData;
|
|
23
35
|
}
|
|
24
36
|
export declare const auditLogger: AuditLogger;
|
|
25
37
|
//# sourceMappingURL=AuditLogger.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuditLogger.d.ts","sourceRoot":"","sources":["../../src/audit/AuditLogger.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE;QACP,OAAO,EAAE,OAAO,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"AuditLogger.d.ts","sourceRoot":"","sources":["../../src/audit/AuditLogger.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAEtD,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE;QACP,OAAO,EAAE,OAAO,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,GAAG,CAAC;KACZ,CAAC;IACF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAU;;IAoB9C,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,eAAe;IA6BvB,GAAG,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAkB/B,iBAAiB,CACf,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,GAAG,EACT,MAAM,EAAE,GAAG,EACX,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;QACR,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,UAAU,CAAC;KACzB,GACA,IAAI;IA+CP;;OAEG;IACH,OAAO,CAAC,kBAAkB;CA2B3B;AAGD,eAAO,MAAM,WAAW,aAAoB,CAAC"}
|
|
@@ -69,22 +69,76 @@ export class AuditLogger {
|
|
|
69
69
|
console.error("Failed to write audit log:", error);
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
-
logToolInvocation(toolName, args, result, durationMs,
|
|
72
|
+
logToolInvocation(toolName, args, result, durationMs, options) {
|
|
73
|
+
const auditLevel = options?.auditLevel ?? "basic";
|
|
74
|
+
// Skip logging entirely for 'none' level
|
|
75
|
+
if (auditLevel === "none") {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// Basic level: minimal info (tool name, success, timing, environment)
|
|
79
|
+
if (auditLevel === "basic") {
|
|
80
|
+
const entry = {
|
|
81
|
+
timestamp: new Date().toISOString(),
|
|
82
|
+
toolName,
|
|
83
|
+
environment: options?.environment,
|
|
84
|
+
result: {
|
|
85
|
+
success: result?.success ?? false,
|
|
86
|
+
recordCount: result?.recordCount ?? result?.rowsAffected,
|
|
87
|
+
error: result?.error,
|
|
88
|
+
},
|
|
89
|
+
durationMs: Math.round(durationMs),
|
|
90
|
+
sessionId: options?.sessionId,
|
|
91
|
+
userId: options?.userId,
|
|
92
|
+
};
|
|
93
|
+
this.log(entry);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
// Verbose level: full arguments and result data
|
|
73
97
|
const entry = {
|
|
74
98
|
timestamp: new Date().toISOString(),
|
|
75
99
|
toolName,
|
|
100
|
+
environment: options?.environment,
|
|
76
101
|
arguments: args || {},
|
|
77
102
|
result: {
|
|
78
103
|
success: result?.success ?? false,
|
|
79
104
|
recordCount: result?.recordCount ?? result?.rowsAffected,
|
|
80
105
|
error: result?.error,
|
|
106
|
+
data: this.truncateResultData(result?.data),
|
|
81
107
|
},
|
|
82
108
|
durationMs: Math.round(durationMs),
|
|
83
|
-
sessionId,
|
|
84
|
-
userId,
|
|
109
|
+
sessionId: options?.sessionId,
|
|
110
|
+
userId: options?.userId,
|
|
85
111
|
};
|
|
86
112
|
this.log(entry);
|
|
87
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Truncate result data for verbose logging to prevent huge log entries
|
|
116
|
+
*/
|
|
117
|
+
truncateResultData(data) {
|
|
118
|
+
if (!data)
|
|
119
|
+
return undefined;
|
|
120
|
+
// If it's an array, limit to first 10 items
|
|
121
|
+
if (Array.isArray(data)) {
|
|
122
|
+
if (data.length > 10) {
|
|
123
|
+
return {
|
|
124
|
+
_truncated: true,
|
|
125
|
+
_totalCount: data.length,
|
|
126
|
+
items: data.slice(0, 10),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return data;
|
|
130
|
+
}
|
|
131
|
+
// If it's a large object (stringified > 10KB), truncate
|
|
132
|
+
const stringified = JSON.stringify(data);
|
|
133
|
+
if (stringified.length > 10000) {
|
|
134
|
+
return {
|
|
135
|
+
_truncated: true,
|
|
136
|
+
_originalSize: stringified.length,
|
|
137
|
+
preview: stringified.substring(0, 1000) + "...",
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
return data;
|
|
141
|
+
}
|
|
88
142
|
}
|
|
89
143
|
// Singleton instance
|
|
90
144
|
export const auditLogger = new AuditLogger();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuditLogger.js","sourceRoot":"","sources":["../../src/audit/AuditLogger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"AuditLogger.js","sourceRoot":"","sources":["../../src/audit/AuditLogger.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import sql from "mssql";
|
|
2
|
+
export type AccessLevel = "server" | "database";
|
|
3
|
+
export type TierLevel = "reader" | "writer" | "admin";
|
|
4
|
+
export type AuditLevel = "none" | "basic" | "verbose";
|
|
2
5
|
export interface EnvironmentConfig {
|
|
3
6
|
name: string;
|
|
7
|
+
description?: string;
|
|
4
8
|
server: string;
|
|
5
9
|
database: string;
|
|
6
10
|
port?: number;
|
|
@@ -12,8 +16,16 @@ export interface EnvironmentConfig {
|
|
|
12
16
|
connectionTimeout?: number;
|
|
13
17
|
readonly?: boolean;
|
|
14
18
|
allowedTools?: string[];
|
|
19
|
+
deniedTools?: string[];
|
|
15
20
|
maxRowsDefault?: number;
|
|
16
|
-
|
|
21
|
+
requireApproval?: boolean;
|
|
22
|
+
auditLevel?: AuditLevel;
|
|
23
|
+
accessLevel?: AccessLevel;
|
|
24
|
+
allowedDatabases?: string[] | "*";
|
|
25
|
+
deniedDatabases?: string[];
|
|
26
|
+
allowedSchemas?: string[];
|
|
27
|
+
deniedSchemas?: string[];
|
|
28
|
+
tier?: TierLevel;
|
|
17
29
|
}
|
|
18
30
|
export interface EnvironmentsConfig {
|
|
19
31
|
defaultEnvironment?: string;
|
|
@@ -28,6 +40,27 @@ export declare class EnvironmentManager {
|
|
|
28
40
|
private loadFromEnvVars;
|
|
29
41
|
getEnvironment(name?: string): EnvironmentConfig;
|
|
30
42
|
listEnvironments(): EnvironmentConfig[];
|
|
43
|
+
/**
|
|
44
|
+
* Check if the environment allows access to a specific database.
|
|
45
|
+
* For database-level access, only the configured database is allowed.
|
|
46
|
+
* For server-level access, checks allowedDatabases/deniedDatabases.
|
|
47
|
+
*/
|
|
48
|
+
isDatabaseAllowed(environmentName: string | undefined, databaseName: string): {
|
|
49
|
+
allowed: boolean;
|
|
50
|
+
reason?: string;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Check if a schema.table reference is allowed based on allowedSchemas/deniedSchemas.
|
|
54
|
+
* Pattern matching supports wildcards (e.g., "audit.*", "*.sensitive_*")
|
|
55
|
+
*/
|
|
56
|
+
isSchemaAllowed(environmentName: string | undefined, schemaName: string, tableName?: string): {
|
|
57
|
+
allowed: boolean;
|
|
58
|
+
reason?: string;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Simple wildcard pattern matching (supports * as wildcard)
|
|
62
|
+
*/
|
|
63
|
+
private matchesPattern;
|
|
31
64
|
getConnection(environmentName?: string): Promise<sql.ConnectionPool>;
|
|
32
65
|
private createSqlConfig;
|
|
33
66
|
closeAll(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnvironmentManager.d.ts","sourceRoot":"","sources":["../../src/config/EnvironmentManager.ts"],"names":[],"mappings":"AAGA,OAAO,GAAG,MAAM,OAAO,CAAC;AAExB,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,GAAG,SAAS,GAAG,KAAK,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,iBAAiB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"EnvironmentManager.d.ts","sourceRoot":"","sources":["../../src/config/EnvironmentManager.ts"],"names":[],"mappings":"AAGA,OAAO,GAAG,MAAM,OAAO,CAAC;AAExB,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC;AAChD,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;AACtD,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAEtD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,GAAG,SAAS,GAAG,KAAK,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAG3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,UAAU,CAAC;IAGxB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAG3B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAGzB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,iBAAiB,EAAE,CAAC;CACnC;AAmCD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiC;IAC9D,OAAO,CAAC,kBAAkB,CAAC,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA8D;gBAE9E,UAAU,CAAC,EAAE,MAAM;IAa/B,OAAO,CAAC,YAAY;IA2BpB,OAAO,CAAC,eAAe;IA+BvB,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,iBAAiB;IAahD,gBAAgB,IAAI,iBAAiB,EAAE;IAIvC;;;;OAIG;IACH,iBAAiB,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IA4CnH;;;OAGG;IACH,eAAe,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAiCnI;;OAEG;IACH,OAAO,CAAC,cAAc;IAQhB,aAAa,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;YA2B5D,eAAe;IAoFvB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAShC;AAKD,wBAAgB,qBAAqB,IAAI,kBAAkB,CAM1D"}
|
|
@@ -2,6 +2,38 @@ import * as fs from "fs";
|
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
import { InteractiveBrowserCredential } from "@azure/identity";
|
|
4
4
|
import sql from "mssql";
|
|
5
|
+
/**
|
|
6
|
+
* Resolves secret placeholders in the format ${secret:NAME}
|
|
7
|
+
* Currently supports environment variables; extensible for Key Vault, etc.
|
|
8
|
+
*/
|
|
9
|
+
function resolveSecrets(value) {
|
|
10
|
+
if (!value)
|
|
11
|
+
return value;
|
|
12
|
+
const secretPattern = /\$\{secret:([^}]+)\}/g;
|
|
13
|
+
return value.replace(secretPattern, (match, secretName) => {
|
|
14
|
+
const envValue = process.env[secretName];
|
|
15
|
+
if (envValue === undefined) {
|
|
16
|
+
console.warn(`Secret '${secretName}' not found in environment variables`);
|
|
17
|
+
return match; // Return original placeholder if not found
|
|
18
|
+
}
|
|
19
|
+
return envValue;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Recursively resolves secrets in an object's string values
|
|
24
|
+
*/
|
|
25
|
+
function resolveSecretsInConfig(config) {
|
|
26
|
+
const resolved = { ...config };
|
|
27
|
+
for (const [key, value] of Object.entries(resolved)) {
|
|
28
|
+
if (typeof value === "string") {
|
|
29
|
+
resolved[key] = resolveSecrets(value);
|
|
30
|
+
}
|
|
31
|
+
else if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
32
|
+
resolved[key] = resolveSecretsInConfig(value);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return resolved;
|
|
36
|
+
}
|
|
5
37
|
export class EnvironmentManager {
|
|
6
38
|
constructor(configPath) {
|
|
7
39
|
this.environments = new Map();
|
|
@@ -27,7 +59,9 @@ export class EnvironmentManager {
|
|
|
27
59
|
const config = JSON.parse(configContent);
|
|
28
60
|
this.defaultEnvironment = config.defaultEnvironment;
|
|
29
61
|
for (const env of config.environments) {
|
|
30
|
-
|
|
62
|
+
// Resolve any secret placeholders in the config
|
|
63
|
+
const resolvedEnv = resolveSecretsInConfig(env);
|
|
64
|
+
this.environments.set(resolvedEnv.name, resolvedEnv);
|
|
31
65
|
}
|
|
32
66
|
console.log(`Loaded ${this.environments.size} environment(s) from ${resolvedPath}`);
|
|
33
67
|
}
|
|
@@ -72,6 +106,88 @@ export class EnvironmentManager {
|
|
|
72
106
|
listEnvironments() {
|
|
73
107
|
return Array.from(this.environments.values());
|
|
74
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Check if the environment allows access to a specific database.
|
|
111
|
+
* For database-level access, only the configured database is allowed.
|
|
112
|
+
* For server-level access, checks allowedDatabases/deniedDatabases.
|
|
113
|
+
*/
|
|
114
|
+
isDatabaseAllowed(environmentName, databaseName) {
|
|
115
|
+
const env = this.getEnvironment(environmentName);
|
|
116
|
+
const accessLevel = env.accessLevel ?? "database";
|
|
117
|
+
// Database-level access: only the configured database is allowed
|
|
118
|
+
if (accessLevel === "database") {
|
|
119
|
+
if (databaseName.toLowerCase() !== env.database.toLowerCase()) {
|
|
120
|
+
return {
|
|
121
|
+
allowed: false,
|
|
122
|
+
reason: `Environment '${env.name}' has database-level access and is restricted to database '${env.database}'. Cannot access '${databaseName}'.`,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
return { allowed: true };
|
|
126
|
+
}
|
|
127
|
+
// Server-level access: check allow/deny lists
|
|
128
|
+
const deniedDatabases = env.deniedDatabases ?? [];
|
|
129
|
+
const allowedDatabases = env.allowedDatabases;
|
|
130
|
+
// Check denied list first (takes precedence)
|
|
131
|
+
if (deniedDatabases.some((db) => db.toLowerCase() === databaseName.toLowerCase())) {
|
|
132
|
+
return {
|
|
133
|
+
allowed: false,
|
|
134
|
+
reason: `Database '${databaseName}' is in the denied list for environment '${env.name}'.`,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
// Check allowed list
|
|
138
|
+
if (allowedDatabases === "*") {
|
|
139
|
+
return { allowed: true };
|
|
140
|
+
}
|
|
141
|
+
if (Array.isArray(allowedDatabases) && allowedDatabases.length > 0) {
|
|
142
|
+
if (!allowedDatabases.some((db) => db.toLowerCase() === databaseName.toLowerCase())) {
|
|
143
|
+
return {
|
|
144
|
+
allowed: false,
|
|
145
|
+
reason: `Database '${databaseName}' is not in the allowed list for environment '${env.name}'. Allowed: ${allowedDatabases.join(", ")}.`,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return { allowed: true };
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Check if a schema.table reference is allowed based on allowedSchemas/deniedSchemas.
|
|
153
|
+
* Pattern matching supports wildcards (e.g., "audit.*", "*.sensitive_*")
|
|
154
|
+
*/
|
|
155
|
+
isSchemaAllowed(environmentName, schemaName, tableName) {
|
|
156
|
+
const env = this.getEnvironment(environmentName);
|
|
157
|
+
const fullRef = tableName ? `${schemaName}.${tableName}` : schemaName;
|
|
158
|
+
const deniedSchemas = env.deniedSchemas ?? [];
|
|
159
|
+
const allowedSchemas = env.allowedSchemas;
|
|
160
|
+
// Check denied patterns first
|
|
161
|
+
for (const pattern of deniedSchemas) {
|
|
162
|
+
if (this.matchesPattern(fullRef, pattern) || this.matchesPattern(schemaName, pattern)) {
|
|
163
|
+
return {
|
|
164
|
+
allowed: false,
|
|
165
|
+
reason: `Schema/table '${fullRef}' matches denied pattern '${pattern}' in environment '${env.name}'.`,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// If allowedSchemas is specified, check against it
|
|
170
|
+
if (allowedSchemas && allowedSchemas.length > 0) {
|
|
171
|
+
const isAllowed = allowedSchemas.some((pattern) => this.matchesPattern(fullRef, pattern) || this.matchesPattern(schemaName, pattern));
|
|
172
|
+
if (!isAllowed) {
|
|
173
|
+
return {
|
|
174
|
+
allowed: false,
|
|
175
|
+
reason: `Schema/table '${fullRef}' does not match any allowed pattern in environment '${env.name}'. Allowed: ${allowedSchemas.join(", ")}.`,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return { allowed: true };
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Simple wildcard pattern matching (supports * as wildcard)
|
|
183
|
+
*/
|
|
184
|
+
matchesPattern(value, pattern) {
|
|
185
|
+
const regexPattern = pattern
|
|
186
|
+
.replace(/[.+?^${}()|[\]\\]/g, "\\$&") // Escape special regex chars except *
|
|
187
|
+
.replace(/\*/g, ".*"); // Convert * to .*
|
|
188
|
+
const regex = new RegExp(`^${regexPattern}$`, "i");
|
|
189
|
+
return regex.test(value);
|
|
190
|
+
}
|
|
75
191
|
async getConnection(environmentName) {
|
|
76
192
|
const env = this.getEnvironment(environmentName);
|
|
77
193
|
const cached = this.connections.get(env.name);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnvironmentManager.js","sourceRoot":"","sources":["../../src/config/EnvironmentManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,GAAG,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"EnvironmentManager.js","sourceRoot":"","sources":["../../src/config/EnvironmentManager.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -27,8 +27,15 @@ import { SearchSchemaTool } from "./tools/SearchSchemaTool.js";
|
|
|
27
27
|
import { ProfileTableTool } from "./tools/ProfileTableTool.js";
|
|
28
28
|
import { RelationshipInspectorTool } from "./tools/RelationshipInspectorTool.js";
|
|
29
29
|
import { ExplainQueryTool } from "./tools/ExplainQueryTool.js";
|
|
30
|
+
import { ListDatabasesTool } from "./tools/ListDatabasesTool.js";
|
|
31
|
+
import { ListEnvironmentsTool } from "./tools/ListEnvironmentsTool.js";
|
|
32
|
+
import { ValidateEnvironmentConfigTool } from "./tools/ValidateEnvironmentConfigTool.js";
|
|
30
33
|
import { auditLogger } from "./audit/AuditLogger.js";
|
|
31
34
|
import { getEnvironmentManager } from "./config/EnvironmentManager.js";
|
|
35
|
+
import * as crypto from "crypto";
|
|
36
|
+
// Generate a unique session ID for this server instance
|
|
37
|
+
// This allows correlation of all tool invocations within a single MCP session
|
|
38
|
+
const SESSION_ID = crypto.randomUUID();
|
|
32
39
|
class IntentRouter {
|
|
33
40
|
constructor(options) {
|
|
34
41
|
this.tools = options.tools;
|
|
@@ -285,6 +292,9 @@ const readDataTool = new ReadDataTool();
|
|
|
285
292
|
const createTableTool = new CreateTableTool();
|
|
286
293
|
const createIndexTool = new CreateIndexTool();
|
|
287
294
|
const listTableTool = new ListTableTool();
|
|
295
|
+
const listDatabasesTool = new ListDatabasesTool();
|
|
296
|
+
const listEnvironmentsTool = new ListEnvironmentsTool();
|
|
297
|
+
const validateEnvironmentConfigTool = new ValidateEnvironmentConfigTool();
|
|
288
298
|
const dropTableTool = new DropTableTool();
|
|
289
299
|
const describeTableTool = new DescribeTableTool();
|
|
290
300
|
const searchSchemaTool = new SearchSchemaTool();
|
|
@@ -409,6 +419,27 @@ const toolRegistry = [
|
|
|
409
419
|
requiredArgs: ["query"],
|
|
410
420
|
baseScore: 1,
|
|
411
421
|
},
|
|
422
|
+
{
|
|
423
|
+
tool: listDatabasesTool,
|
|
424
|
+
name: listDatabasesTool.name,
|
|
425
|
+
intents: ["schema_discovery", "metadata"],
|
|
426
|
+
keywords: ["databases", "list databases", "show databases", "dbs"],
|
|
427
|
+
baseScore: 1.5,
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
tool: listEnvironmentsTool,
|
|
431
|
+
name: listEnvironmentsTool.name,
|
|
432
|
+
intents: ["metadata"],
|
|
433
|
+
keywords: ["environments", "list environments", "connections", "configs"],
|
|
434
|
+
baseScore: 1.5,
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
tool: validateEnvironmentConfigTool,
|
|
438
|
+
name: validateEnvironmentConfigTool.name,
|
|
439
|
+
intents: ["metadata"],
|
|
440
|
+
keywords: ["validate", "check", "config", "configuration", "health"],
|
|
441
|
+
baseScore: 1.5,
|
|
442
|
+
},
|
|
412
443
|
];
|
|
413
444
|
const server = new Server({
|
|
414
445
|
name: "mssql-mcp-server",
|
|
@@ -428,6 +459,8 @@ const intentRouter = new IntentRouter({
|
|
|
428
459
|
});
|
|
429
460
|
const readOnlyToolList = [
|
|
430
461
|
listTableTool,
|
|
462
|
+
listEnvironmentsTool,
|
|
463
|
+
validateEnvironmentConfigTool,
|
|
431
464
|
readDataTool,
|
|
432
465
|
describeTableTool,
|
|
433
466
|
searchSchemaTool,
|
|
@@ -446,6 +479,9 @@ const fullToolList = [
|
|
|
446
479
|
createIndexTool,
|
|
447
480
|
dropTableTool,
|
|
448
481
|
listTableTool,
|
|
482
|
+
listDatabasesTool,
|
|
483
|
+
listEnvironmentsTool,
|
|
484
|
+
validateEnvironmentConfigTool,
|
|
449
485
|
searchSchemaTool,
|
|
450
486
|
profileTableTool,
|
|
451
487
|
relationshipInspectorTool,
|
|
@@ -484,6 +520,15 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
484
520
|
case listTableTool.name:
|
|
485
521
|
result = await listTableTool.run(args);
|
|
486
522
|
break;
|
|
523
|
+
case listDatabasesTool.name:
|
|
524
|
+
result = await listDatabasesTool.run(args);
|
|
525
|
+
break;
|
|
526
|
+
case listEnvironmentsTool.name:
|
|
527
|
+
result = await listEnvironmentsTool.run(args);
|
|
528
|
+
break;
|
|
529
|
+
case validateEnvironmentConfigTool.name:
|
|
530
|
+
result = await validateEnvironmentConfigTool.run(args);
|
|
531
|
+
break;
|
|
487
532
|
case dropTableTool.name:
|
|
488
533
|
result = await dropTableTool.run(args);
|
|
489
534
|
break;
|
|
@@ -555,6 +600,17 @@ runServer().catch((error) => {
|
|
|
555
600
|
console.error("Fatal error running server:", error);
|
|
556
601
|
process.exit(1);
|
|
557
602
|
});
|
|
603
|
+
// Tools that are exempt from requireApproval (metadata-only, no data modification)
|
|
604
|
+
const APPROVAL_EXEMPT_TOOLS = new Set([
|
|
605
|
+
"list_tables",
|
|
606
|
+
"list_databases",
|
|
607
|
+
"list_environments",
|
|
608
|
+
"validate_environment_config",
|
|
609
|
+
"describe_table",
|
|
610
|
+
"test_connection",
|
|
611
|
+
"search_schema",
|
|
612
|
+
"inspect_relationships",
|
|
613
|
+
]);
|
|
558
614
|
// Patch all tool handlers to ensure SQL connection, policy enforcement, and audit logging
|
|
559
615
|
function wrapToolRun(tool) {
|
|
560
616
|
const originalRun = tool.run.bind(tool);
|
|
@@ -568,8 +624,19 @@ function wrapToolRun(tool) {
|
|
|
568
624
|
name: envConfig.name,
|
|
569
625
|
readonly: envConfig.readonly ?? false,
|
|
570
626
|
allowedTools: envConfig.allowedTools,
|
|
627
|
+
deniedTools: envConfig.deniedTools,
|
|
571
628
|
maxRowsDefault: envConfig.maxRowsDefault,
|
|
629
|
+
requireApproval: envConfig.requireApproval ?? false,
|
|
630
|
+
auditLevel: envConfig.auditLevel ?? "basic",
|
|
572
631
|
};
|
|
632
|
+
// Check denied tools policy (takes precedence)
|
|
633
|
+
if (policy.deniedTools && policy.deniedTools.length > 0 && policy.deniedTools.includes(tool.name)) {
|
|
634
|
+
return {
|
|
635
|
+
success: false,
|
|
636
|
+
message: `Tool '${tool.name}' is explicitly denied in environment '${policy.name}'.`,
|
|
637
|
+
error: "TOOL_DENIED",
|
|
638
|
+
};
|
|
639
|
+
}
|
|
573
640
|
// Check allowed tools policy
|
|
574
641
|
if (policy.allowedTools && policy.allowedTools.length > 0 && !policy.allowedTools.includes(tool.name)) {
|
|
575
642
|
return {
|
|
@@ -586,6 +653,22 @@ function wrapToolRun(tool) {
|
|
|
586
653
|
error: "ENVIRONMENT_READONLY",
|
|
587
654
|
};
|
|
588
655
|
}
|
|
656
|
+
// Check requireApproval policy (skip for metadata-only tools)
|
|
657
|
+
if (policy.requireApproval && !APPROVAL_EXEMPT_TOOLS.has(tool.name)) {
|
|
658
|
+
const hasConfirmation = rawArgs.confirm === true;
|
|
659
|
+
if (!hasConfirmation) {
|
|
660
|
+
return {
|
|
661
|
+
success: false,
|
|
662
|
+
requiresApproval: true,
|
|
663
|
+
message: `Environment '${policy.name}' requires explicit approval for '${tool.name}'. Review the operation and re-run with confirm: true to proceed.`,
|
|
664
|
+
error: "APPROVAL_REQUIRED",
|
|
665
|
+
tool: tool.name,
|
|
666
|
+
environment: policy.name,
|
|
667
|
+
providedArguments: rawArgs,
|
|
668
|
+
hint: "Add 'confirm: true' to your arguments after reviewing this operation.",
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
}
|
|
589
672
|
// Enrich args with environment info and policy
|
|
590
673
|
const toolArgs = {
|
|
591
674
|
...rawArgs,
|
|
@@ -599,17 +682,25 @@ function wrapToolRun(tool) {
|
|
|
599
682
|
try {
|
|
600
683
|
const result = await originalRun(toolArgs);
|
|
601
684
|
const durationMs = Date.now() - startTime;
|
|
602
|
-
// Audit log the successful invocation
|
|
603
|
-
auditLogger.logToolInvocation(tool.name, toolArgs, result, durationMs
|
|
685
|
+
// Audit log the successful invocation with environment-specific audit level
|
|
686
|
+
auditLogger.logToolInvocation(tool.name, toolArgs, result, durationMs, {
|
|
687
|
+
sessionId: SESSION_ID,
|
|
688
|
+
environment: policy.name,
|
|
689
|
+
auditLevel: policy.auditLevel,
|
|
690
|
+
});
|
|
604
691
|
return result;
|
|
605
692
|
}
|
|
606
693
|
catch (error) {
|
|
607
694
|
const durationMs = Date.now() - startTime;
|
|
608
695
|
// Audit log the failed invocation
|
|
609
|
-
auditLogger.logToolInvocation(tool.name, toolArgs, { success: false, error: String(error) }, durationMs
|
|
696
|
+
auditLogger.logToolInvocation(tool.name, toolArgs, { success: false, error: String(error) }, durationMs, {
|
|
697
|
+
sessionId: SESSION_ID,
|
|
698
|
+
environment: policy.name,
|
|
699
|
+
auditLevel: policy.auditLevel,
|
|
700
|
+
});
|
|
610
701
|
throw error;
|
|
611
702
|
}
|
|
612
703
|
};
|
|
613
704
|
}
|
|
614
|
-
[insertDataTool, deleteDataTool, readDataTool, updateDataTool, createTableTool, createIndexTool, dropTableTool, listTableTool, describeTableTool, searchSchemaTool, profileTableTool, relationshipInspectorTool, testConnectionTool, explainQueryTool].forEach(wrapToolRun);
|
|
705
|
+
[insertDataTool, deleteDataTool, readDataTool, updateDataTool, createTableTool, createIndexTool, dropTableTool, listTableTool, listDatabasesTool, listEnvironmentsTool, validateEnvironmentConfigTool, describeTableTool, searchSchemaTool, profileTableTool, relationshipInspectorTool, testConnectionTool, explainQueryTool].forEach(wrapToolRun);
|
|
615
706
|
//# sourceMappingURL=index.js.map
|