Initial commit
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
# Snowflake MCP Server
|
||||
|
||||
A read-only [Model Context Protocol](https://modelcontextprotocol.io/) server for Snowflake, using SSO (browser-based) authentication.
|
||||
|
||||
Gives Claude (or any MCP client) the ability to explore your Snowflake account — list databases, schemas, tables, views, describe columns, and run SELECT queries.
|
||||
|
||||
## Features
|
||||
|
||||
- SSO authentication (opens browser on first connection, then reuses the session)
|
||||
- Connection pooling with 30-minute timeout
|
||||
- Query caching (5 min TTL)
|
||||
- Read-only safety: only SELECT / SHOW / DESCRIBE queries are allowed
|
||||
- Async query support for long-running queries
|
||||
- Paginated results
|
||||
- Multiple output formats (records, columns, split, CSV)
|
||||
|
||||
## Quick start with uv
|
||||
|
||||
[uv](https://docs.astral.sh/uv/) is the easiest way to run this without managing a virtualenv yourself.
|
||||
|
||||
### 1. Install uv (if you don't have it)
|
||||
|
||||
```bash
|
||||
# macOS / Linux
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
|
||||
# Windows (PowerShell)
|
||||
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
|
||||
```
|
||||
|
||||
### 2. Configure your Snowflake details
|
||||
|
||||
Set environment variables (recommended) or edit the defaults at the top of `snowflake_mcp_server.py`.
|
||||
|
||||
```bash
|
||||
# Required
|
||||
export SNOWFLAKE_ACCOUNT="your-account-id" # e.g. "xy12345.eu-west-1"
|
||||
export SNOWFLAKE_USER="your.email@company.com"
|
||||
|
||||
# Optional — defaults shown
|
||||
export SNOWFLAKE_AUTHENTICATOR="externalbrowser" # SSO via browser
|
||||
export SNOWFLAKE_WAREHOUSE="" # uses account default if empty
|
||||
export SNOWFLAKE_ROLE="" # uses account default if empty
|
||||
export SNOWFLAKE_DATABASE="" # uses account default if empty
|
||||
export SNOWFLAKE_SCHEMA="" # uses account default if empty
|
||||
```
|
||||
|
||||
On Windows (PowerShell):
|
||||
```powershell
|
||||
$env:SNOWFLAKE_ACCOUNT = "your-account-id"
|
||||
$env:SNOWFLAKE_USER = "your.email@company.com"
|
||||
```
|
||||
|
||||
### 3. Run the server
|
||||
|
||||
```bash
|
||||
uv run --with snowflake-connector-python --with mcp snowflake_mcp_server.py
|
||||
```
|
||||
|
||||
Or, if you prefer to create a project first:
|
||||
|
||||
```bash
|
||||
uv init --no-package
|
||||
uv add snowflake-connector-python mcp
|
||||
uv run snowflake_mcp_server.py
|
||||
```
|
||||
|
||||
### 4. Add to Claude Code
|
||||
|
||||
**Option A — CLI (easiest):**
|
||||
|
||||
```bash
|
||||
claude mcp add --transport stdio snowflake \
|
||||
--env SNOWFLAKE_ACCOUNT=your-account-id \
|
||||
--env SNOWFLAKE_USER=your.email@company.com \
|
||||
--env SNOWFLAKE_ROLE=YOUR_ROLE \
|
||||
-- uv run --with snowflake-connector-python --with mcp /absolute/path/to/snowflake_mcp_server.py
|
||||
```
|
||||
|
||||
**Option B — manual config:**
|
||||
|
||||
Add to `.mcp.json` in your project root (shared with team) or `~/.claude.json` (personal):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"snowflake": {
|
||||
"type": "stdio",
|
||||
"command": "uv",
|
||||
"args": [
|
||||
"run",
|
||||
"--with", "snowflake-connector-python",
|
||||
"--with", "mcp",
|
||||
"/absolute/path/to/snowflake_mcp_server.py"
|
||||
],
|
||||
"env": {
|
||||
"SNOWFLAKE_ACCOUNT": "your-account-id",
|
||||
"SNOWFLAKE_USER": "your.email@company.com",
|
||||
"SNOWFLAKE_ROLE": "YOUR_ROLE"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Verify it's registered with `claude mcp list`.
|
||||
|
||||
## Available tools
|
||||
|
||||
| Tool | Description |
|
||||
|------|-------------|
|
||||
| `test_connection` | Verify connectivity and get session info |
|
||||
| `list_databases` | List all accessible databases |
|
||||
| `list_schemas` | List schemas in a database |
|
||||
| `list_tables` | List tables (optionally with row counts) |
|
||||
| `list_views` | List views in a schema |
|
||||
| `describe_table` | Get column-level schema for a table or view |
|
||||
| `describe_query` | Preview output columns without running the full query |
|
||||
| `read_data` | Run a SELECT query (up to 50k rows) |
|
||||
| `read_data_paginated` | Paginated query results with total count |
|
||||
| `read_data_pandas` | Results in records / columns / split / CSV format |
|
||||
| `execute_async` | Submit a long-running query asynchronously |
|
||||
| `get_query_status` | Check async query progress |
|
||||
| `get_async_results` | Fetch results from a completed async query |
|
||||
| `list_async_queries` | List all tracked async queries |
|
||||
|
||||
## Notes
|
||||
|
||||
- The first connection opens your default browser for SSO login. Subsequent calls reuse the session.
|
||||
- All queries are validated to be read-only — DML and DDL are blocked.
|
||||
- Snowflake object names are case-sensitive when created with quotes. The server will automatically retry with quoted names if the unquoted version fails.
|
||||
@@ -0,0 +1,2 @@
|
||||
snowflake-connector-python>=3.6.0
|
||||
mcp>=1.0.0
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user