Skip to content

feat(mcp): add ALLOW_EXTERNAL_ACCESS and ALLOW_PIPELINE_CHANGES policies for Cloud MCP - #1179

Merged
Aaron ("AJ") Steers (aaronsteers) merged 4 commits into
release-candidate/v1from
devin/1789678460-safe-mode-blocks-agents
Oct 5, 2026
Merged

Aaron ("AJ") Steers (aaronsteers) merged 4 commits into
release-candidate/v1from
devin/1789678460-safe-mode-blocks-agents

Conversation

@aaronsteers

@aaronsteers Aaron ("AJ") Steers (aaronsteers) commented Sep 17, 2026 •

Copy link
Copy Markdown
Member

Overview

👉 TL;DR: Adds two independent on/off switches to the Cloud MCP server: one for whether an agent may reach through Airbyte into a customer's connected SaaS or warehouse, and one for whether it may change Airbyte pipelines. An explicitly declared safe mode also turns off external access as a stopgap, so locked-down deployments gain no new exposure; the unset default does not affect external access.

Specifically, this adds AIRBYTE_CLOUD_MCP_ALLOW_EXTERNAL_ACCESS (X-MCP-Allow-External-Access) and AIRBYTE_CLOUD_MCP_ALLOW_PIPELINE_CHANGES (X-MCP-Allow-Pipeline-Changes), driven by new @mcp_tool(pipeline_change=..., external_access=...) kwargs and enforced by tool filters plus PolicyGuardMiddleware. Rebuilt on release-candidate/v1.

Changes

  • New @mcp_tool kwargs pipeline_change: bool | None = None (default not read_only) and external_access: bool = False, stored in an in-process _TOOL_POLICIES registry keyed by tool name (fastmcp-extensions 0.33 rejects custom annotation keys, so they stay off the wire). Unregistered tools fall back to pipeline_change = not readOnlyHint.
  • airbyte_readonly_mode_filter now hides pipeline_change tools when pipeline changes are disabled; new airbyte_external_access_filter hides external_access tools when external access is disabled.
  • New PolicyGuardMiddleware rejects the same calls at runtime with AirbytePipelineChangesDisabledError / AirbyteExternalAccessDisabledError (user-facing, with guidance). AirbyteSafeModeError is now user-facing too.
  • external_access=True on execute_external_api_query, execute_external_sql_query, execute_external_search_query, get_cloud_search_status, get_agent_skill_docs (examples; tool names will change).
  • pipeline_change=False on run_cloud_sync and cancel_cloud_sync: running or cancelling a sync is not a pipeline edit.
  • Docs in airbyte/mcp/__init__.py; unit tests for filters, middleware (incl. an in-memory client call), and decorator defaults.

Review Spotlight

Reviewers with limited time, please review first:

Feature flags: ALLOW_EXTERNAL_ACCESS, ALLOW_PIPELINE_CHANGES (default unset)

values: 1|true|yes -> allow, 0|false|no -> deny, unset/other (e.g. auto) -> calculated default
env False wins; env True can be narrowed by header False; env unset -> header decides

pipeline_changes_allowed(): AIRBYTE_CLOUD_MCP_READONLY_MODE truthy -> False, else resolved value
external_access_allowed():  resolved value if set,
                            else False if pipeline changes are False or AIRBYTE_CLOUD_MCP_SAFE_MODE is explicitly truthy,
                            else None (allowed)

Risks

  • Behavior change: legacy AIRBYTE_CLOUD_MCP_READONLY_MODE=1 now leaves run_cloud_sync / cancel_cloud_sync available.
  • Deployments that set AIRBYTE_CLOUD_MCP_SAFE_MODE=1 explicitly (e.g. coral-agents) lose external-access tools unless they also set AIRBYTE_CLOUD_MCP_ALLOW_EXTERNAL_ACCESS=1.

Follow-ups

  • Module/tool renames deferred until tool consolidation.
  • External-writes and external read-only tiers not implemented.
  • Possible safe-mode DeprecationWarning (not in this PR).

Test plan

  • uv run ruff format . && uv run ruff check .
  • uv run pyrefly check airbyte/mcp
  • uv run pytest tests/unit_tests/test_mcp_policy_middleware.py tests/unit_tests/test_mcp_tool_filters.py tests/unit_tests/test_mcp_tool_utils.py tests/unit_tests/test_mcp_cloud.py tests/unit_tests/test_mcp_guidance.py tests/unit_tests/test_mcp_tool_errors.py tests/unit_tests/test_exceptions.py -q

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

@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • 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/1789678460-safe-mode-blocks-agents' pyairbyte --help

# Install PyAirbyte from this branch for development:
pip install 'git+https://github.com/airbytehq/PyAirbyte.git@devin/1789678460-safe-mode-blocks-agents'

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.

@devin-ai-integration devin-ai-integration Bot changed the title feat(mcp): block agents tools in cloud safe mode feat(mcp): block agents tools in Cloud safe mode Sep 17, 2026

This comment was marked as resolved.

@github-code-quality

github-code-quality Bot commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: Python

Python / code-coverage/pytest-no-creds

The overall line coverage in commit 0b9eb06 in the devin/1789678460-saf... branch is 78%. The line coverage in commit d9f652f in the release-candidate/v1 branch is 65%.

