Skip to content

feat(mcp): support ?read-only=true URL param for clients without custom headers - #1433

Merged
Aaron ("AJ") Steers (aaronsteers) merged 6 commits into
release-candidate/v1from
devin/1793319647-mcp-url-param-modalities
Oct 30, 2026
Merged

Aaron ("AJ") Steers (aaronsteers) merged 6 commits into
release-candidate/v1from
devin/1793319647-mcp-url-param-modalities

Conversation

@aaronsteers

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

Copy link
Copy Markdown
Member

Summary

Claude's custom connector UI can't send custom headers, so it has no way to turn on read-only mode on the hosted Cloud MCP. This picks up airbytehq/fastmcp-extensions#157 (released in 0.37.0), which adds the ?read-only=true URL query param to the shared standard read-only filter. PyAirbyte already enables include_standard_tool_filters, so no new PyAirbyte config args are needed:

https://mcp.airbyte.com/mcp?read-only=true
  • Bumps fastmcp-extensions to >=0.37.0,<1.0.0 and documents the URL param in airbyte/mcp/__init__.py.
  • Also inherited from Feat: Adapt BigQuery classes to be able to use default credential #157 through run_mcp_http_server: near-miss names (?readonly=, ?read_only=, ...) and invalid values (?read-only=yes) return HTTP 400, and other query params are ignored. A request can't disable read-only when the server sets MCP_READONLY_MODE=1.
  • HTTP tools/list tests:
    • ?read-only=true hides run_connection_sync and keeps list_workspaces.
    • MCP_READONLY_MODE=1 + ?read-only=false still hides run_connection_sync.
  • Per review, the ?allow-* and ?insiders params are left out for now.

Test plan

  • uv run pytest tests/unit_tests/test_mcp_http.py -q passes (12 tests) against 0.37.0.
  • The Feat: Adapt BigQuery classes to be able to use default credential #157 prerelease (same code as 0.37.0) was deployed to https://mcp.internal.airbyte.ai/cloud-mcp-preview and tested with tools/list:
    • ?read-only=true returns 32 tools, all read-only, instead of 55.
    • ?readonly=true and ?read-only=yes return 400.
    • ?utm_source=x is ignored.
  • The prod ingress at mcp.airbyte.com hasn't been tested yet.

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

@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/1793319647-mcp-url-param-modalities' pyairbyte --help

# Install PyAirbyte from this branch for development:
pip install 'git+https://github.com/airbytehq/PyAirbyte.git@devin/1793319647-mcp-url-param-modalities'

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
  • /evals - Runs the Cloud MCP evals that use the MCP tools this PR changed (/evals full=true runs the full suite)
📚 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 30, 2026 •

Copy link
Copy Markdown
Contributor

Code coverage overview

Languages: Python

Python / code-coverage/pytest-no-creds

release-candidate/v1 d9f652f devin/1793319647-mcp... 50d591e +/-
65% 80% +15%
View coverage of the 10 most impacted files.
File release-candidate/v1 d9f652f devin/1793319647-mcp... 50d591e +/-
airbyte/_util/api_util.py 36% 67% +31%
airbyte/mcp/cloud.py 52% 86% +34%
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/1793319647-mcp... 50d591e +/-
71% 82% +11%
View coverage of the 10 most impacted files.
File release-candidate/v1 d9f652f devin/1793319647-mcp... 50d591e +/-
airbyte/cloud/connectors.py 51% 82% +31%
airbyte/mcp/cloud.py 52% 86% +34%
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/1793319647-mcp... 50d591e +/-
— 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/1793319647-mcp... 50d591e +/-
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 — 86% —
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 30, 2026 16:53 UTC

@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Prerelease Build Started

Building and publishing prerelease package from this PR...
Check job output.
Prerelease Published to PyPI

Version: 1.0.0-rc.38.dev143340980621392
View publish workflow

Install with:

pip install airbyte==1.0.0-rc.38.dev143340980621392

@aaronsteers

Copy link
Copy Markdown
Member Author

Let's reduce this to the minimum that we know we need, which is the read-only option, and remove the other options

@devin-ai-integration

Copy link
Copy Markdown
Contributor

Will do. In this PR I'll drop ?allow-pipeline-changes, ?allow-external-access, ?allow-destructive-tools and ?insiders, so it's left with just the fastmcp-extensions bump and the ?read-only=true docs and test. I'll also trim airbytehq/fastmcp-extensions#157 down to the url_param_key mechanism plus read-only; no-destructive-tools, include-modules, exclude-modules and exclude-tools come out.


Posted by Devin, on behalf of Aaron ("AJ") Steers (@aaronsteers).

@devin-ai-integration devin-ai-integration Bot changed the title feat(mcp): accept modality settings as URL query params feat(mcp): support ?read-only=true URL param for clients without custom headers Oct 30, 2026
@devin-ai-integration
devin-ai-integration Bot marked this pull request as ready for review October 30, 2026 15:50
Copilot AI balanced review requested due to automatic review settings October 30, 2026 15:50

@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 1 potential issue.

Devin Review

Comment thread tests/unit_tests/test_mcp_http.py Resolved

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

The pinned dependency allows ?read-only=false to bypass server-configured MCP_READONLY_MODE=1, potentially exposing writable tools despite the read-only setting.

1 open issue
What changed in this PR

Adds URL-based read-only mode to PyAirbyte’s hosted MCP server for clients that cannot send custom headers, using the existing shared tool filters.

Changes:

  • Pins fastmcp-extensions to a prerelease with URL query parameter support.
  • Adds an HTTP test verifying that ?read-only=true hides a writable tool while retaining a read-only tool.
  • Documents the read-only URL parameter and hosted endpoint example.
File Description
uv.lock Locks the selected prerelease and its distribution artifacts.
tests/​unit_tests/​test_mcp_http.py Supports custom session URLs and tests read-only tool visibility.
pyproject.toml Pins the dependency providing query parameter support.
airbyte/​mcp/​__init__.py Documents how HTTP clients enable read-only mode through the URL.

Review effort: Balanced

Comment thread pyproject.toml Resolved
@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Prerelease Build Started

Building and publishing prerelease package from this PR...
Check job output.
Prerelease Published to PyPI

Version: 1.0.0-rc.38.dev143341086074799
View publish workflow

Install with:

pip install airbyte==1.0.0-rc.38.dev143341086074799

Comment thread pyproject.toml Resolved
@aaronsteers
Aaron ("AJ") Steers (aaronsteers) merged commit 1e79888 into release-candidate/v1 Oct 30, 2026
30 checks passed
@aaronsteers
Aaron ("AJ") Steers (aaronsteers) deleted the devin/1793319647-mcp-url-param-modalities branch October 30, 2026 16:59
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