The first thing I tried to do in CoCo Desktop was ask it to pull the open tickets for a data pipeline I was debugging. It couldn’t. Not because it wasn’t smart enough — it’s genuinely good at reasoning over your Snowflake schemas — but because CoCo’s context ends where Snowflake’s context ends. It knew everything about my tables, my RBAC, my lineage. It knew nothing about my Jira board sitting one browser tab away.

That gap is exactly what MCP closes. Once I wired up a couple of MCP servers, CoCo went from “excellent inside Snowflake’s walls” to “reaches into the rest of my stack” — Jira, GitHub, internal APIs — without me writing a line of integration code. This is the practical guide to doing that: the setup flow, where the config actually lives, how credentials are handled, and the operational limits that will trip you up on day one if nobody warns you.

A quick naming note before we start, because it confused me too: CoCo is the new name for Cortex Code. Snowflake renamed it at Summit 2026. Same product, same architecture — you’ll still see “cortex” all over the file paths and environment variables, which is why this guide uses both names where the paths demand it.

TL;DR

→ MCP (Model Context Protocol) is an open standard that connects CoCo Desktop to external tools — GitHub, Jira, internal APIs, databases — without per-tool integration code. Add a server once and its tools appear to the agent automatically.

→ Setup is fast: Agent Settings → MCP tab → + New → pick a scope (Global or Workspace) → pick a transport (Command/stdio or Remote/HTTP) → fill in details → Save. The server starts immediately, no restart.

→ Two transport types: Command (stdio) runs a local process (e.g. uvx mcp-server-git); Remote (HTTP) connects to a URL (e.g. a hosted server with auth headers).

→ Config lives in JSON: global at ~/.snowflake/cortex/mcp.json (all workspaces), workspace at <workspace>/.snowflake/cortex/mcp.json (that project only). Top-level key is "mcpServers".

→ Credentials are handled for you: on first connection CoCo migrates secrets (env vars, headers, OAuth tokens) out of mcp.json and into your OS keychain, then strips them from the file. Never hardcode tokens.

→ The limits that bite: tool output is capped at 50 KB (design servers to return summaries, not raw dumps), default tool timeout is 60 seconds (override with COCO_MCP_TOOL_TIMEOUT_MS), and tool names must be alphanumeric/underscore/hyphen and under 64 characters or the server is rejected outright.

→ If you already run MCP servers for Claude Desktop, Cursor, or Windsurf, CoCo Desktop can often reuse them — MCP is a standard, not a Snowflake-specific connector.

What MCP actually does for CoCo

CoCo is a data-native coding agent. Its whole advantage is that it understands your Snowflake environment — live schemas, access controls, lineage — so it generates SQL and dbt code that actually works against your real objects within your permissions. That’s also its boundary. The moment you need context from outside Snowflake, CoCo is blind to it.

MCP is the bridge. It’s an open protocol (the same one Claude Desktop, Cursor, and Windsurf use) that lets an agent call tools exposed by external “servers.” A GitHub MCP server exposes tools like “search code” and “list pull requests.” A Jira server exposes “find issues” and “create ticket.” Once you register that server with CoCo, those tools become part of the agent’s toolbox automatically — no code changes, no custom connector. You ask CoCo “what are the open bugs on the ingestion pipeline?” and it calls the Jira tool, reads the result, and reasons over it alongside your Snowflake context.

The mental model that helped me: CoCo already has one deep well of context (Snowflake). MCP servers are additional wells you drill wherever you need them. Each server you add widens what the agent can see and do.

Setting up your first MCP server

Coco mcp setup flow x class=

The whole setup is a short form in Agent Settings. The server starts the moment you save — no restart dance.

You manage everything through the Agent Settings panel. Open Agent Settings, select MCP from the sidebar, and you’ll see the MCP Connectors panel listing any configured servers and their status.

To add one, click + New. You’ll fill in a short form:

Server Name — a unique identifier, e.g. github. This name matters more than it looks: it becomes part of the tool namespace. A server named github exposes tools like mcp__github__search. Pick descriptive names so tool calls read clearly — mcp__github__search tells you what it does; mcp__gh1__search doesn’t.

Scope — Global stores the server in ~/.snowflake/cortex/mcp.json and makes it available in every workspace. Workspace stores it in <workspace>/.snowflake/cortex/mcp.json, scoped to the current project so it travels with the repo. Use Global for tools you always want (your personal GitHub); use Workspace for project-specific servers that should live in version control with the code.