Show a line coverage summary of the most impacted files.
File release-candidate/v1 d9f652f devin/1789678460-saf... 0b9eb06 +/-
airbyte/_util/api_util.py 36% 62% +26%
airbyte/mcp/cloud.py 52% 80% +28%
airbyte/cloud/connectors.py 34% 75% +41%
airbyte/mcp/_otel.py 0% 91% +91%
airbyte/mcp/_user_identity.py 0% 93% +93%
airbyte/_direct...ctors/models.py 0% 94% +94%
airbyte/mcp/_telemetry.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

The overall line coverage in commit 0b9eb06 in the devin/1789678460-saf... branch is 81%. The line coverage in commit d9f652f in the release-candidate/v1 branch is 71%.

Show a line coverage summary of the most impacted files.
File release-candidate/v1 d9f652f devin/1789678460-saf... 0b9eb06 +/-
airbyte/mcp/cloud.py 52% 80% +28%
airbyte/cloud/connectors.py 51% 80% +29%
airbyte/mcp/_otel.py 0% 91% +91%
airbyte/mcp/int..._registry_ui.py 0% 92% +92%
airbyte/mcp/_user_identity.py 0% 93% +93%
airbyte/_direct...ctors/models.py 0% 94% +94%
airbyte/mcp/_telemetry.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

The overall line coverage in commit 0b9eb06 in the devin/1789678460-saf... branch is 75%. Line coverage data for the release-candidate/v1 branch is not yet available.

Show a line coverage summary of the most covered files.
File release-candidate/v1 devin/1789678460-saf... 0b9eb06 +/-
airbyte/cloud/models.py — 97% —
airbyte/mcp/_sso_auth.py — 96% —
airbyte/_direct...ctors/models.py — 94% —
airbyte/mcp/_otel.py — 91% —
airbyte/cloud/client.py — 90% —
airbyte/mcp/cloud.py — 80% —
airbyte/progress.py — 80% —
airbyte/cloud/connectors.py — 75% —
airbyte/shared/...ql_processor.py — 68% —
airbyte/_util/api_util.py — 62% —

Updated October 05, 2026 01:31 UTC

@devin-ai-integration devin-ai-integration Bot changed the title feat(mcp): block agents tools in Cloud safe mode feat(mcp): add ALLOW_EXTERNAL_ACCESS and ALLOW_PIPELINE_CHANGES policies for Cloud MCP Sep 17, 2026

This comment was marked as resolved.

Comment thread airbyte/mcp/__init__.py Outdated
@aaronsteers
Aaron ("AJ") Steers (aaronsteers) marked this pull request as ready for review September 18, 2026 07:22
@aaronsteers

Copy link
Copy Markdown
Member Author

Devin, resolve conflicts please

@devin-ai-integration

devin-ai-integration Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

✅ Done. Merged main in 0b2caf7. The only conflict was in airbyte/mcp/agents.py: main removed search_agent_skills (airbytehq/PyAirbyte#1185), so I dropped it and its entry in the policy-guard parametrized test; the external_access=True annotation stays on the remaining Agents tools. Local ruff/pyrefly and the MCP unit tests (207) pass; CI is rerunning.

Written by Devin

@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: 2 flags

Not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)

Devin Review

@aaronsteers

Copy link
Copy Markdown
Member Author

Devin, rebuild on the release candidate trunk.

@devin-ai-integration

Copy link
Copy Markdown
Contributor

👍 On it. Rebuilding this branch on release-candidate/v1 and retargeting the PR there. Same behavior; I'll adapt to RC's tool/module layout where it differs from main.

Written by Devin

…ies for Cloud MCP

Co-Authored-By: AJ Steers <aj@airbyte.io>
@devin-ai-integration
devin-ai-integration Bot force-pushed the devin/1789678460-safe-mode-blocks-agents branch from 0b2caf7 to 62ca2c5 Compare October 5, 2026 01:08
Co-Authored-By: AJ Steers <aj@airbyte.io>
@devin-ai-integration

Copy link
Copy Markdown
Contributor

Devin, rebuild on the release candidate trunk.

Done. Rebuilt on release-candidate/v1 (62ca2c5, bcd86d0) and the PR now targets it. The behavior hasn't changed. Two things changed to fit RC:

  1. The former Agents tools now live in cloud.py/guidance.py. external_access=True is set on execute_external_api_query, execute_external_sql_query, execute_external_search_query, get_cloud_search_status and get_agent_skill_docs.
  2. fastmcp-extensions 0.33 rejects custom annotation keys. The pipeline_change/external_access metadata is now stored in a PyAirbyte-side registry keyed by tool name, so it is no longer sent with the tool's annotations.

Description updated. CI is running.

Written by Devin

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

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.

Copilot review overview

🟡 Changes recommended

check_cloud_connector and run_cloud_sync need correct external-access policy annotations, and external-access denial guidance should cover header narrowing.

Review effort: Lite
Findings: 1 Medium severity · 1 Low severity

Open (2)
Resolved since last review (1)

Comment thread airbyte/mcp/_tool_utils.py
Comment thread airbyte/exceptions.py Outdated
Co-Authored-By: AJ Steers <aj@airbyte.io>
@aaronsteers
Aaron ("AJ") Steers (aaronsteers) merged commit e0ad6f5 into release-candidate/v1 Oct 5, 2026
22 checks passed
@aaronsteers
Aaron ("AJ") Steers (aaronsteers) deleted the devin/1789678460-safe-mode-blocks-agents branch October 5, 2026 01:51
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