Connecting to Snowflake MCP Server

Metric Insights Concierge Service supports integration with Snowflake Agents via the Model Context Protocol (MCP) Server. Establishing this connection allows Users to interact with Snowflake resources directly from the Concierge interface.

This article describes the steps required to set up the Snowflake Agent, configure Concierge External Resource and connect them via a separately set MCP Server.

In this article:

  1. Configure Snowflake via Snowflake CLI
    1. Basic Infrastructure Setup
    2. Role and User Management
    3. Database Permissions
    4. Cortex Functions and Intelligence Setup
    5. RETAIL_SALES Database Setup
    6. Create Cortex Agent
    7. Network Security and Authentication
    8. Generate Programmatic Access Token (PAT)
    9. Advanced Permissions
  2. Test the Snowflake CLI Settings
  3. Gather Data for MCP Server Setup
  4. Set Up the MCP Server
  5. Configure Concierge External Resource

1. Configure Snowflake via Snowflake CLI

First of all, set up the required roles, users, and permissions in Snowflake to get the MCP server working with your existing Snow CLI profile.

PREREQUISITES:

  • Snowflake account with ACCOUNTADMIN privileges.
  • Snow CLI installed and configured with a working profile.
  • Access to Snowsight or Snowflake CLI for executing SQL commands.

All the following steps are performed in Snowflake CLI or Snowflake Web UI.

Expand or collapse content 1.1. Basic Infrastructure Setup

1.1.1. Set Environment Variables

Set up the environment variables. Copy the .env.template to .env and configure:

# Core Snowflake Configuration 

SA_USER="CORTEX_MCP_SERVICE" 
SNOWFLAKE_MCP_DEMO_ROLE="MCP_DEMO_ROLE" 
SNOWFLAKE_MCP_DEMO_DATABASE="MCP_DEMO" 
SNOWFLAKE_ACCOUNT="your_account_identifier" 
SNOWFLAKE_MCP_DEMO_WAREHOUSE="DEMO_WH" 

# Cortex Configuration 

SEMANTIC_MODEL_FILE="@MCP_DEMO.DATA.MY_MODELS/support_tickets.yaml" 
CORTEX_SEARCH_SERVICE="MCP_DEMO.DATA.INVOICE_SEARCH_SERVICE" 
CORTEX_AGENT_LLM_MODEL="claude-3-5-sonnet"

1.1.2. Create Core Database Objects

Run the setup script to create the foundational database objects. Execute scripts/setup.sql with your configured environment variables.

This creates:

  • MCP_DEMO database
  • DATA, MY_MODELS, NETWORKS, POLICIES schemas
  • SUPPORT_TICKETS table with sample data
  • Document processing infrastructure
  • Cortex Search Service
Expand or collapse content 1.2. Role and User Management

1.2.1. Create MCP Demo Role

USE ROLE ACCOUNTADMIN; 

-- Create the main demo role 

CREATE ROLE IF NOT EXISTS MCP_DEMO_ROLE
      COMMENT = 'Role for MCP server demo operations'; 

-- Grant basic compute permissions 

GRANT EXECUTE TASK ON ACCOUNT TO ROLE MCP_DEMO_ROLE; 
GRANT USAGE ON WAREHOUSE DEMO_WH TO ROLE MCP_DEMO_ROLE;

1.2.2. Create Service User

USE ROLE ACCOUNTADMIN; 

-- Create service user for programmatic access 

CREATE USER IF NOT EXISTS CORTEX_MCP_SERVICE
     TYPE = SERVICE
     COMMENT = 'Service User for Cortex Agents MCP Demo'
     DEFAULT_ROLE = MCP_DEMO_ROLE
     DEFAULT_WAREHOUSE = DEMO_WH; 

-- Grant role to service user 

GRANT ROLE MCP_DEMO_ROLE TO USER CORTEX_MCP_SERVICE; 
GRANT APPLY AUTHENTICATION POLICY ON USER CORTEX_MCP_SERVICE TO ROLE MCP_DEMO_ROLE;
Expand or collapse content 1.3. Database Permissions

