Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions .github/ISSUE_TEMPLATE/airbyte-mcp-beta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Airbyte MCP beta feedback
description: Report a bug, request a feature, or share feedback about the Airbyte MCP server.
title: "[Airbyte MCP beta]: "
labels: [airbyte-mcp-beta]
body:
- type: markdown
attributes:
value: |
Thanks for testing the Airbyte MCP server. Your feedback helps us shape it before general availability.

Don't paste API keys, client secrets, passwords, or connector credentials into this issue. GitHub issues in this repository are public.
- type: dropdown
id: feedback-type
attributes:
label: Feedback type
options:
- Bug
- Feature request
- Documentation
- Other feedback
validations:
required: true
- type: dropdown
id: deployment
attributes:
label: How are you running the MCP server?
options:
- Hosted on Airbyte Cloud
- Local (`uvx airbyte-mcp`)
- Self-hosted over HTTP (`airbyte-mcp-http`)
- Not sure
validations:
required: true
- type: input
id: mcp-client
attributes:
label: MCP client
description: The app or agent you connected to the server, and its version if you know it.
placeholder: Claude Desktop, Claude Code, Cursor, VS Code, Codex
validations:
required: true
- type: input
id: pyairbyte-version
attributes:
label: PyAirbyte version
description: For local and self-hosted servers, check the `airbyte@<version>` pin in your MCP config. If you use `airbyte@latest`, enter `latest`. Leave blank for the hosted server.
- type: textarea
id: description
attributes:
label: What happened?
description: Describe the problem or idea. If you're reporting a bug, include the prompt you gave your agent and the MCP tools it called, if you know them.
validations:
required: true
- type: textarea
id: expected
attributes:
label: What did you expect to happen?
- type: textarea
id: steps
attributes:
label: Steps to reproduce
description: For bugs, list the steps that lead to the problem.
placeholder: |
1. Ask the agent to ...
2. The agent calls ...
3. ...
- type: textarea
id: logs
attributes:
label: Relevant log output
description: Paste any error messages or MCP server logs. Remove secrets first. This field is formatted as code automatically.
render: shell
2 changes: 1 addition & 1 deletion .github/workflows/poe-command.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
private-key: ${{ secrets.OCTAVIA_BOT_PRIVATE_KEY }}

