> ## Documentation Index
> Fetch the complete documentation index at: https://explore.airia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Snowflake

Snowflake's own managed MCP server gives your agents governed access to data and AI capabilities that already live in your Snowflake account, without you having to stand up or maintain any separate infrastructure. It's built and maintained by Snowflake, so it stays current as new Cortex AI capabilities ship.

Snowflake is a **catalogue server** marked **Available**, so it shows up automatically for organizations in Default Mode. In Custom Mode, an admin needs to approve it on the [Server Management](/mcps/admin-controls/server-management) page before it can be added to a Gateway or Deployment.

<Warning>
  Of all the MCP servers Airia supports, Snowflake's is consistently the hardest to get running, not because of anything on Airia's end, but because creating the MCP server object in Snowflake itself has a lot of moving parts. The steps below are not the only way to create one, and following them will not produce a server tailored to your organization's data. They exist to walk through a configuration that is known to work end to end. If you're stuck setting up your own server, try these steps exactly to confirm you can connect to the demo server first. If even that fails, it's almost always one of two things: your account type or role doesn't have the entitlements described in [Prerequisites](#prerequisites), or your account has a network policy whose allowlist doesn't include Airia's egress IPs (see [Troubleshooting](#troubleshooting)). Your Snowflake account team can help confirm and resolve either one.
</Warning>

## What It Provides

An admin configures which of the following tool types are exposed when they create the MCP server object in Snowflake (up to 50 tools per server):

| Tool Type          | What It Does                                                                    |
| ------------------ | ------------------------------------------------------------------------------- |
| **Cortex Search**  | Runs unstructured search queries against a Cortex Search Service.               |
| **Cortex Analyst** | Turns natural language questions into SQL using a Cortex Analyst semantic view. |
| **SQL Execution**  | Runs SQL directly against Snowflake. Read-only by default.                      |
| **Cortex Agent**   | Invokes a Cortex Agent and returns its full run, including intermediate steps.  |
| **Custom Tools**   | Wraps an existing user-defined function or stored procedure as a callable tool. |

## Prerequisites

* A **paid Snowflake account**. Free and trial accounts don't have the entitlements needed to create or connect to MCP server objects.
* A Snowflake user with enough privileges to create a warehouse, database, schema, role, and the MCP server object itself (typically `ACCOUNTADMIN`, or a role explicitly granted those privileges).

## Setting Up the MCP Server in Snowflake

If your organization already has an MCP server object configured in Snowflake, skip to [Connecting to Airia](#connecting-to-airia). Otherwise, a Snowflake admin needs to create one first.

<Steps>
  <Step title="Create a warehouse, database, and schema">
    ```sql theme={null}
    CREATE WAREHOUSE IF NOT EXISTS MCP_WH
      WAREHOUSE_SIZE = XSMALL AUTO_SUSPEND = 60
      AUTO_RESUME = TRUE INITIALLY_SUSPENDED = TRUE;
    CREATE DATABASE IF NOT EXISTS MCP_DB;
    USE DATABASE MCP_DB;
    CREATE SCHEMA IF NOT EXISTS PUBLIC;
    ```
  </Step>

  <Step title="Create a role and grant it access">
    ```sql theme={null}
    CREATE ROLE IF NOT EXISTS MCP_ROLE;
    GRANT USAGE ON WAREHOUSE MCP_WH        TO ROLE MCP_ROLE;
    GRANT USAGE ON DATABASE  MCP_DB        TO ROLE MCP_ROLE;
    GRANT USAGE ON SCHEMA    MCP_DB.PUBLIC TO ROLE MCP_ROLE;
    ```

    Also grant this role whatever else your tools need to reach, for example `USAGE` on a Cortex Search Service or `SELECT` on the tables a SQL tool should query.
  </Step>

  <Step title="Assign the role to the connecting user">
    ```sql theme={null}
    GRANT ROLE MCP_ROLE TO USER <your_user>;
    ALTER USER <your_user>
      SET DEFAULT_ROLE = 'MCP_ROLE'
          DEFAULT_WAREHOUSE = 'MCP_WH';
    ```

    <Warning>
      `DEFAULT_ROLE` and `DEFAULT_WAREHOUSE` must both be set on the connecting user. Sessions fail to initialize without them, and this is required even if the user has other roles or warehouses available. Secondary roles aren't supported.
    </Warning>
  </Step>

  <Step title="Create the MCP server object">
    ```sql theme={null}
    USE WAREHOUSE MCP_WH; USE DATABASE MCP_DB; USE SCHEMA PUBLIC;

    CREATE OR REPLACE MCP SERVER MCP_DEMO_SERVER
      FROM SPECIFICATION $$
        tools:
          - title: "SQL Execution Tool"
            name: "sql_exec_tool"
            type: "SYSTEM_EXECUTE_SQL"
            description: "Run read-only SQL queries against Snowflake."
            config:
              read_only: true
              query_timeout: 120
      $$;

    GRANT USAGE ON MCP SERVER MCP_DB.PUBLIC.MCP_DEMO_SERVER TO ROLE MCP_ROLE;
    ```

    This example adds a single SQL tool. Add more entries under `tools` for any of the [tool types](#what-it-provides) above, then grant `USAGE` on the finished server to every role that should be able to use it.
  </Step>
</Steps>

## Connecting to Airia

Snowflake supports two authentication options: a Programmatic Access Token, or an admin-configured OAuth integration. Both give an agent the same access, so pick whichever fits how your organization wants to manage credentials. See [Tenant vs. Personal Level App Credentials](/mcps/admin-controls/tenant-vs-personal-app-credentials) if you're not sure which one you need.

### Option A: Programmatic access token

<Steps>
  <Step title="Generate a token">
    Run the following as, or on behalf of, the user that should connect:

    ```sql theme={null}
    ALTER USER <your_user>
      ADD PROGRAMMATIC ACCESS TOKEN MCP_PAT
      ROLE_RESTRICTION = 'MCP_ROLE'
      DAYS_TO_EXPIRY = 90;
    ```
  </Step>

  <Step title="Copy the token">
    Copy the token value from the result. Snowflake only shows it once.
  </Step>

  <Step title="Add it to Airia">
    Paste the token in as your API key credential when connecting Snowflake to a Gateway or Deployment.
  </Step>
</Steps>

### Option B: OAuth integration

An OAuth integration lets everyone in your organization sign in with their own Snowflake user, while an admin only has to set up the connection once. This requires `ACCOUNTADMIN` (or an equivalent role) to create a security integration.

<Steps>
  <Step title="Create a security integration">
    ```sql theme={null}
    CREATE OR REPLACE SECURITY INTEGRATION MCP_AIRIA_OAUTH
      TYPE = OAUTH OAUTH_CLIENT = CUSTOM ENABLED = TRUE
      OAUTH_CLIENT_TYPE = 'CONFIDENTIAL'
      OAUTH_REDIRECT_URI = 'https://auth.airia.ai/OAuth/callback'
      OAUTH_ISSUE_REFRESH_TOKENS = TRUE
      OAUTH_REFRESH_TOKEN_VALIDITY = 7776000
      PRE_AUTHORIZED_ROLES_LIST = ('MCP_ROLE');
    ```

    <Warning>
      Don't skip `PRE_AUTHORIZED_ROLES_LIST`. Leaving it out can cause the consent screen to fail, or a session to silently pick up the wrong role. Every role listed here also needs `USAGE` on the MCP server object.
    </Warning>
  </Step>

  <Step title="Retrieve the client credentials">
    ```sql theme={null}
    SELECT SYSTEM$SHOW_OAUTH_CLIENT_SECRETS('MCP_AIRIA_OAUTH');
    ```

    Copy the **Client ID** and **Client Secret** from the result.
  </Step>

  <Step title="Add them to Airia">
    Enter the Client ID and Client Secret when registering the Snowflake OAuth app in Airia. After that, each person just clicks **Connect** and signs in with their own Snowflake user.
  </Step>
</Steps>

## Connection Details

Whichever option you use, adding Snowflake to a Gateway or Deployment asks for four fields:

| Field               | What To Enter                                                                     |
| ------------------- | --------------------------------------------------------------------------------- |
| **Account URL**     | Your Snowflake account URL, in the form `myorg-myaccount.snowflakecomputing.com`. |
| **Database**        | The database where the MCP server object was created, for example `MCP_DB`.       |
| **Schema**          | The schema where the MCP server object was created, for example `PUBLIC`.         |
| **MCP Server Name** | The name of the MCP server object itself, for example `MCP_DEMO_SERVER`.          |

If you don't already know your account URL, run:

```sql theme={null}
SELECT REPLACE(LOWER(CURRENT_ORGANIZATION_NAME()), '_', '-') || '-' ||
       REPLACE(LOWER(CURRENT_ACCOUNT_NAME()), '_', '-') ||
       '.snowflakecomputing.com' AS account_url;
```

<Warning>
  The account URL must use hyphens, not underscores, even if your organization or account name contains one. The query above handles this conversion for you; entering underscores directly causes the connection to fail.
</Warning>

## Limitations

* `DEFAULT_ROLE` and `DEFAULT_WAREHOUSE` must be set on the connecting user, this applies to both authentication options but OAuth sessions fail outright without them.
* No support for MCP resources, prompts, roots, notifications, or sampling.
* Responses aren't streamed.
* A single server can expose at most 50 tools.
* SQL and custom tool responses are capped at 250 KB. Cortex Agent responses include every intermediate step and can be considerably larger.

## Troubleshooting

<AccordionGroup>
  <Accordion title="The connection is rejected no matter what you enter" icon="triangle-exclamation">
    Confirm the Snowflake account is on a paid plan. Free and trial accounts can't create or connect to MCP server objects, and this produces the same rejection as a misconfigured connection.
  </Accordion>

  <Accordion title="OAuth succeeds but the connection still fails" icon="shield-halved">
    If your Snowflake account has a network policy in place (check with `SHOW NETWORK POLICIES IN ACCOUNT`), Airia's egress IPs need to be added to the allowed list. Contact Airia support for the current IP range. This applies to both authentication options, but is easy to miss when OAuth sign-in itself appears to succeed.
  </Accordion>

  <Accordion title="OAuth fails with an invalid_client error" icon="key">
    This almost always means the Client ID or Client Secret saved in Airia no longer matches your security integration, for example after it was recreated or the secret was rotated. Re-run `SELECT SYSTEM$SHOW_OAUTH_CLIENT_SECRETS('<integration_name>')` in Snowflake and update the credentials in Airia.
  </Accordion>

  <Accordion title="The connection works, but tools fail or return no data" icon="table">
    Snowflake enforces access control at both the server and tool level, so a successful connection doesn't automatically grant access to everything a tool touches. Check that the connected role has been separately granted whatever each tool needs, such as `USAGE` on a Cortex Search Service or `SELECT` on the underlying tables.
  </Accordion>
</AccordionGroup>

## Learn More

* [Snowflake Managed MCP Server](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp)
* [OAuth Custom Client Security Integration](https://docs.snowflake.com/en/user-guide/oauth-custom)
* [Programmatic Access Tokens](https://docs.snowflake.com/en/user-guide/programmatic-access-tokens)
* [Network Policies](https://docs.snowflake.com/en/user-guide/network-policies)
