@naganpm/snowflake-mcp-server 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/.continue/prompts/new-prompt.md +14 -0
- package/.env.example +7 -0
- package/Dockerfile +21 -0
- package/LICENSE +21 -0
- package/QUICKSTART.md +174 -0
- package/README.md +205 -0
- package/SETUP_COMPLETE.md +226 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server.d.ts +3 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +129 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/middleware/error.middleware.d.ts +3 -0
- package/dist/middleware/error.middleware.d.ts.map +1 -0
- package/dist/middleware/error.middleware.js +18 -0
- package/dist/middleware/error.middleware.js.map +1 -0
- package/dist/routes/snowflake.routes.d.ts +3 -0
- package/dist/routes/snowflake.routes.d.ts.map +1 -0
- package/dist/routes/snowflake.routes.js +120 -0
- package/dist/routes/snowflake.routes.js.map +1 -0
- package/dist/services/snowflake.service.d.ts +32 -0
- package/dist/services/snowflake.service.d.ts.map +1 -0
- package/dist/services/snowflake.service.js +126 -0
- package/dist/services/snowflake.service.js.map +1 -0
- package/docker-compose.yml +16 -0
- package/examples/usage.ts +84 -0
- package/package.json +45 -0
- package/postman_collection.json +148 -0
- package/src/index.ts +51 -0
- package/src/mcp-server.ts +137 -0
- package/src/middleware/error.middleware.ts +22 -0
- package/src/routes/snowflake.routes.ts +123 -0
- package/src/services/snowflake.service.ts +149 -0
- package/test-api.sh +39 -0
- package/tsconfig.json +28 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const express_1 = __importDefault(require("express"));
|
|
8
|
+
const cors_1 = __importDefault(require("cors"));
|
|
9
|
+
const dotenv_1 = __importDefault(require("dotenv"));
|
|
10
|
+
const snowflake_service_1 = require("./services/snowflake.service");
|
|
11
|
+
const error_middleware_1 = require("./middleware/error.middleware");
|
|
12
|
+
const snowflake_routes_1 = require("./routes/snowflake.routes");
|
|
13
|
+
dotenv_1.default.config();
|
|
14
|
+
const app = (0, express_1.default)();
|
|
15
|
+
const port = process.env.PORT || 3000;
|
|
16
|
+
// Middleware
|
|
17
|
+
app.use((0, cors_1.default)());
|
|
18
|
+
app.use(express_1.default.json());
|
|
19
|
+
app.use(express_1.default.urlencoded({ extended: true }));
|
|
20
|
+
// Health check
|
|
21
|
+
app.get('/health', (req, res) => {
|
|
22
|
+
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
|
23
|
+
});
|
|
24
|
+
// Snowflake routes
|
|
25
|
+
app.use('/api/snowflake', snowflake_routes_1.snowflakeRoutes);
|
|
26
|
+
// Error handler
|
|
27
|
+
app.use(error_middleware_1.errorHandler);
|
|
28
|
+
// Initialize Snowflake connection
|
|
29
|
+
const snowflakeService = snowflake_service_1.SnowflakeService.getInstance();
|
|
30
|
+
app.listen(port, () => {
|
|
31
|
+
console.log(`š Snowflake MCP Server running on port ${port}`);
|
|
32
|
+
console.log(`š Health check: http://localhost:${port}/health`);
|
|
33
|
+
});
|
|
34
|
+
// Graceful shutdown
|
|
35
|
+
process.on('SIGINT', async () => {
|
|
36
|
+
console.log('\nš Shutting down gracefully...');
|
|
37
|
+
await snowflakeService.disconnect();
|
|
38
|
+
process.exit(0);
|
|
39
|
+
});
|
|
40
|
+
process.on('SIGTERM', async () => {
|
|
41
|
+
console.log('\nš Shutting down gracefully...');
|
|
42
|
+
await snowflakeService.disconnect();
|
|
43
|
+
process.exit(0);
|
|
44
|
+
});
|
|
45
|
+
exports.default = app;
|
|
46
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AACA,sDAA8D;AAC9D,gDAAwB;AACxB,oDAA4B;AAC5B,oEAAgE;AAChE,oEAA6D;AAC7D,gEAA4D;AAE5D,gBAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,MAAM,GAAG,GAAY,IAAA,iBAAO,GAAE,CAAC;AAC/B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC;AAEtC,aAAa;AACb,GAAG,CAAC,GAAG,CAAC,IAAA,cAAI,GAAE,CAAC,CAAC;AAChB,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AACxB,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAEhD,eAAe;AACf,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;IACjD,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AAClE,CAAC,CAAC,CAAC;AAEH,mBAAmB;AACnB,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,kCAAe,CAAC,CAAC;AAE3C,gBAAgB;AAChB,GAAG,CAAC,GAAG,CAAC,+BAAY,CAAC,CAAC;AAEtB,kCAAkC;AAClC,MAAM,gBAAgB,GAAG,oCAAgB,CAAC,WAAW,EAAE,CAAC;AAExD,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;IACpB,OAAO,CAAC,GAAG,CAAC,2CAA2C,IAAI,EAAE,CAAC,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC,qCAAqC,IAAI,SAAS,CAAC,CAAC;AAClE,CAAC,CAAC,CAAC;AAEH,oBAAoB;AACpB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;IAC9B,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;IAChD,MAAM,gBAAgB,CAAC,UAAU,EAAE,CAAC;IACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;IAC/B,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;IAChD,MAAM,gBAAgB,CAAC,UAAU,EAAE,CAAC;IACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,kBAAe,GAAG,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
8
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
9
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
10
|
+
const snowflake_service_1 = require("./services/snowflake.service");
|
|
11
|
+
const dotenv_1 = __importDefault(require("dotenv"));
|
|
12
|
+
dotenv_1.default.config();
|
|
13
|
+
const snowflakeService = snowflake_service_1.SnowflakeService.getInstance();
|
|
14
|
+
const server = new index_js_1.Server({
|
|
15
|
+
name: 'snowflake-mcp-server',
|
|
16
|
+
version: '1.0.0',
|
|
17
|
+
}, {
|
|
18
|
+
capabilities: {
|
|
19
|
+
tools: {},
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
|
|
23
|
+
return {
|
|
24
|
+
tools: [
|
|
25
|
+
{
|
|
26
|
+
name: 'execute_query',
|
|
27
|
+
description: 'Execute a SQL query on Snowflake database',
|
|
28
|
+
inputSchema: {
|
|
29
|
+
type: 'object',
|
|
30
|
+
properties: {
|
|
31
|
+
query: { type: 'string', description: 'SQL query to execute' },
|
|
32
|
+
binds: { type: 'array', description: 'Optional bind parameters' },
|
|
33
|
+
},
|
|
34
|
+
required: ['query'],
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'list_databases',
|
|
39
|
+
description: 'List all databases',
|
|
40
|
+
inputSchema: { type: 'object', properties: {} },
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'list_schemas',
|
|
44
|
+
description: 'List schemas',
|
|
45
|
+
inputSchema: {
|
|
46
|
+
type: 'object',
|
|
47
|
+
properties: { database: { type: 'string' } },
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'list_tables',
|
|
52
|
+
description: 'List tables',
|
|
53
|
+
inputSchema: {
|
|
54
|
+
type: 'object',
|
|
55
|
+
properties: { database: { type: 'string' }, schema: { type: 'string' } },
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'describe_table',
|
|
60
|
+
description: 'Describe table structure',
|
|
61
|
+
inputSchema: {
|
|
62
|
+
type: 'object',
|
|
63
|
+
properties: { tableName: { type: 'string' } },
|
|
64
|
+
required: ['tableName'],
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'list_warehouses',
|
|
69
|
+
description: 'List warehouses',
|
|
70
|
+
inputSchema: { type: 'object', properties: {} },
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: 'get_session_info',
|
|
74
|
+
description: 'Get session info',
|
|
75
|
+
inputSchema: { type: 'object', properties: {} },
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
81
|
+
try {
|
|
82
|
+
const { name, arguments: args } = request.params;
|
|
83
|
+
let result;
|
|
84
|
+
switch (name) {
|
|
85
|
+
case 'execute_query':
|
|
86
|
+
result = await snowflakeService.executeQuery(args?.query || '', args?.binds);
|
|
87
|
+
break;
|
|
88
|
+
case 'list_databases':
|
|
89
|
+
result = await snowflakeService.listDatabases();
|
|
90
|
+
break;
|
|
91
|
+
case 'list_schemas':
|
|
92
|
+
result = await snowflakeService.listSchemas(args?.database);
|
|
93
|
+
break;
|
|
94
|
+
case 'list_tables':
|
|
95
|
+
result = await snowflakeService.listTables(args?.database, args?.schema);
|
|
96
|
+
break;
|
|
97
|
+
case 'describe_table':
|
|
98
|
+
result = await snowflakeService.describeTable(args?.tableName || '');
|
|
99
|
+
break;
|
|
100
|
+
case 'list_warehouses':
|
|
101
|
+
result = await snowflakeService.listWarehouses();
|
|
102
|
+
break;
|
|
103
|
+
case 'get_session_info':
|
|
104
|
+
result = await snowflakeService.getCurrentSession();
|
|
105
|
+
break;
|
|
106
|
+
default:
|
|
107
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
return {
|
|
115
|
+
content: [{ type: 'text', text: `Error: ${error.message}` }],
|
|
116
|
+
isError: true,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
async function main() {
|
|
121
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
122
|
+
await server.connect(transport);
|
|
123
|
+
console.error('Snowflake MCP server running on stdio');
|
|
124
|
+
}
|
|
125
|
+
main().catch((error) => {
|
|
126
|
+
console.error('Failed to start MCP server:', error);
|
|
127
|
+
process.exit(1);
|
|
128
|
+
});
|
|
129
|
+
//# sourceMappingURL=mcp-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/error.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE1D,eAAO,MAAM,YAAY,GACvB,KAAK,GAAG,EACR,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,MAAM,YAAY,SAenB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.errorHandler = void 0;
|
|
4
|
+
const errorHandler = (err, req, res, next) => {
|
|
5
|
+
console.error('ā Error:', err);
|
|
6
|
+
const statusCode = err.statusCode || 500;
|
|
7
|
+
const message = err.message || 'Internal Server Error';
|
|
8
|
+
res.status(statusCode).json({
|
|
9
|
+
success: false,
|
|
10
|
+
error: {
|
|
11
|
+
message,
|
|
12
|
+
code: err.code || 'INTERNAL_ERROR',
|
|
13
|
+
...(process.env.NODE_ENV === 'development' && { stack: err.stack }),
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
exports.errorHandler = errorHandler;
|
|
18
|
+
//# sourceMappingURL=error.middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.middleware.js","sourceRoot":"","sources":["../../src/middleware/error.middleware.ts"],"names":[],"mappings":";;;AAEO,MAAM,YAAY,GAAG,CAC1B,GAAQ,EACR,GAAY,EACZ,GAAa,EACb,IAAkB,EAClB,EAAE;IACF,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IAE/B,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC;IACzC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,uBAAuB,CAAC;IAEvD,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;QAC1B,OAAO,EAAE,KAAK;QACd,KAAK,EAAE;YACL,OAAO;YACP,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,gBAAgB;YAClC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC;SACpE;KACF,CAAC,CAAC;AACL,CAAC,CAAC;AAnBW,QAAA,YAAY,gBAmBvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snowflake.routes.d.ts","sourceRoot":"","sources":["../../src/routes/snowflake.routes.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAuHxB,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.snowflakeRoutes = void 0;
|
|
4
|
+
const express_1 = require("express");
|
|
5
|
+
const snowflake_service_1 = require("../services/snowflake.service");
|
|
6
|
+
const router = (0, express_1.Router)();
|
|
7
|
+
exports.snowflakeRoutes = router;
|
|
8
|
+
const snowflakeService = snowflake_service_1.SnowflakeService.getInstance();
|
|
9
|
+
// Execute query
|
|
10
|
+
router.post('/query', async (req, res, next) => {
|
|
11
|
+
try {
|
|
12
|
+
const { query, binds } = req.body;
|
|
13
|
+
if (!query) {
|
|
14
|
+
return res.status(400).json({ error: 'Query is required' });
|
|
15
|
+
}
|
|
16
|
+
const result = await snowflakeService.executeQuery(query, binds);
|
|
17
|
+
res.json({
|
|
18
|
+
success: true,
|
|
19
|
+
data: result,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
next(error);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
// List databases
|
|
27
|
+
router.get('/databases', async (req, res, next) => {
|
|
28
|
+
try {
|
|
29
|
+
const result = await snowflakeService.listDatabases();
|
|
30
|
+
res.json({
|
|
31
|
+
success: true,
|
|
32
|
+
data: result,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
next(error);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
// List schemas
|
|
40
|
+
router.get('/schemas', async (req, res, next) => {
|
|
41
|
+
try {
|
|
42
|
+
const { database } = req.query;
|
|
43
|
+
const result = await snowflakeService.listSchemas(database);
|
|
44
|
+
res.json({
|
|
45
|
+
success: true,
|
|
46
|
+
data: result,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
next(error);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
// List tables
|
|
54
|
+
router.get('/tables', async (req, res, next) => {
|
|
55
|
+
try {
|
|
56
|
+
const { database, schema } = req.query;
|
|
57
|
+
const result = await snowflakeService.listTables(database, schema);
|
|
58
|
+
res.json({
|
|
59
|
+
success: true,
|
|
60
|
+
data: result,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
next(error);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
// Describe table
|
|
68
|
+
router.get('/tables/:tableName/describe', async (req, res, next) => {
|
|
69
|
+
try {
|
|
70
|
+
const { tableName } = req.params;
|
|
71
|
+
const result = await snowflakeService.describeTable(tableName);
|
|
72
|
+
res.json({
|
|
73
|
+
success: true,
|
|
74
|
+
data: result,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
next(error);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
// List warehouses
|
|
82
|
+
router.get('/warehouses', async (req, res, next) => {
|
|
83
|
+
try {
|
|
84
|
+
const result = await snowflakeService.listWarehouses();
|
|
85
|
+
res.json({
|
|
86
|
+
success: true,
|
|
87
|
+
data: result,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
next(error);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
// Get current session
|
|
95
|
+
router.get('/session', async (req, res, next) => {
|
|
96
|
+
try {
|
|
97
|
+
const result = await snowflakeService.getCurrentSession();
|
|
98
|
+
res.json({
|
|
99
|
+
success: true,
|
|
100
|
+
data: result,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
next(error);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
// Connection status
|
|
108
|
+
router.get('/status', async (req, res, next) => {
|
|
109
|
+
try {
|
|
110
|
+
const isConnected = snowflakeService.isConnected();
|
|
111
|
+
res.json({
|
|
112
|
+
success: true,
|
|
113
|
+
connected: isConnected,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
next(error);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
//# sourceMappingURL=snowflake.routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snowflake.routes.js","sourceRoot":"","sources":["../../src/routes/snowflake.routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface SnowflakeConfig {
|
|
2
|
+
account: string;
|
|
3
|
+
username: string;
|
|
4
|
+
password: string;
|
|
5
|
+
warehouse?: string;
|
|
6
|
+
database?: string;
|
|
7
|
+
schema?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface QueryResult {
|
|
10
|
+
columns: string[];
|
|
11
|
+
rows: any[];
|
|
12
|
+
rowCount: number;
|
|
13
|
+
executionTime: number;
|
|
14
|
+
}
|
|
15
|
+
export declare class SnowflakeService {
|
|
16
|
+
private static instance;
|
|
17
|
+
private connection;
|
|
18
|
+
private config;
|
|
19
|
+
private constructor();
|
|
20
|
+
static getInstance(): SnowflakeService;
|
|
21
|
+
private connect;
|
|
22
|
+
executeQuery(sqlText: string, binds?: any[]): Promise<QueryResult>;
|
|
23
|
+
listDatabases(): Promise<QueryResult>;
|
|
24
|
+
listSchemas(database?: string): Promise<QueryResult>;
|
|
25
|
+
listTables(database?: string, schema?: string): Promise<QueryResult>;
|
|
26
|
+
describeTable(tableName: string): Promise<QueryResult>;
|
|
27
|
+
listWarehouses(): Promise<QueryResult>;
|
|
28
|
+
getCurrentSession(): Promise<QueryResult>;
|
|
29
|
+
disconnect(): Promise<void>;
|
|
30
|
+
isConnected(): boolean;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=snowflake.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snowflake.service.d.ts","sourceRoot":"","sources":["../../src/services/snowflake.service.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAmB;IAC1C,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,MAAM,CAAkB;IAEhC,OAAO;WAWO,WAAW,IAAI,gBAAgB;YAO/B,OAAO;IA8BR,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IA2BlE,aAAa,IAAI,OAAO,CAAC,WAAW,CAAC;IAIrC,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAOpD,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAOpE,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAItD,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;IAItC,iBAAiB,IAAI,OAAO,CAAC,WAAW,CAAC;IAIzC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBjC,WAAW,IAAI,OAAO;CAG9B"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SnowflakeService = void 0;
|
|
7
|
+
const snowflake_sdk_1 = __importDefault(require("snowflake-sdk"));
|
|
8
|
+
class SnowflakeService {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.connection = null;
|
|
11
|
+
this.config = {
|
|
12
|
+
account: process.env.SNOWFLAKE_ACCOUNT || '',
|
|
13
|
+
username: process.env.SNOWFLAKE_USERNAME || '',
|
|
14
|
+
password: process.env.SNOWFLAKE_PASSWORD || '',
|
|
15
|
+
warehouse: process.env.SNOWFLAKE_WAREHOUSE,
|
|
16
|
+
database: process.env.SNOWFLAKE_DATABASE,
|
|
17
|
+
schema: process.env.SNOWFLAKE_SCHEMA,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
static getInstance() {
|
|
21
|
+
if (!SnowflakeService.instance) {
|
|
22
|
+
SnowflakeService.instance = new SnowflakeService();
|
|
23
|
+
}
|
|
24
|
+
return SnowflakeService.instance;
|
|
25
|
+
}
|
|
26
|
+
async connect() {
|
|
27
|
+
if (this.connection) {
|
|
28
|
+
return this.connection;
|
|
29
|
+
}
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
const connectionOptions = {
|
|
32
|
+
account: this.config.account,
|
|
33
|
+
username: this.config.username,
|
|
34
|
+
password: this.config.password,
|
|
35
|
+
};
|
|
36
|
+
if (this.config.warehouse)
|
|
37
|
+
connectionOptions.warehouse = this.config.warehouse;
|
|
38
|
+
if (this.config.database)
|
|
39
|
+
connectionOptions.database = this.config.database;
|
|
40
|
+
if (this.config.schema)
|
|
41
|
+
connectionOptions.schema = this.config.schema;
|
|
42
|
+
this.connection = snowflake_sdk_1.default.createConnection(connectionOptions);
|
|
43
|
+
this.connection.connect((err, conn) => {
|
|
44
|
+
if (err) {
|
|
45
|
+
console.error('ā Failed to connect to Snowflake:', err.message);
|
|
46
|
+
reject(err);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
console.log('ā
Successfully connected to Snowflake');
|
|
50
|
+
resolve(conn);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
async executeQuery(sqlText, binds) {
|
|
56
|
+
const startTime = Date.now();
|
|
57
|
+
const conn = await this.connect();
|
|
58
|
+
return new Promise((resolve, reject) => {
|
|
59
|
+
conn.execute({
|
|
60
|
+
sqlText,
|
|
61
|
+
binds,
|
|
62
|
+
complete: (err, stmt, rows) => {
|
|
63
|
+
const executionTime = Date.now() - startTime;
|
|
64
|
+
if (err) {
|
|
65
|
+
reject(err);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
const columns = stmt.getColumns().map(col => col.getName());
|
|
69
|
+
resolve({
|
|
70
|
+
columns,
|
|
71
|
+
rows: rows || [],
|
|
72
|
+
rowCount: rows?.length || 0,
|
|
73
|
+
executionTime,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
async listDatabases() {
|
|
81
|
+
return this.executeQuery('SHOW DATABASES');
|
|
82
|
+
}
|
|
83
|
+
async listSchemas(database) {
|
|
84
|
+
if (database) {
|
|
85
|
+
return this.executeQuery(`SHOW SCHEMAS IN DATABASE ${database}`);
|
|
86
|
+
}
|
|
87
|
+
return this.executeQuery('SHOW SCHEMAS');
|
|
88
|
+
}
|
|
89
|
+
async listTables(database, schema) {
|
|
90
|
+
if (database && schema) {
|
|
91
|
+
return this.executeQuery(`SHOW TABLES IN ${database}.${schema}`);
|
|
92
|
+
}
|
|
93
|
+
return this.executeQuery('SHOW TABLES');
|
|
94
|
+
}
|
|
95
|
+
async describeTable(tableName) {
|
|
96
|
+
return this.executeQuery(`DESCRIBE TABLE ${tableName}`);
|
|
97
|
+
}
|
|
98
|
+
async listWarehouses() {
|
|
99
|
+
return this.executeQuery('SHOW WAREHOUSES');
|
|
100
|
+
}
|
|
101
|
+
async getCurrentSession() {
|
|
102
|
+
return this.executeQuery('SELECT CURRENT_USER(), CURRENT_ROLE(), CURRENT_DATABASE(), CURRENT_SCHEMA(), CURRENT_WAREHOUSE()');
|
|
103
|
+
}
|
|
104
|
+
async disconnect() {
|
|
105
|
+
if (this.connection) {
|
|
106
|
+
return new Promise((resolve, reject) => {
|
|
107
|
+
this.connection.destroy((err) => {
|
|
108
|
+
if (err) {
|
|
109
|
+
console.error('ā Error disconnecting from Snowflake:', err.message);
|
|
110
|
+
reject(err);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
console.log('ā
Disconnected from Snowflake');
|
|
114
|
+
this.connection = null;
|
|
115
|
+
resolve();
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
isConnected() {
|
|
122
|
+
return this.connection !== null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
exports.SnowflakeService = SnowflakeService;
|
|
126
|
+
//# sourceMappingURL=snowflake.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snowflake.service.js","sourceRoot":"","sources":["../../src/services/snowflake.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
version: '3.8'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
snowflake-mcp:
|
|
5
|
+
build: .
|
|
6
|
+
ports:
|
|
7
|
+
- "3000:3000"
|
|
8
|
+
environment:
|
|
9
|
+
- SNOWFLAKE_ACCOUNT=${SNOWFLAKE_ACCOUNT}
|
|
10
|
+
- SNOWFLAKE_USERNAME=${SNOWFLAKE_USERNAME}
|
|
11
|
+
- SNOWFLAKE_PASSWORD=${SNOWFLAKE_PASSWORD}
|
|
12
|
+
- SNOWFLAKE_WAREHOUSE=${SNOWFLAKE_WAREHOUSE}
|
|
13
|
+
- SNOWFLAKE_DATABASE=${SNOWFLAKE_DATABASE}
|
|
14
|
+
- SNOWFLAKE_SCHEMA=${SNOWFLAKE_SCHEMA}
|
|
15
|
+
- PORT=3000
|
|
16
|
+
restart: unless-stopped
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example usage of Snowflake MCP Server
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const BASE_URL = 'http://localhost:3000';
|
|
6
|
+
|
|
7
|
+
// Example 1: Execute a simple query
|
|
8
|
+
async function executeQuery() {
|
|
9
|
+
const response = await fetch(`${BASE_URL}/api/snowflake/query`, {
|
|
10
|
+
method: 'POST',
|
|
11
|
+
headers: {
|
|
12
|
+
'Content-Type': 'application/json',
|
|
13
|
+
},
|
|
14
|
+
body: JSON.stringify({
|
|
15
|
+
query: 'SELECT CURRENT_DATE() as today, CURRENT_USER() as user',
|
|
16
|
+
}),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const result = await response.json();
|
|
20
|
+
console.log('Query Result:', result);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Example 2: List all databases
|
|
24
|
+
async function listDatabases() {
|
|
25
|
+
const response = await fetch(`${BASE_URL}/api/snowflake/databases`);
|
|
26
|
+
const result = await response.json();
|
|
27
|
+
console.log('Databases:', result);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Example 3: List tables in a specific database and schema
|
|
31
|
+
async function listTables(database: string, schema: string) {
|
|
32
|
+
const response = await fetch(
|
|
33
|
+
`${BASE_URL}/api/snowflake/tables?database=${database}&schema=${schema}`
|
|
34
|
+
);
|
|
35
|
+
const result = await response.json();
|
|
36
|
+
console.log('Tables:', result);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Example 4: Describe a table
|
|
40
|
+
async function describeTable(tableName: string) {
|
|
41
|
+
const response = await fetch(
|
|
42
|
+
`${BASE_URL}/api/snowflake/tables/${tableName}/describe`
|
|
43
|
+
);
|
|
44
|
+
const result = await response.json();
|
|
45
|
+
console.log('Table Description:', result);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Example 5: Get current session info
|
|
49
|
+
async function getSessionInfo() {
|
|
50
|
+
const response = await fetch(`${BASE_URL}/api/snowflake/session`);
|
|
51
|
+
const result = await response.json();
|
|
52
|
+
console.log('Session Info:', result);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Example 6: Execute query with parameters
|
|
56
|
+
async function executeQueryWithBinds() {
|
|
57
|
+
const response = await fetch(`${BASE_URL}/api/snowflake/query`, {
|
|
58
|
+
method: 'POST',
|
|
59
|
+
headers: {
|
|
60
|
+
'Content-Type': 'application/json',
|
|
61
|
+
},
|
|
62
|
+
body: JSON.stringify({
|
|
63
|
+
query: 'SELECT * FROM table_name WHERE id = ? AND status = ?',
|
|
64
|
+
binds: [123, 'active'],
|
|
65
|
+
}),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const result = await response.json();
|
|
69
|
+
console.log('Query Result with Binds:', result);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Run examples
|
|
73
|
+
async function main() {
|
|
74
|
+
try {
|
|
75
|
+
await executeQuery();
|
|
76
|
+
await listDatabases();
|
|
77
|
+
await getSessionInfo();
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error('Error:', error);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Uncomment to run
|
|
84
|
+
// main();
|