MCP Snowflake Server NSP
<div align="center">
<a href="https://github.com/nsphung/mcp-snowflake-server"><img width="80%" height="80%" alt="mcp-snowflake-server-nsp-banner" src="https://github.com/user-attachments/assets/73ccb230-907e-4b4c-ae51-cbda9cdc8c2c" /></a>
[](https://pypi.org/project/mcp-snowflake-server-nsp/) • [](https://codecov.io/gh/nsphung/mcp-snowflake-server) • [](https://pypi.org/project/mcp-snowflake-server-nsp/) • [](https://hub.docker.com/r/nsphung/mcp-snowflake-server-nsp) • [](https://opensource.org/licenses/MIT)
| | |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Test | [](https://github.com/nsphung/mcp-snowflake-server/actions/workflows/test.yml)  [](https://github.com/nsphung/mcp-snowflake-server/actions/workflows/docker-check.yml) |
| Lint | [](https://github.com/nsphung/mcp-snowflake-server/actions/workflows/lint.yml) [](https://github.com/astral-sh/ruff) [](http://mypy-lang.org/) [](https://github.com/j178/prek) [](https://oxc.rs/docs/guide/usage/formatter) |
| Meta | [](./CODE_OF_CONDUCT.md) [](https://modelcontextprotocol.io/) [](https://www.python.org/) [](https://www.python.org/) |
| Security |  [](https://github.com/nsphung/mcp-snowflake-server/actions/workflows/github-code-scanning/codeql) [](https://scorecard.dev/viewer/?uri=github.com/nsphung/mcp-snowflake-server) [](https://socket.dev/pypi/package/mcp-snowflake-server-nsp) |
| Best Practices | [](https://www.bestpractices.dev/projects/12747) [](https://www.bestpractices.dev/projects/12747) |
| Documentation | [](https://deepwiki.com/nsphung/mcp-snowflake-server) |
</div>
---
# Snowflake MCP Server NSP
A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server / MCP server that connects AI assistants to Snowflake — enabling SQL queries, schema exploration, and data insights directly from your LLM client.
<!-- mcp-name: io.github.nsphung/mcp-snowflake-server -->
**Highlights:**
- Multiple authentication methods: password, key-pair, external browser, OAuth 2.0 (client credentials & bearer token), TOML connection files
- TOML multi-connection config — manage `production`, `staging`, and `development` environments in one file
- Write-safety guard — write operations are disabled by default and must be explicitly enabled
- Exclusion patterns — filter out databases, schemas, or tables from discovery
- `--exclude-json-results` flag — reduces LLM context window usage
- Selective tool exclusion via `--exclude_tools`
- Prefetch mode — pre-load table schema as MCP resources
- Docker support with hardened image ([DHI](https://docs.docker.com/dhi/), nonroot user, no shell in runtime)
---
## Table of Contents
- [Snowflake MCP Server NSP](#snowflake-mcp-server-nsp)
- [Table of Contents](#table-of-contents)
- [Quick Start](#quick-start)
- [Claude Code](#claude-code)
- [Visual Studio Code (VSCode)](#visual-studio-code-vscode)
- [OpenCode](#opencode)
- [Components](#components)
- [Resources](#resources)
- [Tools](#tools)
- [Query Tools](#query-tools)
- [Schema Tools](#schema-tools)
- [Analysis Tools](#analysis-tools)
- [Authentication](#authentication)
- [Password](#password)
- [Key-Pair](#key-pair)
- [External Browser](#external-browser)
- [OAuth 2.0 Client Credentials](#oauth-20-client-credentials)
- [OAuth Bearer Token](#oauth-bearer-token)
- [TOML Connection File (Recommended)](#toml-connection-file-recommended)
- [Installation](#installation)
- [Via UVX](#via-uvx)
- [Via Docker Hub](#via-docker-hub)
- [Configuration Reference](#configuration-reference)
- [Exclusion Patterns](#exclusion-patterns)
- [License](#license)
- [Fork and Attribution](#fork-and-attribution)
---
## Quick Start
The fastest way to try it — using `uvx` with a TOML connection file:
```bash
# 1. Create a connections file
cat > ~/snowflake_connections.toml << 'EOF'
[myconn]
account = "your_account"
user = "your_user"
password = "your_password"
warehouse = "COMPUTE_WH"
database = "MY_DB"
schema = "PUBLIC"
role = "MYROLE"
EOF
# 2. Run the server
uvx --python=3.13 --from mcp-snowflake-server-nsp mcp_snowflake_server \
--connections-file ~/snowflake_connections.toml \
--connection-name myconn
```
### Claude Code
Add to your MCP client config (e.g. `claude_desktop_config.json`) using `snowflake_connections.toml`:
```jsonc
"mcpServers": {
"snowflake": {
"command": "uvx",
"args": [
"--python=3.13",
"--from", "mcp-snowflake-server-nsp",
"mcp_snowflake_server",
"--connections-file", "/absolute/path/to/snowflake_connections.toml",
"--connection-name", "myconn"
]
}
}
```
### Visual Studio Code (VSCode)
**uvx** — [](https://insiders.vscode.dev/redirect?url=vscode%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522snowflake%2522%252C%2522command%2522%253A%2522uvx%2522%252C%2522args%2522%253A%255B%2522--python%253D3.13%2522%252C%2522--from%2522%252C%2522mcp-snowflake-server-nsp%2522%252C%2522mcp_snowflake_server%2522%255D%257D) [](https://insiders.vscode.dev/redirect?url=vscode-insiders%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522snowflake%2522%252C%2522command%2522%253A%2522uvx%2522%252C%2522args%2522%253A%255B%2522--python%253D3.13%2522%252C%2522--from%2522%252C%2522mcp-snowflake-server-nsp%2522%252C%2522mcp_snowflake_server%2522%255D%257D)
**Docker** — [](https://insiders.vscode.dev/redirect?url=vscode%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522snowflake%2522%252C%2522command%2522%253A%2522docker%2522%252C%2522args%2522%253A%255B%2522run%2522%252C%2522--rm%2522%252C%2522-i%2522%252C%2522nsphung%252Fmcp-snowflake-server-nsp%2522%255D%257D) [](https://insiders.vscode.dev/redirect?url=vscode-insiders%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522snowflake%2522%252C%2522command%2522%253A%2522docker%2522%252C%2522args%2522%253A%255B%2522run%2522%252C%2522--rm%2522%252C%2522-i%2522%252C%2522nsphung%252Fmcp-snowflake-server-nsp%2522%255D%257D)
Or add manually to your MCP client config (e.g. `.vscode/mcp.json`) using `.env` file (see [Authentication](#authentication)):
```jsonc
"snowflake": {
// Snowflake MCP server
"type": "stdio",
"command": "uvx",
"args": [
"--from", "mcp-snowflake-server-nsp",
"--python=3.13",
"mcp_snowflake_server"
],
"envFile": "${workspaceFolder}/.env"
}
```
### OpenCode
Add to your MCP client config (e.g. `opencode.jsonc`) with `.env` file (see [Authentication](#authentication)):
```jsonc
"snowflake": {
"type": "local",
"command": [
"uvx",
"--from",
"mcp-snowflake-server-nsp",
"--python=3.13",
"mcp_snowflake_server",
],
"enabled": true,
"timeout": 300000,
}
```
---
## Components
### Resources
| URI | Description |
| ------------------------------ | ------------------------------------------------------------------------------------ |
| `memo://insights` | A continuously updated memo aggregating data insights appended via `append_insight`. |
| `context://table/{table_name}` | _(Prefetch mode only)_ Per-table schema summaries including columns and comments. |
---
### Tools
#### Query Tools
| Tool | Description | Requires |
| -------------- | ----------------------------------------------------------------------------- | --------------- |
| `read_query` | Execute `SELECT` queries. **Input:** `query` (string). | — |
| `write_query` | Execute `INSERT`, `UPDATE`, or `DELETE` queries. **Input:** `query` (string). | `--allow_write` |
| `create_table` | Execute `CREATE TABLE` statements. **Input:** `query` (string). | `--allow_write` |
#### Schema Tools
| Tool | Description | Input |
| ---------------- | ------------------------------------------------------------------------ | --------------------------------------- |
| `list_databases` | List all databases in the Snowflake instance. | — |
| `list_schemas` | List all schemas within a database. | `database` (string) |
| `list_tables` | List all tables within a database and schema. | `database`, `schema` (strings) |
| `describe_table` | Describe columns of a table (name, type, nullability, default, comment). | `table_name` as `database.schema.table` |
#### Analysis Tools
| Tool | Description | Input |
| ---------------- | ----------------------------------------------------- | ------------------ |
| `append_insight` | Add a data insight to the `memo://insights` resource. | `insight` (string) |
---
## Authentication
### Password
Set credentials via environment variables or CLI flags (see [Configuration Reference](#configuration-reference)):
```bash
SNOWFLAKE_USER="user@example.com"
SNOWFLAKE_ACCOUNT="myaccount"
SNOWFLAKE_AUTHENTICATOR="snowflake"
SNOWFLAKE_PASSWORD="secret"
SNOWFLAKE_WAREHOUSE="COMPUTE_WH"
SNOWFLAKE_DATABASE="MY_DB"
SNOWFLAKE_SCHEMA="PUBLIC"
SNOWFLAKE_ROLE="MYROLE"
```
### Key-Pair
Both RSA (RS256) and ECDSA (ES256, ES384, ES512) private keys are supported (requires `snowflake-connector-python` ≥ 4.5.0 for ECDSA).
```bash
SNOWFLAKE_USER="user@example.com"
SNOWFLAKE_ACCOUNT="myaccount"
SNOWFLAKE_AUTHENTICATOR="snowflake_jwt"
SNOWFLAKE_PRIVATE_KEY_FILE="/absolute/path/to/key.p8"
SNOWFLAKE_PRIVATE_KEY_FILE_PWD="passphrase" # Optional — only if key is encrypted
SNOWFLAKE_WAREHOUSE="COMPUTE_WH"
SNOWFLAKE_DATABASE="MY_DB"
SNOWFLAKE_SCHEMA="PUBLIC"
SNOWFLAKE_ROLE="MYROLE"
```
Or via CLI: `--private_key_file /path/to/key.p8 --private_key_file_pwd passphrase`
### External Browser
```bash
SNOWFLAKE_AUTHENTICATOR="externalbrowser"
```
Or in a TOML connection entry: `authenticator = "externalbrowser"`
### OAuth 2.0 Client Credentials
Use the [OAuth 2.0 client credentials flow](https://docs.snowflake.com/en/developer-guide/python-connector/python-connector-connect#using-oauth) to authenticate with a client ID and secret (no user interaction required):
```bash
SNOWFLAKE_AUTHENTICATOR="oauth_client_credentials"
SNOWFLAKE_ACCOUNT="myaccount"
SNOWFLAKE_OAUTH_CLIENT_ID="your_client_id"
SNOWFLAKE_OAUTH_CLIENT_SECRET="your_client_secret"
SNOWFLAKE_OAUTH_TOKEN_REQUEST_URL="https://your-idp.example.com/oauth/token"
SNOWFLAKE_OAUTH_SCOPE="session:role:MY_ROLE" # Optional
SNOWFLAKE_WAREHOUSE="COMPUTE_WH"
SNOWFLAKE_DATABASE="MY_DB"
SNOWFLAKE_SCHEMA="PUBLIC"
SNOWFLAKE_ROLE="MYROLE"
```
### OAuth Bearer Token
Use a pre-fetched OAuth bearer token:
```bash
SNOWFLAKE_AUTHENTICATOR="oauth"
SNOWFLAKE_ACCOUNT="myaccount"
SNOWFLAKE_TOKEN="eyJhbGciOiJSUzI1NiJ9..."
SNOWFLAKE_WAREHOUSE="COMPUTE_WH"
SNOWFLAKE_DATABASE="MY_DB"
SNOWFLAKE_SCHEMA="PUBLIC"
SNOWFLAKE_ROLE="MYROLE"
```
### TOML Connection File (Recommended)
Manage multiple environments in a single file. See [`example_connections.toml`](https://github.com/nsphung/mcp-snowflake-server/blob/main/example_connections.toml) for a full template.
```toml
[production]
account = "your_account"
user = "your_user"
password = "your_password"
authenticator = "snowflake"
warehouse = "COMPUTE_WH"
database = "PROD_DB"
schema = "PUBLIC"
role = "ACCOUNTADMIN"
[development]
account = "your_account"
user = "dev_user"
authenticator = "externalbrowser"
warehouse = "DEV_WH"
database = "DEV_DB"
schema = "PUBLIC"
role = "DEVELOPER"
[reporting]
account = "your_account"
user = "reporting_user"
authenticator = "snowflake_jwt"
private_key_file = "/path/to/private_key.pem"
private_key_file_pwd = "passphrase" # Optional
warehouse = "REPORTING_WH"
database = "REPORTING_DB"
schema = "REPORTS"
role = "REPORTING_ROLE"
[analytics_oauth]
account = "your_account"
authenticator = "oauth_client_credentials"
oauth_client_id = "your_client_id"
oauth_client_secret = "your_client_secret"
oauth_token_request_url = "https://your-idp.example.com/oauth/token"
oauth_scope = "session:role:ANALYTICS_ROLE" # Optional
warehouse = "ANALYTICS_WH"
database = "ANALYTICS_DB"
schema = "PUBLIC"
role = "ANALYTICS_ROLE"
```
Pass the file with `--connections-file` and select a profile with `--connection-name`. Both flags are required together.
---
## Installation
The package is published on [PyPI as `mcp-snowflake-server-nsp`](https://pypi.org/project/mcp-snowflake-server-nsp/).
> **Contributing or running from source?** See [`CONTRIBUTING.md`](./CONTRIBUTING.md) for local development setup, test commands, formatting, and building the Docker image from source.
---
### Via UVX
<details>
<summary><strong>TOML configuration (recommended)</strong></summary>
```jsonc
"mcpServers": {
"snowflake_production": {
"command": "uvx",
"args": [
"--python=3.13",
"--from", "mcp-snowflake-server-nsp",
"mcp_snowflake_server",
"--connections-file", "/path/to/snowflake_connections.toml",
"--connection-name", "production"
// Optional flags — see Configuration Reference
]
},
"snowflake_staging": {
"command": "uvx",
"args": [
"--python=3.13",
"--from", "mcp-snowflake-server-nsp",
"mcp_snowflake_server",
"--connections-file", "/path/to/snowflake_connections.toml",
"--connection-name", "staging"
]
}
}
```
</details>
<details>
<summary><strong>Individual parameters</strong></summary>
```jsonc
"mcpServers": {
"snowflake": {
"command": "uvx",
"args": [
"--python=3.13",
"--from", "mcp-snowflake-server-nsp",
"mcp_snowflake_server",
"--account", "your_account",
"--warehouse", "your_warehouse",
"--user", "your_user",
"--password", "your_password",
"--role", "your_role",
"--database", "your_database",
"--schema", "your_schema"
// Optional: "--private_key_file", "/absolute/path/key.p8"
// Optional: "--private_key_file_pwd", "passphrase"
// Optional flags — see Configuration Reference
]
}
}
```
</details>
---
### Via Docker Hub
The image is published on [Docker Hub](https://hub.docker.com/r/nsphung/mcp-snowflake-server-nsp) — no build step required:
```bash
docker pull nsphung/mcp-snowflake-server-nsp
```
> **Note:** `-i` (`--interactive`) is required to keep stdin open for the MCP stdio transport. Do **not** use `-d` (detach).
<details>
<summary><strong>Claude Desktop — <code>claude_desktop_config.json</code></strong></summary>
With `.env` file (see [Authentication](#authentication)):
```jsonc
"mcpServers": {
"snowflake": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"--env-file", "/absolute/path/to/.env",
"nsphung/mcp-snowflake-server-nsp"
]
}
}
```
With TOML connections file:
```jsonc
"mcpServers": {
"snowflake": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-v", "/path/to/snowflake_connections.toml:/app/snowflake_connections.toml:ro",
"nsphung/mcp-snowflake-server-nsp",
"--connections-file", "/app/snowflake_connections.toml",
"--connection-name", "production"
]
}
}
```
</details>
<details>
<summary><strong>VS Code — <code>.vscode/mcp.json</code></strong></summary>
With `.env` file:
```jsonc
"snowflake": {
"type": "stdio",
"command": "docker",
"args": [
"run", "--rm", "-i",
"nsphung/mcp-snowflake-server-nsp"
],
"envFile": "${workspaceFolder}/.env"
}
```
With TOML connections file:
```jsonc
"snowflake": {
"type": "stdio",
"command": "docker",
"args": [
"run", "--rm", "-i",
"-v", "/path/to/snowflake_connections.toml:/app/snowflake_connections.toml:ro",
"nsphung/mcp-snowflake-server-nsp",
"--connections-file", "/app/snowflake_connections.toml",
"--connection-name", "production"
]
}
```
</details>
<details>
<summary><strong>OpenCode — <code>opencode.jsonc</code></strong></summary>
```jsonc
"snowflake": {
"type": "local",
"command": [
"docker", "run", "--rm", "-i",
"--env-file", "/absolute/path/to/.env",
"nsphung/mcp-snowflake-server-nsp"
],
"enabled": true,
"timeout": 300000
}
```
</details>
---
## Configuration Reference
All connection parameters can also be set as environment variables (`SNOWFLAKE_<PARAM_UPPER>`).
| Flag | Env var | Default | Description |
| ------------------------------ | -------------------------------- | ------------ | -------------------------------------------------------------------------------------------------- |
| `--account` | `SNOWFLAKE_ACCOUNT` | — | Snowflake account identifier |
| `--user` | `SNOWFLAKE_USER` | — | Snowflake username |
| `--password` | `SNOWFLAKE_PASSWORD` | — | Password (not required for key-pair / SSO) |
| `--warehouse` | `SNOWFLAKE_WAREHOUSE` | — | Virtual warehouse to use |
| `--database` | `SNOWFLAKE_DATABASE` | _(required)_ | Default database |
| `--schema` | `SNOWFLAKE_SCHEMA` | _(required)_ | Default schema |
| `--role` | `SNOWFLAKE_ROLE` | — | Role to assume |
| `--private_key_file` | `SNOWFLAKE_PRIVATE_KEY_FILE` | — | Absolute path to RSA or ECDSA (ES256/384/512) private key file (`.p8` / `.pem`) |
| `--private_key_file_pwd` | `SNOWFLAKE_PRIVATE_KEY_FILE_PWD` | — | Passphrase for encrypted private key |
| `--connections-file` | — | — | Path to TOML connections file |
| `--connection-name` | — | — | Connection profile name in TOML file (required with `--connections-file`) |
| `--allow_write` | — | `false` | Enable `write_query` and `create_table` tools |
| `--prefetch` / `--no-prefetch` | — | `false` | Pre-load table schema as `context://table/*` resources (disables `list_tables` / `describe_table`) |
| `--exclude_tools` | — | `[]` | Space-separated list of tool names to disable |
| `--exclude-json-results` | — | `false` | Omit embedded JSON resources from responses (reduces context window usage) |
| `--log_dir` | — | — | Directory for log file output |
| `--log_level` | — | `INFO` | Log verbosity: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL` |
---
## Exclusion Patterns
Edit [`runtime_config.json`](https://github.com/nsphung/mcp-snowflake-server/blob/main/runtime_config.json) to exclude databases, schemas, or tables from all discovery tools. Patterns are matched case-insensitively as substrings.
```json
{
"exclude_patterns": {
"databases": ["temp"],
"schemas": ["temp", "information_schema"],
"tables": ["temp"]
}
}
```
The server loads this file automatically at startup from the working directory.
---
## License
This project is licensed under the **MIT License**. See the [`LICENSE`](https://github.com/nsphung/mcp-snowflake-server/blob/main/LICENSE) file for the full text.
---
## Fork and Attribution
This repository is a fork of [`isaacwasserman/mcp-snowflake-server`](https://github.com/isaacwasserman/mcp-snowflake-server).
[](https://mseep.ai/app/isaacwasserman-mcp-snowflake-server)
- Upstream authors and contributors retain copyright for their contributions.
- Fork-specific changes are maintained by `nsphung`.
- A summary of notable modifications is tracked in [`NOTICE`](https://github.com/nsphung/mcp-snowflake-server/blob/main/NOTICE).
TDQS
Scored across 6 tools
Each tool has a clearly distinct purpose: listing databases, schemas, tables, describing a table's schema, executing queries, and appending a text insight. There is no ambiguity or overlap between them.
All tool names follow the consistent verb_noun pattern with lowercase and underscores (e.g., list_databases, describe_table, append_insight). The naming is uniform and predictable.
With 6 tools, the set is well-scoped for a Snowflake exploration and insight server. It covers basic metadata discovery, querying, and an insight-add feature without being bloated or insufficient.
The tool set covers read operations and metadata listing well, but lacks write capabilities beyond appending insights (no INSERT/UPDATE/DELETE queries, no DDL operations like creating tables). This creates a notable gap for many database workflows.