1.3.1. Grant Database and Schema Access

USE ROLE ACCOUNTADMIN; 

-- Grant ownership of demo database to MCP role 

GRANT OWNERSHIP ON DATABASE MCP_DEMO TO ROLE MCP_DEMO_ROLE; 

-- Switch to MCP role for schema creation 

USE ROLE MCP_DEMO_ROLE; 
USE DATABASE MCP_DEMO; 

-- Ensure all required schemas exist 

CREATE SCHEMA IF NOT EXISTS DATA; 
CREATE SCHEMA IF NOT EXISTS MY_MODELS; 
CREATE SCHEMA IF NOT EXISTS NETWORKS; 
CREATE SCHEMA IF NOT EXISTS POLICIES;

1.3.2. Grant Table and View Permissions

USE ROLE ACCOUNTADMIN; 

-- Grant comprehensive access to all objects in MCP_DEMO database 

GRANT SELECT ON ALL TABLES IN DATABASE MCP_DEMO TO ROLE MCP_DEMO_ROLE; 
GRANT SELECT ON FUTURE TABLES IN DATABASE MCP_DEMO TO ROLE MCP_DEMO_ROLE; 
GRANT SELECT ON ALL VIEWS IN DATABASE MCP_DEMO TO ROLE MCP_DEMO_ROLE; 
GRANT SELECT ON FUTURE VIEWS IN DATABASE MCP_DEMO TO ROLE MCP_DEMO_ROLE; 

-- Grant stage permissions 

GRANT READ, WRITE ON ALL STAGES IN DATABASE MCP_DEMO TO ROLE MCP_DEMO_ROLE; 
GRANT READ, WRITE ON FUTURE STAGES IN DATABASE MCP_DEMO TO ROLE MCP_DEMO_ROLE;
Expand or collapse content 1.4. Cortex Functions and Intelligence Setup

1.4.1. Grant Cortex Function Permissions

USE ROLE ACCOUNTADMIN; 

-- Grant access to Snowflake Cortex functions 

GRANT USAGE ON DATABASE SNOWFLAKE TO ROLE MCP_DEMO_ROLE; 
GRANT USAGE ON SCHEMA SNOWFLAKE.CORTEX TO ROLE MCP_DEMO_ROLE; 

-- Grant specific Cortex function permissions 

GRANT USAGE ON FUNCTION SNOWFLAKE.CORTEX.COMPLETE TO ROLE MCP_DEMO_ROLE; 
GRANT USAGE ON FUNCTION SNOWFLAKE.CORTEX.EMBED_TEXT_768 TO ROLE MCP_DEMO_ROLE; 
GRANT USAGE ON FUNCTION SNOWFLAKE.CORTEX.SENTIMENT TO ROLE MCP_DEMO_ROLE; 
GRANT USAGE ON FUNCTION SNOWFLAKE.CORTEX.SUMMARIZE TO ROLE MCP_DEMO_ROLE; 
GRANT USAGE ON FUNCTION SNOWFLAKE.CORTEX.TRANSLATE TO ROLE MCP_DEMO_ROLE; 
GRANT USAGE ON FUNCTION SNOWFLAKE.CORTEX.EXTRACT_ANSWER TO ROLE MCP_DEMO_ROLE; 
GRANT USAGE ON FUNCTION SNOWFLAKE.CORTEX.PARSE_DOCUMENT TO ROLE MCP_DEMO_ROLE; 
GRANT USAGE ON FUNCTION SNOWFLAKE.CORTEX.SPLIT_TEXT_RECURSIVE_CHARACTER TO ROLE MCP_DEMO_ROLE;

1.4.2. Set Up Snowflake Intelligence Access

USE ROLE ACCOUNTADMIN; 

-- Grant access to Snowflake Intelligence database 

GRANT USAGE ON DATABASE SNOWFLAKE_INTELLIGENCE TO ROLE MCP_DEMO_ROLE; 
GRANT USAGE ON SCHEMA SNOWFLAKE_INTELLIGENCE.AGENTS TO ROLE MCP_DEMO_ROLE; 

