Snowflake supports Model Context Protocol revision 2025-11-25.
Model Context Protocol (MCP), is an open-source standard (https://modelcontextprotocol.io/docs/getting-started/intro) that lets AI agents securely interact with business applications and external data systems, such as databases and content repositories. MCP lets enterprise businesses reduce integration challenges and quickly deliver outcomes from models. Since its launch, MCP has become foundational for agentic applications, providing a consistent and secure mechanism for invoking tools and retrieving data.
The Snowflake-managed MCP server lets AI agents securely retrieve data from Snowflake accounts without needing to deploy separate infrastructure. You can configure the MCP server to serve Cortex Analyst, Cortex Search, and Cortex Agents as tools, along with custom tools and SQL executions on the standards-based interface. MCP clients discover and invoke these tools, and retrieve data required for the application. With managed MCP servers on Snowflake, you can build scalable enterprise-grade applications while maintaining access and privacy controls. The MCP server on Snowflake provides:
When you configure hostnames for MCP server connections, use hyphens (-) instead of underscores (_). MCP servers have connection issues with hostnames containing underscores.
Using multiple MCP servers without verifying tools and descriptions could lead to vulnerabilities such as tool poisoning or tool shadowing. Snowflake recommends verifying third-party MCP servers before using them. This includes any MCP server from another Snowflake user or account. Verify all tools offered by third-party MCP servers.
We recommend using OAuth as the authentication method. Using hardcoded tokens can lead to token leakage.
When using a Programmatic Access Token (PAT), set it to use the least-privileged role allowed to work with MCP. This will help prevent leaking a secret with access to a highly-privileged role.
Configure proper permissions for the MCP server and tools following the least-privilege principle. Access to the MCP Server does not give access to the tools. Permission needs to be granted for each tool.
CREATE [ ORREPLACE ] MCPSERVER [ IFNOTEXISTS ] <server_name>FROMSPECIFICATION$$tools:-name:"product-search"type:"CORTEX_SEARCH_SERVICE_QUERY"identifier:"database1.schema1.Cortex_Search_Service1"description:"cortex search service for all products"title:"Product Search"-name:"revenue-semantic-view"type:"CORTEX_ANALYST_MESSAGE"identifier:"database1.schema1.Semantic_View_1"description:"Semantic view for all revenue tables"title:"Semantic view for revenue"$$
Snowflake currently supports the following tool types:
CORTEX_SEARCH_SERVICE_QUERY: Cortex Search Service tool
CORTEX_ANALYST_MESSAGE: Cortex Analyst tool
SYSTEM_EXECUTE_SQL: SQL execution
CORTEX_AGENT_RUN: Cortex Agent tool
GENERIC: tool for UDFs and stored procedures
The following examples show how to configure different tool types:
Using the Analyst tool, your client can generate SQL from natural language text. Use the following code to specify the tool configuration.
Note
The Snowflake-managed MCP server only supports using semantic views with Cortex Analyst. It does not support semantic models.
tools:-name:"revenue-semantic-view"type:"CORTEX_ANALYST_MESSAGE"identifier:"database1.schema1.Semantic_View_1"description:"Semantic view for all revenue tables"title:"Semantic view for revenue"
Using the Search tool requests, your client can perform unstructured search on their data.
tools:-name:"product-search"type:"CORTEX_SEARCH_SERVICE_QUERY"identifier:"database1.schema1.Cortex_Search_Service1"description:"cortex search service for all products"title:"Product Search"
For the SQL execution tool, your client can execute SQL queries on Snowflake. You can optionally configure the following options:
read_only: When set to true, only read operations (SELECT queries) are allowed. Defaults to false.
query_timeout: Maximum time in seconds for query execution.
warehouse: The warehouse to use for query execution. If not specified, the default warehouse is used.
Use the following code to specify the tool configuration:
tools:-title:"SQL Execution Tool"name:"sql_exec_tool"type:"SYSTEM_EXECUTE_SQL"description:"A tool to execute SQL queries against the connected Snowflake database."config:read_only:falsequery_timeout:600warehouse:"WAREHOUSE"
For the Agent tool, your client passes a message to the agent. The agent processes the request and returns a response. Use the following code to specify the tool configuration.
tools:-title:"Agent V2"name:"agent_1"type:"CORTEX_AGENT_RUN"identifier:"db.schema.agent"description:"agent that gives the ability to..."
For your custom tools, you must provide the user-defined function (UDF) or stored procedure signature in the tool configuration. The custom tool enables you to invoke UDFs and stored procedures as tools through the MCP server.
You can specify the following in the tool configuration:
type: function for UDF, procedure for stored procedure
warehouse: The warehouse to use. If you don’t specify a warehouse, the default warehouse is used.
query_timeout: Maximum time in seconds for tool execution.
input_schema: Corresponds to the function signature.
Use the following examples to create and configure custom tools using UDFs and stored procedures:
The following examples demonstrate creating UDFs that can be used as custom tools:
-- create a simple udf
CREATE OR REPLACE FUNCTION MULTIPLY_BY_TEN(x FLOAT)
RETURNS FLOAT
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
HANDLER = 'multiply_by_ten'
AS
$$
defmultiply_by_ten(x: float) -> float:
return x * 10
$$;
SHOW FUNCTIONS LIKE 'MULTIPLY_BY_TEN';
-- test return json/variant
CREATE OR REPLACE FUNCTION CALCULATE_PRODUCT_AND_SUM(x FLOAT, y FLOAT)
RETURNS VARIANT
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
HANDLER = 'calculate_values'
AS
$$
import json
defcalculate_values(x: float, y: float) -> dict:
"""
Calculates the product and sum of two numbers and returns them in a dictionary.
The dictionary is converted to a VARIANT (JSON) in the SQL return.
"""
product = x * y
sum_val = x + y
return {
"product": product,
"sum": sum_val
}
$$;
-- test returnlist/array
CREATE OR REPLACE FUNCTION GET_NUMBERS_IN_RANGE(x FLOAT, y FLOAT)
RETURNS ARRAY -- Use ARRAY to explicitly state a listis being returned
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
HANDLER = 'get_numbers'
AS
$$
defget_numbers(x: float, y: float) -> list:
"""
Returns a list of integers between x (exclusive) and y (inclusive).
Assumes x < y.
"""# Ensure x and y are treated as integers for range generation
start = int(x) + 1
end = int(y) + 1# range() is exclusive on the stop value# Use a list comprehension to generate the numbers# The Python list will be converted to a Snowflake ARRAY.returnlist(range(start, end))
$$;
The following examples demonstrate creating stored procedures that can be used as custom tools:
-- create a simple stored procedure
CREATE OR REPLACE PROCEDURE MULTIPLY_BY_TEN_SP(x FLOAT)
RETURNS FLOAT
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
PACKAGES = ('snowflake-snowpark-python')
HANDLER = 'multiply_by_ten'
AS
$$
# The handler logic is identical to the UDF for a scalar returndefmultiply_by_ten(x: float) -> float:
return x * 10
$$;
-- test return json/variant
CREATE OR REPLACE PROCEDURE CALCULATE_VALUES_SP(x FLOAT, y FLOAT)
RETURNS VARIANT
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
PACKAGES = ('snowflake-snowpark-python')
HANDLER = 'calculate_values'
AS
$$
# The handler logic is identical to the UDF for a VARIANT returndefcalculate_values(x: float, y: float) -> dict:
"""
Calculates the product and sum of two numbers and returns them in a dictionary.
The dictionary is converted to a VARIANT (JSON) in the SQL return.
"""
product = x * y
sum_val = x + y
return {
"product": product,
"sum": sum_val
}
$$;
-- test returnlist/array
CREATE OR REPLACE PROCEDURE GET_NUMBERS_SP(x FLOAT, y FLOAT)
RETURNS ARRAY
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
PACKAGES = ('snowflake-snowpark-python')
HANDLER = 'get_numbers'
AS
$$
defget_numbers(x: float, y: float) -> list:
"""
Returns a list of integers between x (exclusive) and y (inclusive).
The Python list will be converted to a Snowflake ARRAY.
"""# Ensure x and y are treated as integers for range generation
start = int(x) + 1
end = int(y) + 1# range() is exclusive on the stop value# Use a list comprehension to generate the numbersreturnlist(range(start, end))
$$;
The following examples demonstrate configuring custom tools for UDFs and stored procedures:
CREATEMCPSERVERmy_mcp_serverFROMSPECIFICATION$$tools:-title:"Custom Tool 1"identifier:"EXAMPLE_DATABASE.AGENTS.MULTIPLY_BY_TEN"name:"multiply_by_ten"type:"GENERIC"description:"Multiplied input value by ten and returns the result."config:type:"function"warehouse:"COMPUTE_SERVICE_WAREHOUSE"input_schema:type:"object"properties:x:description:"A number to be multiplied by ten"type:"number"-title:"Custom Tool 2"identifier:"EXAMPLE_DATABASE.AGENTS.CALCULATE_PRODUCT_AND_SUM"name:"calculate_product_and_sum"type:"GENERIC"description:"Calculates the product and sum of two numbers and returns them in a JSON object."config:type:"function"warehouse:"COMPUTE_SERVICE_WAREHOUSE"input_schema:type:"object"properties:x:description:"First number"type:"number"y:description:"Second number"type:"number"-title:"Custom Tool 3"identifier:"EXAMPLE_DATABASE.AGENTS.GET_NUMBERS_IN_RANGE"name:"get_numbers_in_range"type:"GENERIC"description:"Returns a list of integers between two numbers."config:type:"function"warehouse:"COMPUTE_SERVICE_WAREHOUSE"input_schema:type:"object"properties:x:description:"Start number (exclusive)"type:"number"y:description:"End number (inclusive)"type:"number"-title:"Custom Tool 4"identifier:"EXAMPLE_DATABASE.AGENTS.MULTIPLY_BY_TEN_SP"name:"multiply_by_ten_sp"type:"GENERIC"description:"Multiplied input value by ten and returns the result."config:type:"procedure"warehouse:"COMPUTE_SERVICE_WAREHOUSE"input_schema:type:"object"properties:x:description:"A number to be multiplied by ten"type:"number"-title:"Custom Tool 5"identifier:"EXAMPLE_DATABASE.AGENTS.CALCULATE_PRODUCT_AND_SUM_SP"name:"calculate_product_and_sum_sp"type:"GENERIC"description:"Calculates the product and sum of two numbers and returns them in a JSON object."config:type:"procedure"warehouse:"COMPUTE_SERVICE_WAREHOUSE"input_schema:type:"object"properties:x:description:"First number"type:"number"y:description:"Second number"type:"number"-title:"Custom Tool 6"identifier:"EXAMPLE_DATABASE.AGENTS.GET_NUMBERS_IN_RANGE_SP"name:"get_numbers_in_range_sp"type:"GENERIC"description:"Returns a list of integers between two numbers."config:type:"procedure"warehouse:"COMPUTE_SERVICE_WAREHOUSE"input_schema:type:"object"properties:x:description:"Start number (exclusive)"type:"number"y:description:"End number (inclusive)"type:"number"$$;
To show MCP servers, use the following commands:
SHOW MCP SERVERSINDATABASE<database_name>;SHOW MCP SERVERSINSCHEMA<schema_name>;SHOW MCP SERVERSINACCOUNT;
The following shows the output of the command:
| created_on |name|database_name|schema_name|owner|comment|------------------------------------------+-------------------+---------------+-------------+--------------+------------------------------| Fri,23 Jun 196707:00:00.123000+0000| TEST_MCP_SERVER | TEST_DATABASE | TEST_SCHEMA |ACCOUNTADMIN|[NULL]|| Fri,23 Jun 196707:00:00.123000+0000| TEST_MCP_SERVER_2 | TEST_DATABASE | TEST_SCHEMA |ACCOUNTADMIN| Test MCP serverwithcomment|
To describe an MCP server, use the following command:
For the Analyst tool, your client passes messages in the request. The SQL statement is listed in the output. You must pass the name of the tool that you’re invoking in the request in the name parameter.
POST /api/v2/databases/<database>/schemas/<schema>/mcp-servers/<name>{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"test-analyst","arguments":{"message":"text"}}}
For Search tool requests, your client can pass the query and the following optional arguments:
columns
limit
The search results and request ID are returned in the output. You must pass the name of the tool that you’re invoking in the request as the name parameter.
POST /api/v2/databases/{database}/schemas/{schema}/mcp-servers/{name}{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"product-search","arguments":{"query":"Hotels in NYC","columns": arrayof strings,"limit": int}}}