Skip to content
Status

Snowflake

Connect the Speakeasy AI Control Plane to a Snowflake-managed MCP server that exposes an existing Cortex Agent.

Use a Snowflake role/security administrator account to create and assign a non-privileged runtime role. You also need ACCOUNTADMIN, or an organization-approved delegated role with global CREATE INTEGRATION, for the OAuth integration only. Obtain the connecting usernames, default warehouse, approved MCP server object names, and an existing Cortex Agent’s database, schema, name, and complete agent-tool grants from the security, application, and agent owners. You need an existing, approved MCP database and schema, or a Snowflake object or security owner who can create them. Obtain a server-creator role with CREATE MCP SERVER on the target schema, USAGE on the target database and schema, and USAGE on the existing Cortex Agent and its database and schema. Sign in at app.snowflake.com.

Snowflake-managed MCP servers and Cortex Agents are unavailable in the People’s Republic of China. Snowflake-managed MCP servers are also unsupported in government regions.

Open a Snowflake SQL workspace

  1. Select Projects > Workspaces.
  2. Select + beside a folder, or select + Add New on first use.
  3. Select SQL File.
  4. In the workspace context controls, select the organization-approved role for the statement group you are running.
  5. Select an available warehouse.
  6. Before pasting any SQL from this guide, replace every complete angle-bracket placeholder, including the < and > characters, with the corresponding value supplied by the named owner.
  7. Paste each completed statement into the blank SQL file.
  8. Select the complete statement.
  9. Invoke Run selected with Ctrl+Enter on Windows/Linux or Command+Return on macOS.

When a code block contains multiple statements, select and run each completed statement separately.

Create and assign the MCP access role

  1. Obtain the approved non-privileged role name, connecting usernames, default warehouse, existing Cortex Agent database, schema, and name, and complete agent-tool grants from the security and agent owners.

  2. With USERADMIN or a delegated role holding account-level CREATE ROLE, run:

    CREATE ROLE IF NOT EXISTS <mcp_access_role>;
  3. With ACCOUNTADMIN or the role authorized to grant Snowflake database roles, run:

    GRANT DATABASE ROLE SNOWFLAKE.CORTEX_AGENT_USER
    TO ROLE <mcp_access_role>;
  4. With the role that owns <mcp_access_role> or holds MANAGE GRANTS, run this statement for each connecting user:

    GRANT ROLE <mcp_access_role> TO USER <username>;
  5. With the security or agent owner role, run:

    GRANT USAGE ON WAREHOUSE <warehouse_name>
    TO ROLE <mcp_access_role>;
    GRANT USAGE ON DATABASE <agent_database>
    TO ROLE <mcp_access_role>;
    GRANT USAGE ON SCHEMA <agent_database>.<agent_schema>
    TO ROLE <mcp_access_role>;
    GRANT USAGE ON AGENT <agent_database>.<agent_schema>.<agent_name>
    TO ROLE <mcp_access_role>;
  6. Have the agent owner grant <mcp_access_role> every additional privilege required by the objects configured in the existing Cortex Agent.

  7. With the role authorized to alter each user, run:

    ALTER USER <username>
    SET DEFAULT_ROLE = '<mcp_access_role>'
    DEFAULT_WAREHOUSE = '<warehouse_name>';

