-
Notifications
You must be signed in to change notification settings - Fork 71
feat(mcp): Add HTTP header bearer token authentication support #914
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(mcp): Add HTTP header bearer token authentication support #914
Conversation
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ility (#912) Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Enable PyAirbyte MCP tools to authenticate via Authorization header when running over HTTP transport. This allows a single shared MCP server to handle requests from multiple users with different bearer tokens. Changes: - Add get_bearer_token_from_headers() utility in airbyte/mcp/_util.py - Update resolve_cloud_bearer_token() to check HTTP headers first Resolution order for bearer token: 1. Explicit input_value parameter 2. HTTP Authorization header (when running as MCP HTTP server) 3. AIRBYTE_CLOUD_BEARER_TOKEN environment variable Co-Authored-By: [email protected] <[email protected]>
Original prompt from [email protected]Required Changes1. Add HTTP header extraction utilityFile: from fastmcp.server.dependencies import get_http_headers
def get_bearer_token_from_headers() -> str | None:
"""Extract bearer token from HTTP Authorization header.
Returns None if not running over HTTP transport or no header present.
"""
try:
headers = get_http_headers()
auth_header = headers.get("authorization", "")
if auth_header.startswith("Bearer "):
return auth_header[7:] # Strip "Bearer " prefix
return None
except Exception:
# Not running over HTTP transport
return None2. Update
|
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
👋 Greetings, Airbyte Team Member!Here are some helpful tips and reminders for your convenience. Testing This PyAirbyte VersionYou 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/1765845063-http-header-bearer-token' pyairbyte --help
# Install PyAirbyte from this branch for development:
pip install 'git+https://github.com/airbytehq/PyAirbyte.git@devin/1765845063-http-header-bearer-token'Helpful ResourcesPR Slash CommandsAirbyte Maintainers can execute the following slash commands on your PR:
Community SupportQuestions? Join the #pyairbyte channel in our Slack workspace. |
- Move fastmcp.server.dependencies.get_http_headers import to top-level in _util.py - Move airbyte.mcp._util.get_bearer_token_from_headers import to top-level in auth.py - Remove noqa: PLC0415 comments as inline imports are no longer used Co-Authored-By: [email protected] <[email protected]>
…th' into devin/1765845063-http-header-bearer-token
|
Devin CI is failing |
… all API call sites Co-Authored-By: [email protected] <[email protected]>
|
|
||
| - name: Compute prerelease version | ||
| id: version | ||
| run: | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📝 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2086:info:7:39: Double quote to prevent globbing and word splitting [shellcheck]
.github/workflows/pypi_publish.yml
Outdated
| - uses: hynek/build-and-inspect-python-package@efb823f52190ad02594531168b7a2d5790e66516 # v2.14.0 | ||
| - name: Prepare version override | ||
| id: version | ||
| run: | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📝 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2086:info:1:51: Double quote to prevent globbing and word splitting [shellcheck]
.github/workflows/pypi_publish.yml
Outdated
| - uses: hynek/build-and-inspect-python-package@efb823f52190ad02594531168b7a2d5790e66516 # v2.14.0 | ||
| - name: Prepare version override | ||
| id: version | ||
| run: | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📝 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2086:info:2:61: Double quote to prevent globbing and word splitting [shellcheck]
… favor of PR branch Co-Authored-By: [email protected] <[email protected]>
…lint fixes Co-Authored-By: [email protected] <[email protected]>
Co-Authored-By: [email protected] <[email protected]>
PyTest Results (Full)416 tests ±0 391 ✅ ±0 23m 23s ⏱️ + 1m 39s For more details on these failures, see this check. Results for commit 98d6d26. ± Comparison against base commit 4f05142. |
| """Authentication-related constants and utilities for the Airbyte Cloud.""" | ||
|
|
||
| from airbyte import constants | ||
| from airbyte.mcp._util import get_bearer_token_from_headers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Devin, Can you create a follow-on issue to refactor slightly...
Ideally nothing outside the MCP module would import from the MCP module. That said, this is expedient and doesn't seem to create circular dependencies or side effects (that I can see). So I'm inclined to merge and create follow-on issue for refactoring.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created follow-on issue: #915
The issue proposes moving get_bearer_token_from_headers() to a shared utility location (like airbyte/_util/http_auth.py) so the MCP module can import from it rather than the other way around.
aaronsteers
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving with one post-merge update requested: https://github.com/airbytehq/PyAirbyte/pull/914/changes#r2625121278
…on support This commit consolidates authentication handling for Airbyte Cloud API: - Add CloudCredentials dataclass in airbyte/cloud/credentials.py that encapsulates auth configuration (client_id/secret or bearer_token) - Add bearer token authentication support to api_util functions - Add resolve_cloud_credentials() in MCP _util.py for multi-source credential resolution (explicit params -> HTTP headers -> env vars) - Add HTTP header extraction helpers for MCP HTTP/SSE transport - Update CloudWorkspace to support bearer token authentication - Export CloudCredentials from airbyte.cloud module This replaces PRs #866, #867, and #914 with a unified implementation. Co-Authored-By: AJ Steers <[email protected]>
|
Replaced by #916 |
This PR targets the following PR:
Summary
Enable PyAirbyte MCP tools to authenticate via
Authorizationheader when running over HTTP transport. This allows a single shared MCP server to handle requests from multiple users with different bearer tokens, rather than requiring a subprocess per request.Changes:
get_bearer_token_from_headers()utility inairbyte/mcp/_util.pythat extracts bearer tokens from HTTP Authorization headers using fastmcp'sget_http_headers()resolve_cloud_bearer_token()inairbyte/cloud/auth.pyto check HTTP headers first before falling back to environment variablesnoqa: SLF001comments inairbyte/cloud/connectors.pyfor private member access (lint fixes)noqa: PLR0904comment onCloudWorkspaceclass (lint fix for too many public methods)Token resolution order:
input_valueparameterAuthorization: Bearer <token>header (when running as MCP HTTP server)AIRBYTE_CLOUD_BEARER_TOKENenvironment variableReview & Testing Checklist for Human
airbyte.cloud.authnow imports fromairbyte.mcp._utilat module load time, which triggers fastmcp imports. Verify this doesn't break code that imports auth.py but doesn't use MCP.resolve_cloud_bearer_token()passedinput_valueas default totry_get_secret(). Now it checksinput_valuefirst explicitly and passesdefault=Noneto the env var fallback - verify this doesn't break existing callers.Authorization: Bearer <token>header, verify API calls use that tokenRecommended test plan:
Notes
airbyte.cloud.authandairbyte.mcp._utilUpdates since last revision
api_util.py,cloud_ops.py, and.github/workflow files)