@naganpm/snowflake-mcp-server 1.0.2 โ†’ 1.0.5

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 CHANGED
@@ -22,6 +22,26 @@ npm install
22
22
 
23
23
  ## Configuration
24
24
 
25
+ #### Approach1
26
+
27
+ Note: If you are trying to configure MCP using continue.dev
28
+
29
+ ```
30
+ mcpServers:
31
+ - name: snowflake MCP
32
+ command: npx
33
+ args:
34
+ - -y
35
+ - "@naganpm/snowflake-mcp-server@latest"
36
+ env:
37
+ SNOWFLAKE_ACCOUNT: <account-id>.us-east-2.aws
38
+ SNOWFLAKE_USERNAME: <your-username>
39
+ SNOWFLAKE_PASSWORD: <your-password>
40
+ SNOWFLAKE_WAREHOUSE: <warehouse-name>
41
+ SNOWFLAKE_DATABASE: <database-name>
42
+ SNOWFLAKE_SCHEMA: <schema-name>
43
+ ```
44
+ #### Approach2
25
45
  1. Copy `.env.example` to `.env`:
26
46
  ```bash
27
47
  cp .env.example .env
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naganpm/snowflake-mcp-server",
3
- "version": "1.0.2",
3
+ "version": "1.0.5",
4
4
  "description": "MCP server for Snowflake database integration",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -23,6 +23,11 @@
23
23
  "express",
24
24
  "typescript"
25
25
  ],
26
+ "files": [
27
+ "dist",
28
+ "README.md",
29
+ "LICENSE"
30
+ ],
26
31
  "author": "",
27
32
  "license": "MIT",
28
33
  "dependencies": {
@@ -42,4 +47,4 @@
42
47
  "engines": {
43
48
  "node": ">=18.0.0"
44
49
  }
45
- }
50
+ }
@@ -1,14 +0,0 @@
1
- ---
2
- name: Snowflake MCP
3
- description: Create a snowflake MCP
4
- invokable: true
5
- ---
6
-
7
- URL: https://bd50859.us-east-2.aws.snowflakecomputing.com/
8
- USERNAME: DEP_QA2
9
- PASSWORD: Depqa2222$
10
-
11
- ### Instructions
12
- - Create a snowflake mcp server in current folder and I want to configure this MCP as npm package.
13
- - Use express.js and typescript preferrably.
14
- - You can refer to @naganpm/mysql-mcp-server npm package for reference.
package/.env.example DELETED
@@ -1,7 +0,0 @@
1
- SNOWFLAKE_ACCOUNT=your-account.region.cloud
2
- SNOWFLAKE_USERNAME=your-username
3
- SNOWFLAKE_PASSWORD=your-password
4
- SNOWFLAKE_WAREHOUSE=
5
- SNOWFLAKE_DATABASE=
6
- SNOWFLAKE_SCHEMA=
7
- PORT=3000
package/Dockerfile DELETED
@@ -1,21 +0,0 @@
1
- FROM node:18-alpine
2
-
3
- WORKDIR /app
4
-
5
- # Copy package files
6
- COPY package*.json ./
7
-
8
- # Install dependencies
9
- RUN npm ci --only=production
10
-
11
- # Copy built files
12
- COPY dist ./dist
13
-
14
- # Expose port
15
- EXPOSE 3000
16
-
17
- # Set environment variable
18
- ENV NODE_ENV=production
19
-
20
- # Start the server
21
- CMD ["node", "dist/index.js"]
package/QUICKSTART.md DELETED
@@ -1,174 +0,0 @@
1
- # Snowflake MCP Server - Quick Start Guide
2
-
3
- ## ๐Ÿš€ Getting Started
4
-
5
- ### 1. Install Dependencies
6
- ```bash
7
- npm install
8
- ```
9
-
10
- ### 2. Configure Environment
11
- Edit `.env` file with your Snowflake credentials:
12
- ```env
13
- SNOWFLAKE_ACCOUNT=your-account.region.cloud
14
- SNOWFLAKE_USERNAME=your-username
15
- SNOWFLAKE_PASSWORD=your-password
16
- SNOWFLAKE_WAREHOUSE=YOUR_WAREHOUSE # Optional
17
- SNOWFLAKE_DATABASE=YOUR_DATABASE # Optional
18
- SNOWFLAKE_SCHEMA=YOUR_SCHEMA # Optional
19
- PORT=3000
20
- ```
21
-
22
- ### 3. Run the Server
23
-
24
- **Development Mode:**
25
- ```bash
26
- npm run dev
27
- ```
28
-
29
- **Production Mode:**
30
- ```bash
31
- npm run build
32
- npm start
33
- ```
34
-
35
- ## ๐Ÿ“ก API Endpoints
36
-
37
- | Method | Endpoint | Description |
38
- |--------|----------|-------------|
39
- | GET | `/health` | Health check |
40
- | GET | `/api/snowflake/status` | Connection status |
41
- | POST | `/api/snowflake/query` | Execute SQL query |
42
- | GET | `/api/snowflake/databases` | List databases |
43
- | GET | `/api/snowflake/schemas` | List schemas |
44
- | GET | `/api/snowflake/tables` | List tables |
45
- | GET | `/api/snowflake/tables/:name/describe` | Describe table |
46
- | GET | `/api/snowflake/warehouses` | List warehouses |
47
- | GET | `/api/snowflake/session` | Current session info |
48
-
49
- ## ๐Ÿงช Testing
50
-
51
- ### Using cURL
52
- ```bash
53
- # Health check
54
- curl http://localhost:3000/health
55
-
56
- # Execute query
57
- curl -X POST http://localhost:3000/api/snowflake/query \
58
- -H "Content-Type: application/json" \
59
- -d '{"query": "SELECT CURRENT_DATE()"}'
60
- ```
61
-
62
- ### Using the test script
63
- ```bash
64
- ./test-api.sh
65
- ```
66
-
67
- ### Import Postman Collection
68
- Import `postman_collection.json` into Postman for easy testing.
69
-
70
- ## ๐Ÿ“ฆ NPM Package Usage
71
-
72
- After publishing to NPM, users can install:
73
- ```bash
74
- npm install @naganpm/snowflake-mcp-server
75
- ```
76
-
77
- Then use programmatically:
78
- ```typescript
79
- import { SnowflakeService } from '@naganpm/snowflake-mcp-server';
80
-
81
- const service = SnowflakeService.getInstance();
82
- const result = await service.executeQuery('SELECT 1');
83
- ```
84
-
85
- ## ๐Ÿณ Docker Deployment
86
-
87
- ```bash
88
- # Build and run with Docker Compose
89
- docker-compose up -d
90
-
91
- # Or build manually
92
- docker build -t snowflake-mcp .
93
- docker run -p 3000:3000 --env-file .env snowflake-mcp
94
- ```
95
-
96
- ## ๐Ÿ“ Project Structure
97
-
98
- ```
99
- snowflake-mcp-server/
100
- โ”œโ”€โ”€ src/
101
- โ”‚ โ”œโ”€โ”€ index.ts # Main server entry
102
- โ”‚ โ”œโ”€โ”€ services/
103
- โ”‚ โ”‚ โ””โ”€โ”€ snowflake.service.ts # Snowflake SDK wrapper
104
- โ”‚ โ”œโ”€โ”€ routes/
105
- โ”‚ โ”‚ โ””โ”€โ”€ snowflake.routes.ts # API routes
106
- โ”‚ โ””โ”€โ”€ middleware/
107
- โ”‚ โ””โ”€โ”€ error.middleware.ts # Error handling
108
- โ”œโ”€โ”€ dist/ # Compiled JavaScript
109
- โ”œโ”€โ”€ examples/ # Usage examples
110
- โ”œโ”€โ”€ package.json
111
- โ”œโ”€โ”€ tsconfig.json
112
- โ”œโ”€โ”€ .env # Environment config
113
- โ”œโ”€โ”€ Dockerfile
114
- โ”œโ”€โ”€ docker-compose.yml
115
- โ””โ”€โ”€ README.md
116
- ```
117
-
118
- ## ๐Ÿ”’ Security Notes
119
-
120
- - Never commit `.env` file to version control
121
- - Use environment variables for sensitive data
122
- - Consider using Snowflake key-pair authentication for production
123
- - Implement rate limiting for production use
124
- - Add authentication/authorization middleware
125
-
126
- ## ๐Ÿ› ๏ธ Development Commands
127
-
128
- | Command | Description |
129
- |---------|-------------|
130
- | `npm run dev` | Run in development mode |
131
- | `npm run build` | Build TypeScript to JavaScript |
132
- | `npm start` | Run production build |
133
- | `npm run watch` | Watch mode for development |
134
- | `npm run clean` | Clean dist folder |
135
-
136
- ## ๐Ÿ“ Publishing to NPM
137
-
138
- 1. Update version in `package.json`
139
- 2. Build the project: `npm run build`
140
- 3. Login to NPM: `npm login`
141
- 4. Publish: `npm publish --access public`
142
-
143
- ## ๐Ÿค Contributing
144
-
145
- 1. Fork the repository
146
- 2. Create a feature branch
147
- 3. Make your changes
148
- 4. Submit a pull request
149
-
150
- ## ๐Ÿ“„ License
151
-
152
- MIT License - see LICENSE file for details
153
-
154
- ## ๐Ÿ†˜ Troubleshooting
155
-
156
- ### Connection Issues
157
- - Verify Snowflake credentials in `.env`
158
- - Check network connectivity to Snowflake
159
- - Ensure account format is correct (account.region.cloud)
160
-
161
- ### Build Issues
162
- - Clear node_modules: `rm -rf node_modules && npm install`
163
- - Clear dist: `npm run clean && npm run build`
164
-
165
- ### Runtime Issues
166
- - Check logs for error messages
167
- - Verify environment variables are loaded
168
- - Test with simple queries first
169
-
170
- ## ๐Ÿ“š Additional Resources
171
-
172
- - [Snowflake SDK Documentation](https://docs.snowflake.com/en/user-guide/nodejs-driver)
173
- - [Express.js Documentation](https://expressjs.com/)
174
- - [TypeScript Documentation](https://www.typescriptlang.org/)
package/SETUP_COMPLETE.md DELETED
@@ -1,226 +0,0 @@
1
- # Snowflake MCP Server - Complete Setup โœ…
2
-
3
- ## โœจ What Has Been Created
4
-
5
- A production-ready Snowflake MCP (Model Context Protocol) server configured as an NPM package with the following features:
6
-
7
- ### ๐ŸŽฏ Core Features
8
- - **Express.js REST API** with TypeScript
9
- - **Snowflake SDK Integration** for database operations
10
- - **Singleton Pattern** for connection management
11
- - **Error Handling Middleware**
12
- - **CORS Support**
13
- - **Environment Configuration**
14
- - **Health Monitoring**
15
-
16
- ### ๐Ÿ“‚ Project Structure
17
- ```
18
- snowflake-mcp-server/
19
- โ”œโ”€โ”€ src/
20
- โ”‚ โ”œโ”€โ”€ index.ts # Main server (Express app)
21
- โ”‚ โ”œโ”€โ”€ services/
22
- โ”‚ โ”‚ โ””โ”€โ”€ snowflake.service.ts # Snowflake connection & queries
23
- โ”‚ โ”œโ”€โ”€ routes/
24
- โ”‚ โ”‚ โ””โ”€โ”€ snowflake.routes.ts # API endpoints
25
- โ”‚ โ””โ”€โ”€ middleware/
26
- โ”‚ โ””โ”€โ”€ error.middleware.ts # Error handling
27
- โ”œโ”€โ”€ dist/ # Compiled JavaScript
28
- โ”œโ”€โ”€ examples/
29
- โ”‚ โ””โ”€โ”€ usage.ts # Usage examples
30
- โ”œโ”€โ”€ node_modules/ # Dependencies
31
- โ”œโ”€โ”€ .env # Your Snowflake credentials
32
- โ”œโ”€โ”€ .env.example # Template
33
- โ”œโ”€โ”€ package.json # NPM configuration
34
- โ”œโ”€โ”€ tsconfig.json # TypeScript config
35
- โ”œโ”€โ”€ Dockerfile # Docker image
36
- โ”œโ”€โ”€ docker-compose.yml # Docker compose
37
- โ”œโ”€โ”€ postman_collection.json # API testing
38
- โ”œโ”€โ”€ test-api.sh # Bash test script
39
- โ”œโ”€โ”€ README.md # Full documentation
40
- โ”œโ”€โ”€ QUICKSTART.md # Quick start guide
41
- โ””โ”€โ”€ LICENSE # MIT license
42
- ```
43
-
44
- ### ๐Ÿ”Œ Available API Endpoints
45
-
46
- | Endpoint | Method | Description |
47
- |----------|--------|-------------|
48
- | `/health` | GET | Health check |
49
- | `/api/snowflake/status` | GET | Connection status |
50
- | `/api/snowflake/query` | POST | Execute SQL query |
51
- | `/api/snowflake/databases` | GET | List all databases |
52
- | `/api/snowflake/schemas` | GET | List schemas |
53
- | `/api/snowflake/tables` | GET | List tables |
54
- | `/api/snowflake/tables/:name/describe` | GET | Describe table structure |
55
- | `/api/snowflake/warehouses` | GET | List warehouses |
56
- | `/api/snowflake/session` | GET | Current session info |
57
-
58
- ### ๐Ÿ”ง Configuration
59
-
60
- **Port:** 3000
61
-
62
- All credentials should be stored in `.env` file (not committed to git).
63
-
64
- See `.env.example` for configuration template.
65
-
66
- ## ๐Ÿš€ Quick Start Commands
67
-
68
- ### 1. Development Mode
69
- ```bash
70
- npm run dev
71
- # Server runs at: http://localhost:3000
72
- ```
73
-
74
- ### 2. Build for Production
75
- ```bash
76
- npm run build
77
- ```
78
-
79
- ### 3. Run Production Build
80
- ```bash
81
- npm start
82
- ```
83
-
84
- ### 4. Test the API
85
- ```bash
86
- # Using curl
87
- curl http://localhost:3000/health
88
-
89
- # Using the test script
90
- ./test-api.sh
91
-
92
- # Using Postman
93
- # Import postman_collection.json into Postman
94
- ```
95
-
96
- ## ๐Ÿ“ฆ NPM Package Details
97
-
98
- - **Package Name:** `@naganpm/snowflake-mcp-server`
99
- - **Version:** 1.0.0
100
- - **Main Entry:** `dist/index.js`
101
- - **TypeScript Definitions:** `dist/index.d.ts`
102
- - **Binary:** `snowflake-mcp-server`
103
-
104
- ### To Publish to NPM:
105
- ```bash
106
- npm login
107
- npm publish --access public
108
- ```
109
-
110
- ## ๐Ÿงช Testing Examples
111
-
112
- ### Test Health Check
113
- ```bash
114
- curl http://localhost:3000/health
115
- ```
116
-
117
- ### Execute a Query
118
- ```bash
119
- curl -X POST http://localhost:3000/api/snowflake/query \
120
- -H "Content-Type: application/json" \
121
- -d '{
122
- "query": "SELECT CURRENT_DATE(), CURRENT_USER(), CURRENT_ROLE()"
123
- }'
124
- ```
125
-
126
- ### List Databases
127
- ```bash
128
- curl http://localhost:3000/api/snowflake/databases
129
- ```
130
-
131
- ### Get Session Info
132
- ```bash
133
- curl http://localhost:3000/api/snowflake/session
134
- ```
135
-
136
- ## ๐Ÿณ Docker Deployment
137
-
138
- ### Build and Run
139
- ```bash
140
- docker-compose up -d
141
- ```
142
-
143
- ### Manual Docker Build
144
- ```bash
145
- docker build -t snowflake-mcp .
146
- docker run -p 3000:3000 --env-file .env snowflake-mcp
147
- ```
148
-
149
- ## ๐Ÿ“š Key Dependencies
150
-
151
- - **express** ^4.18.2 - Web framework
152
- - **snowflake-sdk** ^1.11.0 - Snowflake database driver
153
- - **typescript** ^5.3.3 - Type safety
154
- - **dotenv** ^16.4.1 - Environment configuration
155
- - **cors** ^2.8.5 - CORS support
156
-
157
- ## ๐ŸŽ“ Usage as NPM Package
158
-
159
- After installation:
160
- ```typescript
161
- import { SnowflakeService } from '@naganpm/snowflake-mcp-server';
162
-
163
- // Get singleton instance
164
- const service = SnowflakeService.getInstance();
165
-
166
- // Execute queries
167
- const result = await service.executeQuery('SELECT * FROM my_table LIMIT 10');
168
- console.log(result.rows);
169
-
170
- // List databases
171
- const databases = await service.listDatabases();
172
-
173
- // Describe table
174
- const tableInfo = await service.describeTable('my_table');
175
- ```
176
-
177
- ## โœ… Verified Working
178
-
179
- - โœ… Server starts successfully
180
- - โœ… Health endpoint responds
181
- - โœ… Status endpoint works
182
- - โœ… TypeScript compiles without errors
183
- - โœ… All dependencies installed
184
- - โœ… Environment configuration loaded
185
-
186
- ## ๐Ÿ“– Documentation Files
187
-
188
- - **README.md** - Comprehensive documentation
189
- - **QUICKSTART.md** - Quick start guide
190
- - **postman_collection.json** - Postman API collection
191
- - **examples/usage.ts** - Code examples
192
- - **test-api.sh** - Automated testing script
193
-
194
- ## ๐Ÿ” Security Notes
195
-
196
- - `.env` file is in `.gitignore` (not committed)
197
- - Password stored only locally
198
- - Add authentication middleware for production
199
- - Consider using Snowflake key-pair auth for production
200
- - Implement rate limiting
201
-
202
- ## ๐Ÿ› ๏ธ Development Workflow
203
-
204
- 1. **Make changes** in `src/` directory
205
- 2. **Test** with `npm run dev`
206
- 3. **Build** with `npm run build`
207
- 4. **Deploy** with `npm start` or Docker
208
-
209
- ## ๐Ÿ“ Next Steps
210
-
211
- 1. Add your Snowflake warehouse, database, and schema to `.env` (optional)
212
- 2. Start the server: `npm run dev`
213
- 3. Test with Postman or curl
214
- 4. Deploy to production or publish to NPM
215
- 5. Add authentication/authorization if needed
216
- 6. Set up CI/CD pipeline
217
-
218
- ## ๐ŸŽ‰ Success!
219
-
220
- Your Snowflake MCP server is ready to use! It's configured as a proper NPM package following the structure of `@naganpm/mysql-mcp-server`.
221
-
222
- Start the server with `npm run dev` and visit:
223
- - Health: http://localhost:3000/health
224
- - API Docs: See README.md for all endpoints
225
-
226
- Happy coding! ๐Ÿš€
@@ -1,16 +0,0 @@
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
package/examples/usage.ts DELETED
@@ -1,84 +0,0 @@
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();
@@ -1,148 +0,0 @@
1
- {
2
- "info": {
3
- "name": "Snowflake MCP Server",
4
- "description": "API collection for Snowflake MCP Server",
5
- "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
6
- },
7
- "item": [
8
- {
9
- "name": "Health Check",
10
- "request": {
11
- "method": "GET",
12
- "header": [],
13
- "url": {
14
- "raw": "{{base_url}}/health",
15
- "host": ["{{base_url}}"],
16
- "path": ["health"]
17
- }
18
- }
19
- },
20
- {
21
- "name": "Connection Status",
22
- "request": {
23
- "method": "GET",
24
- "header": [],
25
- "url": {
26
- "raw": "{{base_url}}/api/snowflake/status",
27
- "host": ["{{base_url}}"],
28
- "path": ["api", "snowflake", "status"]
29
- }
30
- }
31
- },
32
- {
33
- "name": "Execute Query",
34
- "request": {
35
- "method": "POST",
36
- "header": [
37
- {
38
- "key": "Content-Type",
39
- "value": "application/json"
40
- }
41
- ],
42
- "body": {
43
- "mode": "raw",
44
- "raw": "{\n \"query\": \"SELECT CURRENT_DATE(), CURRENT_USER(), CURRENT_ROLE()\"\n}"
45
- },
46
- "url": {
47
- "raw": "{{base_url}}/api/snowflake/query",
48
- "host": ["{{base_url}}"],
49
- "path": ["api", "snowflake", "query"]
50
- }
51
- }
52
- },
53
- {
54
- "name": "List Databases",
55
- "request": {
56
- "method": "GET",
57
- "header": [],
58
- "url": {
59
- "raw": "{{base_url}}/api/snowflake/databases",
60
- "host": ["{{base_url}}"],
61
- "path": ["api", "snowflake", "databases"]
62
- }
63
- }
64
- },
65
- {
66
- "name": "List Schemas",
67
- "request": {
68
- "method": "GET",
69
- "header": [],
70
- "url": {
71
- "raw": "{{base_url}}/api/snowflake/schemas?database=YOUR_DATABASE",
72
- "host": ["{{base_url}}"],
73
- "path": ["api", "snowflake", "schemas"],
74
- "query": [
75
- {
76
- "key": "database",
77
- "value": "YOUR_DATABASE"
78
- }
79
- ]
80
- }
81
- }
82
- },
83
- {
84
- "name": "List Tables",
85
- "request": {
86
- "method": "GET",
87
- "header": [],
88
- "url": {
89
- "raw": "{{base_url}}/api/snowflake/tables?database=YOUR_DATABASE&schema=PUBLIC",
90
- "host": ["{{base_url}}"],
91
- "path": ["api", "snowflake", "tables"],
92
- "query": [
93
- {
94
- "key": "database",
95
- "value": "YOUR_DATABASE"
96
- },
97
- {
98
- "key": "schema",
99
- "value": "PUBLIC"
100
- }
101
- ]
102
- }
103
- }
104
- },
105
- {
106
- "name": "Describe Table",
107
- "request": {
108
- "method": "GET",
109
- "header": [],
110
- "url": {
111
- "raw": "{{base_url}}/api/snowflake/tables/YOUR_TABLE/describe",
112
- "host": ["{{base_url}}"],
113
- "path": ["api", "snowflake", "tables", "YOUR_TABLE", "describe"]
114
- }
115
- }
116
- },
117
- {
118
- "name": "List Warehouses",
119
- "request": {
120
- "method": "GET",
121
- "header": [],
122
- "url": {
123
- "raw": "{{base_url}}/api/snowflake/warehouses",
124
- "host": ["{{base_url}}"],
125
- "path": ["api", "snowflake", "warehouses"]
126
- }
127
- }
128
- },
129
- {
130
- "name": "Get Current Session",
131
- "request": {
132
- "method": "GET",
133
- "header": [],
134
- "url": {
135
- "raw": "{{base_url}}/api/snowflake/session",
136
- "host": ["{{base_url}}"],
137
- "path": ["api", "snowflake", "session"]
138
- }
139
- }
140
- }
141
- ],
142
- "variable": [
143
- {
144
- "key": "base_url",
145
- "value": "http://localhost:3000"
146
- }
147
- ]
148
- }
package/src/index.ts DELETED
@@ -1,51 +0,0 @@
1
- #!/usr/bin/env node
2
- import express, { Express, Request, Response } from 'express';
3
- import cors from 'cors';
4
- import dotenv from 'dotenv';
5
- import { SnowflakeService } from './services/snowflake.service';
6
- import { errorHandler } from './middleware/error.middleware';
7
- import { snowflakeRoutes } from './routes/snowflake.routes';
8
-
9
- dotenv.config();
10
-
11
- const app: Express = express();
12
- const port = process.env.PORT || 3000;
13
-
14
- // Middleware
15
- app.use(cors());
16
- app.use(express.json());
17
- app.use(express.urlencoded({ extended: true }));
18
-
19
- // Health check
20
- app.get('/health', (req: Request, res: Response) => {
21
- res.json({ status: 'ok', timestamp: new Date().toISOString() });
22
- });
23
-
24
- // Snowflake routes
25
- app.use('/api/snowflake', snowflakeRoutes);
26
-
27
- // Error handler
28
- app.use(errorHandler);
29
-
30
- // Initialize Snowflake connection
31
- const snowflakeService = SnowflakeService.getInstance();
32
-
33
- app.listen(port, () => {
34
- console.log(`๐Ÿš€ Snowflake MCP Server running on port ${port}`);
35
- console.log(`๐Ÿ“Š Health check: http://localhost:${port}/health`);
36
- });
37
-
38
- // Graceful shutdown
39
- process.on('SIGINT', async () => {
40
- console.log('\n๐Ÿ›‘ Shutting down gracefully...');
41
- await snowflakeService.disconnect();
42
- process.exit(0);
43
- });
44
-
45
- process.on('SIGTERM', async () => {
46
- console.log('\n๐Ÿ›‘ Shutting down gracefully...');
47
- await snowflakeService.disconnect();
48
- process.exit(0);
49
- });
50
-
51
- export default app;
package/src/mcp-server.ts DELETED
@@ -1,137 +0,0 @@
1
- #!/usr/bin/env node
2
- import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
- import {
5
- CallToolRequestSchema,
6
- ListToolsRequestSchema,
7
- } from '@modelcontextprotocol/sdk/types.js';
8
- import { SnowflakeService } from './services/snowflake.service';
9
- import dotenv from 'dotenv';
10
-
11
- dotenv.config();
12
-
13
- const snowflakeService = SnowflakeService.getInstance();
14
-
15
- const server = new Server(
16
- {
17
- name: 'snowflake-mcp-server',
18
- version: '1.0.0',
19
- },
20
- {
21
- capabilities: {
22
- tools: {},
23
- },
24
- }
25
- );
26
-
27
- server.setRequestHandler(ListToolsRequestSchema, async () => {
28
- return {
29
- tools: [
30
- {
31
- name: 'execute_query',
32
- description: 'Execute a SQL query on Snowflake database',
33
- inputSchema: {
34
- type: 'object',
35
- properties: {
36
- query: { type: 'string', description: 'SQL query to execute' },
37
- binds: { type: 'array', description: 'Optional bind parameters' },
38
- },
39
- required: ['query'],
40
- },
41
- },
42
- {
43
- name: 'list_databases',
44
- description: 'List all databases',
45
- inputSchema: { type: 'object', properties: {} },
46
- },
47
- {
48
- name: 'list_schemas',
49
- description: 'List schemas',
50
- inputSchema: {
51
- type: 'object',
52
- properties: { database: { type: 'string' } },
53
- },
54
- },
55
- {
56
- name: 'list_tables',
57
- description: 'List tables',
58
- inputSchema: {
59
- type: 'object',
60
- properties: { database: { type: 'string' }, schema: { type: 'string' } },
61
- },
62
- },
63
- {
64
- name: 'describe_table',
65
- description: 'Describe table structure',
66
- inputSchema: {
67
- type: 'object',
68
- properties: { tableName: { type: 'string' } },
69
- required: ['tableName'],
70
- },
71
- },
72
- {
73
- name: 'list_warehouses',
74
- description: 'List warehouses',
75
- inputSchema: { type: 'object', properties: {} },
76
- },
77
- {
78
- name: 'get_session_info',
79
- description: 'Get session info',
80
- inputSchema: { type: 'object', properties: {} },
81
- },
82
- ],
83
- };
84
- });
85
-
86
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
87
- try {
88
- const { name, arguments: args } = request.params;
89
- let result;
90
-
91
- switch (name) {
92
- case 'execute_query':
93
- result = await snowflakeService.executeQuery((args?.query as string) || '', args?.binds as any);
94
- break;
95
- case 'list_databases':
96
- result = await snowflakeService.listDatabases();
97
- break;
98
- case 'list_schemas':
99
- result = await snowflakeService.listSchemas(args?.database as string);
100
- break;
101
- case 'list_tables':
102
- result = await snowflakeService.listTables(args?.database as string, args?.schema as string);
103
- break;
104
- case 'describe_table':
105
- result = await snowflakeService.describeTable((args?.tableName as string) || '');
106
- break;
107
- case 'list_warehouses':
108
- result = await snowflakeService.listWarehouses();
109
- break;
110
- case 'get_session_info':
111
- result = await snowflakeService.getCurrentSession();
112
- break;
113
- default:
114
- throw new Error(`Unknown tool: ${name}`);
115
- }
116
-
117
- return {
118
- content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
119
- };
120
- } catch (error: any) {
121
- return {
122
- content: [{ type: 'text', text: `Error: ${error.message}` }],
123
- isError: true,
124
- };
125
- }
126
- });
127
-
128
- async function main() {
129
- const transport = new StdioServerTransport();
130
- await server.connect(transport);
131
- console.error('Snowflake MCP server running on stdio');
132
- }
133
-
134
- main().catch((error) => {
135
- console.error('Failed to start MCP server:', error);
136
- process.exit(1);
137
- });
@@ -1,22 +0,0 @@
1
- import { Request, Response, NextFunction } from 'express';
2
-
3
- export const errorHandler = (
4
- err: any,
5
- req: Request,
6
- res: Response,
7
- next: NextFunction
8
- ) => {
9
- console.error('โŒ Error:', err);
10
-
11
- const statusCode = err.statusCode || 500;
12
- const message = err.message || 'Internal Server Error';
13
-
14
- res.status(statusCode).json({
15
- success: false,
16
- error: {
17
- message,
18
- code: err.code || 'INTERNAL_ERROR',
19
- ...(process.env.NODE_ENV === 'development' && { stack: err.stack }),
20
- },
21
- });
22
- };
@@ -1,123 +0,0 @@
1
- import { Router, Request, Response, NextFunction } from 'express';
2
- import { SnowflakeService } from '../services/snowflake.service';
3
-
4
- const router = Router();
5
- const snowflakeService = SnowflakeService.getInstance();
6
-
7
- // Execute query
8
- router.post('/query', async (req: Request, res: Response, next: NextFunction) => {
9
- try {
10
- const { query, binds } = req.body;
11
-
12
- if (!query) {
13
- return res.status(400).json({ error: 'Query is required' });
14
- }
15
-
16
- const result = await snowflakeService.executeQuery(query, binds);
17
- res.json({
18
- success: true,
19
- data: result,
20
- });
21
- } catch (error: any) {
22
- next(error);
23
- }
24
- });
25
-
26
- // List databases
27
- router.get('/databases', async (req: Request, res: Response, next: NextFunction) => {
28
- try {
29
- const result = await snowflakeService.listDatabases();
30
- res.json({
31
- success: true,
32
- data: result,
33
- });
34
- } catch (error: any) {
35
- next(error);
36
- }
37
- });
38
-
39
- // List schemas
40
- router.get('/schemas', async (req: Request, res: Response, next: NextFunction) => {
41
- try {
42
- const { database } = req.query;
43
- const result = await snowflakeService.listSchemas(database as string);
44
- res.json({
45
- success: true,
46
- data: result,
47
- });
48
- } catch (error: any) {
49
- next(error);
50
- }
51
- });
52
-
53
- // List tables
54
- router.get('/tables', async (req: Request, res: Response, next: NextFunction) => {
55
- try {
56
- const { database, schema } = req.query;
57
- const result = await snowflakeService.listTables(
58
- database as string,
59
- schema as string
60
- );
61
- res.json({
62
- success: true,
63
- data: result,
64
- });
65
- } catch (error: any) {
66
- next(error);
67
- }
68
- });
69
-
70
- // Describe table
71
- router.get('/tables/:tableName/describe', async (req: Request, res: Response, next: NextFunction) => {
72
- try {
73
- const { tableName } = req.params;
74
- const result = await snowflakeService.describeTable(tableName);
75
- res.json({
76
- success: true,
77
- data: result,
78
- });
79
- } catch (error: any) {
80
- next(error);
81
- }
82
- });
83
-
84
- // List warehouses
85
- router.get('/warehouses', async (req: Request, res: Response, next: NextFunction) => {
86
- try {
87
- const result = await snowflakeService.listWarehouses();
88
- res.json({
89
- success: true,
90
- data: result,
91
- });
92
- } catch (error: any) {
93
- next(error);
94
- }
95
- });
96
-
97
- // Get current session
98
- router.get('/session', async (req: Request, res: Response, next: NextFunction) => {
99
- try {
100
- const result = await snowflakeService.getCurrentSession();
101
- res.json({
102
- success: true,
103
- data: result,
104
- });
105
- } catch (error: any) {
106
- next(error);
107
- }
108
- });
109
-
110
- // Connection status
111
- router.get('/status', async (req: Request, res: Response, next: NextFunction) => {
112
- try {
113
- const isConnected = snowflakeService.isConnected();
114
- res.json({
115
- success: true,
116
- connected: isConnected,
117
- });
118
- } catch (error: any) {
119
- next(error);
120
- }
121
- });
122
-
123
- export { router as snowflakeRoutes };
@@ -1,149 +0,0 @@
1
- import snowflake from 'snowflake-sdk';
2
-
3
- export interface SnowflakeConfig {
4
- account: string;
5
- username: string;
6
- password: string;
7
- warehouse?: string;
8
- database?: string;
9
- schema?: string;
10
- }
11
-
12
- export interface QueryResult {
13
- columns: string[];
14
- rows: any[];
15
- rowCount: number;
16
- executionTime: number;
17
- }
18
-
19
- export class SnowflakeService {
20
- private static instance: SnowflakeService;
21
- private connection: snowflake.Connection | null = null;
22
- private config: SnowflakeConfig;
23
-
24
- private constructor() {
25
- this.config = {
26
- account: process.env.SNOWFLAKE_ACCOUNT || '',
27
- username: process.env.SNOWFLAKE_USERNAME || '',
28
- password: process.env.SNOWFLAKE_PASSWORD || '',
29
- warehouse: process.env.SNOWFLAKE_WAREHOUSE,
30
- database: process.env.SNOWFLAKE_DATABASE,
31
- schema: process.env.SNOWFLAKE_SCHEMA,
32
- };
33
- }
34
-
35
- public static getInstance(): SnowflakeService {
36
- if (!SnowflakeService.instance) {
37
- SnowflakeService.instance = new SnowflakeService();
38
- }
39
- return SnowflakeService.instance;
40
- }
41
-
42
- private async connect(): Promise<snowflake.Connection> {
43
- if (this.connection) {
44
- return this.connection;
45
- }
46
-
47
- return new Promise((resolve, reject) => {
48
- const connectionOptions: any = {
49
- account: this.config.account,
50
- username: this.config.username,
51
- password: this.config.password,
52
- };
53
-
54
- if (this.config.warehouse) connectionOptions.warehouse = this.config.warehouse;
55
- if (this.config.database) connectionOptions.database = this.config.database;
56
- if (this.config.schema) connectionOptions.schema = this.config.schema;
57
-
58
- this.connection = snowflake.createConnection(connectionOptions);
59
-
60
- this.connection.connect((err, conn) => {
61
- if (err) {
62
- console.error('โŒ Failed to connect to Snowflake:', err.message);
63
- reject(err);
64
- } else {
65
- console.log('โœ… Successfully connected to Snowflake');
66
- resolve(conn);
67
- }
68
- });
69
- });
70
- }
71
-
72
- public async executeQuery(sqlText: string, binds?: any[]): Promise<QueryResult> {
73
- const startTime = Date.now();
74
- const conn = await this.connect();
75
-
76
- return new Promise((resolve, reject) => {
77
- conn.execute({
78
- sqlText,
79
- binds,
80
- complete: (err, stmt, rows) => {
81
- const executionTime = Date.now() - startTime;
82
-
83
- if (err) {
84
- reject(err);
85
- } else {
86
- const columns = stmt.getColumns().map(col => col.getName());
87
- resolve({
88
- columns,
89
- rows: rows || [],
90
- rowCount: rows?.length || 0,
91
- executionTime,
92
- });
93
- }
94
- },
95
- });
96
- });
97
- }
98
-
99
- public async listDatabases(): Promise<QueryResult> {
100
- return this.executeQuery('SHOW DATABASES');
101
- }
102
-
103
- public async listSchemas(database?: string): Promise<QueryResult> {
104
- if (database) {
105
- return this.executeQuery(`SHOW SCHEMAS IN DATABASE ${database}`);
106
- }
107
- return this.executeQuery('SHOW SCHEMAS');
108
- }
109
-
110
- public async listTables(database?: string, schema?: string): Promise<QueryResult> {
111
- if (database && schema) {
112
- return this.executeQuery(`SHOW TABLES IN ${database}.${schema}`);
113
- }
114
- return this.executeQuery('SHOW TABLES');
115
- }
116
-
117
- public async describeTable(tableName: string): Promise<QueryResult> {
118
- return this.executeQuery(`DESCRIBE TABLE ${tableName}`);
119
- }
120
-
121
- public async listWarehouses(): Promise<QueryResult> {
122
- return this.executeQuery('SHOW WAREHOUSES');
123
- }
124
-
125
- public async getCurrentSession(): Promise<QueryResult> {
126
- return this.executeQuery('SELECT CURRENT_USER(), CURRENT_ROLE(), CURRENT_DATABASE(), CURRENT_SCHEMA(), CURRENT_WAREHOUSE()');
127
- }
128
-
129
- public async disconnect(): Promise<void> {
130
- if (this.connection) {
131
- return new Promise((resolve, reject) => {
132
- this.connection!.destroy((err) => {
133
- if (err) {
134
- console.error('โŒ Error disconnecting from Snowflake:', err.message);
135
- reject(err);
136
- } else {
137
- console.log('โœ… Disconnected from Snowflake');
138
- this.connection = null;
139
- resolve();
140
- }
141
- });
142
- });
143
- }
144
- }
145
-
146
- public isConnected(): boolean {
147
- return this.connection !== null;
148
- }
149
- }
package/test-api.sh DELETED
@@ -1,39 +0,0 @@
1
- #!/bin/bash
2
-
3
- echo "๐Ÿงช Testing Snowflake MCP Server..."
4
-
5
- # Base URL
6
- BASE_URL="http://localhost:3000"
7
-
8
- # Colors
9
- GREEN='\033[0;32m'
10
- RED='\033[0;31m'
11
- NC='\033[0m' # No Color
12
-
13
- # Health check
14
- echo -e "\n๐Ÿ“Š Testing Health Check..."
15
- curl -s ${BASE_URL}/health | jq .
16
-
17
- # Connection status
18
- echo -e "\n๐Ÿ”Œ Testing Connection Status..."
19
- curl -s ${BASE_URL}/api/snowflake/status | jq .
20
-
21
- # Current session
22
- echo -e "\n๐Ÿ‘ค Testing Current Session..."
23
- curl -s ${BASE_URL}/api/snowflake/session | jq .
24
-
25
- # List databases
26
- echo -e "\n๐Ÿ—„๏ธ Testing List Databases..."
27
- curl -s ${BASE_URL}/api/snowflake/databases | jq .
28
-
29
- # List warehouses
30
- echo -e "\n๐Ÿญ Testing List Warehouses..."
31
- curl -s ${BASE_URL}/api/snowflake/warehouses | jq .
32
-
33
- # Execute query
34
- echo -e "\nโšก Testing Execute Query..."
35
- curl -s -X POST ${BASE_URL}/api/snowflake/query \
36
- -H "Content-Type: application/json" \
37
- -d '{"query": "SELECT CURRENT_DATE(), CURRENT_TIME(), CURRENT_TIMESTAMP()"}' | jq .
38
-
39
- echo -e "\n${GREEN}โœ… Tests completed!${NC}"
package/tsconfig.json DELETED
@@ -1,28 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2020",
4
- "module": "commonjs",
5
- "lib": [
6
- "ES2020"
7
- ],
8
- "outDir": "./dist",
9
- "rootDir": "./src",
10
- "strict": true,
11
- "esModuleInterop": true,
12
- "skipLibCheck": true,
13
- "forceConsistentCasingInFileNames": true,
14
- "resolveJsonModule": true,
15
- "declaration": true,
16
- "declarationMap": true,
17
- "sourceMap": true,
18
- "moduleResolution": "node"
19
- },
20
- "include": [
21
- "src/**/*",
22
- "src/mcp-server.ts"
23
- ],
24
- "exclude": [
25
- "node_modules",
26
- "dist"
27
- ]
28
- }