Create the Cortex Agent MCP server

  1. Obtain the approved MCP server database, schema, and name, and the MCP tool name, title, and description from the application owner.

  2. Confirm that the approved MCP database and schema already exist.

  3. If either object is absent, have the Snowflake object or security owner create it through your organization’s approved process.

  4. Retain the resulting MCP database and schema names.

  5. Obtain the approved <mcp_server_creator_role> name from the security owner.

  6. Confirm that <mcp_server_creator_role> is assigned to the Snowflake user who will create the MCP server.

  7. Have the security owner grant the server-creator role access to the MCP namespace and existing Cortex Agent:

    GRANT USAGE ON DATABASE <mcp_database>
    TO ROLE <mcp_server_creator_role>;
    GRANT USAGE ON SCHEMA <mcp_database>.<mcp_schema>
    TO ROLE <mcp_server_creator_role>;
    GRANT CREATE MCP SERVER ON SCHEMA <mcp_database>.<mcp_schema>
    TO ROLE <mcp_server_creator_role>;
    GRANT USAGE ON DATABASE <agent_database>
    TO ROLE <mcp_server_creator_role>;
    GRANT USAGE ON SCHEMA <agent_database>.<agent_schema>
    TO ROLE <mcp_server_creator_role>;
    GRANT USAGE ON AGENT <agent_database>.<agent_schema>.<agent_name>
    TO ROLE <mcp_server_creator_role>;
  8. Form and record the fully qualified Cortex Agent identifier as <cortex_agent_fqn> = <agent_database>.<agent_schema>.<agent_name>.

  9. Switch to <mcp_server_creator_role>.

  10. Run:

CREATE MCP SERVER <mcp_database>.<mcp_schema>.<mcp_server_name>
FROM SPECIFICATION $$
tools:
- title: "<approved_title>"
name: "<mcp_tool_name>"
type: "CORTEX_AGENT_RUN"
identifier: "<cortex_agent_fqn>"
description: "<approved_description>"
$$;
  1. Retain the exact MCP database, schema, and server name.
  2. Ask the account or network security owner whether the Snowflake account uses PrivateLink.
  3. Select your user name.
  4. Select Connect a tool to Snowflake.
  5. In the Account Details dialog, copy Account/Server URL.
  6. If the account uses PrivateLink, have the account or network security owner confirm that the copied Account/Server hostname is the public hostname, not the PrivateLink hostname.
  7. For <account_url>, use the confirmed public Account/Server hostname from the copied value without the leading https:// or a trailing /. USE_PRIVATELINK_FOR_AUTHORIZATION_ENDPOINT = TRUE affects browser authorization, not the public MCP Server URL.
  8. Form the account-specific MCP Server URL:
https://<account_url>/api/v2/databases/<mcp_database>/schemas/<mcp_schema>/mcp-servers/<mcp_server_name>
  1. Retain the URL for the Speakeasy AI Control Plane setup.

Grant access to the MCP server

With the security owner role, run:

GRANT USAGE ON DATABASE <mcp_database>
TO ROLE <mcp_access_role>;
GRANT USAGE ON SCHEMA <mcp_database>.<mcp_schema>
TO ROLE <mcp_access_role>;
GRANT USAGE ON MCP SERVER <mcp_database>.<mcp_schema>.<mcp_server_name>
TO ROLE <mcp_access_role>;

If authorization succeeds but initialization fails, confirm the user’s DEFAULT_ROLE, DEFAULT_WAREHOUSE, role assignment, and warehouse USAGE. If the MCP server is visible but the Agent tool cannot run, confirm SNOWFLAKE.CORTEX_AGENT_USER, Cortex Agent USAGE, parent namespace USAGE, and every privilege required by the agent’s configured tools.

Create the OAuth integration

Before you continue: Confirm that each connecting user’s DEFAULT_ROLE is the non-privileged <mcp_access_role>. Snowflake blocks ACCOUNTADMIN, SECURITYADMIN, GLOBALORGADMIN, and ORGADMIN from custom Snowflake OAuth by default, even when listed in ALLOWED_ROLES_LIST.

  1. Obtain the approved integration name.

  2. Ask the account or network security owner whether the Snowflake account uses PrivateLink.

  3. Switch to ACCOUNTADMIN, or an organization-approved delegated role with global CREATE INTEGRATION.

  4. For a PrivateLink account, add USE_PRIVATELINK_FOR_AUTHORIZATION_ENDPOINT = TRUE on a new line immediately before ALLOWED_ROLES_LIST.

  5. Run:

    CREATE SECURITY INTEGRATION <integration_name>
    TYPE = OAUTH
    OAUTH_CLIENT = CUSTOM
    ENABLED = TRUE
    OAUTH_CLIENT_TYPE = 'CONFIDENTIAL'
    OAUTH_REDIRECT_URI = 'https://app.getgram.ai/mcp/remote_login_callback'
    OAUTH_USE_SECONDARY_ROLES = NONE
    ALLOWED_ROLES_LIST = ('<mcp_access_role>');
  6. Keep this exact integration-owner role selected for Copy the OAuth credentials.

