Snowflake
Snowflake runs MCP servers inside your own Snowflake account. You define each one as a schema-level MCP server object, choose which tools it exposes, and connect it to QuilrAI like any other remote MCP server. Requests run in Snowflake under the connecting user's role, so Snowflake's own grants and governance apply to every tool call.
See Overview for shared prerequisites and secret-handling guidance.
How Snowflake Differs
- You build the server first. There is no ready-made Snowflake MCP to install. An admin creates an MCP server object with
CREATE MCP SERVERand lists the tools it exposes. Until then there is no URL to connect. - You create an OAuth app, as a security integration. Snowflake does not support Dynamic Client Registration. You create a Snowflake OAuth security integration and give QuilrAI its client ID and client secret. A programmatic access token (PAT) is the non-OAuth alternative.
- Access follows the role. Tools run with the connecting user's default role, or the PAT's restricted role. That role needs
USAGEon the MCP server and on every object its tools use. - Tools only. Snowflake implements MCP tools (protocol revision
2025-11-25). It does not offer MCP resources, prompts or sampling. One server can expose up to 50 tools.
Before You Start
Snowflake account URLs can contain underscores, for example myorg-my_account.snowflakecomputing.com. MCP connections fail with underscores in the hostname. Replace them with hyphens: myorg-my-account.snowflakecomputing.com.
Connect Snowflake
1. Create The MCP Server
Run this in a Snowflake worksheet as a role that can create objects in the target schema. Keep only the tools you need:
CREATE OR REPLACE MCP SERVER analytics_db.mcp.quilr_mcp
FROM SPECIFICATION $$
tools:
- name: "sql_exec_tool"
title: "SQL Execution Tool"
type: "SYSTEM_EXECUTE_SQL"
description: "Run read-only SQL against Snowflake."
config:
read_only: true
query_timeout: 600
warehouse: "ANALYTICS_WH"
- name: "revenue-semantic-view"
title: "Revenue semantic view"
type: "CORTEX_ANALYST_MESSAGE"
identifier: "analytics_db.sales.revenue_semantic_view"
description: "Answer revenue questions from the revenue semantic view."
- name: "product-search"
title: "Product search"
type: "CORTEX_SEARCH_SERVICE_QUERY"
identifier: "analytics_db.sales.product_search_service"
description: "Search the product catalog."
$$;
Write each description for the model: it is how an agent decides which tool to call.
Set read_only: true on SYSTEM_EXECUTE_SQL. Without it, agents can run any SQL the role is allowed to run, including DML and DDL. Snowflake truncates SQL and GENERIC tool results at 250 KB.
The server's URL is:
https://<account-url>/api/v2/databases/<database>/schemas/<schema>/mcp-servers/<server-name>
For the example above: https://myorg-myaccount.snowflakecomputing.com/api/v2/databases/analytics_db/schemas/mcp/mcp-servers/quilr_mcp.
2. Grant An MCP Access Role
Create one role for MCP access, grant it only what the tools need, and make it the default role for the users who will connect:
CREATE ROLE IF NOT EXISTS mcp_access_role;
GRANT USAGE ON DATABASE analytics_db TO ROLE mcp_access_role;
GRANT USAGE ON SCHEMA analytics_db.mcp TO ROLE mcp_access_role;
GRANT USAGE ON MCP SERVER analytics_db.mcp.quilr_mcp TO ROLE mcp_access_role;
-- One grant per tool, matching the server specification
GRANT USAGE ON WAREHOUSE analytics_wh TO ROLE mcp_access_role;
GRANT SELECT ON SEMANTIC VIEW analytics_db.sales.revenue_semantic_view TO ROLE mcp_access_role;
GRANT USAGE ON CORTEX SEARCH SERVICE analytics_db.sales.product_search_service TO ROLE mcp_access_role;
GRANT ROLE mcp_access_role TO USER jane_doe;
ALTER USER jane_doe SET DEFAULT_ROLE = 'MCP_ACCESS_ROLE' DEFAULT_WAREHOUSE = 'ANALYTICS_WH';
For a CORTEX_AGENT_RUN tool, also grant USAGE ON AGENT <db>.<schema>.<agent> and the SNOWFLAKE.CORTEX_AGENT_USER database role. Tools also need privileges on the data underneath, such as SELECT on the tables a semantic view reads.
An OAuth session uses the user's DEFAULT_ROLE as its primary role. If a user's default role cannot use the MCP server, connecting succeeds but tool discovery or calls fail. Setting DEFAULT_ROLE as above avoids that.
3. Choose How QuilrAI Signs In
3a. Snowflake OAuth
Create a confidential OAuth client whose redirect URI is the QuilrAI callback URL:
CREATE OR REPLACE SECURITY INTEGRATION QUILR_MCP_OAUTH
TYPE = OAUTH
OAUTH_CLIENT = CUSTOM
ENABLED = TRUE
OAUTH_CLIENT_TYPE = 'CONFIDENTIAL'
OAUTH_REDIRECT_URI = 'https://mcpgateway.quilrai.com/oauth/callback'
OAUTH_ISSUE_REFRESH_TOKENS = TRUE
OAUTH_USE_SECONDARY_ROLES = NONE
ALLOWED_ROLES_LIST = ('MCP_ACCESS_ROLE');
Use the callback URL exactly as QuilrAI shows it on the Connect with OAuth step. ALLOWED_ROLES_LIST and OAUTH_USE_SECONDARY_ROLES = NONE keep MCP sessions on the MCP access role only. Snowflake blocks ACCOUNTADMIN, ORGADMIN and SECURITYADMIN from OAuth sessions by default.
Read the client credentials. The integration name must be in upper case here:
SELECT SYSTEM$SHOW_OAUTH_CLIENT_SECRETS('QUILR_MCP_OAUTH');
The result is JSON. Copy OAUTH_CLIENT_ID and OAUTH_CLIENT_SECRET.
Then add the server in QuilrAI:
- Go to MCP Gateway and click Add MCP server.
- Enter a Name and paste the MCP server URL from step 1 as the Transport URL.
- Leave How the gateway signs in on Auto-detect (recommended) and click Probe and continue. Snowflake advertises OAuth, so the Connect with OAuth step opens.
- Paste
OAUTH_CLIENT_IDas the OAuth client ID andOAUTH_CLIENT_SECRETas the OAuth client secret. - Click Create MCP, then sign in to Snowflake as a user whose default role is the MCP access role, and approve the consent screen. This administrator sign-in only lets the gateway discover the tools.
- After authorization, QuilrAI fetches the tools. Enable the ones you want in Tools.
Each user then connects their own Snowflake account the first time they use the server, and their calls run with their own default role. See OAuth Connect.
Give your MCP clients the QuilrAI gateway URL shown on the MCP card, not the snowflakecomputing.com URL, so traffic goes through the gateway's controls.
If your account uses an external identity provider such as Okta or Microsoft Entra ID for Snowflake sign-in, Snowflake can bind an EXTERNAL_OAUTH security integration to the MCP server's schema, database or account with OAUTH_AUTHORIZATION_SERVER. Register the QuilrAI callback URL in that provider instead, and use that provider's client ID and secret. See Snowflake's MCP server documentation.
3b. Programmatic Access Token
Create a token that can only use the MCP access role:
ALTER USER mcp_service_user ADD PROGRAMMATIC ACCESS TOKEN quilr_mcp
ROLE_RESTRICTION = 'MCP_ACCESS_ROLE';
Snowflake shows the token once. Then add the server in QuilrAI:
- Go to MCP Gateway and click Add MCP server, and paste the MCP server URL as the Transport URL.
- Under How the gateway signs in, choose Upstream API key.
- Paste the token as the Upstream API key. Set Authentication placement to Authorization bearer header with Value prefix
Bearer. - Choose Shared by the whole tenant for one service identity, or Each user brings their own so each user enters their own token.
- Click Create MCP and enable the tools you want.
By default Snowflake only accepts a PAT from a user who is subject to a network policy. Add the QuilrAI gateway's egress IPs, listed under MCP Library: Internal MCPs, to that policy. An account-level network policy applies to OAuth sessions too.
A PAT is a long-lived credential. Never commit it to Git or paste it into tickets or chat. Prefer OAuth when you can.
Verify The Connection
Start with a read-only request that only uses the SQL tool:
Using Snowflake, run SELECT CURRENT_ROLE(), CURRENT_WAREHOUSE() and show the result.
The role should be your MCP access role. Then try a Cortex Analyst or Cortex Search tool if you added one:
Using Snowflake, what was total revenue last quarter? Show the SQL you used.
Troubleshooting
MCP server objects are not replicated in failover groups. After a failover, recreate the MCP server on the secondary account. OAuth security integrations are replicated.