Skip to content

fix(cloud): default to sole instance workspace; MCP tool names in guidance - #1305

Merged
Aaron ("AJ") Steers (aaronsteers) merged 2 commits into
release-candidate/v1from
devin/1790904754-oss-mcp-workspace-defaults
Oct 2, 2026
Merged

Aaron ("AJ") Steers (aaronsteers) merged 2 commits into
release-candidate/v1from
devin/1790904754-oss-mcp-workspace-defaults

Conversation

@aaronsteers

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

Copy link
Copy Markdown
Member

Summary

Fixes two problems found while testing the local stdio MCP against Airbyte OSS 2.3.0 (abctl). Requested by AJ Steers.

  1. Fresh self-managed installs have no default workspace. The default OSS user is an instance admin with no workspace memberships and no defaultWorkspaceId. resolve_default_workspace_id() therefore returned None, and every tool that needs a workspace failed. This PR adds a last fallback that applies only when the user has no direct workspace grants at all:

    # CloudClient.resolve_default_workspace_id, after the direct-grant check
    if live_workspaces or unvalidated_count:
        return None
    return self._get_sole_instance_workspace_id()
    # -> instance admins only: list_workspaces_by_user(limit=2, page_size=2); returns the ID if exactly one workspace exists, else None

    api_util.list_workspaces_by_user gains an optional page_size (default 100, so existing callers are unchanged). The fallback therefore requests only two rows, even on Cloud.

  2. In local MCP mode, the AirbyteMissingWorkspaceContextError guidance named tools that don't exist. MCP tool names (list_cloud_workspaces, ...) were used only when is_hosted_mcp_mode() was true. Local stdio MCP users were therefore told to call list_workspaces / list_organizations / get_default_context_for_user, which are Python method names. The check is now is_mcp_mode(), which is set for both stdio and HTTP. Python library users still get the method names.

Not in this PR: the self-managed web URL fix (get_web_url_root, #563), which is being handled separately. The structured JSON returns for deploy and sync tools are tracked in #1306.

Tests: a new parametrized test in test_cloud_client.py covers an instance admin with one workspace, an instance admin with several, and a non-admin. A new test checks that list_workspaces_by_user honors page_size. test_exceptions.py was updated for the mode check. I also verified both fixes end to end against a fresh OSS install; details are in the PR comment.

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

…ol names in local MCP guidance

Co-Authored-By: AJ Steers <aj@airbyte.io>
@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

github-actions Bot commented Oct 2, 2026

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/1790904754-oss-mcp-workspace-defaults' pyairbyte --help

# Install PyAirbyte from this branch for development:
pip install 'git+https://github.com/airbytehq/PyAirbyte.git@devin/1790904754-oss-mcp-workspace-defaults'

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.

This comment was marked as resolved.

…llback

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

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

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: Python

Python / code-coverage/pytest-no-creds

The overall line coverage in commit 93e122c in the devin/1790904754-oss... 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/1790904754-oss... 93e122c +/-
airbyte/_util/api_util.py 36% 61% +25%
airbyte/mcp/cloud.py 52% 80% +28%
airbyte/cloud/connectors.py 34% 73% +39%
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 93e122c in the devin/1790904754-oss... branch is 80%. 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/1790904754-oss... 93e122c +/-
airbyte/cloud/connectors.py 51% 78% +27%
airbyte/mcp/cloud.py 52% 80% +28%
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 93e122c in the devin/1790904754-oss... branch is 74%. 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/1790904754-oss... 93e122c +/-
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 — 73% —
airbyte/shared/...ql_processor.py — 68% —
airbyte/_util/api_util.py — 61% —

Updated October 02, 2026 01:53 UTC

@devin-ai-integration

Copy link
Copy Markdown
Contributor

E2E verification at 93e122c8: I tested against a fresh Airbyte OSS 2.3.0 install (abctl v0.30.4) through the real local stdio MCP (uv run airbyte-mcp), with AIRBYTE_CLOUD_WORKSPACE_ID unset and /setup never completed.

The test user was an instance admin with no direct workspace memberships and no stored default.

  1. get_default_cloud_context({}) returned the sole "Default Workspace" (default_workspace_verified: true, configured_workspace_id: null, member_workspaces: []).
  2. Without a workspace_id, list_cloud_connections({}) returned [] with no error, and deploy_noop_destination_to_cloud and a Faker source deploy both landed in that workspace.
  3. After I created a second workspace, the default became unresolved, as expected. An implicit call then failed with:
    Workspace ID is required but not provided. The authenticated user's default workspace was checked and none was available. `list_cloud_workspaces` returns direct workspace memberships by default; pass `organization_id`/`organization_name` or a broader `privilege_scope` for organization-wide discovery, or call `list_cloud_organizations` to search organizations by name. If exactly one workspace is found, use it; otherwise ask the user to choose. Call `get_default_cloud_context` to inspect your memberships.
    
    The message uses MCP tool names only; none of the Python method names appear.
  4. Selecting a workspace explicitly worked. After deleting the second workspace in cleanup, the sole-workspace default resolved again.

Not covered: creating a connection and running a sync. Connector discovery hit Docker Hub rate limits (HTTP 429) in the test environment, and neither is affected by this PR.

Written by Devin

@aaronsteers
Aaron ("AJ") Steers (aaronsteers) marked this pull request as ready for review October 2, 2026 17:22
@aaronsteers
Aaron ("AJ") Steers (aaronsteers) merged commit b76087a into release-candidate/v1 Oct 2, 2026
24 checks passed
@aaronsteers
Aaron ("AJ") Steers (aaronsteers) deleted the devin/1790904754-oss-mcp-workspace-defaults branch October 2, 2026 17:22

@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.

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

Devin Review

Comment thread airbyte/cloud/client.py
Comment on lines +736 to +737
except (AirbyteError, exc.PyAirbyteInputError):
return None

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.

🟡 Workspace lookup failures escape default resolution

If instance-wide discovery times out, _get_sole_instance_workspace_id propagates the transport error. _make_config_api_request leaves request failures unwrapped, so workspace-dependent calls fail instead of reporting missing workspace context.

Learn more

The fallback runs only after the user has no verified direct workspaces and has instance-admin permission. It calls the Config API through _make_config_api_request, which makes a requests.request call without converting connection or timeout failures to AirbyteError. Those failures bypass this handler, unlike Config API HTTP errors, so a failed optional lookup interrupts default resolution instead of returning None.

Example: An instance admin has no workspace memberships or stored default. The permissions lookup succeeds, then the workspace-list request times out. resolve_default_workspace_id() raises requests.Timeout rather than returning None; an MCP tool cannot raise its missing-workspace guidance.

Recommended fix: Catch the transport exceptions raised by _make_config_api_request in this optional fallback, or normalize them into AirbyteError at the API boundary. Preserve the current behavior for successful lookups and ambiguous workspace lists.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

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