An unquoted integration name is stored in uppercase. Retain that case-sensitive uppercase name for the next step.

Copy the OAuth credentials

Do not capture the result because it exposes secrets.

  1. Still using the role that created and owns the integration, run:

    WITH oauth_secrets AS (
    SELECT PARSE_JSON(
    SYSTEM$SHOW_OAUTH_CLIENT_SECRETS('<INTEGRATION_NAME>')
    ) AS secret_values
    )
    SELECT
    secret_values:oauth_client_id::STRING AS "oauth_client_id",
    secret_values:oauth_client_secret::STRING AS "oauth_client_secret"
    FROM oauth_secrets;
  2. Use the uppercase, case-sensitive integration name in single quotes.

  3. Copy the result cell under oauth_client_id as Client ID.

  4. Copy the result cell under oauth_client_secret as Client Secret.

  5. Store both values in the approved password manager.

  6. Switch away from the integration-owner role.

The query omits oauth_client_secret_2. Do not use that secondary secret for initial setup.

Add the server in Speakeasy

  1. In the Speakeasy AI Control Plane sidebar, under MCP Gateway, select MCP.
  2. Click Add new to open the Add MCP server page.
  3. Choose Hosted remotely.
  4. On the New remote MCP server page, paste the account-specific URL retained in Create the Cortex Agent MCP server into MCP server URL.
  5. Click Verify connectivity, then Save.

This creates the hosted MCP server and opens its Overview page.

Connect your credentials

From the server’s Overview, open Settings.

Under Authentication, if unconfigured, select Use Discovered when available; otherwise select Configure Manually. If configured but no provider is attached, use Connected services > Add provider. If the intended provider is already attached, use its existing controls and skip the provider/client creation and attachment steps below; do not add a duplicate.

Select the identity provider

In Attach Remote Identity Provider, Identity Provider defaults to Select existing when project issuers are available. Select the matching provider and skip the new-provider fields below. Otherwise choose Add new (or use the new-provider form shown when none exist).

For a new provider only, confirm Issuer URL, the auto-derived Slug, and Endpoints. Discovery runs automatically for a seeded issuer; after typing or changing the URL, select Discover only if offered.

If no matching provider or complete discovered configuration is available, ask your administrator for the documented Issuer URL and authorization and token Endpoints before continuing. Do not infer them from the MCP server URL.

Select the session client

Under Session Client, choose Select existing only for a client whose saved credentials, scopes, and audience match the requirements below; otherwise choose Add new. When reusing a matching client, skip directly to Verify the callback and attach below. Do not create credentials or register the client again. Otherwise choose Add new (or use the new-client form shown when no clients exist) and complete these new-client-only steps:

  1. In the Attach Remote Identity Provider sheet, set Client Type to Manual.
  2. Paste the Client ID into Client ID.
  3. Paste the Client Secret into Client Secret (optional).

Verify the callback and attach

  1. Confirm that the callback URL registered with the provider is https://app.getgram.ai/mcp/remote_login_callback. For a new manual client, also compare it with the sheet’s displayed Redirect URI. The existing-client selection does not display that field; check the registered callback in the provider’s app settings instead.
  2. Click Attach Identity Provider.

For the provider-side callback setting, see Create the OAuth integration.

When a client first requests Snowflake access, Snowflake’s OAuth flow opens in a browser. Each user signs in with their own Snowflake credentials and consents to the non-privileged default role. The resulting session uses that user’s DEFAULT_ROLE.

This guide covers setup only. For anything beyond it — billing, tool behavior, limits — see Snowflake’s MCP documentation.