Snowflake turned nine agent capabilities into one tool declaration. The Snowflake Cortex Agents Coding Agent, generally available on August 26, 2026, can get a managed shell, filesystem, web search, SQL access, and skills from code_toolset_all. That is wonderfully little plumbing for something allowed to run Bash. It is not wonderfully little responsibility.
Start with a stateless request that can inspect but not change anything. Then add the identity context, workspace, skills, and approval policy one boundary at a time. By the end, the endpoint will be ready for a real workflow without quietly becoming a very fast permissions incident.
What the Snowflake Cortex Agents Coding Agent actually is
Snowflake’s August 26 GA release packages the runtime behind Cortex Code, also called CoCo, as a hosted Cortex Agent tool. Your application sends a request; Snowflake provisions the sandbox, executes the tool loop, and streams the result. You do not build the planner, shell wrapper, or file-edit dispatcher.
The official Coding Agent guide lists Bash, read, write, edit, grep, glob, web search, Snowflake SQL execution, and skills. The SQL tool accepts SELECT and SHOW queries and can write to stages; it is not a general invitation to improvise DDL.
| Snowflake surface | Use it when | Where it runs |
|---|---|---|
code_toolset_all | The agent needs files, shell, SQL, web search, and skills | Managed Cortex Agent sandbox |
code_execution | An analytics or search agent occasionally needs Python | Lightweight managed sandbox |
| Cortex Code CLI | A developer wants an interactive local client | Your terminal |
The first two tool types are mutually exclusive in one request. Bigger is not automatically better: choosing the full toolset for a charting task is the agent equivalent of issuing a master key because one door was inconvenient.
Prerequisites: role, warehouse, and token
The awkward prerequisite is not JSON. It is Snowflake context. Cortex Agents evaluates the querying user’s default role and default warehouse, according to Snowflake’s access-control requirements. A privileged role selected in another session will not rescue a caller whose default role lacks the grants.
- Grant the default role either
SNOWFLAKE.CORTEX_AGENT_USERor the broaderSNOWFLAKE.CORTEX_USERdatabase role. - Grant object-specific access:
USAGEon the default warehouse and relevant databases, schemas, agents, and stages where applicable;READorWRITEon each workspace; plus the privileges required by tool-specific objects. - Use a programmatic access token for this walkthrough. Snowflake also supports key-pair JWT and OAuth authentication.
- Keep the token in an environment variable or secret manager, never in the request file or repository.
Start with the narrowest role that can complete the job. Our six-layer agent security checklist goes deeper on command policy, credentials, network access, and isolation. Here, the critical rule is simpler: the sandbox inherits useful authority from the caller, so “the sandbox is managed” does not mean “the blast radius is imaginary.”
Run your first Snowflake Cortex Agents Coding Agent
The fastest test uses the stateless /api/v2/cortex/agent:run endpoint. You send the complete configuration with every request, which is clumsy for an application but excellent for proving that authentication, orchestration, and the toolset work before creating a persistent agent object.
Send the minimal request
Save this as agent-request.json and choose an orchestration model available in your Snowflake region. The August 2026 schema pairs models with instructions; mixing those fields with the legacy model and response_instruction pair returns an error.
{
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "List the files you can access, then explain which one you would inspect first. Do not modify anything."
}
]
}
],
"models": {
"orchestration": "claude-sonnet-4-5"
},
"instructions": {
"system": "You are a cautious data engineering assistant. Explain proposed changes before making them."
},
"tools": [
{
"tool_spec": {
"type": "code_toolset_all",
"name": "code_toolset_all"
}
}
],
"tool_resources": {
"code_toolset_all": {
"permission_policy": {
"type": "always_ask"
}
}
}
}
Then send it with curl. -N disables output buffering so Server-Sent Events appear as Snowflake emits them.
export SNOWFLAKE_ACCOUNT_BASE_URL="https://ORG-ACCOUNT.snowflakecomputing.com"
export SNOWFLAKE_PAT="YOUR_PROGRAMMATIC_ACCESS_TOKEN"
curl -N -X POST \
"$SNOWFLAKE_ACCOUNT_BASE_URL/api/v2/cortex/agent:run" \
--header "Authorization: Bearer $SNOWFLAKE_PAT" \
--header "X-Snowflake-Authorization-Token-Type: PROGRAMMATIC_ACCESS_TOKEN" \
--header "Content-Type: application/json" \
--header "Accept: text/event-stream" \
--data @agent-request.json
Read the event stream
The Run API reference defines typed events for text deltas, tool activity, and the final response. The last response event contains the complete output, so a production client should parse events rather than scrape terminal lines. If streaming is unnecessary, request application/json and set stream to false.
The first prompt asks for inspection only. That is deliberate. Confirm what the agent can see before asking what it can change; otherwise your first integration test may double as an unusually expensive inventory exercise.