-- Grant ability to create and manage Cortex Agents 

GRANT CREATE CORTEX AGENT ON SCHEMA SNOWFLAKE_INTELLIGENCE.AGENTS TO ROLE MCP_DEMO_ROLE;
Expand or collapse content 1.5. RETAIL_SALES Database Setup

This step is optional, but recommended.

1.5.1. Create RETAIL_SALES Database and Objects

USE ROLE ACCOUNTADMIN; 

-- Create RETAIL_SALES database for semantic models 

CREATE DATABASE IF NOT EXISTS RETAIL_SALES
     COMMENT = 'Database for retail sales data and semantic models'; 

USE DATABASE RETAIL_SALES; 

-- Create schema 

CREATE SCHEMA IF NOT EXISTS RETAIL_SALES_DEMO
     COMMENT = 'Schema for retail sales demo data and models'; 

USE SCHEMA RETAIL_SALES_DEMO; 

-- Create stage for semantic models 

CREATE STAGE IF NOT EXISTS RETAIL_SALES_STAGE
     COMMENT = 'Stage for storing semantic model YAML files'; 

-- Create sample tables 

CREATE TABLE IF NOT EXISTS CUSTOMERS (
     customer_id INT PRIMARY KEY,
     customer_name VARCHAR(100),
     email VARCHAR(100),
     phone VARCHAR(20),
     address VARCHAR(200),
     city VARCHAR(50),
     state VARCHAR(50),
     country VARCHAR(50),
     created_date DATE 
); 
CREATE TABLE IF NOT EXISTS SUPPORT_TICKETS (
     ticket_id INT PRIMARY KEY,
     customer_id INT,
     service_type VARCHAR(50),
     issue_description TEXT,
     status VARCHAR(20),
     created_date TIMESTAMP,
     resolved_date TIMESTAMP,
     priority VARCHAR(20),
     assigned_to VARCHAR(100)
 );

-- Create semantic model view 

CREATE OR REPLACE VIEW CUSTOMER_SUPPORT_MODEL AS 

SELECT
     st.ticket_id,
     st.service_type,
     st.issue_description,
     st.status,
     st.priority,
     st.created_date,
     st.resolved_date,
     st.assigned_to,
     c.customer_name,
     c.email as customer_email,
     c.city as customer_city,
     c.state as customer_state,
     DATEDIFF(day, st.created_date, COALESCE(st.resolved_date, CURRENT_TIMESTAMP())) as resolution_time_days 

FROM SUPPORT_TICKETS st 

LEFT JOIN CUSTOMERS c ON st.customer_id = c.customer_id;

1.5.2. Grant RETAIL_SALES Permissions

USE ROLE ACCOUNTADMIN; 

-- Grant comprehensive access to RETAIL_SALES database 

GRANT USAGE ON DATABASE RETAIL_SALES TO ROLE MCP_DEMO_ROLE; 
GRANT USAGE ON SCHEMA RETAIL_SALES.RETAIL_SALES_DEMO TO ROLE MCP_DEMO_ROLE; 

-- Grant permissions on all objects 

GRANT SELECT ON ALL TABLES IN SCHEMA RETAIL_SALES.RETAIL_SALES_DEMO TO ROLE MCP_DEMO_ROLE; 
GRANT SELECT ON FUTURE TABLES IN SCHEMA RETAIL_SALES.RETAIL_SALES_DEMO TO ROLE MCP_DEMO_ROLE; 
GRANT SELECT ON ALL VIEWS IN SCHEMA RETAIL_SALES.RETAIL_SALES_DEMO TO ROLE MCP_DEMO_ROLE; 
GRANT SELECT ON FUTURE VIEWS IN SCHEMA RETAIL_SALES.RETAIL_SALES_DEMO TO ROLE MCP_DEMO_ROLE; 

-- Grant stage permissions 

GRANT READ, WRITE ON STAGE RETAIL_SALES.RETAIL_SALES_DEMO.RETAIL_SALES_STAGE TO ROLE MCP_DEMO_ROLE;
Expand or collapse content 1.6. Create Cortex Agent

