Skip to content

feat(mcp): add batch stream config overrides and update_cloud_connection_unsafe - #1397

Open
Aaron ("AJ") Steers (aaronsteers) wants to merge 17 commits into
release-candidate/v1from
devin/1792179543-rc-stream-sync-mode
Open

Aaron ("AJ") Steers (aaronsteers) wants to merge 17 commits into
release-candidate/v1from
devin/1792179543-rc-stream-sync-mode

Conversation

@aaronsteers

@aaronsteers Aaron ("AJ") Steers (aaronsteers) commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Overview

👉 TL;DR: Agents can change how several streams on a Cloud connection sync, all in one call. The default tool refuses changes that would invalidate a stream's saved progress, and a separate unsafe tool allows them.

Specifically, this adds override_stream_configs: list[StreamConfigOverride] to update_cloud_connection (now destructive=False), the new update_cloud_connection_unsafe (destructive=True), and CloudConnection.update_stream_configs.

Merges before (pairs with) #1392:

Replaces (with #1392):

Changes

  • StreamConfigOverride: stream_name, stream_namespace (None = any, "" = unnamespaced), sync_mode, destination_sync_mode, cursor_field (top-level str). At least one setting is required.
  • CloudConnection.update_stream_configs(overrides, *, allow_unsafe=False): the only public entry point. In one call it reads the catalog and state, evaluates every override on a typed ConfiguredAirbyteCatalog (private _evaluate_stream_config_updates; API-only fields like selected/mappers round-trip unchanged), and writes the catalog once. Helpers live in private airbyte/cloud/_stream_config_overrides.py. No method takes a precomputed plan. Returns StreamConfigUpdateResult; reset_streams is only filled when a reset was requested.
  • Validation errors (AirbyteLibInputError): missing stream (the available streams are listed once per call), ambiguous name, unsupported sync mode, incremental with no cursor, and *_dedup with no primary key. Any invalid override rejects the whole batch.
  • Safety check: _find_unsafe_stream_changes flags changes to syncMode, destinationSyncMode, cursorField, or primaryKey on streams with saved state, and the safe path raises AirbyteUnsafeStreamConfigChangeError (naming each stream and changed field) without writing anything.
  • MCP update_cloud_connection: gains override_stream_configs, drops to destructive=False, always sends skipReset=true, and writes stream overrides before enabled/schedule.
  • New MCP update_cloud_connection_unsafe: same inputs; sends skipReset=false when unsafe streams exist and lists every stream the platform will refresh or reset. The MCP layer only adds error guidance; arg validation and schedule setting live in private airbyte/cloud/_connection_settings.py.
  • api_util.replace_connection_catalog and import_raw_catalog take skip_reset (default True).
  • import_raw_catalog clears the cached _connection_info (shared with feat(mcp): add async source catalog discovery and comparison (discover_cloud_source_catalog) #1392).

Review Spotlight

Reviewers with limited time, please review first:

Risks

Test plan

  • AIRBYTE_MCP_TRUSTED_EXECUTION=1 uv run pytest tests/unit_tests/test_cloud_connection_catalog_edits.py tests/unit_tests/test_mcp_connection_schedules.py tests/unit_tests/test_mcp_tool_errors.py tests/unit_tests/test_mcp_arg_trace_parity.py
  • ruff check, ruff format --check

Link to Devin session: https://app.devin.ai/sessions/4d1ece6885c44c52a07034e025db11e6
Open in Devin Desktop: https://app.devin.ai/desktop/session/4d1ece6885c44c52a07034e025db11e6?variant=devin
Requested by: Aaron ("AJ") Steers (@aaronsteers)

devin-ai-integration Bot and others added 8 commits October 16, 2026 02:35
…loud connections

Co-Authored-By: AJ Steers <aj@airbyte.io>
Co-Authored-By: AJ Steers <aj@airbyte.io>
Co-Authored-By: AJ Steers <aj@airbyte.io>
…_catalog_refresh

Co-Authored-By: AJ Steers <aj@airbyte.io>
…nto devin/1792179543-rc-stream-sync-mode

Co-Authored-By: AJ Steers <aj@airbyte.io>

# Conflicts:
#	airbyte/mcp/cloud.py
…/1792117913-rc-stream-sync-mode-refresh-catalog
@devin-ai-integration

Copy link
Copy Markdown
Contributor

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@github-actions

Copy link
Copy Markdown

👋 Greetings, Airbyte Team Member!

Here are some helpful tips and reminders for your convenience.

💡 Show Tips and Tricks

Testing This PyAirbyte Version

You can test this version of PyAirbyte using the following:

# Run PyAirbyte CLI from this branch:
uvx --from 'git+https://github.com/airbytehq/PyAirbyte.git@devin/1792179543-rc-stream-sync-mode' pyairbyte --help

# Install PyAirbyte from this branch for development:
pip install 'git+https://github.com/airbytehq/PyAirbyte.git@devin/1792179543-rc-stream-sync-mode'

PR Slash Commands

Airbyte Maintainers can execute the following slash commands on your PR:

  • /fix-pr - Fixes most formatting and linting issues
  • /uv-lock - Updates uv.lock file
  • /test-pr - Runs tests with the updated PyAirbyte
  • /prerelease - Builds and publishes a prerelease version to PyPI
📚 Show Repo Guidance

Helpful Resources

Community Support

Questions? Join the #pyairbyte channel in our Slack workspace.

📝 Edit this welcome message.

@github-code-quality

github-code-quality Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Code coverage overview

Languages: Python

Python / code-coverage/pytest-no-creds

release-candidate/v1 d9f652f devin/1792179543-rc-... 585268d +/-
65% 80% +15%
View coverage of the 10 most impacted files.
File release-candidate/v1 d9f652f devin/1792179543-rc-... 585268d +/-
airbyte/_util/api_util.py 36% 67% +31%
airbyte/mcp/cloud.py 52% 85% +33%
airbyte/cloud/connectors.py 34% 79% +45%
airbyte/mcp/_datadog.py 0% 50% +50%
airbyte/mcp/_telemetry.py 0% 94% +94%
airbyte/cloud/c...lder/project.py 0% 94% +94%
airbyte/_direct...ctors/models.py 0% 95% +95%
airbyte/mcp/_sso_auth.py 0% 96% +96%
airbyte/cloud/models.py 0% 97% +97%
airbyte/mcp/int...nc_status_ui.py 0% 97% +97%

Python / code-coverage/pytest

release-candidate/v1 d9f652f devin/1792179543-rc-... 585268d +/-
71% 82% +11%
View coverage of the 10 most impacted files.
File release-candidate/v1 d9f652f devin/1792179543-rc-... 585268d +/-
airbyte/cloud/connectors.py 51% 82% +31%
airbyte/mcp/cloud.py 52% 85% +33%
airbyte/mcp/_datadog.py 0% 50% +50%
airbyte/mcp/_user_identity.py 0% 93% +93%
airbyte/mcp/_telemetry.py 0% 94% +94%
airbyte/cloud/c...lder/project.py 0% 94% +94%
airbyte/_direct...ctors/models.py 0% 95% +95%
airbyte/mcp/_sso_auth.py 0% 96% +96%
airbyte/cloud/models.py 0% 97% +97%
airbyte/mcp/int...nc_status_ui.py 0% 97% +97%

Python / code-coverage/pytest-unit

release-candidate/v1 devin/1792179543-rc-... 585268d +/-
— 77% —

Line coverage data for the release-candidate/v1 branch is not yet available.

View coverage of the 10 most covered files.
File release-candidate/v1 devin/1792179543-rc-... 585268d +/-
airbyte/cloud/models.py — 97% —
airbyte/mcp/_sso_auth.py — 96% —
airbyte/_direct...ctors/models.py — 95% —
airbyte/cloud/client.py — 90% —
airbyte/exceptions.py — 90% —
airbyte/mcp/cloud.py — 85% —
airbyte/progress.py — 80% —
airbyte/cloud/connectors.py — 79% —
airbyte/shared/...ql_processor.py — 68% —
airbyte/_util/api_util.py — 67% —

ℹ️ Calculations represent line coverage. Results may change as calculations are updated.


Updated October 20, 2026 06:18 UTC

@aaronsteers
Aaron ("AJ") Steers (aaronsteers) added this pull request to stack #1398 October 16, 2026 20:01
Comment thread airbyte/cloud/connections.py Outdated
Co-Authored-By: AJ Steers <aj@airbyte.io>
@devin-ai-integration
devin-ai-integration Bot removed this pull request from stack #1398 October 16, 2026 20:38
@devin-ai-integration
devin-ai-integration Bot changed the base branch from devin/1792117913-rc-stream-sync-mode-refresh-catalog to release-candidate/v1 October 16, 2026 21:21
@devin-ai-integration devin-ai-integration Bot changed the title feat(mcp): add stream sync mode overrides to Cloud connections feat(mcp): add batch stream config overrides and update_cloud_connection_unsafe Oct 16, 2026
Comment thread airbyte/cloud/connections.py Outdated
Comment thread airbyte/cloud/models.py Outdated
Comment thread airbyte/mcp/cloud.py Outdated
@aaronsteers
Aaron ("AJ") Steers (aaronsteers) marked this pull request as ready for review October 16, 2026 22:09
Copilot AI balanced review requested due to automatic review settings October 16, 2026 22:09

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 4 potential issues.

1 flag not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)

Devin Review

Comment thread airbyte/mcp/cloud.py Outdated
Comment thread airbyte/mcp/cloud.py Outdated
Comment thread airbyte/cloud/connections.py Outdated
Comment thread airbyte/cloud/connections.py Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Safety decisions can become stale before catalog application, allowing unsafe writes through the safe tool.

3 open issues
What changed in this PR

Adds batch stream configuration updates to Cloud connections, with separate safe and unsafe MCP tools.

Changes:

  • Adds override models, batch validation, and saved-state safety checks.
  • Introduces unsafe updates with reset controls and reporting.
  • Adds tests, tracing metadata, and catalog-cache invalidation.
File Description
tests/​unit_tests/​test_mcp_tool_errors.py Tests unsafe-change error handling.
tests/​unit_tests/​test_mcp_connection_schedules.py Tests tool annotations, resets, and guidance.
tests/​unit_tests/​test_cloud_connection_catalog_edits.py Tests batch validation and catalog updates.
tests/​unit_tests/​fixtures/​arg_trace_plan.json Adds override and unsafe-tool tracing expectations.
airbyte/​mcp/​cloud.py Exposes safe and unsafe batch updates.
airbyte/​mcp/​_error_handling.py Registers unsafe-change errors.
airbyte/​exceptions.py Defines the unsafe-change exception.
airbyte/​cloud/​models.py Defines override and result models.
airbyte/​cloud/​connections.py Implements planning, safety checks, and application.
airbyte/​cloud/​__init__.py Exports stream configuration models.
airbyte/​_util/​api_util.py Adds catalog reset control.

Review effort: Balanced

Comment thread airbyte/cloud/connections.py Outdated
Comment thread airbyte/cloud/connections.py Outdated
Comment thread airbyte/cloud/connections.py Outdated
…ection update tool

Co-Authored-By: AJ Steers <aj@airbyte.io>
Comment thread airbyte/cloud/connections.py Outdated
Co-Authored-By: AJ Steers <aj@airbyte.io>
Comment thread airbyte/mcp/cloud.py Outdated
Comment thread airbyte/mcp/cloud.py Outdated
devin-ai-integration Bot and others added 2 commits October 16, 2026 22:32
…/1792179543-rc-stream-sync-mode

Co-Authored-By: AJ Steers <aj@airbyte.io>

# Conflicts:
#	airbyte/cloud/connections.py
Comment thread airbyte/cloud/connections.py Outdated
Comment thread airbyte/mcp/cloud.py Outdated
default=None,
),
TraceArg.FINGERPRINT,
] = None,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defaults should be defined in Field(), not as python param defaults.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 0552371. I removed the Python-level = None from all four params this PR added: override_stream_configs and workspace_id on both update_cloud_connection and update_cloud_connection_unsafe. The default now lives only in Field(default=None). One direct-call test needed override_stream_configs=None passed explicitly.

Written by Devin

Comment thread airbyte/mcp/cloud.py Outdated
),
TraceArg.OMIT,
],
] = None,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 0552371. workspace_id on both tools is back to the Field(default=None) default only.

Written by Devin

devin-ai-integration Bot and others added 2 commits October 20, 2026 01:39
Co-Authored-By: AJ Steers <aj@airbyte.io>
Co-Authored-By: AJ Steers <aj@airbyte.io>

# Conflicts:
#	airbyte/mcp/cloud.py

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants