Skip to Content

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:

    SQL
    CREATE 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 PUBLIC or 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.

    SQL
    CREATE 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_URI as 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 = NONE plus a tightly scoped ALLOWED_ROLES_LIST is 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:

    SQL
    SELECT 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_ROLE as 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’s DEFAULT_ROLE isn’t the MCP access role, or they have no DEFAULT_WAREHOUSE set, the session either uses the wrong privileges or fails to initialize:

    SQL
    ALTER 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:

    SQL
    CREATE 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_client from 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:

PLAINTEXT
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_SECRETS above.
  • 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:

SQL
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_URI to the exact value Arcade generated.
  • error: invalid_client from 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_WAREHOUSE set.
  • The session uses the wrong role, or aren’t visible at all: the ’s DEFAULT_ROLE isn’t the access role, or that role doesn’t have USAGE on 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

Last updated on