Snowflake MCP Server
The Snowflake MCP Server provides secure, read-only access to Snowflake data warehouses, enabling AI assistants (Claude, Cursor, Gemini CLI, etc.) to explore schemas, run queries, and analyze data.
Key Features
Secure Read-Only Access: Strict query validation blocks write operations.
Flexible Authentication: Browser-based SSO or headless key-pair auth.
Smart Schema Caching: 5-day cache TTL reduces Snowflake credit usage.
Tools
refresh_catalog: Scans and caches all accessible databases, schemas, and tables. Supports forced refresh and checkpoint resumption.show_tables: Browses the database hierarchy (database → schema → tables) with pattern filtering. Large results auto-spill to a temp file.find_tables: Searches for tables by keyword across all databases, matching against table names and comments.describe_table: Returns detailed column info — name, type, nullability, position, default value, comment, and primary key status.execute_query: Runs read-only SQL (SELECT,SHOW,DESCRIBE,WITH), returning results inline or auto-spilling large results to a temp TSV file.execute_query_to_file: Executes a read-only query and writes full results to a specified file path (CSV or TSV). Cannot overwrite existing files; supports configurable timeouts up to 1 hour.
Provides secure read-only access to Snowflake, enabling schema exploration, query execution, and data analysis through AI assistants.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Snowflake MCP Serverlist all tables in the sales schema"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
What is Snowflake MCP?
Snowflake MCP Server bridges the gap between your Snowflake data warehouse and AI assistants like Claude. It provides a secure, read-only interface that lets AI help you explore schemas, write queries, and analyze data—all while maintaining enterprise-grade security through SSO authentication.
Related MCP server: Snowflake MCP Server
Features
🔒 Strict Read-Only Access: Multiple layers of protection against write operations
🔑 Flexible Authentication: Browser-based SSO or headless key-pair auth via credential file
💾 Smart Caching: 5-day schema cache for fast metadata access, reducing generic Snowflake schema queries and credit usage
📄 TSV Export: Write query results directly to TSV files, at any size
🛡️ Query Validation: Every query is validated as read-only before execution
🎯 Responsible Token Management: Lightweight outputs to minimize token usage
🚀 Easy Setup For LLM Agents
Already in Claude Code, OpenCode, Cursor, or another AI coding agent? Paste this into your agent:
Set up the Snowflake MCP server for me by following this guide:
https://raw.githubusercontent.com/ncejda-g2/snowflake_mcp_server/main/docs/guide/agent-setup.mdYour agent will walk you through everything interactively — including installing prerequisites. No manual config editing required.
uvx (Recommended — no Node.js required)
Just configure your MCP client using the examples in the Configuration section below.
Requires uv (curl -LsSf https://astral.sh/uv/install.sh | sh).
npx (requires Node.js)
Just configure your MCP client using the examples in the Configuration section below.
From Source
git clone git@github.com:ncejda-g2/snowflake_mcp_server.git
cd snowflake_mcp_server
python3 -m venv snowflake_mcp_env
source snowflake_mcp_env/bin/activate # On Windows: snowflake_mcp_env\Scripts\activate
pip install -r requirements.txtConfiguration
Edit your ~/.claude.json file:
Using uvx (Recommended):
{
"mcpServers": {
"snowflake-readonly": {
"command": "uvx",
"args": ["snowflake-readonly-mcp"],
"env": {
"SNOWFLAKE_ACCOUNT": "your-account",
"SNOWFLAKE_USERNAME": "your-email@company.com",
"SNOWFLAKE_WAREHOUSE": "YOUR_WAREHOUSE",
"SNOWFLAKE_ROLE": "YOUR_ROLE",
"SNOWFLAKE_CREDENTIAL_FILE": "/path/to/credentials.json" // optional — omit to use browser SSO
}
}
}
}Using npx:
{
"mcpServers": {
"snowflake-readonly": {
"command": "npx",
"args": ["-y", "snowflake-readonly-mcp"],
"env": {
"SNOWFLAKE_ACCOUNT": "your-account",
"SNOWFLAKE_USERNAME": "your-email@company.com",
"SNOWFLAKE_WAREHOUSE": "YOUR_WAREHOUSE",
"SNOWFLAKE_ROLE": "YOUR_ROLE",
"SNOWFLAKE_CREDENTIAL_FILE": "/path/to/credentials.json" // optional — omit to use browser SSO
}
}
}
}Using local clone:
{
"mcpServers": {
"snowflake-readonly": {
"command": "/path/to/snowflake_mcp_server/snowflake_mcp_env/bin/python",
"args": ["/path/to/snowflake_mcp_server/main.py"],
"env": {
"SNOWFLAKE_ACCOUNT": "your-account",
"SNOWFLAKE_USERNAME": "your-email@company.com",
"SNOWFLAKE_WAREHOUSE": "YOUR_WAREHOUSE",
"SNOWFLAKE_ROLE": "YOUR_ROLE",
"SNOWFLAKE_CREDENTIAL_FILE": "/path/to/credentials.json" // optional — omit to use browser SSO
}
}
}
}Replace:
/path/to/snowflake_mcp_server: Absolute path to your cloned repository (local clone only)your-account: Your Snowflake account identifier (e.g.,xy12345.us-east-1)your-email@company.com: Your Snowflake usernameYOUR_WAREHOUSE: Your Snowflake warehouse nameYOUR_ROLE: Your Snowflake role (e.g.,ANALYST,PUBLIC)SNOWFLAKE_CREDENTIAL_FILE(optional): Path to a JSON credential file for headless key-pair auth (omit to use browser SSO)
One-click install: Download the latest .mcpb extension and double-click it. Claude Desktop will prompt you for your Snowflake credentials.
Edit your configuration file:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.jsonLinux:
~/.config/claude/claude_desktop_config.json
{
"mcpServers": {
"snowflake-readonly": {
"command": "uvx",
"args": ["snowflake-readonly-mcp"],
"env": {
"SNOWFLAKE_ACCOUNT": "your-account",
"SNOWFLAKE_USERNAME": "your-email@company.com",
"SNOWFLAKE_WAREHOUSE": "YOUR_WAREHOUSE",
"SNOWFLAKE_ROLE": "YOUR_ROLE"
}
}
}
}Requires uv.
Edit your Cursor settings:
Using uvx (Recommended):
{
"mcpServers": {
"snowflake-readonly": {
"command": "uvx",
"args": ["snowflake-readonly-mcp"],
"env": {
"SNOWFLAKE_ACCOUNT": "your-account",
"SNOWFLAKE_USERNAME": "your-email@company.com",
"SNOWFLAKE_WAREHOUSE": "YOUR_WAREHOUSE",
"SNOWFLAKE_ROLE": "YOUR_ROLE",
"SNOWFLAKE_CREDENTIAL_FILE": "/path/to/credentials.json" // optional — omit to use browser SSO
}
}
}
}Using npx:
{
"mcpServers": {
"snowflake-readonly": {
"command": "npx",
"args": ["-y", "snowflake-readonly-mcp"],
"env": {
"SNOWFLAKE_ACCOUNT": "your-account",
"SNOWFLAKE_USERNAME": "your-email@company.com",
"SNOWFLAKE_WAREHOUSE": "YOUR_WAREHOUSE",
"SNOWFLAKE_ROLE": "YOUR_ROLE",
"SNOWFLAKE_CREDENTIAL_FILE": "/path/to/credentials.json" // optional — omit to use browser SSO
}
}
}
}Using local clone:
{
"mcpServers": {
"snowflake-readonly": {
"command": "/path/to/snowflake_mcp_server/snowflake_mcp_env/bin/python",
"args": ["/path/to/snowflake_mcp_server/main.py"],
"env": {
"SNOWFLAKE_ACCOUNT": "your-account",
"SNOWFLAKE_USERNAME": "your-email@company.com",
"SNOWFLAKE_WAREHOUSE": "YOUR_WAREHOUSE",
"SNOWFLAKE_ROLE": "YOUR_ROLE",
"SNOWFLAKE_CREDENTIAL_FILE": "/path/to/credentials.json" // optional — omit to use browser SSO
}
}
}
}Replace:
/path/to/snowflake_mcp_server: Absolute path to your cloned repository (local clone only)your-account: Your Snowflake account identifier (e.g.,xy12345.us-east-1)your-email@company.com: Your Snowflake usernameYOUR_WAREHOUSE: Your Snowflake warehouse nameYOUR_ROLE: Your Snowflake role (e.g.,ANALYST,PUBLIC)SNOWFLAKE_CREDENTIAL_FILE(optional): Path to a JSON credential file for headless key-pair auth (omit to use browser SSO)
Edit your ~/.config/opencode/opencode.json file (global) or opencode.json in your project root (project-level):
Note: OpenCode uses
"mcp"(not"mcpServers"),"command"as a single array (not separatecommand/args), and"environment"(not"env").
Using uvx (Recommended):
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"snowflake-readonly": {
"type": "local",
"command": ["uvx", "snowflake-readonly-mcp"],
"environment": {
"SNOWFLAKE_ACCOUNT": "your-account",
"SNOWFLAKE_USERNAME": "your-email@company.com",
"SNOWFLAKE_WAREHOUSE": "YOUR_WAREHOUSE",
"SNOWFLAKE_ROLE": "YOUR_ROLE",
"SNOWFLAKE_CREDENTIAL_FILE": "/path/to/credentials.json" // optional — omit to use browser SSO
}
}
}
}Using npx:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"snowflake-readonly": {
"type": "local",
"command": ["npx", "-y", "snowflake-readonly-mcp"],
"environment": {
"SNOWFLAKE_ACCOUNT": "your-account",
"SNOWFLAKE_USERNAME": "your-email@company.com",
"SNOWFLAKE_WAREHOUSE": "YOUR_WAREHOUSE",
"SNOWFLAKE_ROLE": "YOUR_ROLE",
"SNOWFLAKE_CREDENTIAL_FILE": "/path/to/credentials.json" // optional — omit to use browser SSO
}
}
}
}Using local clone:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"snowflake-readonly": {
"type": "local",
"command": ["/path/to/snowflake_mcp_server/snowflake_mcp_env/bin/python", "/path/to/snowflake_mcp_server/main.py"],
"environment": {
"SNOWFLAKE_ACCOUNT": "your-account",
"SNOWFLAKE_USERNAME": "your-email@company.com",
"SNOWFLAKE_WAREHOUSE": "YOUR_WAREHOUSE",
"SNOWFLAKE_ROLE": "YOUR_ROLE",
"SNOWFLAKE_CREDENTIAL_FILE": "/path/to/credentials.json" // optional — omit to use browser SSO
}
}
}
}Replace:
/path/to/snowflake_mcp_server: Absolute path to your cloned repository (local clone only)your-account: Your Snowflake account identifier (e.g.,xy12345.us-east-1)your-email@company.com: Your Snowflake usernameYOUR_WAREHOUSE: Your Snowflake warehouse nameYOUR_ROLE: Your Snowflake role (e.g.,ANALYST,PUBLIC)SNOWFLAKE_CREDENTIAL_FILE(optional): Path to a JSON credential file for headless key-pair auth (omit to use browser SSO)
Edit your ~/.gemini/settings.json file:
Using uvx (Recommended):
{
"mcpServers": {
"snowflake-readonly": {
"command": "uvx",
"args": ["snowflake-readonly-mcp"],
"env": {
"SNOWFLAKE_ACCOUNT": "your-account",
"SNOWFLAKE_USERNAME": "your-email@company.com",
"SNOWFLAKE_WAREHOUSE": "YOUR_WAREHOUSE",
"SNOWFLAKE_ROLE": "YOUR_ROLE",
"SNOWFLAKE_CREDENTIAL_FILE": "/path/to/credentials.json" // optional — omit to use browser SSO
}
}
}
}Using npx:
{
"mcpServers": {
"snowflake-readonly": {
"command": "npx",
"args": ["-y", "snowflake-readonly-mcp"],
"env": {
"SNOWFLAKE_ACCOUNT": "your-account",
"SNOWFLAKE_USERNAME": "your-email@company.com",
"SNOWFLAKE_WAREHOUSE": "YOUR_WAREHOUSE",
"SNOWFLAKE_ROLE": "YOUR_ROLE",
"SNOWFLAKE_CREDENTIAL_FILE": "/path/to/credentials.json" // optional — omit to use browser SSO
}
}
}
}Using local clone:
{
"mcpServers": {
"snowflake-readonly": {
"command": "/path/to/snowflake_mcp_server/snowflake_mcp_env/bin/python",
"args": ["/path/to/snowflake_mcp_server/main.py"],
"env": {
"SNOWFLAKE_ACCOUNT": "your-account",
"SNOWFLAKE_USERNAME": "your-email@company.com",
"SNOWFLAKE_WAREHOUSE": "YOUR_WAREHOUSE",
"SNOWFLAKE_ROLE": "YOUR_ROLE",
"SNOWFLAKE_CREDENTIAL_FILE": "/path/to/credentials.json" // optional — omit to use browser SSO
}
}
}
}Replace:
/path/to/snowflake_mcp_server: Absolute path to your cloned repository (local clone only)your-account: Your Snowflake account identifier (e.g.,xy12345.us-east-1)your-email@company.com: Your Snowflake usernameYOUR_WAREHOUSE: Your Snowflake warehouse nameYOUR_ROLE: Your Snowflake role (e.g.,ANALYST,PUBLIC)SNOWFLAKE_CREDENTIAL_FILE(optional): Path to a JSON credential file for headless key-pair auth (omit to use browser SSO)
Available Commands
The server provides powerful tools for interacting with Snowflake:
Tool | Description |
| Scan and cache all database schemas |
| Browse database hierarchy with pattern filters (like SHOW TABLES) |
| Search for tables by keyword across all databases |
| View detailed column information (like DESCRIBE TABLE) |
| Run read-only SQL queries (inline, or auto-spill large results to a temp file) |
| Execute a query and write its results to a TSV / CSV file at a chosen path (any size) |
📚 Documentation
Changelog - Version history and updates
Available Tools
6 toolsdescribe_tableDescribe TableA
Get detailed column information for a specific table.
USE THIS WHEN: You need column names, types, and constraints to write a query.
Like SQL's: DESCRIBE TABLE database.schema.table
RETURNS: Detailed column information
- For each column: name, data_type, nullable, position, default, comment, is_primary_key
HOW IT WORKS:
- Looks up table in cache; fetches column details on-demand if not yet loaded
- First call for a table queries Snowflake live (~200ms), subsequent calls use cache
- If table not in cache at all, returns error (use show_tables or find_tables first)
Note: To get sample data rows, use execute_query tool separately.
Parameters:
- database: Database name
- schema: Schema name
- table: Table name
Examples:
- describe_table("SALES_DB", "PUBLIC", "CUSTOMERS")
- describe_table("GDC", "STAGING", "ADMIN__CATEGORIES")
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes | ||
| schema | Yes | ||
| database | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral disclosure burden, and it does so thoroughly. It explains the cache lookup, on-demand fetch, ~200ms live query on first call, subsequent cache use, and the error condition when the table is not cached. It also clarifies this is a metadata retrieval operation rather than a data query.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear headings: purpose, when to use, returns, how it works, parameters, and examples. It is detailed but every section earns its place and contributes actionable information, with the core purpose front-loaded at the top.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple 3-parameter metadata tool with no annotations and no output schema, this description is remarkably complete. It covers return fields, performance/caching behavior, error conditions, prerequisites, and the correct alternative for data rows, so an agent has everything needed to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does by naming each parameter (database, schema, table) and providing two realistic examples. It adds meaning beyond the bare string types in the schema, though it stops short of extra details like case sensitivity or fully-qualified name formatting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action and resource: 'Get detailed column information for a specific table.' It clearly distinguishes itself from siblings by explicitly directing users to show_tables/find_tables for table discovery and execute_query for sample data, so an agent can tell exactly what this tool is and is not for.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes an explicit 'USE THIS WHEN' section: when column names, types, and constraints are needed to write a query. It also warns that tables not in cache will error and that show_tables/find_tables should be called first, providing clear when-to-use and when-not-to-use guidance relative to alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
execute_queryExecute QueryA
Execute a read-only SQL query (SELECT, SHOW, DESCRIBE, WITH) and return results.
Requires a populated schema cache; auto-refreshes on first use if empty.
Parameters:
- sql: read-only SQL query
- database: optional database context
- schema: optional schema context
Returns a compact TEXT payload (not JSON): a `key: value` header
(status, rows, cols, execution_time, query_id), a `---` separator, then a
result block whose shape depends on row count:
- ONE row: aligned `NAME value` lines (one column per line), any width.
- 2+ narrow rows: positional TSV (line 1 = tab-separated column names, one
row per line after). Parse with awk/cut, e.g. `awk -F'\t' 'NR>1 && $3=="X"'`.
NULL = `\N`; tabs/newlines escaped so each field is one line.
Multi-row results that are wide, tall, or too large auto-spill the COMPLETE
result to a temp `.tsv` file; the payload then carries `results_file` and
`column_index` (name->position) and NO inline rows. Read/grep/awk the file
(it has its own header line); `rows:` is always the true total.
Example: execute_query("SELECT * FROM SALES_DB.PUBLIC.CUSTOMERS LIMIT 10")
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | ||
| schema | No | ||
| database | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description carries the full behavioral burden. It thoroughly discloses the read-only safety profile, the TEXT payload format, header fields, row-count-dependent result shapes, NULL escaping, and the automatic spill to a .tsv file with results_file and column_index. This is exemplary transparency beyond the structured schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured and information-dense. It front-loads the core purpose, then parameters, then a detailed return contract with examples. Every section earns its place, and the formatting makes the complexity navigable rather than overwhelming.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema and no annotations, the description is remarkably complete: it documents two result shapes, the compact header, the spill-to-file path, parsing guidance, NULL handling, and an example call. Missing error-case documentation and explicit sibling routing are minor relative to what is covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, so the description must compensate. It lists all three parameters and assigns basic meaning: sql is a read-only SQL query, and database/schema are 'optional context.' This is helpful but thin—'database context' and 'schema context' are vague and do not explain how they affect query resolution or default behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Execute a read-only SQL query' and lists allowed statement types (SELECT, SHOW, DESCRIBE, WITH) plus 'return results'. It is clear and actionable, but it does not explicitly contrast itself with the sibling execute_query_to_file, so sibling differentiation is only implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives useful operational context: read-only queries, schema cache requirements, auto-refresh behavior, and when results spill to a file. However, it never explicitly states when to prefer this tool over execute_query_to_file or other siblings; the file-spill behavior implies it but does not provide direct routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
execute_query_to_fileExecute Query To FileA
Writes read-only query results to a file at a path you choose.
Use when the result needs to land at a specific path -- to share or persist.
Format follows the extension: `.csv` writes CSV (NULL = empty field);
anything else writes TSV (same as execute_query: tab-delimited, NULL = `\N`).
Parameters:
- sql: read-only SQL (SELECT, SHOW, DESCRIBE, WITH)
- file_path: output path (absolute recommended; end with `.csv` for CSV,
else `.tsv` is used/appended)
- database: optional database context
- schema: optional schema context
- timeout_seconds: query timeout (default 300, max 3600)
Requires a populated schema cache. Will not overwrite an existing file.
Example: execute_query_to_file("SELECT * FROM t", "/tmp/export.csv")
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | ||
| schema | No | ||
| database | No | ||
| file_path | Yes | ||
| timeout_seconds | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden and does so well. It discloses that the SQL must be read-only, that a populated schema cache is required, and that existing files will not be overwritten. It also explains extension-dependent formatting and NULL representation, which are non-obvious behaviors.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action, followed by targeted when-to-use guidance, format rules, parameter details, and a concrete example. Every sentence contributes information, and the parameter list is compact without unnecessary filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a five-parameter tool with no annotations and no output schema, the description covers prerequisites, formatting, side-effect safety (no overwrite), supported SQL types, timeout limits, and an example call. This is sufficient for an agent to invoke the tool correctly and anticipate its behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides no textual descriptions, but the description documents all five parameters: sql's allowed statement types, file_path's output semantics and extension-based format selection, optional database/schema context, and timeout_seconds defaults and maximum. This goes well beyond the schema's raw types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a concrete verb and resource: 'Writes read-only query results to a file at a path you choose.' It clearly distinguishes itself from execute_query by focusing on the file-output behavior, and it is not merely a restatement of the tool name.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use it: 'Use when the result needs to land at a specific path -- to share or persist.' It also references execute_query as the format baseline, giving agents a clear sibling comparison and an implied alternative when file output is not needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_tablesFind TablesA
Search for tables by keyword across ALL databases.
USE THIS WHEN: You don't know where a table is, but know part of its name or purpose.
Matches against both table names AND table comments (so a cryptically-named
table is still found when its comment mentions the term).
RETURNS (small result): flat list of matches
- [{database, schema, table, type, full_name}, ...]
Note: neither the comment nor a column count is returned. The comment is the
one unbounded field (can be a multi-KB doc-block); a column count does not
help locate a table. For a table's comment and columns, use describe_table.
RETURNS (broad result): when too many tables match to return inline, the
COMPLETE result is written to a temp `.tsv` file and the response is instead a
compact summary built to help you NARROW: `total_hits`, `results_file`, a
bounded `top_groups` breakdown of the top database.schema clusters (with a
`(+X more groups, Y hits)` tail marker), and a `spilled` hint. To narrow, call
show_tables with database_pattern/schema_pattern from top_groups and/or a more
specific table_pattern -- don't blindly re-search.
HOW IT WORKS:
- Auto-refreshes cache if expired/empty (requires Snowflake auth on first use)
- Uses cached data if available (no auth needed)
- Searches table names and comments for the keyword (case-insensitive)
Parameters:
- search_term: Keyword to search for (case-insensitive)
Examples:
- find_tables("customer") - Find all customer-related tables across all databases
- find_tables("revenue") - Find revenue tables anywhere
- find_tables("staging") - Find tables with "staging" in name or comment
| Name | Required | Description | Default |
|---|---|---|---|
| search_term | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and delivers. It discloses cache auto-refresh, Snowflake auth on first use, cached-data fallback, case-insensitive search, and the exact small/broad return behaviors including the temp .tsv spill and the bounded summary fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but tightly organized with clear section headers (USE THIS WHEN, RETURNS, HOW IT WORKS, Examples). Every sentence carries operational value; examples are illustrative and the flow from purpose to usage to behavior is logical.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter search tool with no output schema, the description fully specifies both return modes, auth requirements, narrowing strategies, and what is intentionally omitted (comments/column count). An agent can correctly invoke and interpret the tool without further guidance.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 0%, the description compensates with a dedicated parameter explanation: 'search_term: Keyword to search for (case-insensitive)' plus three examples showing realistic usage. It also explains matching semantics against names and comments.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening line 'Search for tables by keyword across ALL databases' states a specific verb, resource, and scope. It further distinguishes the tool by noting it matches table names AND comments, which sets it apart from schema-based navigation tools like show_tables.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'USE THIS WHEN' section explicitly defines the condition: 'You don't know where a table is, but know part of its name or purpose.' It also routes to siblings: 'use describe_table' for comments/columns and 'call show_tables with database_pattern/schema_pattern' to narrow broad results, with a warning not to blindly re-search.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
refresh_catalogRefresh CatalogA
Refresh the schema catalog by scanning all accessible Snowflake databases.
This tool queries INFORMATION_SCHEMA across all databases to build a comprehensive
index of tables, schemas, and columns. The cache has a 5-day TTL.
Use this tool when:
- First connecting to Snowflake
- Schema changes have been made
- Cache has expired (after 5 days)
Parameters:
- force: Force refresh even if cache is not expired (default: false)
- resume: Resume from checkpoints if they exist (default: true)
| Name | Required | Description | Default |
|---|---|---|---|
| force | No | ||
| resume | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It reveals that the tool queries INFORMATION_SCHEMA, maintains a cache with a 5-day TTL, supports force refresh, and can resume from checkpoints—useful operational context beyond the schema. It does not mention runtime cost or whether the operation is synchronous, but it covers the core behavioral traits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded: the core action is stated first, followed by mechanism, TTL, use cases, and parameter explanations. Every sentence adds useful information, with no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with two optional boolean parameters, no output schema, and no annotations, the description provides enough context to invoke it correctly: what it does, when to use it, and what the parameters control. It does not specify the return value or expected response, but that is not critical for a catalog refresh operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does. Both parameters are explained with meaningful semantics: 'force' means refresh even if cache is not expired, and 'resume' means continue from existing checkpoints. This goes well beyond the bare boolean schema definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('refresh') and resource ('schema catalog') and clarifies the scope ('scanning all accessible Snowflake databases'). This clearly differentiates it from sibling tools like execute_query or find_tables, which handle querying and table discovery rather than catalog maintenance.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use scenarios: first connecting to Snowflake, after schema changes, or when the cache has expired after 5 days. It does not explicitly describe when not to use it or name alternatives, so it falls just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
show_tablesShow TablesA
Browse databases, schemas, and tables using pattern-based filtering.
USE THIS WHEN: You want to explore what databases/schemas exist, or need to filter by exact patterns.
Like SQL's: SHOW TABLES IN database LIKE 'pattern'
RETURNS (small result): hierarchical tree
- database → schema → list of tables
RETURNS (broad result): when the matching tree is too large to return inline
(e.g. show_tables() with no filter, or a broad database_pattern matching tens
of thousands of tables), the COMPLETE tree is written to a temp `.json` file
and the response is instead a compact summary built to help you NARROW:
`total_tables`, `total_schemas`, `results_file`, and a bounded breakdown that
adapts to what's left to narrow -- `top_schemas` (db.schema=count) when the
result is a single database, else `top_databases` (db=count) -- each with a
`(+X more ..., Y tables)` tail marker, plus a `spilled` hint.
To act on a spilled result, prefer RE-CALLING show_tables with a tighter
database_pattern/schema_pattern (served from cache, no Snowflake) until it
fits inline. To read results_file directly instead -- it is compact JSON
nested THREE levels deep, `{"DB": {"SCHEMA": ["TABLE", ...]}}` (so table
names are the innermost array, not a key) -- list its schemas WITHOUT loading
every table name into context:
jq -r 'to_entries[]|.key as $d|.value|keys[]|"\($d).\(.)"' <results_file>
or, if jq is unavailable:
python3 -c "import json,sys;d=json.load(open(sys.argv[1]));print(chr(10).join(f'{db}.{s}' for db,sc in d.items() for s in sc))" <results_file>
Mind the nesting depth when counting: `jq '[.[][][]]|length'` counts TABLES
(three flattens to reach the leaf array); `jq '[.[][]]|length'` counts
SCHEMAS. (total_tables/total_schemas in the summary already give both.)
HOW IT WORKS:
- Auto-refreshes cache if expired/empty (requires Snowflake auth on first use)
- Uses cached data if available (no auth needed)
- Pattern matching is case-insensitive substring search
Parameters:
- database_pattern: Filter databases (e.g., "SALES" matches "SALES_DB", "SALES_PROD")
- schema_pattern: Filter schemas (e.g., "PUBLIC")
- table_pattern: Filter tables (e.g., "CUSTOMER" matches "CUSTOMERS", "CUSTOMER_ORDERS")
Examples:
- show_tables() - Browse all databases
- show_tables(database_pattern="SALES") - Only SALES databases
- show_tables(schema_pattern="PUBLIC") - All PUBLIC schemas across databases
| Name | Required | Description | Default |
|---|---|---|---|
| table_pattern | No | ||
| schema_pattern | No | ||
| database_pattern | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully carries the behavioral disclosure burden. It richly explains return formats for small vs broad results, spill-to-file behavior, cache refresh and authentication needs, pattern-matching semantics, and even provides jq/python commands for interacting with spilled results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Although long, the description is well-structured with clear sections: use case, return behavior, how it works, parameters, and examples. The density is justified by the tool's non-trivial spill behavior; every section earns its place and information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is exceptionally complete given no output schema exists. It covers return values in both normal and spilled cases, parameter usage, cache behavior, authentication, and concrete examples. An agent has everything needed to call this tool correctly and interpret either response form.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate, and it does: each of the three parameters is explained with matching examples and substring semantics. It adds far more meaning than the bare schema, which only provides type and default information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear purpose: browse databases, schemas, and tables with pattern-based filtering, and explicitly compares to SQL's SHOW TABLES. It is specific about the resource and operation, though it does not explicitly differentiate itself from siblings like find_tables or describe_table.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'USE THIS WHEN' section gives explicit guidance for when the tool is appropriate: exploring existing databases/schemas or filtering by exact patterns. It provides clear context but does not mention when not to use it or name alternative sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v1.0.3- Changed
describe_table4 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / properties / database / titleRemoved value: -"Database" - removed
Input schema / properties / schema / titleRemoved value: -"Schema" - removed
Input schema / properties / table / titleRemoved value: -"Table"
- Changed
execute_query4 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / properties / database / titleRemoved value: -"Database" - removed
Input schema / properties / schema / titleRemoved value: -"Schema" - removed
Input schema / properties / sql / titleRemoved value: -"Sql"
- Changed
execute_query_to_file6 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / properties / database / titleRemoved value: -"Database" - removed
Input schema / properties / file_path / titleRemoved value: -"File Path" - removed
Input schema / properties / schema / titleRemoved value: -"Schema" - removed
Input schema / properties / sql / titleRemoved value: -"Sql" - removed
Input schema / properties / timeout_seconds / titleRemoved value: -"Timeout Seconds"
- Changed
find_tables2 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / properties / search_term / titleRemoved value: -"Search Term"
- Changed
refresh_catalog3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / properties / force / titleRemoved value: -"Force" - removed
Input schema / properties / resume / titleRemoved value: -"Resume"
- Changed
show_tables4 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / properties / database_pattern / titleRemoved value: -"Database Pattern" - removed
Input schema / properties / schema_pattern / titleRemoved value: -"Schema Pattern" - removed
Input schema / properties / table_pattern / titleRemoved value: -"Table Pattern"
10 tool updates
v1.0.0- Changed
describe_table1 field changed- changed
Output schema / (root)Previous value: -{ - "additionalProperties": true, - "type": "object" -}New value: +null
- Removed
execute_big_query_to_disk - Changed
execute_query1 field changed- changed
Output schema / (root)Previous value: -{ - "additionalProperties": true, - "type": "object" -}New value: +null
- Added
execute_query_to_file - Changed
find_tables1 field changed- changed
Output schema / (root)Previous value: -{ - "additionalProperties": true, - "type": "object" -}New value: +null
- Removed
get_query_history - Changed
refresh_catalog1 field changed- changed
Output schema / (root)Previous value: -{ - "additionalProperties": true, - "type": "object" -}New value: +null
- Removed
save_last_query_to_csv - Changed
show_tables1 field changed- changed
Output schema / (root)Previous value: -{ - "additionalProperties": true, - "type": "object" -}New value: +null
- Removed
validate_query_without_execution
9 tool updates
v0.2.3- First observed
describe_table - First observed
execute_big_query_to_disk - First observed
execute_query - First observed
find_tables - First observed
get_query_history - First observed
refresh_catalog - First observed
save_last_query_to_csv - First observed
show_tables - First observed
validate_query_without_execution
TDQS
Scored across 6 tools
Each tool has a distinct role: inline query execution, query-to-file export, catalog refresh, hierarchical table browsing, keyword search, and table description. Even the two query tools are clearly separated by output destination, and the two discovery tools differ by browse-versus-search behavior.
All six tools follow the same imperative verb_noun pattern in snake_case: execute_query, execute_query_to_file, refresh_catalog, show_tables, find_tables, describe_table. The only compound name uses a consistent '_to_file' suffix rather than introducing a different naming style.
Six tools is a well-scoped size for a Snowflake read-only exploration server: refresh metadata, browse tables, search tables, describe a table, run a query, and export query results. Each tool earns its place without redundancy or bloat.
The tool surface covers the full read-only workflow: refresh catalog metadata, discover tables via browsing or keyword search, inspect column details, execute SELECT-style queries, and persist results to a file. Within the server's explicitly read-only scope there are no dead ends or obvious missing operations.
Maintenance
Related MCP Connectors
Query 40 databases from Claude, ChatGPT, or Cursor — on any device. Read-only, encrypted, audited.
Query your org's data in natural language — read-only MCP access to SQL, NoSQL, files & warehouses.
Safe, read-only Postgres and MySQL access for AI agents. Audit log + column-level controls.
Query BigQuery, Snowflake, Redshift & Azure Synapse with natural language
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to interact with Snowflake databases through SQL queries, table previews, and metadata operations. Features built-in safety checks that block destructive operations and intelligent error handling optimized for AI workflows.1MIT
- AlicenseAqualityNot gradedmaintenanceEnables AI assistants to securely connect to Snowflake data warehouses and execute SQL queries through natural language interactions. Supports multiple authentication methods and provides formatted query results with built-in security controls.12MIT
- AlicenseAqualityDmaintenanceEnables AI agents to execute SQL queries and explore Snowflake databases using natural language, with schema discovery, table inspection, and readonly mode.11547 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables secure, read-only access to Amazon Redshift data warehouses for AI assistants, allowing schema inspection, query execution, and data understanding.17 npm1MIT