Server Type (transport) — pick Command (stdio) to run a local process, then enter the command (for example uvx mcp-server-git). Pick Remote (HTTP) to connect to a hosted server, then enter the Server URL (for example https://your-mcp-server-url) and optionally add auth Headers. For stdio servers you can add Environment Variables instead.

Click Save, and the server starts. Its tools are available to the agent immediately.

If you don’t have a specific server in mind, click + New and select Browse MCP Servers — CoCo Desktop ships with a gallery of ready-to-install integrations you can add straight from the UI.

Editing the config directly (JSON)

The form is convenient, but for anything repeatable — sharing setup with a team, checking config into git — you’ll want the JSON. In the Add New MCP Server form, switch to the JSON tab, or edit the files directly. The top-level key is "mcpServers", and each entry is keyed by server name:

{
  "mcpServers": {
    "git": {
      "command": "uvx",
      "args": ["mcp-server-git"]
    },
    "internal-api": {
      "type": "http",
      "url": "https://your-mcp-server-url",
      "headers": { "Authorization": "Bearer ${API_TOKEN}" }
    }
  }
}

CoCo expands environment variables in config fields before connecting, so you can reference ${API_TOKEN} and similar. Prefer the braced form ${VAR} over bare $VAR to avoid ambiguity. There’s also a special ${workspaceFolder} variable that resolves to the current workspace root — handy for paths like cwd or envFile.

How config files stack (the merge order)

Coco mcp merge order x class=

Config merges from multiple sources; later layers win on name collisions. Workspace beats global beats admin-enforced — unless the admin has locked things down.

This is the part that saves you a confusing debugging session later. CoCo Desktop merges MCP config from several sources, and when two sources define a server with the same name, the later source wins. The order, from lowest to highest priority:

First, administrator-enforced servers from managed settings. Then user (global) servers from ~/.snowflake/cortex/mcp.json. Then workspace servers from <workspace>/.snowflake/cortex/mcp.json. So if you have a server named github in both your global and your workspace config, the workspace definition takes precedence. This is usually what you want — a project can override your personal defaults — but it also means a workspace config you forgot about can silently shadow your global one.

On managed accounts there’s an extra wrinkle: admins can restrict MCP usage through managed settings and URL allowlists, and can even disable user MCP servers entirely so that only admin-enforced servers load. If a server you configured refuses to appear on a corporate account, check whether the admin has locked MCP down before you assume your config is broken.

How credentials are handled (better than you’d expect)

This surprised me pleasantly. When you add a server with environment variables, headers, or OAuth, CoCo doesn’t leave your secrets sitting in a plaintext JSON file. On first connection it migrates those sensitive values out of mcp.json and into your operating system’s keychain, then rewrites the JSON file with those fields removed. Credentials are stored under a keychain entry named mcp_oauth_<server-name> as a single blob containing tokens, OAuth registration, headers, and environment variables.

Practically, this means: put your token in as an env var reference or let the OAuth flow run, and after the first connect it won’t be in the file anymore. Don’t hardcode raw tokens in mcp.json expecting them to stay — and don’t panic when they disappear from the file, that’s the migration working. If you ever need to reset a credential, remove and re-add the server to trigger a fresh flow.

The operational limits nobody warns you about

These three cost me time before I understood them, and they’re the difference between “MCP is flaky” and “MCP works fine, I just configured it wrong.”

Tool output is capped at 50 KB. If you point an MCP server at something that returns large result sets — a query that dumps thousands of rows, an API that returns a giant JSON blob — CoCo truncates the output and appends a notice. The fix isn’t to raise a limit; it’s to design the server to return summaries or pointers, not raw dumps. Have the tool return “here are the top 20 rows and a row count” or “results written to this file,” and let CoCo read the detail in a follow-up step if it needs to.

The default tool timeout is 60 seconds. Wire up a server that hits a slow internal API and you can spend ten minutes assuming the connection is broken when the tool is just slow. Override the timeout globally with the COCO_MCP_TOOL_TIMEOUT_MS environment variable — raise it for genuinely long-running tools, or lower it to fail fast on servers that should be quick.

Tool names must be alphanumeric, underscores, or hyphens, and under 64 characters. An MCP server that exposes a tool with a non-conforming name gets rejected outright — not silently renamed, rejected. If a server won’t load and the config looks right, check the tool names it exposes.

The gotchas nobody warns you about

Cross-app discovery on shared machines. Because MCP is a shared standard, CoCo can discover servers you set up for other tools — and on a shared machine, that can mean picking up someone else’s servers or exposing yours. Be deliberate about scope on multi-user boxes.

Variables expand from the launch environment, not your editor’s shell. CoCo expands ${VAR} from the environment it was launched in, not from a shell embedded in an editor. If a variable resolves to empty, check that it’s actually set in the environment where CoCo (not your terminal-inside-the-app) started.

Descriptive server names aren’t cosmetic. Because the server name becomes the tool namespace prefix, a vague name makes every downstream permission rule and tool call harder to read. Name servers for what they connect to, once, up front.

Permissions are per-tool and worth configuring. MCP tools participate in CoCo’s standard permission system. You can allow, deny, or prompt per tool, matching individual tools by full name (mcp__github__read_file) or all tools from a server with a wildcard (mcp__github__*). At runtime CoCo also asks on first use and can remember the choice for the session. Denying destructive tools explicitly — mcp__github__delete_repo, say — is cheap insurance.

A sensible starting setup

If you’re setting this up for the first time on a Snowflake data project, here’s the configuration I’d start with. Add a Git server (Command/stdio, uvx mcp-server-git) at Workspace scope so it travels with the repo. Add your issue tracker (Jira or GitHub Issues) at Global scope since you’ll want it everywhere. Set a permission policy that allows read tools freely, asks on writes, and denies anything destructive. Bump COCO_MCP_TOOL_TIMEOUT_MS only if you actually add a slow server. And design any custom internal-API server to return summaries under 50 KB from the start, so you never hit the truncation wall.

That gives you a CoCo that reasons over your Snowflake data and your tickets and your code history, with guardrails on the actions that matter — which is the whole point of MCP here.

The one principle

CoCo’s native genius is Snowflake context; MCP is how you extend its reach past Snowflake’s walls without writing integration code. Add servers deliberately, name them clearly, let the keychain hold your secrets, and design tools to return summaries — then the agent can reason across your whole stack instead of just your warehouse.

Related reading: CoCo Desktop MCP support (official docs) · Model Context Protocol specification · Snowflake CoCo product page · Snowflake Interactive Tables: How and When to Use Them · Orchestrating dbt With Airflow on Snowflake