Summary
With if_not_exists=false, the cortex_mcp_api_integration materialization (#34) and the create_mcp_api_integration run-operation emit CREATE OR REPLACE API INTEGRATION ... API_PROVIDER = EXTERNAL_MCP. Snowflake doesn't support OR REPLACE for this integration type, so the only documented way to rotate or reconfigure an integration fails every time:
003535 (0A000): The OR REPLACE option is not supported for external_mcp API integrations.
The run-operation defaults to if_not_exists=false, so a plain dbt run-operation create_mcp_api_integration ... against an integration that already exists also hits this error.
Repro
- Build a
cortex_mcp_api_integration model once so the integration exists.
- Change a property (e.g.
allowed_prefixes / oauth_resource_url), set if_not_exists = false, and rebuild.
- The build fails with the error above.
Generated DDL (macros/operations/create_mcp_api_integration.sql, _mcp_api_integration_ddl):
create {% if if_not_exists %}api integration if not exists{% else %}or replace api integration{% endif %} {{ integration_name }}
Current workaround
Keep the default if_not_exists=true and add a temporary pre-hook:
pre_hook = "drop api integration if exists {{ this.identifier }}"
Suggested fix
When if_not_exists=false, emit DROP API INTEGRATION IF EXISTS <name> followed by a plain CREATE API INTEGRATION <name> (two statements) instead of CREATE OR REPLACE. Also:
- Update the docs/comments in the materialization and operation that describe
if_not_exists=false as "replace-in-place" / OR REPLACE semantics.
- Call out that dropping an integration invalidates every
EXTERNAL MCP SERVER that references it (those need to be recreated) and wipes users' stored OAuth tokens.
- Optionally, rename the flag to something like
recreate so the drop-and-create behavior is explicit.
Summary
With
if_not_exists=false, thecortex_mcp_api_integrationmaterialization (#34) and thecreate_mcp_api_integrationrun-operation emitCREATE OR REPLACE API INTEGRATION ... API_PROVIDER = EXTERNAL_MCP. Snowflake doesn't supportOR REPLACEfor this integration type, so the only documented way to rotate or reconfigure an integration fails every time:The run-operation defaults to
if_not_exists=false, so a plaindbt run-operation create_mcp_api_integration ...against an integration that already exists also hits this error.Repro
cortex_mcp_api_integrationmodel once so the integration exists.allowed_prefixes/oauth_resource_url), setif_not_exists = false, and rebuild.Generated DDL (
macros/operations/create_mcp_api_integration.sql,_mcp_api_integration_ddl):create {% if if_not_exists %}api integration if not exists{% else %}or replace api integration{% endif %} {{ integration_name }}Current workaround
Keep the default
if_not_exists=trueand add a temporary pre-hook:Suggested fix
When
if_not_exists=false, emitDROP API INTEGRATION IF EXISTS <name>followed by a plainCREATE API INTEGRATION <name>(two statements) instead ofCREATE OR REPLACE. Also:if_not_exists=falseas "replace-in-place" /OR REPLACEsemantics.EXTERNAL MCP SERVERthat references it (those need to be recreated) and wipes users' stored OAuth tokens.recreateso the drop-and-create behavior is explicit.