- name: Run Poe Slash Command Processor
uses: aaronsteers/poe-command-processor@v1.3.3
uses: airbytehq/poe-command-processor@v1.3.3
with:
pr: ${{ github.event.inputs.pr }}
comment-id: ${{ github.event.inputs.comment-id }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release_drafter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
fetch-depth: 1

- name: Create draft release (not ready)
uses: aaronsteers/semantic-pr-release-drafter@v2.5.1
uses: airbytehq/semantic-pr-release-drafter@v2.5.1
id: not-ready-draft
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -52,7 +52,7 @@ jobs:
run: UV_DYNAMIC_VERSIONING_BYPASS="${VERSION#v}" uv build

- name: Attach assets and finalize draft
uses: aaronsteers/semantic-pr-release-drafter@v2.5.1
uses: airbytehq/semantic-pr-release-drafter@v2.5.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tk-todo-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ jobs:
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6

- name: Check for TK-TODO markers # IGNORE:TK
uses: aaronsteers/tk-todo-check-action@76cd8dbb434bc93c7898ebdf43eff6105ca186ac # v1.0.0 IGNORE:TK
uses: airbytehq/tk-todo-check-action@76cd8dbb434bc93c7898ebdf43eff6105ca186ac # v1.0.0 IGNORE:TK
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ Use **Markdown** formatting in all docstrings — not reStructuredText (reST).

## 🚀 Releasing

This project uses [`semantic-pr-release-drafter`](https://github.com/aaronsteers/semantic-pr-release-drafter) for automated release management. To release, simply click "`Edit`" on the latest release draft from the [releases page](https://github.com/airbytehq/PyAirbyte/releases), and then click "`Publish release`". This publish operation will trigger all necessary downstream publish operations.
This project uses [`semantic-pr-release-drafter`](https://github.com/airbytehq/semantic-pr-release-drafter) for automated release management. To release, simply click "`Edit`" on the latest release draft from the [releases page](https://github.com/airbytehq/PyAirbyte/releases), and then click "`Publish release`". This publish operation will trigger all necessary downstream publish operations.

ℹ️ For more detailed instructions, please see the [Releasing Guide](https://github.com/aaronsteers/semantic-pr-release-drafter/blob/main/docs/releasing.md).
ℹ️ For more detailed instructions, please see the [Releasing Guide](https://github.com/airbytehq/semantic-pr-release-drafter/blob/main/docs/releasing.md).
22 changes: 22 additions & 0 deletions airbyte/_util/api_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,28 @@
"""Connect and read timeouts for a deferred-credential create on the Config API."""


def _register_queued_job_status() -> None:
"""Register the `queued` job status on the `airbyte-api` SDK enum.

The Airbyte API returns `queued` for jobs waiting to start, but `airbyte-api<1.0` doesn't
define it, so decoding any job response with that status raises a `ValueError`.
"""
sdk_enum: Any = models.JobStatusEnum
if "queued" in sdk_enum._value2member_map_:
return

member: Any = str.__new__(sdk_enum, "queued")
member._name_ = "QUEUED"
member._value_ = "queued"
sdk_enum.QUEUED = member
sdk_enum._member_names_.append("QUEUED")
sdk_enum._member_map_["QUEUED"] = member
sdk_enum._value2member_map_["queued"] = member


_register_queued_job_status()


def status_ok(status_code: int) -> bool:
"""Check if a status code is OK."""
return status_code >= 200 and status_code < 300 # noqa: PLR2004 # allow inline magic numbers
Expand Down
1 change: 1 addition & 0 deletions airbyte/cloud/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class JobStatusEnum(str, Enum):
"""Status values for an Airbyte Cloud job."""

PENDING = "pending"
QUEUED = "queued"
RUNNING = "running"
INCOMPLETE = "incomplete"
FAILED = "failed"
Expand Down
2 changes: 1 addition & 1 deletion airbyte/mcp/cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ class SyncJobResult(BaseModel):
job_id: int
"""The job ID."""
status: str
"""The job status (e.g., 'succeeded', 'failed', 'running', 'pending')."""
"""The job status (e.g., 'succeeded', 'failed', 'running', 'queued', 'pending')."""
bytes_synced: int
"""Number of bytes synced in this job."""
records_synced: int
Expand Down
2 changes: 1 addition & 1 deletion airbyte/mcp/http_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@

# Human-facing landing page shown when a browser GETs the MCP endpoint.
MCP_LANDING_TITLE = "Airbyte MCP Server"
MCP_LANDING_DOCS_URL = "https://docs.airbyte.com/community/mcp-servers/replication-mcp"
MCP_LANDING_DOCS_URL = "https://docs.airbyte.com/platform/airbyte-mcp"
RELEASE_TAG_URL_TEMPLATE = "https://github.com/airbytehq/PyAirbyte/releases/tag/v{}"
COMMIT_URL_TEMPLATE = "https://github.com/airbytehq/PyAirbyte/commit/{}"
RELEASES_URL = "https://github.com/airbytehq/PyAirbyte/releases"
Expand Down
24 changes: 23 additions & 1 deletion tests/unit_tests/test_cloud_api_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,23 @@

from __future__ import annotations

import json
from collections.abc import Callable
from types import SimpleNamespace

import pytest
import requests
from airbyte import constants
from airbyte._util import api_util, meta
from airbyte.cloud.models import CloudJobInfo, JobStatusEnum
from airbyte.exceptions import (
AirbyteError,
AirbyteMissingResourceError,
AirbyteWorkspaceNotEmptyError,
PyAirbyteInputError,
)
from airbyte.secrets.base import SecretString
from airbyte_api import api, models
from airbyte_api import api, models, utils
from airbyte_api.errors import SDKError


Expand Down Expand Up @@ -966,6 +968,26 @@ def test_list_connections_rejects_invalid_limits(limit: int) -> None:
)


def test_sdk_decodes_queued_job_status() -> None:
payload = {
"data": [
{
"connectionId": "connection-id",
"jobId": 1,
"jobType": "sync",
"startTime": "2026-01-01T00:00:00Z",
"status": "queued",
}
]
}

response = utils.unmarshal_json(json.dumps(payload), models.JobsResponse)
job = response.data[0]

assert job.status is models.JobStatusEnum("queued")
assert CloudJobInfo.from_api_response(job).status is JobStatusEnum.QUEUED


def test_get_job_logs_paginates_until_limit(monkeypatch: pytest.MonkeyPatch) -> None:
"""Verify job log pagination stops after collecting the requested limit."""
captured_requests: list[api.ListJobsRequest] = []
Expand Down
Loading