Create RETAIL_SALES Agent.

USE ROLE ACCOUNTADMIN; 
USE DATABASE SNOWFLAKE_INTELLIGENCE; 
USE SCHEMA AGENTS; 

-- Create the RETAIL_SALES agent 

CREATE CORTEX AGENT IF NOT EXISTS RETAIL_SALES
     WAREHOUSE = 'DEMO_WH'
     COMMENT = 'Retail sales analysis agent for MCP demo'; 

-- Grant permissions on the agent 

GRANT USAGE ON CORTEX AGENT SNOWFLAKE_INTELLIGENCE.AGENTS.RETAIL_SALES TO ROLE MCP_DEMO_ROLE; 
GRANT OPERATE ON CORTEX AGENT SNOWFLAKE_INTELLIGENCE.AGENTS.RETAIL_SALES TO ROLE MCP_DEMO_ROLE;
Expand or collapse content 1.7. Network Security and Authentication

1.7.1. Set Up Network Policy

USE ROLE MCP_DEMO_ROLE; 
USE DATABASE MCP_DEMO; 

-- Create network rule for local access (you may need to update the IP) 

CREATE OR REPLACE NETWORK RULE MCP_DEMO.networks.pat_local_access_rule
   mode = ingress
   type = ipv4
   value_list = ('YOUR_LOCAL_IP/32')  -- Replace with your actual IP
   comment = 'Allow local machine IPv4 access'; 

-- Create network policy 

USE ROLE ACCOUNTADMIN; 
CREATE OR REPLACE NETWORK POLICY LOCAL_PAT_NETWORK_POLICY
   allowed_network_rule_list = ('MCP_DEMO.networks.pat_local_access_rule')
   comment = 'Network policy for PAT access';

1.7.2. Set Up Authentication Policy

USE ROLE MCP_DEMO_ROLE; 

-- Create authentication policy for PAT 

CREATE OR REPLACE AUTHENTICATION POLICY MCP_DEMO.policies.mcp_auth_policy
   authentication_methods = ('PROGRAMMATIC_ACCESS_TOKEN')
   pat_policy = (
     default_expiry_in_days=15,
     max_expiry_in_days=90,
     network_policy_evaluation = ENFORCED_REQUIRED
   ); 

-- Apply policies to service user 

USE ROLE ACCOUNTADMIN; 
ALTER USER CORTEX_MCP_SERVICE SET
    NETWORK_POLICY = 'LOCAL_PAT_NETWORK_POLICY',
    AUTHENTICATION_POLICY = 'MCP_DEMO.policies.mcp_auth_policy';
Expand or collapse content 1.8. Generate Programmatic Access Token (PAT)

1.8.1. Create PAT

USE ROLE ACCOUNTADMIN; 

-- Create PAT for service user 

ALTER USER CORTEX_MCP_SERVICE ADD PAT mcp_demo
    ROLE_RESTRICTION = MCP_DEMO_ROLE
    COMMENT = 'PAT for MCP server access';

The output will contain the token_secret - save this for your .env file.

1.8.2. Use the PAT Script

Alternatively, you can use the provided script: ./scripts/pat.sh Run it after seting environment variables first, then run:

This script will:

  • Create the service user;
  • Set up network policies;
  • Create authentication policies;
  • Generate the PAT;
  • Update your .env file with the token.
Expand or collapse content 1.9. Advanced Permissions

Optionally, it is possible to grant ACCOUNTADMIN to service accounts.

NOTE: Granting ACCOUNTADMIN to service accounts is a security risk. Only do this if you need maximum privileges for testing.

USE ROLE ACCOUNTADMIN; 

-- Grant ACCOUNTADMIN role (SECURITY RISK!) 

GRANT ROLE ACCOUNTADMIN TO USER CORTEX_MCP_SERVICE; 

-- Set as default role 

ALTER USER CORTEX_MCP_SERVICE SET DEFAULT_ROLE = ACCOUNTADMIN; 

-- Regenerate PAT with admin access 