Add a workspace, skills, and instructions
An empty sandbox proves the endpoint, not the workflow. Add a Snowflake workspace under tool_resources.code_toolset_all.workspace_mounts. The object must have a live version, mounts read-write by default, and needs a unique top-level path such as /workspace. Nested paths such as /workspace/project are unsupported, and an ordinary internal stage is not a workspace substitute.
"skills": [
{
"name": "data-quality-review",
"source": {
"type": "STAGE",
"path": "@OPS.AGENTS.SKILL_STAGE/skills/data-quality-review"
}
}
],
"tool_resources": {
"code_toolset_all": {
"permission_policy": { "type": "always_ask" },
"workspace_mounts": [
{
"name": "USER$.PUBLIC.DEFAULT$",
"type": "workspace",
"mount_path": "/workspace"
}
],
"disabled_skills": ["streamlit"]
}
}
Stage skills belong in the top-level skills array and require USAGE on the stage. Skills stored under .snowflake/cortex/skills/ in a mounted workspace attach automatically. If you are standardizing capabilities across coding tools, our portable agent capability guide explains why the manifest is the easy part and scoped behavior is the durable asset.
Leave always_ask in place while testing. always_allow lets state-changing tools run without approval, which can be correct for a trusted automated job after its role, files, prompts, and failure handling are constrained. It is not a speed setting. It is an authority setting wearing a speed-setting costume.
Test the boundaries before automation
A 200 response proves that an endpoint answered. It does not prove that the intended tools, role, and policy produced the answer. Run five tests before creating a persistent agent:
- Read a known workspace file and verify the mount path.
- Ask for a one-line edit and confirm an approval is required.
- Run harmless
SELECTandSHOWstatements against allowed objects. - Attempt an operation outside the role or workspace and confirm it fails cleanly.
- Remove access to one dependency and inspect the inaccessible-tool warning.
Diagnose failures from the boundary inward. Authentication errors come before model behavior; object privileges come before prompting; mount configuration comes before file reasoning. Asking the model to “try harder” cannot grant USAGE, although it can produce an impressively sincere explanation of why the file remains absent.
| Symptom | Likely boundary | First check |
|---|---|---|
| 401 or token error | Authentication | PAT value, token type, and network policy |
| Tool or object unavailable | Authorization | Default role, warehouse, and object grants |
| Files missing | Workspace mount | Live version, object name, and top-level mount path |
| Edit waits or stops | Approval policy | Expected always_ask interaction |
Snowflake’s default inaccessible-tool mode can continue with the tools that remain available. That may be graceful degradation, or it may be an application quietly doing the wrong job. The same trap appears in model routing: our production fallback guide shows why technical availability is not semantic compatibility.
Synchronous agent runs time out after 15 minutes. Thread-backed background runs can continue for up to six hours and return a run_id for later streaming or polling. Graduate to that path only after the short request behaves predictably; six hours is a generous amount of time for an unclear permission boundary to become a detailed incident report.
Once those checks pass, create a persistent agent object and switch to /api/v2/databases/{database}/schemas/{schema}/agents/{name}:run. Add a thread only when the application needs state across turns. Keep the agent specification in version control beside its client; a reusable agent with an invisible configuration change is merely a stateless bug with a better memory.
The managed loop is the easy part
The unresolved question is not whether Snowflake can host a competent tool loop. It is whether your team can make the agent’s effective authority as reviewable as the JSON that declares it.
A managed runtime does not eliminate infrastructure; it turns permissions into the infrastructure that matters. Review the first 30 days of traces, approval prompts, denied actions, and inaccessible-tool warnings before changing always_ask or widening a workspace mount. The useful production milestone is not the first successful run. It is the first boring audit.
Get the Daily Pulse
Sharp analysis on what's actually moving in AI. No hype, no filler, no weekly digest.



