Connect Snowflake Cortex Agents
Snowflake Cortex Agents run an agent as a native Cortex agent object inside your own Snowflake account. The agent answers questions over the data its tools expose — structured data through Cortex Analyst (text-to-SQL over semantic views) and unstructured data through Cortex Search — and executes on a warehouse you choose. Willow maps a background agent onto that Cortex agent object so it shows up alongside your other agents, with the same identity, ownership, and deploy flow.
On this platform the agent lives in Snowflake, not on Willow's infrastructure. Willow addresses it over the Cortex REST API using an account identifier and a programmatic access token (PAT) you supply once at the org level.
The Snowflake connector is a data source: an MCP server your users query with OAuth. The Snowflake Cortex Agents platform is a background-agent runtime: your agent is a Cortex agent object. They are configured separately and can be used independently.
How it fits together
| Piece | Where it runs | Who owns it |
|---|---|---|
| Cortex agent object | Your Snowflake account | You (surfaced in Willow) |
| Semantic views / Cortex Search services | Your Snowflake account | You |
| Warehouse | Your Snowflake account | You |
| Programmatic access token | Stored encrypted in Willow | You issue it in Snowflake |
At run time, a caller sends a question to the agent's agent:run endpoint. Cortex plans the request with its orchestration model, calls the attached Cortex Analyst and Cortex Search tools, and runs the underlying queries on the agent's warehouse under the caller's default role.
Prerequisites
- A Snowflake account with Cortex Agents available in your region, and Cortex features enabled.
- At least one semantic view (for Cortex Analyst) and/or a Cortex Search service (for unstructured retrieval) that the agent should answer over.
- A warehouse the agent can use to run its queries.
- A Snowflake user whose default role grants access to the warehouse, the agent object's database and schema, and the objects behind each tool. Cortex resolves privileges from the caller's default role — not the role active in the session — so this matters even if your current role has every privilege.
- Privileges to create a programmatic access token for that user.
Step 1: Note your account identifier
Willow addresses the Cortex REST API at https://<account_identifier>.snowflakecomputing.com. The account identifier has the form orgname-account_name (for example acme-analytics). You can read it from a SQL worksheet:
SELECT CURRENT_ORGANIZATION_NAME() || '-' || CURRENT_ACCOUNT_NAME() AS account_identifier;
Step 2: Create a programmatic access token
Cortex REST calls authenticate with a Snowflake programmatic access token (PAT). Create one for the user the agent should act as, and restrict it to the role that has the agent's data access:
ALTER USER my_agent_user
ADD PROGRAMMATIC ACCESS TOKEN willow_cortex
ROLE_RESTRICTION = 'MY_AGENT_ROLE'
DAYS_TO_EXPIRY = 90;
Copy the returned token secret immediately — Snowflake shows it only once.
ROLE_RESTRICTION pins the token (and therefore the agent) to one role. Make sure that role can use the warehouse and reach the semantic views, Cortex Search services, and tables behind the agent's tools. This is the single most common cause of "the agent runs but returns no data."
Step 3: Connect the platform in Willow
- Go to Manage → Machine Users → Background Agents (see the list page), open Settings (gear icon), and find Snowflake Cortex Agents under Agent Types.
- Select Set credentials and enter:
- Select Connect.
Once connected, Snowflake Cortex Agents appears as a selectable platform when creating an agent.
Step 4: Map the agent to a Cortex agent object
When you create the agent, its platform configuration describes the Cortex agent object it maps to and the data its tools can reach:
| Field | Meaning |
|---|---|
| Database / Schema | Where the Cortex agent object lives. With the agent name these form its fully-qualified name, DATABASE.SCHEMA.AGENT_NAME, used in SQL and in the agent:run path. |
| Agent name | The object name used in SQL and in agent:run requests. |
| Display name | The name client applications show to users, from the agent's PROFILE. |
| Warehouse | The warehouse the agent's tools run queries on. |
| Orchestration model | The model Cortex uses to plan tool calls. auto lets Snowflake pick. |
| Semantic views | Semantic views reachable through the agent's Cortex Analyst (text-to-SQL) tools. |
| Cortex Search services | Cortex Search services reachable for unstructured data. |
Step 5: Deploy
Select Deploy in the detail-page header (Deploy changes once the agent has edits that have not reached Snowflake). Deploying reconciles the Cortex agent object and reads back its resolved configuration — account, fully-qualified name, warehouse, orchestration model, and attached tools — which then appear on the agent's card.
The card reports the result:
| State | Meaning |
|---|---|
| Synced | The Cortex agent object is in place. The card shows its fully-qualified name, account, warehouse, orchestration model, semantic views, Cortex Search services, and when it last synced, with a How to use this agent action and a link to open it in Snowsight. |
| Pending sync | Waiting for an administrator to deploy. Usage instructions appear once synced. |
An agent must be synced before it can be invoked. For the deploy action and the sync-state fields, see Deploy an Agent.
Using the agent
Send a question to the agent object with the Cortex agent:run endpoint, authenticating with the programmatic access token:
curl -X POST \
"https://<account_identifier>.snowflakecomputing.com/api/v2/databases/<database>/schemas/<schema>/agents/<agent_name>:run" \
-H "Authorization: Bearer $SNOWFLAKE_PAT" \
-H "X-Snowflake-Authorization-Token-Type: PROGRAMMATIC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"stream": false,
"messages": [{"role": "user",
"content": [{"type": "text",
"text": "What is the average order value by market segment?"}]}]
}'
Pass a thread_id and parent_message_id to continue a conversation, or drop stream to receive server-sent events instead. The exact fields on the card's How to use this agent dialog are prefilled with your agent's account, database, schema, and name.
Cortex resolves permissions from the caller's default role and runs queries on their default warehouse, not the role active in the session. Calls fail if either is missing, even when the current role has every required privilege. See the Cortex Agents run documentation.
Troubleshooting
The agent runs but returns no data
The token's role can't reach the data. Confirm the ROLE_RESTRICTION role from Step 2 can use the agent's warehouse and has SELECT/usage privileges on the semantic views, Cortex Search services, and tables behind its tools.
Calls fail with a role or warehouse error
Cortex uses the caller's default role and warehouse, not the session's. Set them on the user:
ALTER USER my_agent_user SET DEFAULT_ROLE = MY_AGENT_ROLE;
ALTER USER my_agent_user SET DEFAULT_WAREHOUSE = MY_WAREHOUSE;
Authentication is rejected
Confirm both PAT headers are sent — Authorization: Bearer <token> and X-Snowflake-Authorization-Token-Type: PROGRAMMATIC_ACCESS_TOKEN — and that the token has not passed its DAYS_TO_EXPIRY. Re-issue the token in Step 2 and update it under Set credentials if it has expired.
The host can't be resolved
The account identifier is wrong. It must be orgname-account_name (a hyphen, not a dot). Re-read it with the query in Step 1.