Connect a Snowflake-Managed MCP Server
Snowflake can host an server object inside a database and schema, exposing Cortex Analyst, Cortex Search, Cortex Agents, SQL execution, and custom UDF/stored procedure tools without any separate infrastructure to deploy. This guide covers the Arcade-side setup for connecting a Snowflake-managed as a remote MCP server, plus the Snowflake settings that most commonly trip people up.
This guide is about connecting to a Snowflake-managed server, not the Arcade Snowflake toolkit. Arcade’s Snowflake toolkit covers query and write access, with none of the setup below.
The managed server can front tools no generic toolkit could ever pre-build, since a customer defines them for their own :
- Custom UDFs and stored procedures a Snowflake administrator writes and governs directly
- Cortex Analyst, Cortex Search, and Cortex as callable
This guide draws directly from Snowflake’s own MCP server documentation , which is unusually precise about exact SQL, error strings, and failure modes, more so than the vendor docs behind some of the other guides in this section. Even so, the Arcade-side field mapping hasn’t been walked through end-to-end against a live . Confirm before treating this as authoritative.
Outcomes
Connect a Snowflake-managed server to Arcade and use its in gateways and SDKs.
You will Learn
- Which Snowflake security integration and role settings matter for Arcade specifically, and why
- Configure the remote server’s OAuth 2.0 settings in Arcade
- Diagnose the most common setup mistakes from their error messages
Prerequisites
- An Arcade
- A Snowflake account with an server object already created (
CREATE MCP SERVER), exposing the you want Arcade to reach ACCOUNTADMIN, or a role with the privileges to create a security integration and grant access
Set up Snowflake
Use hyphens, not underscores, in any hostname involved in this setup. Snowflake calls this out repeatedly in its own docs: servers have connection issues with hostnames containing underscores, and this affects both your account URL and any schema name that ends up in the ’s URL path.
-
Create a least-privileged access role for , and grant it only what it needs. Access to the object itself does not grant access to the tools behind it. Each tool’s underlying object (a Cortex , Search Service, Semantic View, function, or procedure) needs its own grant:
SQLCREATE ROLE mcp_access_role; GRANT USAGE ON WAREHOUSE <warehouse_name> TO ROLE mcp_access_role; GRANT USAGE ON DATABASE <database_name> TO ROLE mcp_access_role; GRANT USAGE ON SCHEMA <database_name>.<schema_name> TO ROLE mcp_access_role; GRANT USAGE ON MCP SERVER <database_name>.<schema_name>.<server_name> TO ROLE mcp_access_role; -- Then grant access to whatever the server's tools actually use, for example: GRANT USAGE ON CORTEX SEARCH SERVICE <database_name>.<schema_name>.<search_service_name> TO ROLE mcp_access_role; GRANT SELECT ON SEMANTIC VIEW <database_name>.<schema_name>.<semantic_view_name> TO ROLE mcp_access_role;Don’t grant this role to
PUBLICor give it broad future-table access just to make an connection work. Scope it to exactly what the server’s require. -
Create a Snowflake OAuth security integration for Arcade. The Snowflake-managed server doesn’t support Dynamic Client Registration. As with the other providers in this section, you create this manually and supply the resulting Client ID and Secret to Arcade yourself.
SQLCREATE OR REPLACE SECURITY INTEGRATION arcade_mcp_integration TYPE = OAUTH OAUTH_CLIENT = CUSTOM ENABLED = TRUE OAUTH_CLIENT_TYPE = 'CONFIDENTIAL' OAUTH_REDIRECT_URI = '<redirect_URI>' OAUTH_USE_SECONDARY_ROLES = NONE ALLOWED_ROLES_LIST = ('mcp_access_role');Leave
OAUTH_REDIRECT_URIas a placeholder for now; you’ll set it to the value Arcade generates once you register the server (see Add the redirect URI to your security integration below).OAUTH_USE_SECONDARY_ROLES = NONEplus a tightly scopedALLOWED_ROLES_LISTis Snowflake’s own recommended least-privilege pattern for . Leaving secondary roles implicit is technically supported, but it broadens the session’s effective access beyond what’s usually intended.Retrieve the Client ID and Secret with:
SQLSELECT SYSTEM$SHOW_OAUTH_CLIENT_SECRETS('ARCADE_MCP_INTEGRATION');The integration name is case-sensitive in this call and must be uppercase, regardless of the case you used when creating it.
-
Set each authorizing ’s default role and warehouse. By default, an OAuth session uses the connecting user’s
DEFAULT_ROLEas its primary role. The scope Claude and some other MCP clients request (session:role:all) doesn’t let you pick a different role at connect time. If a user’sDEFAULT_ROLEisn’t the MCP access role, or they have noDEFAULT_WAREHOUSEset, the session either uses the wrong privileges or fails to initialize:SQLALTER USER <username> SET DEFAULT_ROLE = 'mcp_access_role' DEFAULT_WAREHOUSE = '<warehouse_name>'; -
Check your ’s network policy. If the Snowflake account has network policies enabled, requests from Arcade’s infrastructure, not the end ’s browser, need to be explicitly allowed, since the token request originates from Arcade’s servers:
SQLCREATE NETWORK RULE mcp_client_ingress_rule MODE = INGRESS TYPE = IPV4 VALUE_LIST = ('<arcade_outbound_ip_1>', '<arcade_outbound_ip_2>', ...); ALTER NETWORK POLICY <your_policy_name> ADD ALLOWED_NETWORK_RULE_LIST = ('mcp_client_ingress_rule');If this is blocked, Snowflake’s error is
error: invalid_clientfrom the token endpoint, identical to what you’d see for wrong credentials. That overlap can lead to a misdiagnosis as a Client ID/Secret problem instead of a network policy one.
Configure the remote server in Arcade
Register the server
Go to the MCP servers dashboard , click Add Server, choose Remote , and enter a server ID and the server URL:
https://<account_url>/api/v2/databases/<database>/schemas/<schema>/mcp-servers/<name>Use the fully qualified database, schema, and server name. An incomplete path is a common cause of “authentication succeeds, but the server doesn’t connect.”
Configure OAuth2 authorization
Open Advanced settings → OAuth2 authorization and enter:
- Client ID / Client Secret: from
SYSTEM$SHOW_OAUTH_CLIENT_SECRETSabove. - Authorization URL / Token URL: leave these empty. Snowflake advertises its OAuth metadata via Protected Resource Metadata (RFC 9728) when a client connects, and Arcade should discover the correct endpoints automatically. Only set these manually if discovery fails.
Add the redirect URI to your security integration
Copy the redirect URI Arcade generates and set it as OAUTH_REDIRECT_URI on the security integration:
ALTER SECURITY INTEGRATION arcade_mcp_integration
SET OAUTH_REDIRECT_URI = '<arcade_redirect_uri>';If Arcade ever needs more than one redirect URI, add the others with
OAUTH_ALTERNATE_REDIRECT_URIS rather than replacing the primary one.
Authorize and confirm
Save the server to open the authorization prompt. Sign in as a Snowflake whose DEFAULT_ROLE is the access role you configured, with a DEFAULT_WAREHOUSE set. Both are required for the session to initialize with the access you expect.
Troubleshooting
This list mirrors Snowflake’s own troubleshooting guidance, applied to an Arcade connection:
- OAuth consent or connection fails: the redirect URI doesn’t match. Set
OAUTH_REDIRECT_URIto the exact value Arcade generated. error: invalid_clientfrom the token endpoint, even though the Client ID and Secret look correct: a network policy is blocking Arcade’s outbound IP addresses. See Set up Snowflake. This error is identical to a credentials error, so don’t assume the Client ID/Secret is wrong before checking the network policy.- Authentication succeeds, but the server doesn’t connect: the server URL is missing part of the fully qualified database/schema/server path.
- A hostname-related connection failure: the hostname (or a schema name in the URL) contains an underscore. Replace it with a hyphen.
- The session fails to initialize: the authorizing has no
DEFAULT_WAREHOUSEset. - The session uses the wrong role, or aren’t visible at all: the ’s
DEFAULT_ROLEisn’t the access role, or that role doesn’t haveUSAGEon the object. - A is visible but can’t be invoked: the access role is missing the underlying grant for that specific tool’s object. Access to the doesn’t imply access to what it exposes.
- The consent screen shows “secondary roles = ALL” even though the integration sets
OAUTH_USE_SECONDARY_ROLES = NONE: this label is cosmetic. Snowflake enforces the security integration’s actual setting regardless of what the client’s consent screen displays.
Next steps
- Create an MCP Gateway to expose this server’s .
- Connect to MCP clients.