ALTER USER CORTEX_MCP_SERVICE ROTATE PAT mcp_demo
   COMMENT = 'PAT with elevated privileges';

2. Test the Snowflake CLI Settings

Test and verify the setup to make sure everything works fine.

2.1. Check User Configuration

USE ROLE ACCOUNTADMIN; 
DESC USER CORTEX_MCP_SERVICE; 
SHOW USER PATS FOR USER CORTEX_MCP_SERVICE;

2.2. Check Role Permissions

SHOW GRANTS TO ROLE MCP_DEMO_ROLE; 
SHOW GRANTS TO USER CORTEX_MCP_SERVICE;

2.3. Check Agent Access

USE ROLE MCP_DEMO_ROLE; 
USE DATABASE SNOWFLAKE_INTELLIGENCE; 
USE SCHEMA AGENTS; 
DESC CORTEX AGENT RETAIL_SALES;

2.4. Test Database Access

USE ROLE MCP_DEMO_ROLE; 
USE DATABASE MCP_DEMO; 
SELECT COUNT(*) FROM DATA.SUPPORT_TICKETS; 

-- If RETAIL_SALES is set up: 

USE DATABASE RETAIL_SALES; 
SELECT COUNT(*) FROM RETAIL_SALES_DEMO.CUSTOMER_SUPPORT_MODEL;

2.5. Test PAT Access via API

# Test Cortex Search Service 

curl --location \   "https://${SNOWFLAKE_ACCOUNT}.snowflakecomputing.com/api/v2/databases/${SNOWFLAKE_MCP_DEMO_DATABASE}/schemas/data/cortex-search-services/invoice_search_service:query" \
   --header 'X-Snowflake-Authorization-Token-Type: PROGRAMMATIC_ACCESS_TOKEN' \
   --header 'Content-Type: application/json' \
   --header 'Accept: application/json' \
   --header "Authorization: Bearer ${SNOWFLAKE_PASSWORD}" \
   --data '{
     "query": "What kind of service does Gregory have?",
     "columns": ["CHUNK", "FILE_NAME"],
     "limit": 1
   }'

2.6. Test Snow CLI Connection

snow connection test -x \
   --user "${SA_USER}" \
   --role "${SNOWFLAKE_MCP_DEMO_ROLE}"

2.7. Configuration Summary

After completing this setup, the .env file should look like:

SA_USER="CORTEX_MCP_SERVICE" 
SNOWFLAKE_MCP_DEMO_ROLE="MCP_DEMO_ROLE" 
SNOWFLAKE_MCP_DEMO_DATABASE="MCP_DEMO" 
SNOWFLAKE_ACCOUNT="your_account_identifier" 
SNOWFLAKE_PASSWORD="generated_pat_token_here" 
SEMANTIC_MODEL_FILE="@MCP_DEMO.DATA.MY_MODELS/support_tickets.yaml" 
CORTEX_SEARCH_SERVICE="MCP_DEMO.DATA.INVOICE_SEARCH_SERVICE" 
SNOWFLAKE_MCP_DEMO_WAREHOUSE="DEMO_WH" 
CORTEX_AGENT_LLM_MODEL="claude-3-5-sonnet"

2.8. Troubleshooting

Common issues are:

  1. PAT Authentication Fails:
    • Verify network policy allows your IP;
    • Check PAT expiry date;
    • Ensure user has correct default role.
  2. Agent API Returns 401 Unauthorized:
    • Check SNOWFLAKE_INTELLIGENCE database access;
    • Verify USAGE and OPERATE permissions on agent;
    • Ensure Cortex function permissions are granted.
  3. Database Access Denied:
    • Verify USAGE permissions on database and schema;
    • Check that service user has the correct default role;
    • Ensure SELECT permissions on tables/views.
  4. Network Policy Issues:
    • Update IP address in network rule;
    • Check if your IP has changed;
    • Verify network policy is applied to user.

3. Gather Data for MCP Server Setup

During the MCP Server setup the following data is required:

  • account;
  • database;
  • schema;
  • token.

To get that data login into the Snowflake account.

3.1. "account" Value

Go to Admin > Accounts

  1. In the row of the account that has ACCOUNTADMIN privileges hover over the link icon to show the account's locator.
  2. Copy the xxxxxxx.us-east-2.aws part, this is the account value.

3.2. "database" and "schema" Values

Access Catalog

Copy the titles of database and schema used for the connection with MCP server.

3.3. "token" Value

Access User menu > Settings > Authentication

  1. [Generate new token]
  2. Name: Give the token a descriptive name.
  3. Expires in: Select the expiration period.
  4. Grant access: Select the account to which the access is given.
  5. [Generate]
  6. Copy the token and save it somewhere. Its impossible to see it ever again after you close this window.

4. Set Up the MCP Server

An MCP server can be runlocally on the same machine where the application is running or remotely on a separate server or cloud platform. After choosing the platform:

  1. Clone this repository ```bash git clone [email protected]:metricinsights/snowflake-cortex-mcp-server.git ```
  2. Copy [config.example.py](https://github.com/metricinsights/snowflake-cortex-mcp-server/blob/main/config.example.py) to config.py folder and fill in the Snowflake account values.
  3. Run the service via docker ```bash docker-compose up -d ```
Expand or collapse content Config Example
_defaults = Config(
     account="TTXXXXX.us-east-2.aws",
     database="SNOWFLAKE_INTELLIGENCE",
     schema="AGENTS",
     token="<TOKEN>",
 )
 agent_configs = {
     "CUSTOMER_SUPPORT": Config(agent="CUSTOMER_SUPPORT", defaults=_defaults),
     "INVENTORY": Config(agent="INVENTORY", defaults=_defaults),
     "RETAIL_SALES": Config(agent="RETAIL_SALES", defaults=_defaults), }

5. Configure Concierge External Resource

Go to Metric Insights, accessAdmin Concierge Setupand open theContent Sourcestab

  1. [+ Add External Resource Configuration]
  2. Name: Give the external resource a descriptive name.
  3. Add a block of JSON code.

It is recommended to use the following JSON code for Snowflake External Resource configuration.

Code Example

{
     "name": "snowflake-int",
     "title": "Snowflake Intelligence1",
     "display": "raw",
     "scope": "Questions about customer_support, retail sales, inventory. Available agent_ids: 'CUSTOMER_SUPPORT', 'INVENTORY', 'RETAIL_SALES'",
     "scenario_type":"mcp_single_tool",
     "domain_id_field":"agent",
     "mcp_server": {
         "url": "http://<mcp_hostname>:<port>/mcp",
         "name": "snowflake-int"
     },
     "tool": "ask",
     "display_progress": "{{title}}: {{message}}",
     "timeout": 600
 }

Snowflake Code Specifics

VariableDescription
name
The value of this variable should be unique and exactly match the Name field in the UI above the editor. It is allowed to use A-Z/a-z alphabetic symbols, digits, and underscore (_) when setting a name.
title
The display name. This name is shown in the All Sources button and in Concierge responses.
display
Defines how data from the external agent is shown. The raw is the required option for this variable. It means that MCP tool execution results will be immediately displayed to the User as is. Snowflake uses custom MCP server which performs all required result formatting, so no additional post-processing is needed.
scenario_type
The mcp_single_tool option is mandatory for this variable.
scope
A prompt that instructs the LLM when to use this external resource.
domain_id_field
The agent option is mandatory for this variable. For MCP Servers that support domain transferring as the instrument's argument, this field defines where to transfer the domain ID.
mcp_server
url
URL of the MCP Server is a required value. Replace mcp_hostname and port with actual values.
name
Name of MCP Server. It should be unique, but is an optional variable.
tool
scenario_type variable is set to mcp_single_tool, so this field is required. The ask option is mandatory for this variable.
display_progress
The template for displaying MCP execution progress status messages from the MCP server if available.
timeout
Recommended value is 300 seconds.

Don't forget to [Save] the External Resource.

Snowflake will appear in the All Sources menu after adding a Domain to its external resource.