airbyte_ops_mcp.mcp.prod_db_ops
MCP tools for querying the Airbyte Cloud Prod DB Replica.
This module provides MCP tools that wrap the query functions from airbyte_ops_mcp.prod_db_access.queries for use by AI agents.
MCP reference
MCP primitives registered by the prod_db_ops module of the airbyte-internal-ops server: 20 tool(s), 0 prompt(s), 0 resource(s).
Tools (20)
query_connector_pin_stats
Hints: read-only · idempotent · open-world
Query connector versions that have at least one scoped configuration pin.
Returns versions from the prod DB that are referenced by at least one
scoped_configuration pin (key = 'connector_version'). Each version
appears exactly once with per-scope pin breakdown (actor, workspace, org).
If neither filter is provided, returns the global superset across all connectors.
Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
connector_definition_id |
string | null |
no | null |
Connector definition UUID to filter by (optional). Mutually exclusive with connector_canonical_name. |
connector_canonical_name |
string | null |
no | null |
Connector canonical name (e.g. source-postgres) to filter by. Resolved to a definition ID via the registry. Mutually exclusive with connector_definition_id. |
Show input JSON schema
{
"additionalProperties": false,
"properties": {
"connector_definition_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Connector definition UUID to filter by (optional). Mutually exclusive with `connector_canonical_name`."
},
"connector_canonical_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Connector canonical name (e.g. `source-postgres`) to filter by. Resolved to a definition ID via the registry. Mutually exclusive with `connector_definition_id`."
}
},
"type": "object"
}
Show output JSON schema
{
"properties": {
"result": {
"items": {
"description": "A connector version that has at least one scoped configuration pin.",
"properties": {
"version_id": {
"description": "The actor_definition_version UUID",
"type": "string"
},
"connector_definition_id": {
"description": "The connector definition UUID",
"type": "string"
},
"connector_name": {
"description": "Human-readable connector name",
"type": "string"
},
"docker_repository": {
"description": "Docker repository path",
"type": "string"
},
"docker_image_tag": {
"description": "Docker image tag for this version",
"type": "string"
},
"last_published": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ISO timestamp when this version was last published"
},
"pin_count": {
"description": "Total number of scoped_configuration rows pinning to this version",
"type": "integer"
},
"breaking_change_pins": {
"default": 0,
"description": "Number of actor-scoped pins created by breaking changes",
"type": "integer"
},
"rollout_pins": {
"default": 0,
"description": "Number of pins created by connector rollouts",
"type": "integer"
},
"actor_pins": {
"description": "Number of actor-scoped pins (excludes breaking change and rollout pins)",
"type": "integer"
},
"workspace_pins": {
"description": "Number of workspace-scoped pins",
"type": "integer"
},
"org_pins": {
"description": "Number of organization-scoped pins",
"type": "integer"
}
},
"required": [
"version_id",
"connector_definition_id",
"connector_name",
"docker_repository",
"docker_image_tag",
"pin_count",
"actor_pins",
"workspace_pins",
"org_pins"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"result"
],
"type": "object",
"x-fastmcp-wrap-result": true
}
query_connector_population_summary
Hints: read-only · idempotent · open-world
Summarize the applied vs potential pinning audience for a connector, by tier.
Answers "how many actors are pinned and how many are eligible for pinning, split by tier" — the population view analogous to a rollout's audience.
active: the potential audience — non-tombstoned actors of the definition that have at least one active connection (connection.status = 'active'). Inactive/disabled and deprecated connections are excluded, so this reflects the enabled, rollout-touchable population rather than every actor ever created.pinned_any: active actors that already have an effectiveconnector_versionpin at any scope (actor/workspace/org).eligible:activeminuspinned_any— actors available to pin.pinned_to_version: the applied audience for the requested version (only when a version identifier was provided).
Backed by scoped_configuration + actor/connection tables, so it is cheap
to compute. Accepts a version identifier (preferred, adds
pinned_to_version) or a definition-level identifier.
Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
connector_version_id |
string | null |
no | null |
Connector version UUID. When provided, the applied audience (pinned_to_version) is included. Provide this OR connector_name + connector_version OR a definition-level identifier. |
connector_name |
string | null |
no | null |
Canonical connector name (e.g. source-postgres). Used with connector_version to resolve the version UUID. |
connector_version |
string | null |
no | null |
Semver version tag (e.g. 0.3.59). Used with connector_name. |
connector_definition_id |
string | null |
no | null |
Connector definition UUID for a definition-level summary (no pinned_to_version breakdown). |
connector_canonical_name |
string | null |
no | null |
Canonical connector name resolved to a definition ID via the registry, for a definition-level summary. |
customer_tier_filter |
enum("TIER_0", "TIER_1", "TIER_2", "UNKNOWN", "ALL") |
no | "TIER_2" |
Which customer tiers to count. Defaults to TIER_2; pass ALL to include TIER_0/TIER_1 (revenue-critical) customers. |
Show input JSON schema
{
"additionalProperties": false,
"properties": {
"connector_version_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Connector version UUID. When provided, the applied audience (`pinned_to_version`) is included. Provide this OR `connector_name` + `connector_version` OR a definition-level identifier."
},
"connector_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Canonical connector name (e.g. `source-postgres`). Used with `connector_version` to resolve the version UUID."
},
"connector_version": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Semver version tag (e.g. `0.3.59`). Used with `connector_name`."
},
"connector_definition_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Connector definition UUID for a definition-level summary (no `pinned_to_version` breakdown)."
},
"connector_canonical_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Canonical connector name resolved to a definition ID via the registry, for a definition-level summary."
},
"customer_tier_filter": {
"default": "TIER_2",
"description": "Which customer tiers to count. Defaults to `TIER_2`; pass `ALL` to include TIER_0/TIER_1 (revenue-critical) customers.",
"enum": [
"TIER_0",
"TIER_1",
"TIER_2",
"UNKNOWN",
"ALL"
],
"type": "string"
}
},
"type": "object"
}
Show output JSON schema
{
"description": "Applied vs potential pinning audience for a connector, split by tier.",
"properties": {
"connector_definition_id": {
"description": "The connector definition UUID",
"type": "string"
},
"connector_version_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The version UUID, when a specific version was requested"
},
"docker_repository": {
"description": "Docker repository path",
"type": "string"
},
"docker_image_tag": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Docker image tag, when a version was requested"
},
"customer_tier_filter": {
"description": "Tier filter applied to the counts (`TIER_0`/`TIER_1`/`TIER_2`/`UNKNOWN`/`ALL`)",
"type": "string"
},
"active": {
"description": "Potential audience: enabled actors of the definition (those with at least one active connection, `status = 'active'`), by tier",
"properties": {
"tier_0_count": {
"default": 0,
"description": "Number of TIER_0 entries",
"type": "integer"
},
"tier_1_count": {
"default": 0,
"description": "Number of TIER_1 entries",
"type": "integer"
},
"tier_2_count": {
"default": 0,
"description": "Number of TIER_2 entries",
"type": "integer"
},
"unknown_count": {
"default": 0,
"description": "Number of UNKNOWN entries",
"type": "integer"
},
"total": {
"default": 0,
"description": "Total number of entries",
"type": "integer"
},
"warnings": {
"description": "Warnings raised while building this summary.",
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
},
"pinned_any": {
"description": "Active actors already pinned to any version, by tier",
"properties": {
"tier_0_count": {
"default": 0,
"description": "Number of TIER_0 entries",
"type": "integer"
},
"tier_1_count": {
"default": 0,
"description": "Number of TIER_1 entries",
"type": "integer"
},
"tier_2_count": {
"default": 0,
"description": "Number of TIER_2 entries",
"type": "integer"
},
"unknown_count": {
"default": 0,
"description": "Number of UNKNOWN entries",
"type": "integer"
},
"total": {
"default": 0,
"description": "Total number of entries",
"type": "integer"
},
"warnings": {
"description": "Warnings raised while building this summary.",
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
},
"eligible": {
"description": "Active actors not pinned to any version (available to pin), by tier",
"properties": {
"tier_0_count": {
"default": 0,
"description": "Number of TIER_0 entries",
"type": "integer"
},
"tier_1_count": {
"default": 0,
"description": "Number of TIER_1 entries",
"type": "integer"
},
"tier_2_count": {
"default": 0,
"description": "Number of TIER_2 entries",
"type": "integer"
},
"unknown_count": {
"default": 0,
"description": "Number of UNKNOWN entries",
"type": "integer"
},
"total": {
"default": 0,
"description": "Total number of entries",
"type": "integer"
},
"warnings": {
"description": "Warnings raised while building this summary.",
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
},
"pinned_to_version": {
"anyOf": [
{
"description": "Summary of tier distribution across a set of results.",
"properties": {
"tier_0_count": {
"default": 0,
"description": "Number of TIER_0 entries",
"type": "integer"
},
"tier_1_count": {
"default": 0,
"description": "Number of TIER_1 entries",
"type": "integer"
},
"tier_2_count": {
"default": 0,
"description": "Number of TIER_2 entries",
"type": "integer"
},
"unknown_count": {
"default": 0,
"description": "Number of UNKNOWN entries",
"type": "integer"
},
"total": {
"default": 0,
"description": "Total number of entries",
"type": "integer"
},
"warnings": {
"description": "Warnings raised while building this summary.",
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
},
{
"type": "null"
}
],
"default": null,
"description": "Applied audience: actors pinned to the requested version, by tier. `None` when no specific version was requested."
}
},
"required": [
"connector_definition_id",
"docker_repository",
"customer_tier_filter",
"active",
"pinned_any",
"eligible"
],
"type": "object"
}
query_connector_version_health_summary
Hints: read-only · idempotent · open-world
Summarize actor health for a connector version into four buckets.
Answers "how many actors on a version are healthy / unhealthy / awaiting / disabled". Classification per actor over the lookback window:
healthy: at least one successful sync (the same success signal the autopilot health gate uses).unhealthy: failures and no successes.awaiting: ran but produced only non-terminal jobs (no result yet).disabled: (wheninclude_pinned_disabled) pinned to the version with no jobs at all in the window — the dormant/inactive audience.
Built on the attempt/version primitive — the version stamped into
jobs.config at job-creation time — not the current pin state, so it
reflects actors that actually ran this version. This scans jobs over the
window and is more expensive than the population summary; keep days
bounded and query per-version.
Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
connector_version_id |
string | null |
no | null |
Connector version UUID. Provide this OR connector_name + connector_version. |
connector_name |
string | null |
no | null |
Canonical connector name (e.g. source-postgres). Used with connector_version to resolve the version UUID. |
connector_version |
string | null |
no | null |
Semver version tag (e.g. 0.3.59). Used with connector_name. |
days |
integer |
no | 7 |
Number of days to look back (default: 7, max: 30) |
include_pinned_disabled |
boolean |
no | true |
If True (default), actors pinned to the version that ran no jobs in the window are counted as disabled. |
customer_tier_filter |
enum("TIER_0", "TIER_1", "TIER_2", "UNKNOWN", "ALL") |
no | "TIER_2" |
Which customer tiers to count. Defaults to TIER_2; pass ALL to include TIER_0/TIER_1 (revenue-critical) customers. |
Show input JSON schema
{
"additionalProperties": false,
"properties": {
"connector_version_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Connector version UUID. Provide this OR `connector_name` + `connector_version`."
},
"connector_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Canonical connector name (e.g. `source-postgres`). Used with `connector_version` to resolve the version UUID."
},
"connector_version": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Semver version tag (e.g. `0.3.59`). Used with `connector_name`."
},
"days": {
"default": 7,
"description": "Number of days to look back (default: 7, max: 30)",
"maximum": 30,
"minimum": 1,
"type": "integer"
},
"include_pinned_disabled": {
"default": true,
"description": "If `True` (default), actors pinned to the version that ran no jobs in the window are counted as `disabled`.",
"type": "boolean"
},
"customer_tier_filter": {
"default": "TIER_2",
"description": "Which customer tiers to count. Defaults to `TIER_2`; pass `ALL` to include TIER_0/TIER_1 (revenue-critical) customers.",
"enum": [
"TIER_0",
"TIER_1",
"TIER_2",
"UNKNOWN",
"ALL"
],
"type": "string"
}
},
"type": "object"
}
Show output JSON schema
{
"description": "Four-bucket health rollup for the actors running a connector version.",
"properties": {
"connector_version_id": {
"description": "The connector version UUID",
"type": "string"
},
"connector_definition_id": {
"description": "The connector definition UUID",
"type": "string"
},
"docker_repository": {
"description": "Docker repository path",
"type": "string"
},
"docker_image_tag": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Docker image tag for this version"
},
"days": {
"description": "Lookback window in days",
"type": "integer"
},
"customer_tier_filter": {
"description": "Tier filter applied to the counts (`TIER_0`/`TIER_1`/`TIER_2`/`UNKNOWN`/`ALL`)",
"type": "string"
},
"healthy": {
"description": "Actors with at least one successful sync",
"type": "integer"
},
"unhealthy": {
"description": "Actors with failures and no successes in the window",
"type": "integer"
},
"awaiting": {
"description": "Actors that ran but produced only non-terminal jobs (no result yet)",
"type": "integer"
},
"disabled": {
"description": "Actors pinned to the version that produced no jobs in the window \u2014 the dormant/inactive audience",
"type": "integer"
},
"total_actors": {
"description": "Total actors counted across all states",
"type": "integer"
},
"healthy_by_tier": {
"description": "Healthy actors by tier",
"properties": {
"tier_0_count": {
"default": 0,
"description": "Number of TIER_0 entries",
"type": "integer"
},
"tier_1_count": {
"default": 0,
"description": "Number of TIER_1 entries",
"type": "integer"
},
"tier_2_count": {
"default": 0,
"description": "Number of TIER_2 entries",
"type": "integer"
},
"unknown_count": {
"default": 0,
"description": "Number of UNKNOWN entries",
"type": "integer"
},
"total": {
"default": 0,
"description": "Total number of entries",
"type": "integer"
},
"warnings": {
"description": "Warnings raised while building this summary.",
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
},
"unhealthy_by_tier": {
"description": "Unhealthy actors by tier",
"properties": {
"tier_0_count": {
"default": 0,
"description": "Number of TIER_0 entries",
"type": "integer"
},
"tier_1_count": {
"default": 0,
"description": "Number of TIER_1 entries",
"type": "integer"
},
"tier_2_count": {
"default": 0,
"description": "Number of TIER_2 entries",
"type": "integer"
},
"unknown_count": {
"default": 0,
"description": "Number of UNKNOWN entries",
"type": "integer"
},
"total": {
"default": 0,
"description": "Total number of entries",
"type": "integer"
},
"warnings": {
"description": "Warnings raised while building this summary.",
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
},
"awaiting_by_tier": {
"description": "Awaiting-results actors by tier",
"properties": {
"tier_0_count": {
"default": 0,
"description": "Number of TIER_0 entries",
"type": "integer"
},
"tier_1_count": {
"default": 0,
"description": "Number of TIER_1 entries",
"type": "integer"
},
"tier_2_count": {
"default": 0,
"description": "Number of TIER_2 entries",
"type": "integer"
},
"unknown_count": {
"default": 0,
"description": "Number of UNKNOWN entries",
"type": "integer"
},
"total": {
"default": 0,
"description": "Total number of entries",
"type": "integer"
},
"warnings": {
"description": "Warnings raised while building this summary.",
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
},
"disabled_by_tier": {
"description": "Disabled actors by tier",
"properties": {
"tier_0_count": {
"default": 0,
"description": "Number of TIER_0 entries",
"type": "integer"
},
"tier_1_count": {
"default": 0,
"description": "Number of TIER_1 entries",
"type": "integer"
},
"tier_2_count": {
"default": 0,
"description": "Number of TIER_2 entries",
"type": "integer"
},
"unknown_count": {
"default": 0,
"description": "Number of UNKNOWN entries",
"type": "integer"
},
"total": {
"default": 0,
"description": "Total number of entries",
"type": "integer"
},
"warnings": {
"description": "Warnings raised while building this summary.",
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
}
},
"required": [
"connector_version_id",
"connector_definition_id",
"docker_repository",
"days",
"customer_tier_filter",
"healthy",
"unhealthy",
"awaiting",
"disabled",
"total_actors",
"healthy_by_tier",
"unhealthy_by_tier",
"awaiting_by_tier",
"disabled_by_tier"
],
"type": "object"
}
query_prod_actors_by_pinned_connector_version
Hints: read-only · idempotent
List actors (sources/destinations) effectively pinned to a specific connector version.
Returns all actors that are effectively pinned to a specific connector version, considering all scope levels: actor-level pins, workspace-level pins, and organization-level pins (with actor > workspace > organization precedence). Useful for monitoring rollouts and understanding which customers are affected.
The actor_id field is the actor ID (superset of source_id/destination_id).
Returns list of dicts with keys: actor_id, connector_definition_id, origin_type, origin, description, created_at, expires_at, pin_scope_type, actor_name, workspace_id, workspace_name, organization_id, dataplane_group_id, dataplane_name
pin_scope_type is 'actor', 'workspace', or 'organization' indicating which scope level the effective pin came from.
Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
connector_version_id |
string |
yes | — | Connector version UUID to find pinned instances for |
Show input JSON schema
{
"additionalProperties": false,
"properties": {
"connector_version_id": {
"description": "Connector version UUID to find pinned instances for",
"type": "string"
}
},
"required": [
"connector_version_id"
],
"type": "object"
}
Show output JSON schema
{
"properties": {
"result": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
}
},
"required": [
"result"
],
"type": "object",
"x-fastmcp-wrap-result": true
}
query_prod_connection_sync_activity
Hints: read-only · idempotent · open-world
List recent sync jobs and attempts from the Prod DB Replica.
Returns one row per (job, attempt) pair for sync jobs whose updated_at
falls in [start_at, end_at), scoped to the provided organization,
workspace, or connection IDs. Designed for live operational lookups —
e.g. "what happened on this connection in the last hour" — not for
historical analysis.
Each row is enriched with customer_tier and is_eu for the owning
organization. Tier filtering is intentionally not applied — this is a
read-only observability query.
Input requirements:
- At least one of
organization_id,workspace_id, orconnection_idsmust be provided (any combination is accepted). start_atandend_atmust be timezone-aware andstart_at < end_at.
Key fields in each row:
job_id,attempt_id,attempt_numberjob_status,attempt_statusjob_started_at,job_updated_at,attempt_ended_atfailure_summary(JSON; populated when an attempt failed)connection_id,connection_name,connection_statussource_actor_id,source_actor_name,source_actor_definition_iddestination_actor_id,destination_actor_name,destination_actor_definition_idworkspace_id,workspace_name,organization_iddataplane_group_id,dataplane_namecustomer_tier,is_eu(added by tier enrichment)
Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
start_at |
string |
yes | — | Inclusive start timestamp for the sync activity window. Must be timezone-aware (ISO 8601 with offset or Z). |
end_at |
string |
yes | — | Exclusive end timestamp for the sync activity window. Must be timezone-aware and strictly after start_at. |
organization_id |
string | enum("664c690e-5263-49ba-b01f-4a6759b3330a") | null |
no | null |
Optional organization UUID or alias. At least one of organization_id, workspace_id, or connection_ids is required. Accepts @airbyte-internal as an alias for the Airbyte internal org. |
workspace_id |
string | enum("266ebdfe-0d7b-4540-9817-de7e4505ba61") | null |
no | null |
Optional workspace UUID or alias. At least one of organization_id, workspace_id, or connection_ids is required. Accepts @devin-ai-sandbox as an alias for the Devin AI sandbox workspace. |
connection_ids |
array<string> | null |
no | null |
Optional list of connection UUIDs. At least one of organization_id, workspace_id, or connection_ids is required. |
status_filter |
enum("all", "succeeded", "failed") |
no | "all" |
Filter by job status: all (default), succeeded, or failed. Applied to jobs.status in the Prod DB Replica. |
limit |
integer |
no | 1000 |
Maximum number of attempt rows to return. |
Show input JSON schema
{
"additionalProperties": false,
"properties": {
"start_at": {
"description": "Inclusive start timestamp for the sync activity window. Must be timezone-aware (ISO 8601 with offset or `Z`).",
"format": "date-time",
"type": "string"
},
"end_at": {
"description": "Exclusive end timestamp for the sync activity window. Must be timezone-aware and strictly after `start_at`.",
"format": "date-time",
"type": "string"
},
"organization_id": {
"anyOf": [
{
"type": "string"
},
{
"description": "Organization ID aliases that can be used in place of UUIDs.\n\nEach member's name is the alias (e.g., \"@airbyte-internal\") and its value\nis the actual organization UUID. Use `OrganizationAliasEnum.resolve()` to\nresolve aliases to actual IDs.",
"enum": [
"664c690e-5263-49ba-b01f-4a6759b3330a"
],
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Optional organization UUID or alias. At least one of `organization_id`, `workspace_id`, or `connection_ids` is required. Accepts `@airbyte-internal` as an alias for the Airbyte internal org."
},
"workspace_id": {
"anyOf": [
{
"type": "string"
},
{
"description": "Workspace ID aliases that can be used in place of UUIDs.\n\nEach member's name is the alias (e.g., \"@devin-ai-sandbox\") and its value\nis the actual workspace UUID. Use `WorkspaceAliasEnum.resolve()` to\nresolve aliases to actual IDs.",
"enum": [
"266ebdfe-0d7b-4540-9817-de7e4505ba61"
],
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Optional workspace UUID or alias. At least one of `organization_id`, `workspace_id`, or `connection_ids` is required. Accepts `@devin-ai-sandbox` as an alias for the Devin AI sandbox workspace."
},
"connection_ids": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Optional list of connection UUIDs. At least one of `organization_id`, `workspace_id`, or `connection_ids` is required."
},
"status_filter": {
"description": "Filter by job status: `all` (default), `succeeded`, or `failed`. Applied to `jobs.status` in the Prod DB Replica.",
"enum": [
"all",
"succeeded",
"failed"
],
"type": "string",
"default": "all"
},
"limit": {
"default": 1000,
"description": "Maximum number of attempt rows to return.",
"type": "integer"
}
},
"required": [
"start_at",
"end_at"
],
"type": "object"
}
Show output JSON schema
{
"properties": {
"result": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
}
},
"required": [
"result"
],
"type": "object",
"x-fastmcp-wrap-result": true
}
query_prod_connections_by_connector
Hints: read-only · idempotent · open-world
Search for all connections using a specific source or destination connector type.
This tool queries the Airbyte Cloud Prod DB Replica directly for fast results. It finds all connections where the source or destination connector matches the specified type, regardless of how the connector is named by users.
Results are always enriched with customer_tier and is_eu fields. The customer_tier_filter parameter is required to ensure tier-aware querying.
Optionally filter by organization_id to limit results to a specific organization. Use '@airbyte-internal' as an alias for the Airbyte internal organization.
Set exclude_pinned=True to filter out connections that are already pinned to a
specific version. This is useful for 'prove fix' live connection testing workflows
where you want to find unpinned connections to test against.
Set enabled_schedules_only=True to restrict results to connections that are both
enabled (status='active') and on an automated schedule (not manual-trigger-only).
This is useful for canary prerelease workflows where you need connections that
will run organically during the monitoring window.
Returns a list of connection dicts with workspace context and clickable Cloud UI URLs. For source queries, returns: connection_id, connection_name, connection_url, source_id, source_name, source_definition_id, workspace_id, workspace_name, organization_id, dataplane_group_id, dataplane_name, pin_origin_type, pin_origin, pinned_version_id, pin_scope_type, customer_tier, is_eu. For destination queries, returns: connection_id, connection_name, connection_url, destination_id, destination_name, destination_definition_id, workspace_id, workspace_name, organization_id, dataplane_group_id, dataplane_name, pin_origin_type, pin_origin, pinned_version_id, pin_scope_type, customer_tier, is_eu.
pin_scope_type is 'actor', 'workspace', or 'organization' indicating which scope level the effective pin came from (NULL if not pinned).
Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
source_definition_id |
string | null |
no | null |
Source connector definition ID (UUID) to search for. Exactly one of source_definition_id, source_canonical_name, destination_definition_id, or destination_canonical_name is required. Example: 'afa734e4-3571-11ec-991a-1e0031268139' for YouTube Analytics. |
source_canonical_name |
string | null |
no | null |
Canonical source connector name to search for. Exactly one of source_definition_id, source_canonical_name, destination_definition_id, or destination_canonical_name is required. Examples: 'source-youtube-analytics', 'YouTube Analytics'. |
destination_definition_id |
string | null |
no | null |
Destination connector definition ID (UUID) to search for. Exactly one of source_definition_id, source_canonical_name, destination_definition_id, or destination_canonical_name is required. Example: 'e5c8e66c-a480-4a5e-9c0e-e8e5e4c5c5c5' for DuckDB. |
destination_canonical_name |
string | null |
no | null |
Canonical destination connector name to search for. Exactly one of source_definition_id, source_canonical_name, destination_definition_id, or destination_canonical_name is required. Examples: 'destination-duckdb', 'DuckDB'. |
organization_id |
string | enum("664c690e-5263-49ba-b01f-4a6759b3330a") | null |
no | null |
Optional organization ID (UUID) or alias to filter results. If provided, only connections in this organization will be returned. Accepts '@airbyte-internal' as an alias for the Airbyte internal org. |
limit |
integer |
no | 1000 |
Maximum number of results (default: 1000) |
customer_tier_filter |
enum("TIER_0", "TIER_1", "TIER_2", "UNKNOWN", "ALL") |
no | "TIER_2" |
Required tier filter: 'TIER_0', 'TIER_1', 'TIER_2', 'UNKNOWN', or 'ALL'. Filters results to only include connections belonging to organizations in the specified tier. Use 'ALL' to include all tiers. |
exclude_pinned |
boolean |
no | false |
If True, exclude connections whose connector is already pinned to a specific version (at any scope level: actor, workspace, or organization). Useful for 'prove fix' workflows where you want to find unpinned connections for live testing. Default: False (include all connections). |
enabled_schedules_only |
boolean |
no | false |
If True, only return connections that are both active (not paused/inactive) and on an automated sync schedule (not manual-trigger-only). Useful for canary workflows where you need connections that will produce organic syncs during a monitoring window. Default: False (include all connections). |
Show input JSON schema
{
"additionalProperties": false,
"properties": {
"source_definition_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Source connector definition ID (UUID) to search for. Exactly one of source_definition_id, source_canonical_name, destination_definition_id, or destination_canonical_name is required. Example: 'afa734e4-3571-11ec-991a-1e0031268139' for YouTube Analytics."
},
"source_canonical_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Canonical source connector name to search for. Exactly one of source_definition_id, source_canonical_name, destination_definition_id, or destination_canonical_name is required. Examples: 'source-youtube-analytics', 'YouTube Analytics'."
},
"destination_definition_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Destination connector definition ID (UUID) to search for. Exactly one of source_definition_id, source_canonical_name, destination_definition_id, or destination_canonical_name is required. Example: 'e5c8e66c-a480-4a5e-9c0e-e8e5e4c5c5c5' for DuckDB."
},
"destination_canonical_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Canonical destination connector name to search for. Exactly one of source_definition_id, source_canonical_name, destination_definition_id, or destination_canonical_name is required. Examples: 'destination-duckdb', 'DuckDB'."
},
"organization_id": {
"anyOf": [
{
"type": "string"
},
{
"description": "Organization ID aliases that can be used in place of UUIDs.\n\nEach member's name is the alias (e.g., \"@airbyte-internal\") and its value\nis the actual organization UUID. Use `OrganizationAliasEnum.resolve()` to\nresolve aliases to actual IDs.",
"enum": [
"664c690e-5263-49ba-b01f-4a6759b3330a"
],
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Optional organization ID (UUID) or alias to filter results. If provided, only connections in this organization will be returned. Accepts '@airbyte-internal' as an alias for the Airbyte internal org."
},
"limit": {
"default": 1000,
"description": "Maximum number of results (default: 1000)",
"type": "integer"
},
"customer_tier_filter": {
"default": "TIER_2",
"description": "Required tier filter: 'TIER_0', 'TIER_1', 'TIER_2', 'UNKNOWN', or 'ALL'. Filters results to only include connections belonging to organizations in the specified tier. Use 'ALL' to include all tiers.",
"enum": [
"TIER_0",
"TIER_1",
"TIER_2",
"UNKNOWN",
"ALL"
],
"type": "string"
},
"exclude_pinned": {
"default": false,
"description": "If True, exclude connections whose connector is already pinned to a specific version (at any scope level: actor, workspace, or organization). Useful for 'prove fix' workflows where you want to find unpinned connections for live testing. Default: False (include all connections).",
"type": "boolean"
},
"enabled_schedules_only": {
"default": false,
"description": "If True, only return connections that are both active (not paused/inactive) and on an automated sync schedule (not manual-trigger-only). Useful for canary workflows where you need connections that will produce organic syncs during a monitoring window. Default: False (include all connections).",
"type": "boolean"
}
},
"type": "object"
}
Show output JSON schema
{
"properties": {
"result": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
}
},
"required": [
"result"
],
"type": "object",
"x-fastmcp-wrap-result": true
}
query_prod_connections_by_stream
Hints: read-only · idempotent · open-world
Find connections that have a specific stream enabled in their catalog.
This tool searches the connection's configured catalog (JSONB) for streams matching the specified name. It's particularly useful when validating connector fixes that affect specific streams - you can quickly find customer connections that use the affected stream.
Results are always enriched with customer_tier and is_eu fields. The customer_tier_filter parameter is required to ensure tier-aware querying.
Use cases:
- Finding connections with a specific stream enabled for regression testing
- Validating connector fixes that affect particular streams
- Identifying which customers use rarely-enabled streams
Returns a list of connection dicts with workspace context and clickable Cloud UI URLs.
Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
stream_name |
string |
yes | — | Name of the stream to search for in connection catalogs. This must match the exact stream name as configured in the connection. Examples: 'global_exclusions', 'campaigns', 'users'. |
source_definition_id |
string | null |
no | null |
Source connector definition ID (UUID) to search for. Provide this OR source_canonical_name (exactly one required). Example: 'afa734e4-3571-11ec-991a-1e0031268139' for YouTube Analytics. |
source_canonical_name |
string | null |
no | null |
Canonical source connector name to search for. Provide this OR source_definition_id (exactly one required). Examples: 'source-klaviyo', 'Klaviyo', 'source-youtube-analytics'. |
organization_id |
string | enum("664c690e-5263-49ba-b01f-4a6759b3330a") | null |
no | null |
Optional organization ID (UUID) or alias to filter results. If provided, only connections in this organization will be returned. Accepts '@airbyte-internal' as an alias for the Airbyte internal org. |
limit |
integer |
no | 100 |
Maximum number of results (default: 100) |
customer_tier_filter |
enum("TIER_0", "TIER_1", "TIER_2", "UNKNOWN", "ALL") |
no | "TIER_2" |
Required tier filter: 'TIER_0', 'TIER_1', 'TIER_2', 'UNKNOWN', or 'ALL'. Filters results to only include connections belonging to organizations in the specified tier. Use 'ALL' to include all tiers. |
Show input JSON schema
{
"additionalProperties": false,
"properties": {
"stream_name": {
"description": "Name of the stream to search for in connection catalogs. This must match the exact stream name as configured in the connection. Examples: 'global_exclusions', 'campaigns', 'users'.",
"type": "string"
},
"source_definition_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Source connector definition ID (UUID) to search for. Provide this OR source_canonical_name (exactly one required). Example: 'afa734e4-3571-11ec-991a-1e0031268139' for YouTube Analytics."
},
"source_canonical_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Canonical source connector name to search for. Provide this OR source_definition_id (exactly one required). Examples: 'source-klaviyo', 'Klaviyo', 'source-youtube-analytics'."
},
"organization_id": {
"anyOf": [
{
"type": "string"
},
{
"description": "Organization ID aliases that can be used in place of UUIDs.\n\nEach member's name is the alias (e.g., \"@airbyte-internal\") and its value\nis the actual organization UUID. Use `OrganizationAliasEnum.resolve()` to\nresolve aliases to actual IDs.",
"enum": [
"664c690e-5263-49ba-b01f-4a6759b3330a"
],
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Optional organization ID (UUID) or alias to filter results. If provided, only connections in this organization will be returned. Accepts '@airbyte-internal' as an alias for the Airbyte internal org."
},
"limit": {
"default": 100,
"description": "Maximum number of results (default: 100)",
"type": "integer"
},
"customer_tier_filter": {
"default": "TIER_2",
"description": "Required tier filter: 'TIER_0', 'TIER_1', 'TIER_2', 'UNKNOWN', or 'ALL'. Filters results to only include connections belonging to organizations in the specified tier. Use 'ALL' to include all tiers.",
"enum": [
"TIER_0",
"TIER_1",
"TIER_2",
"UNKNOWN",
"ALL"
],
"type": "string"
}
},
"required": [
"stream_name"
],
"type": "object"
}
Show output JSON schema
{
"properties": {
"result": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
}
},
"required": [
"result"
],
"type": "object",
"x-fastmcp-wrap-result": true
}
query_prod_connector_connection_stats
Hints: read-only · idempotent · open-world
Get aggregate connection stats for multiple connectors.
Returns counts of connections grouped by pinned version for each connector, including:
- Total, enabled, and active connection counts
- Pinned vs unpinned breakdown
- Latest attempt status breakdown (succeeded, failed, cancelled, running, unknown)
This tool is designed for release monitoring workflows. It allows you to:
- Query recently released connectors to identify which ones to monitor
- Get aggregate stats showing how many connections are using each version
- See health metrics (pass/fail) broken down by version
The lookback_days parameter controls the lookback window for:
- Counting 'active' connections (those with recent sync activity)
- Determining 'latest attempt status' (most recent attempt within the window)
Connections with no sync activity in the lookback window will have 'unknown' status in the latest_attempt breakdown.
Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
source_definition_ids |
array<string> | null |
no | null |
List of source connector definition IDs (UUIDs) to get stats for. Example: ['afa734e4-3571-11ec-991a-1e0031268139'] |
destination_definition_ids |
array<string> | null |
no | null |
List of destination connector definition IDs (UUIDs) to get stats for. Example: ['94bd199c-2ff0-4aa2-b98e-17f0acb72610'] |
lookback_days |
integer |
no | 7 |
Number of days to look back for 'active' connections (default: 7). Connections with sync activity within this window are counted as active. |
Show input JSON schema
{
"additionalProperties": false,
"properties": {
"source_definition_ids": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "List of source connector definition IDs (UUIDs) to get stats for. Example: ['afa734e4-3571-11ec-991a-1e0031268139']"
},
"destination_definition_ids": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "List of destination connector definition IDs (UUIDs) to get stats for. Example: ['94bd199c-2ff0-4aa2-b98e-17f0acb72610']"
},
"lookback_days": {
"default": 7,
"description": "Number of days to look back for 'active' connections (default: 7). Connections with sync activity within this window are counted as active.",
"type": "integer"
}
},
"type": "object"
}
Show output JSON schema
{
"description": "Response containing connection stats for multiple connectors.",
"properties": {
"sources": {
"description": "Stats for source connectors",
"items": {
"description": "Aggregate connection stats for a connector.",
"properties": {
"connector_definition_id": {
"description": "The connector definition UUID",
"type": "string"
},
"connector_type": {
"description": "'source' or 'destination'",
"type": "string"
},
"canonical_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The canonical connector name if resolved"
},
"total_connections": {
"description": "Total number of non-deprecated connections",
"type": "integer"
},
"enabled_connections": {
"description": "Number of enabled (active status) connections",
"type": "integer"
},
"active_connections": {
"description": "Number of connections with recent sync activity",
"type": "integer"
},
"pinned_connections": {
"description": "Number of connections with explicit version pins",
"type": "integer"
},
"unpinned_connections": {
"description": "Number of connections on default version",
"type": "integer"
},
"latest_attempt": {
"description": "Overall breakdown by latest attempt status",
"properties": {
"succeeded": {
"default": 0,
"description": "Connections where latest attempt succeeded",
"type": "integer"
},
"failed": {
"default": 0,
"description": "Connections where latest attempt failed",
"type": "integer"
},
"cancelled": {
"default": 0,
"description": "Connections where latest attempt was cancelled",
"type": "integer"
},
"running": {
"default": 0,
"description": "Connections where latest attempt is still running",
"type": "integer"
},
"unknown": {
"default": 0,
"description": "Connections with no recent attempts in the lookback window",
"type": "integer"
}
},
"type": "object"
},
"by_version": {
"description": "Stats broken down by pinned version",
"items": {
"description": "Stats for connections pinned to a specific version.",
"properties": {
"pinned_version_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "The connector version UUID (None for unpinned connections)"
},
"docker_image_tag": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The docker image tag for this version"
},
"total_connections": {
"description": "Total number of connections",
"type": "integer"
},
"enabled_connections": {
"description": "Number of enabled (active status) connections",
"type": "integer"
},
"active_connections": {
"description": "Number of connections with recent sync activity",
"type": "integer"
},
"latest_attempt": {
"description": "Breakdown by latest attempt status",
"properties": {
"succeeded": {
"default": 0,
"description": "Connections where latest attempt succeeded",
"type": "integer"
},
"failed": {
"default": 0,
"description": "Connections where latest attempt failed",
"type": "integer"
},
"cancelled": {
"default": 0,
"description": "Connections where latest attempt was cancelled",
"type": "integer"
},
"running": {
"default": 0,
"description": "Connections where latest attempt is still running",
"type": "integer"
},
"unknown": {
"default": 0,
"description": "Connections with no recent attempts in the lookback window",
"type": "integer"
}
},
"type": "object"
}
},
"required": [
"pinned_version_id",
"total_connections",
"enabled_connections",
"active_connections",
"latest_attempt"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"connector_definition_id",
"connector_type",
"total_connections",
"enabled_connections",
"active_connections",
"pinned_connections",
"unpinned_connections",
"latest_attempt",
"by_version"
],
"type": "object"
},
"type": "array"
},
"destinations": {
"description": "Stats for destination connectors",
"items": {
"description": "Aggregate connection stats for a connector.",
"properties": {
"connector_definition_id": {
"description": "The connector definition UUID",
"type": "string"
},
"connector_type": {
"description": "'source' or 'destination'",
"type": "string"
},
"canonical_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The canonical connector name if resolved"
},
"total_connections": {
"description": "Total number of non-deprecated connections",
"type": "integer"
},
"enabled_connections": {
"description": "Number of enabled (active status) connections",
"type": "integer"
},
"active_connections": {
"description": "Number of connections with recent sync activity",
"type": "integer"
},
"pinned_connections": {
"description": "Number of connections with explicit version pins",
"type": "integer"
},
"unpinned_connections": {
"description": "Number of connections on default version",
"type": "integer"
},
"latest_attempt": {
"description": "Overall breakdown by latest attempt status",
"properties": {
"succeeded": {
"default": 0,
"description": "Connections where latest attempt succeeded",
"type": "integer"
},
"failed": {
"default": 0,
"description": "Connections where latest attempt failed",
"type": "integer"
},
"cancelled": {
"default": 0,
"description": "Connections where latest attempt was cancelled",
"type": "integer"
},
"running": {
"default": 0,
"description": "Connections where latest attempt is still running",
"type": "integer"
},
"unknown": {
"default": 0,
"description": "Connections with no recent attempts in the lookback window",
"type": "integer"
}
},
"type": "object"
},
"by_version": {
"description": "Stats broken down by pinned version",
"items": {
"description": "Stats for connections pinned to a specific version.",
"properties": {
"pinned_version_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "The connector version UUID (None for unpinned connections)"
},
"docker_image_tag": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The docker image tag for this version"
},
"total_connections": {
"description": "Total number of connections",
"type": "integer"
},
"enabled_connections": {
"description": "Number of enabled (active status) connections",
"type": "integer"
},
"active_connections": {
"description": "Number of connections with recent sync activity",
"type": "integer"
},
"latest_attempt": {
"description": "Breakdown by latest attempt status",
"properties": {
"succeeded": {
"default": 0,
"description": "Connections where latest attempt succeeded",
"type": "integer"
},
"failed": {
"default": 0,
"description": "Connections where latest attempt failed",
"type": "integer"
},
"cancelled": {
"default": 0,
"description": "Connections where latest attempt was cancelled",
"type": "integer"
},
"running": {
"default": 0,
"description": "Connections where latest attempt is still running",
"type": "integer"
},
"unknown": {
"default": 0,
"description": "Connections with no recent attempts in the lookback window",
"type": "integer"
}
},
"type": "object"
}
},
"required": [
"pinned_version_id",
"total_connections",
"enabled_connections",
"active_connections",
"latest_attempt"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"connector_definition_id",
"connector_type",
"total_connections",
"enabled_connections",
"active_connections",
"pinned_connections",
"unpinned_connections",
"latest_attempt",
"by_version"
],
"type": "object"
},
"type": "array"
},
"lookback_days": {
"description": "Lookback window used for 'active' connections",
"type": "integer"
},
"generated_at": {
"description": "When this response was generated",
"format": "date-time",
"type": "string"
}
},
"required": [
"lookback_days",
"generated_at"
],
"type": "object"
}
query_prod_connector_rollouts
Hints: read-only · idempotent
Query connector rollouts with flexible filtering.
Returns rollouts based on the provided filters. If no filters are specified, returns all active rollouts. Useful for monitoring rollout status and history.
Filter behavior:
- rollout_id: Returns that specific rollout (ignores other filters)
- active_only: Returns only active (non-terminal) rollouts
- actor_definition_id: Returns rollouts for that specific connector
- No filters: Returns all active rollouts (same as active_only=True)
Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
actor_definition_id |
string | null |
no | null |
Connector definition UUID to filter by (optional) |
rollout_id |
string | null |
no | null |
Specific rollout UUID to look up (optional) |
active_only |
boolean |
no | false |
If true, only return active (non-terminal) rollouts |
limit |
integer |
no | 100 |
Maximum number of results (default: 100) |
Show input JSON schema
{
"additionalProperties": false,
"properties": {
"actor_definition_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Connector definition UUID to filter by (optional)"
},
"rollout_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Specific rollout UUID to look up (optional)"
},
"active_only": {
"default": false,
"description": "If true, only return active (non-terminal) rollouts",
"type": "boolean"
},
"limit": {
"default": 100,
"description": "Maximum number of results (default: 100)",
"type": "integer"
}
},
"type": "object"
}
Show output JSON schema
{
"properties": {
"result": {
"items": {
"description": "Information about a connector rollout.",
"properties": {
"rollout_id": {
"description": "The rollout UUID",
"type": "string"
},
"actor_definition_id": {
"description": "The connector definition UUID",
"type": "string"
},
"state": {
"description": "Rollout state: initialized, workflow_started, in_progress, paused, finalizing, succeeded, errored, failed_rolled_back, canceled",
"type": "string"
},
"initial_rollout_pct": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"description": "Initial rollout percentage"
},
"current_target_rollout_pct": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"description": "Current target rollout percentage"
},
"final_target_rollout_pct": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"description": "Final target rollout percentage"
},
"has_breaking_changes": {
"description": "Whether the RC has breaking changes",
"type": "boolean"
},
"max_step_wait_time_mins": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"description": "Maximum wait time between rollout steps in minutes"
},
"rollout_strategy": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Rollout strategy: manual, automated, overridden"
},
"updated_by_user_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "User ID recorded as last updating the rollout"
},
"updated_by_user_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Name recorded as last updating the rollout"
},
"updated_by_user_email": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Email recorded as last updating the rollout"
},
"workflow_run_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Temporal workflow run ID"
},
"error_msg": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Error message if errored"
},
"failed_reason": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Reason for failure if failed"
},
"paused_reason": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Reason for pause if paused"
},
"tag": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Optional tag for the rollout"
},
"created_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the rollout was created"
},
"updated_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the rollout was last updated"
},
"completed_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the rollout completed (if terminal)"
},
"expires_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the rollout expires"
},
"rc_docker_image_tag": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Docker image tag of the release candidate"
},
"rc_docker_repository": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Docker repository of the release candidate"
},
"initial_docker_image_tag": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Docker image tag of the initial version"
},
"initial_docker_repository": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Docker repository of the initial version"
},
"filters": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null,
"description": "Raw rollout filters JSON (e.g., {'tierFilter': {'tier': 'TIER_0'}})"
},
"customer_tier": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Customer tier targeted by this rollout (extracted from filters), e.g., 'TIER_0', 'TIER_1'. None if no tier filter is set."
}
},
"required": [
"rollout_id",
"actor_definition_id",
"state",
"has_breaking_changes"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"result"
],
"type": "object",
"x-fastmcp-wrap-result": true
}
query_prod_connector_versions
Hints: read-only · idempotent
List all versions for a connector definition.
Returns all published versions of a connector, ordered by last_published date descending. Useful for understanding version history and finding specific version IDs for pinning or rollout monitoring.
Returns list of dicts with keys: version_id, docker_image_tag, docker_repository, release_stage, support_level, cdk_version, language, last_published, release_date
Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
connector_definition_id |
string |
yes | — | Connector definition UUID to list versions for |
Show input JSON schema
{
"additionalProperties": false,
"properties": {
"connector_definition_id": {
"description": "Connector definition UUID to list versions for",
"type": "string"
}
},
"required": [
"connector_definition_id"
],
"type": "object"
}
Show output JSON schema
{
"properties": {
"result": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
}
},
"required": [
"result"
],
"type": "object",
"x-fastmcp-wrap-result": true
}
query_prod_dataplanes
Hints: read-only · idempotent
List all dataplane groups with workspace counts.
Returns information about all active dataplane groups in Airbyte Cloud, including the number of workspaces in each. Useful for understanding the distribution of workspaces across regions (US, US-Central, EU).
Returns list of dicts with keys: dataplane_group_id, dataplane_name, organization_id, enabled, tombstone, created_at, workspace_count
Parameters:
_No parameters._
Show input JSON schema
{
"additionalProperties": false,
"properties": {},
"type": "object"
}
Show output JSON schema
{
"properties": {
"result": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
}
},
"required": [
"result"
],
"type": "object",
"x-fastmcp-wrap-result": true
}
query_prod_failed_sync_attempts_for_connector
Hints: read-only · idempotent · open-world
List failed sync attempts for ALL actors using a source connector type.
This tool finds all actors with the given connector definition and returns their failed sync attempts, regardless of whether they have explicit version pins.
Results are always enriched with customer_tier and is_eu fields. The customer_tier_filter parameter is required to ensure tier-aware querying.
This is useful for investigating connector issues across all users. Use this when you want to find failures for a connector type regardless of which version users are on.
Note: This tool only supports SOURCE connectors. For destination connectors, a separate tool would be needed.
Key fields in results:
- failure_summary: JSON containing failure details including failureType and messages
- customer_tier: TIER_0, TIER_1, TIER_2, or UNKNOWN
- is_eu: Whether the workspace is in the EU region
- pin_origin_type, pin_origin, pinned_version_id: Version pin context (NULL if not pinned)
- pin_scope_type: 'actor', 'workspace', or 'organization' (NULL if not pinned)
Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
source_definition_id |
string | null |
no | null |
Source connector definition ID (UUID) to search for. Exactly one of this or source_canonical_name is required. Example: 'afa734e4-3571-11ec-991a-1e0031268139' for YouTube Analytics. |
source_canonical_name |
string | null |
no | null |
Canonical source connector name to search for. Exactly one of this or source_definition_id is required. Examples: 'source-youtube-analytics', 'YouTube Analytics'. |
organization_id |
string | enum("664c690e-5263-49ba-b01f-4a6759b3330a") | null |
no | null |
Optional organization ID (UUID) or alias to filter results. If provided, only failed attempts from this organization will be returned. Accepts '@airbyte-internal' as an alias for the Airbyte internal org. |
lookback_days |
integer |
no | 7 |
Number of days to look back (default: 7) |
limit |
integer |
no | 100 |
Maximum number of results (default: 100) |
customer_tier_filter |
enum("TIER_0", "TIER_1", "TIER_2", "UNKNOWN", "ALL") |
no | "TIER_2" |
Required tier filter: 'TIER_0', 'TIER_1', 'TIER_2', 'UNKNOWN', or 'ALL'. Filters results to only include connections belonging to organizations in the specified tier. Use 'ALL' to include all tiers. |
Show input JSON schema
{
"additionalProperties": false,
"properties": {
"source_definition_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Source connector definition ID (UUID) to search for. Exactly one of this or source_canonical_name is required. Example: 'afa734e4-3571-11ec-991a-1e0031268139' for YouTube Analytics."
},
"source_canonical_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Canonical source connector name to search for. Exactly one of this or source_definition_id is required. Examples: 'source-youtube-analytics', 'YouTube Analytics'."
},
"organization_id": {
"anyOf": [
{
"type": "string"
},
{
"description": "Organization ID aliases that can be used in place of UUIDs.\n\nEach member's name is the alias (e.g., \"@airbyte-internal\") and its value\nis the actual organization UUID. Use `OrganizationAliasEnum.resolve()` to\nresolve aliases to actual IDs.",
"enum": [
"664c690e-5263-49ba-b01f-4a6759b3330a"
],
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Optional organization ID (UUID) or alias to filter results. If provided, only failed attempts from this organization will be returned. Accepts '@airbyte-internal' as an alias for the Airbyte internal org."
},
"lookback_days": {
"default": 7,
"description": "Number of days to look back (default: 7)",
"type": "integer"
},
"limit": {
"default": 100,
"description": "Maximum number of results (default: 100)",
"type": "integer"
},
"customer_tier_filter": {
"default": "TIER_2",
"description": "Required tier filter: 'TIER_0', 'TIER_1', 'TIER_2', 'UNKNOWN', or 'ALL'. Filters results to only include connections belonging to organizations in the specified tier. Use 'ALL' to include all tiers.",
"enum": [
"TIER_0",
"TIER_1",
"TIER_2",
"UNKNOWN",
"ALL"
],
"type": "string"
}
},
"type": "object"
}
Show output JSON schema
{
"properties": {
"result": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
}
},
"required": [
"result"
],
"type": "object",
"x-fastmcp-wrap-result": true
}
query_prod_new_connector_releases
Hints: read-only · idempotent
List recently published connector versions.
Returns connector versions published within the specified number of days. Uses last_published timestamp which reflects when the version was actually deployed to the registry (not the changelog date).
Returns list of dicts with keys: version_id, connector_definition_id, docker_repository, docker_image_tag, last_published, release_date, release_stage, support_level, cdk_version, language, created_at
Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
days |
integer |
no | 7 |
Number of days to look back (default: 7) |
limit |
integer |
no | 100 |
Maximum number of results (default: 100) |
Show input JSON schema
{
"additionalProperties": false,
"properties": {
"days": {
"default": 7,
"description": "Number of days to look back (default: 7)",
"type": "integer"
},
"limit": {
"default": 100,
"description": "Maximum number of results (default: 100)",
"type": "integer"
}
},
"type": "object"
}
Show output JSON schema
{
"properties": {
"result": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
}
},
"required": [
"result"
],
"type": "object",
"x-fastmcp-wrap-result": true
}
query_prod_organizations
Hints: read-only · idempotent
Search organizations by name or email substring.
Performs a case-insensitive substring match on organization name and email.
Use the returned organization_id values with other tools like
query_prod_connections_by_connector or lookup_customer_tiers.
Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
name_contains |
string |
yes | — | Case-insensitive substring to search for in organization name or email. For example, 'acme' will match organizations named 'Acme Corp' or with email 'admin@acme.io'. |
limit |
integer |
no | 20 |
Maximum number of organizations to return (default: 20) |
Show input JSON schema
{
"additionalProperties": false,
"properties": {
"name_contains": {
"description": "Case-insensitive substring to search for in organization name or email. For example, 'acme' will match organizations named 'Acme Corp' or with email 'admin@acme.io'.",
"type": "string"
},
"limit": {
"default": 20,
"description": "Maximum number of organizations to return (default: 20)",
"type": "integer"
}
},
"required": [
"name_contains"
],
"type": "object"
}
Show output JSON schema
{
"description": "Result of searching organizations by name substring.",
"properties": {
"name_contains": {
"description": "The search substring that was used",
"type": "string"
},
"total_found": {
"description": "Total number of organizations matching",
"type": "integer"
},
"organizations": {
"description": "List of matching organizations",
"items": {
"description": "A single organization returned by a name/email search.",
"properties": {
"organization_id": {
"description": "The organization UUID",
"type": "string"
},
"organization_name": {
"description": "The name of the organization",
"type": "string"
},
"email": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The email address associated with the organization"
},
"customer_tier": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Customer tier (TIER_0, TIER_1, TIER_2, or UNKNOWN). Enriched from the GCS tier cache."
}
},
"required": [
"organization_id",
"organization_name"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"name_contains",
"total_found",
"organizations"
],
"type": "object"
}
query_prod_pin_stats_for_organization
Hints: read-only · idempotent · open-world
Query connector versions pinned anywhere under an organization.
Returns one row per pinned version, aggregating every connector_version
pin whose scope belongs to the organization — the org itself, one of its
workspaces, or an actor within one of those workspaces (actor, workspace,
and organization scopes). Each row carries the per-scope pin breakdown, the
manual/rollout/breaking-change split, and a has_active_rollout flag.
This powers the first step of the Organization Pins view (pick an org, then
see the versions pinned under it). Use query_prod_pins_for_organization
for the individual pins behind a selected version.
Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
organization_id |
string | enum("664c690e-5263-49ba-b01f-4a6759b3330a") |
yes | — | Organization UUID (or @airbyte-internal alias) to scope pins to. Resolve organization names to an ID first via search_organizations. |
connector_definition_id |
string | null |
no | null |
Connector definition UUID to filter by (optional). Mutually exclusive with connector_canonical_name. |
connector_canonical_name |
string | null |
no | null |
Connector canonical name (e.g. source-postgres) to filter by. Resolved to a definition ID via the registry. Mutually exclusive with connector_definition_id. |
limit |
integer |
no | 1000 |
Maximum number of versions to return (default: 1000). |
Show input JSON schema
{
"additionalProperties": false,
"properties": {
"organization_id": {
"anyOf": [
{
"type": "string"
},
{
"description": "Organization ID aliases that can be used in place of UUIDs.\n\nEach member's name is the alias (e.g., \"@airbyte-internal\") and its value\nis the actual organization UUID. Use `OrganizationAliasEnum.resolve()` to\nresolve aliases to actual IDs.",
"enum": [
"664c690e-5263-49ba-b01f-4a6759b3330a"
],
"type": "string"
}
],
"description": "Organization UUID (or `@airbyte-internal` alias) to scope pins to. Resolve organization names to an ID first via `search_organizations`."
},
"connector_definition_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Connector definition UUID to filter by (optional). Mutually exclusive with `connector_canonical_name`."
},
"connector_canonical_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Connector canonical name (e.g. `source-postgres`) to filter by. Resolved to a definition ID via the registry. Mutually exclusive with `connector_definition_id`."
},
"limit": {
"default": 1000,
"description": "Maximum number of versions to return (default: 1000).",
"type": "integer"
}
},
"required": [
"organization_id"
],
"type": "object"
}
Show output JSON schema
{
"properties": {
"result": {
"items": {
"description": "A connector version pinned somewhere under an organization, with counts.",
"properties": {
"version_id": {
"description": "The actor_definition_version UUID",
"type": "string"
},
"connector_definition_id": {
"description": "The connector definition UUID",
"type": "string"
},
"connector_name": {
"description": "Human-readable connector name",
"type": "string"
},
"docker_repository": {
"description": "Docker repository path",
"type": "string"
},
"docker_image_tag": {
"description": "Docker image tag for this version",
"type": "string"
},
"last_published": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ISO timestamp when this version was last published"
},
"pin_count": {
"description": "Total pins under the org targeting this version (all scopes)",
"type": "integer"
},
"manual_pins": {
"default": 0,
"description": "Pins with no system origin (user-created manual pins), any scope",
"type": "integer"
},
"rollout_pins": {
"default": 0,
"description": "Pins created by connector rollouts",
"type": "integer"
},
"breaking_change_pins": {
"default": 0,
"description": "Pins created by breaking changes",
"type": "integer"
},
"actor_pins": {
"description": "Manual actor-scoped pins (excludes rollout and breaking-change)",
"type": "integer"
},
"workspace_pins": {
"description": "Workspace-scoped pins under the org",
"type": "integer"
},
"org_pins": {
"description": "Organization-scoped pins",
"type": "integer"
},
"has_active_rollout": {
"default": false,
"description": "`True` if at least one rollout pin is backed by a non-terminal `connector_rollout`",
"type": "boolean"
}
},
"required": [
"version_id",
"connector_definition_id",
"connector_name",
"docker_repository",
"docker_image_tag",
"pin_count",
"actor_pins",
"workspace_pins",
"org_pins"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"result"
],
"type": "object",
"x-fastmcp-wrap-result": true
}
query_prod_pins_for_organization
Hints: read-only · idempotent · open-world
List the individual connector-version pins discovered under an organization.
Returns one row per scoped_configuration pin whose scope belongs to the
organization (org/workspace/actor), resolving the pinned connector and
version, the scope's display name, the manual author's email, and — for
rollout-origin pins — the backing connector_rollout id and state. This
directly answers whether each pin is manual or caused by an active rollout.
This powers the second step of the Organization Pins view: after picking a
version from query_prod_pin_stats_for_organization, pass its
pinned_version_id here to list the pins behind it.
Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
organization_id |
string | enum("664c690e-5263-49ba-b01f-4a6759b3330a") |
yes | — | Organization UUID (or @airbyte-internal alias) to scope pins to. Resolve organization names to an ID first via search_organizations. |
connector_definition_id |
string | null |
no | null |
Connector definition UUID to filter by (optional). Mutually exclusive with connector_canonical_name. |
connector_canonical_name |
string | null |
no | null |
Connector canonical name (e.g. source-postgres) to filter by. Resolved to a definition ID via the registry. Mutually exclusive with connector_definition_id. |
pinned_version_id |
string | null |
no | null |
Actor_definition_version UUID to return only pins targeting that version. This is the post-selection filter for the org pins tab. |
origin_filter |
enum("all", "manual", "connector_rollout", "breaking_change") |
no | "all" |
Restrict by how the pin was created: all (default), manual, connector_rollout, or breaking_change. |
limit |
integer |
no | 1000 |
Maximum number of pins to return (default: 1000). |
Show input JSON schema
{
"additionalProperties": false,
"properties": {
"organization_id": {
"anyOf": [
{
"type": "string"
},
{
"description": "Organization ID aliases that can be used in place of UUIDs.\n\nEach member's name is the alias (e.g., \"@airbyte-internal\") and its value\nis the actual organization UUID. Use `OrganizationAliasEnum.resolve()` to\nresolve aliases to actual IDs.",
"enum": [
"664c690e-5263-49ba-b01f-4a6759b3330a"
],
"type": "string"
}
],
"description": "Organization UUID (or `@airbyte-internal` alias) to scope pins to. Resolve organization names to an ID first via `search_organizations`."
},
"connector_definition_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Connector definition UUID to filter by (optional). Mutually exclusive with `connector_canonical_name`."
},
"connector_canonical_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Connector canonical name (e.g. `source-postgres`) to filter by. Resolved to a definition ID via the registry. Mutually exclusive with `connector_definition_id`."
},
"pinned_version_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Actor_definition_version UUID to return only pins targeting that version. This is the post-selection filter for the org pins tab."
},
"origin_filter": {
"description": "Restrict by how the pin was created: `all` (default), `manual`, `connector_rollout`, or `breaking_change`.",
"enum": [
"all",
"manual",
"connector_rollout",
"breaking_change"
],
"type": "string",
"default": "all"
},
"limit": {
"default": 1000,
"description": "Maximum number of pins to return (default: 1000).",
"type": "integer"
}
},
"required": [
"organization_id"
],
"type": "object"
}
Show output JSON schema
{
"properties": {
"result": {
"items": {
"description": "A single `scoped_configuration` pin discovered under an organization.",
"properties": {
"connector_definition_id": {
"description": "The connector definition UUID",
"type": "string"
},
"connector_name": {
"description": "Human-readable connector name",
"type": "string"
},
"docker_repository": {
"description": "Docker repository path",
"type": "string"
},
"pinned_version_id": {
"description": "The pinned actor_definition_version UUID",
"type": "string"
},
"pinned_version_tag": {
"description": "Docker image tag of the pinned version",
"type": "string"
},
"pin_scope_type": {
"description": "Scope of the pin: `organization`, `workspace`, or `actor`",
"type": "string"
},
"scope_id": {
"description": "UUID of the scoped entity",
"type": "string"
},
"scope_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Display name of the scoped entity, when resolvable"
},
"pin_category": {
"description": "Derived pin type: `manual`, `rollout`, or `breaking_change`",
"type": "string"
},
"set_by": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Email (or name) of the user who set a manual pin, when known"
},
"rollout_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Backing connector_rollout UUID for rollout pins"
},
"rollout_state": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "State of the backing rollout, for rollout pins"
},
"is_active_rollout": {
"default": false,
"description": "`True` when `rollout_state` is a non-terminal (active) state",
"type": "boolean"
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Free-text pin reason"
},
"reference_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Reference URL attached to the pin, when present"
},
"created_at": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ISO timestamp when the pin was created"
},
"expires_at": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ISO timestamp when the pin expires, when set"
}
},
"required": [
"connector_definition_id",
"connector_name",
"docker_repository",
"pinned_version_id",
"pinned_version_tag",
"pin_scope_type",
"scope_id",
"pin_category"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"result"
],
"type": "object",
"x-fastmcp-wrap-result": true
}
query_prod_recent_syncs_for_connector
Hints: read-only · idempotent · open-world
List recent sync jobs for ALL actors using a connector type.
This tool finds all actors with the given connector definition and returns their recent sync jobs, regardless of whether they have explicit version pins. It filters out deleted actors, deleted workspaces, and deprecated connections.
Results are always enriched with customer_tier and is_eu fields. The customer_tier_filter parameter is required to ensure tier-aware querying.
Use this tool to:
- Find healthy connections with recent successful syncs (status_filter='succeeded')
- Investigate connector issues across all users (status_filter='failed')
- Get an overview of all recent sync activity (status_filter='all')
Set exclude_pinned=True to filter out syncs for actors that are already pinned to a
specific version. This is useful for 'prove fix' live connection testing workflows
where you want to find unpinned connections to test against.
Set enabled_schedules_only=True to restrict results to connections that are both
enabled (status='active') and on an automated schedule (not manual-trigger-only).
This is useful for canary prerelease workflows where you need connections that
will run organically during the monitoring window.
Supports both SOURCE and DESTINATION connectors. Provide exactly one of: source_definition_id, source_canonical_name, destination_definition_id, or destination_canonical_name.
Key fields in results:
- job_status: 'succeeded', 'failed', 'cancelled', etc.
- connection_id, connection_name: The connection that ran the sync
- actor_id, actor_name: The source or destination actor
- customer_tier: TIER_0, TIER_1, TIER_2, or UNKNOWN
- is_eu: Whether the workspace is in the EU region
- pin_origin_type, pin_origin, pinned_version_id: Version pin context (NULL if not pinned)
- pin_scope_type: 'actor', 'workspace', or 'organization' (NULL if not pinned)
Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
source_definition_id |
string | null |
no | null |
Source connector definition ID (UUID) to search for. Provide this OR source_canonical_name OR destination_definition_id OR destination_canonical_name (exactly one required). Example: 'afa734e4-3571-11ec-991a-1e0031268139' for YouTube Analytics. |
source_canonical_name |
string | null |
no | null |
Canonical source connector name to search for. Provide this OR source_definition_id OR destination_definition_id OR destination_canonical_name (exactly one required). Examples: 'source-youtube-analytics', 'YouTube Analytics'. |
destination_definition_id |
string | null |
no | null |
Destination connector definition ID (UUID) to search for. Provide this OR destination_canonical_name OR source_definition_id OR source_canonical_name (exactly one required). Example: '94bd199c-2ff0-4aa2-b98e-17f0acb72610' for DuckDB. |
destination_canonical_name |
string | null |
no | null |
Canonical destination connector name to search for. Provide this OR destination_definition_id OR source_definition_id OR source_canonical_name (exactly one required). Examples: 'destination-duckdb', 'DuckDB'. |
status_filter |
enum("all", "succeeded", "failed") |
no | "all" |
Filter by job status: 'all' (default), 'succeeded', or 'failed'. Use 'succeeded' to find healthy connections with recent successful syncs. Use 'failed' to find connections with recent failures. |
organization_id |
string | enum("664c690e-5263-49ba-b01f-4a6759b3330a") | null |
no | null |
Optional organization ID (UUID) or alias to filter results. If provided, only syncs from this organization will be returned. Accepts '@airbyte-internal' as an alias for the Airbyte internal org. |
lookback_days |
integer |
no | 7 |
Number of days to look back (default: 7) |
limit |
integer |
no | 100 |
Maximum number of results (default: 100) |
customer_tier_filter |
enum("TIER_0", "TIER_1", "TIER_2", "UNKNOWN", "ALL") |
no | "TIER_2" |
Required tier filter: 'TIER_0', 'TIER_1', 'TIER_2', 'UNKNOWN', or 'ALL'. Filters results to only include connections belonging to organizations in the specified tier. Use 'ALL' to include all tiers. |
exclude_pinned |
boolean |
no | false |
If True, exclude syncs for actors that are already pinned to a specific version (at any scope level: actor, workspace, or organization). Useful for 'prove fix' workflows where you want to find unpinned connections for live testing. Default: False (include all syncs). |
enabled_schedules_only |
boolean |
no | false |
If True, only return syncs for connections that are both active (not paused/inactive) and on an automated sync schedule (not manual-trigger-only). Useful for canary workflows where you need connections that will produce organic syncs during a monitoring window. Default: False (include all connections). |
Show input JSON schema
{
"additionalProperties": false,
"properties": {
"source_definition_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Source connector definition ID (UUID) to search for. Provide this OR source_canonical_name OR destination_definition_id OR destination_canonical_name (exactly one required). Example: 'afa734e4-3571-11ec-991a-1e0031268139' for YouTube Analytics."
},
"source_canonical_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Canonical source connector name to search for. Provide this OR source_definition_id OR destination_definition_id OR destination_canonical_name (exactly one required). Examples: 'source-youtube-analytics', 'YouTube Analytics'."
},
"destination_definition_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Destination connector definition ID (UUID) to search for. Provide this OR destination_canonical_name OR source_definition_id OR source_canonical_name (exactly one required). Example: '94bd199c-2ff0-4aa2-b98e-17f0acb72610' for DuckDB."
},
"destination_canonical_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Canonical destination connector name to search for. Provide this OR destination_definition_id OR source_definition_id OR source_canonical_name (exactly one required). Examples: 'destination-duckdb', 'DuckDB'."
},
"status_filter": {
"description": "Filter by job status: 'all' (default), 'succeeded', or 'failed'. Use 'succeeded' to find healthy connections with recent successful syncs. Use 'failed' to find connections with recent failures.",
"enum": [
"all",
"succeeded",
"failed"
],
"type": "string",
"default": "all"
},
"organization_id": {
"anyOf": [
{
"type": "string"
},
{
"description": "Organization ID aliases that can be used in place of UUIDs.\n\nEach member's name is the alias (e.g., \"@airbyte-internal\") and its value\nis the actual organization UUID. Use `OrganizationAliasEnum.resolve()` to\nresolve aliases to actual IDs.",
"enum": [
"664c690e-5263-49ba-b01f-4a6759b3330a"
],
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Optional organization ID (UUID) or alias to filter results. If provided, only syncs from this organization will be returned. Accepts '@airbyte-internal' as an alias for the Airbyte internal org."
},
"lookback_days": {
"default": 7,
"description": "Number of days to look back (default: 7)",
"type": "integer"
},
"limit": {
"default": 100,
"description": "Maximum number of results (default: 100)",
"type": "integer"
},
"customer_tier_filter": {
"default": "TIER_2",
"description": "Required tier filter: 'TIER_0', 'TIER_1', 'TIER_2', 'UNKNOWN', or 'ALL'. Filters results to only include connections belonging to organizations in the specified tier. Use 'ALL' to include all tiers.",
"enum": [
"TIER_0",
"TIER_1",
"TIER_2",
"UNKNOWN",
"ALL"
],
"type": "string"
},
"exclude_pinned": {
"default": false,
"description": "If True, exclude syncs for actors that are already pinned to a specific version (at any scope level: actor, workspace, or organization). Useful for 'prove fix' workflows where you want to find unpinned connections for live testing. Default: False (include all syncs).",
"type": "boolean"
},
"enabled_schedules_only": {
"default": false,
"description": "If True, only return syncs for connections that are both active (not paused/inactive) and on an automated sync schedule (not manual-trigger-only). Useful for canary workflows where you need connections that will produce organic syncs during a monitoring window. Default: False (include all connections).",
"type": "boolean"
}
},
"type": "object"
}
Show output JSON schema
{
"properties": {
"result": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
}
},
"required": [
"result"
],
"type": "object",
"x-fastmcp-wrap-result": true
}
query_prod_recent_syncs_for_connector_version
Hints: read-only · idempotent
List sync jobs that were run with a specific connector version.
Works for both source and destination connectors. Automatically detects the connector type from the version metadata and uses the appropriate query variant.
Accepts either connector_version_id (UUID) or connector_name +
connector_version (e.g. source-pokeapi + 0.3.59). When using
name + version, the docker_repository is derived from the canonical
name (e.g. source-pokeapi → airbyte/source-pokeapi).
Filters on the version stamped into jobs.config at job-creation time,
not the current pin state. This avoids false positives (pre-pin syncs
counted as RC) and false negatives (post-unpin syncs missed).
Pin columns (pin_origin_type, pin_origin, pin_scope_type) are
still included as informational output but are not used for filtering.
Returns list of dicts with keys: job_id, connection_id, job_status,
started_at, job_updated_at, connection_name, actor_id, actor_name,
actor_definition_id, source_definition_version_id,
destination_definition_version_id, pin_origin_type,
pin_origin, pin_scope_type, workspace_id, workspace_name,
organization_id, dataplane_group_id, dataplane_name.
Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
connector_version_id |
string | null |
no | null |
Connector version UUID. Provide this OR connector_name + connector_version. |
connector_name |
string | null |
no | null |
Canonical connector name (e.g. source-pokeapi, destination-duckdb). Used with connector_version to resolve the version UUID. |
connector_version |
string | null |
no | null |
Semver version tag (e.g. 0.3.59). Used with connector_name to resolve the version UUID. |
days |
integer |
no | 7 |
Number of days to look back (default: 7) |
limit |
integer |
no | 100 |
Maximum number of results (default: 100) |
successful_only |
boolean |
no | false |
If True, only return successful syncs (default: False) |
Show input JSON schema
{
"additionalProperties": false,
"properties": {
"connector_version_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Connector version UUID. Provide this OR connector_name + connector_version."
},
"connector_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Canonical connector name (e.g. `source-pokeapi`, `destination-duckdb`). Used with `connector_version` to resolve the version UUID."
},
"connector_version": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Semver version tag (e.g. `0.3.59`). Used with `connector_name` to resolve the version UUID."
},
"days": {
"default": 7,
"description": "Number of days to look back (default: 7)",
"type": "integer"
},
"limit": {
"default": 100,
"description": "Maximum number of results (default: 100)",
"type": "integer"
},
"successful_only": {
"default": false,
"description": "If `True`, only return successful syncs (default: `False`)",
"type": "boolean"
}
},
"type": "object"
}
Show output JSON schema
{
"properties": {
"result": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
}
},
"required": [
"result"
],
"type": "object",
"x-fastmcp-wrap-result": true
}
query_prod_workspace_info
Hints: read-only · idempotent
Get workspace information including dataplane group.
Returns details about a specific workspace, including which dataplane (region) it belongs to. Useful for determining if a workspace is in the EU region for filtering purposes.
Returns dict with keys: workspace_id, workspace_name, slug, organization_id, dataplane_group_id, dataplane_name, created_at, tombstone Or None if workspace not found.
Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
workspace_id |
string | enum("266ebdfe-0d7b-4540-9817-de7e4505ba61") |
yes | — | Workspace UUID or alias to look up. Accepts '@devin-ai-sandbox' as an alias for the Devin AI sandbox workspace. |
Show input JSON schema
{
"additionalProperties": false,
"properties": {
"workspace_id": {
"anyOf": [
{
"type": "string"
},
{
"description": "Workspace ID aliases that can be used in place of UUIDs.\n\nEach member's name is the alias (e.g., \"@devin-ai-sandbox\") and its value\nis the actual workspace UUID. Use `WorkspaceAliasEnum.resolve()` to\nresolve aliases to actual IDs.",
"enum": [
"266ebdfe-0d7b-4540-9817-de7e4505ba61"
],
"type": "string"
}
],
"description": "Workspace UUID or alias to look up. Accepts '@devin-ai-sandbox' as an alias for the Devin AI sandbox workspace."
}
},
"required": [
"workspace_id"
],
"type": "object"
}
Show output JSON schema
{
"properties": {
"result": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
]
}
},
"required": [
"result"
],
"type": "object",
"x-fastmcp-wrap-result": true
}
query_prod_workspaces
Hints: read-only · idempotent
Search workspaces by name substring or email domain.
At least one of name_contains or email_domain must be provided.
When name_contains is given, performs a case-insensitive substring match
on workspace name and slug. When email_domain is given, matches
workspaces by user email domain.
The returned organization IDs can be used with other tools like
query_prod_connections_by_connector to find connections within
those organizations for safe testing.
Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
name_contains |
string | null |
no | null |
Case-insensitive substring to search for in workspace name or slug. For example, 'acme' will match workspaces named 'Acme Staging'. |
email_domain |
string | null |
no | null |
Email domain to search for (e.g., 'motherduck.com'). Do not include the '@' symbol. |
limit |
integer |
no | 100 |
Maximum number of workspaces to return (default: 100) |
Show input JSON schema
{
"additionalProperties": false,
"properties": {
"name_contains": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Case-insensitive substring to search for in workspace name or slug. For example, 'acme' will match workspaces named 'Acme Staging'."
},
"email_domain": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Email domain to search for (e.g., 'motherduck.com'). Do not include the '@' symbol."
},
"limit": {
"default": 100,
"description": "Maximum number of workspaces to return (default: 100)",
"type": "integer"
}
},
"type": "object"
}
Show output JSON schema
{
"description": "Result of searching workspaces by name or email domain.",
"properties": {
"name_contains": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The name substring that was searched for"
},
"email_domain": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The email domain that was searched for (e.g., 'motherduck.com')"
},
"total_workspaces_found": {
"description": "Total number of workspaces matching",
"type": "integer"
},
"unique_organization_ids": {
"description": "List of unique organization IDs found",
"items": {
"type": "string"
},
"type": "array"
},
"workspaces": {
"description": "List of matching workspaces",
"items": {
"description": "Information about a workspace.",
"properties": {
"organization_id": {
"description": "The organization UUID",
"type": "string"
},
"workspace_id": {
"description": "The workspace UUID",
"type": "string"
},
"workspace_name": {
"description": "The name of the workspace",
"type": "string"
},
"slug": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The workspace slug (URL-friendly identifier)"
},
"email": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The email address associated with the workspace"
},
"dataplane_group_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The dataplane group UUID (region)"
},
"dataplane_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The name of the dataplane (e.g., 'US', 'EU')"
},
"created_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When the workspace was created"
},
"customer_tier": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Customer tier (TIER_0, TIER_1, TIER_2, or UNKNOWN). Enriched from the GCS tier cache."
},
"is_eu": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"description": "Whether the workspace is in the EU region (derived from dataplane_name)."
}
},
"required": [
"organization_id",
"workspace_id",
"workspace_name"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"total_workspaces_found",
"unique_organization_ids",
"workspaces"
],
"type": "object"
}
1# Copyright (c) 2025 Airbyte, Inc., all rights reserved. 2"""MCP tools for querying the Airbyte Cloud Prod DB Replica. 3 4This module provides MCP tools that wrap the query functions from 5airbyte_ops_mcp.prod_db_access.queries for use by AI agents. 6 7## MCP reference 8 9.. include:: ../../../docs/mcp-generated/prod_db_ops.md 10 :start-line: 2 11""" 12 13from __future__ import annotations 14 15__all__: list[str] = [] 16 17import json 18import uuid 19from datetime import datetime, timezone 20from enum import StrEnum 21from typing import Annotated, Any 22 23from airbyte.exceptions import PyAirbyteInputError 24from fastmcp import FastMCP 25from fastmcp_extensions import mcp_tool, register_mcp_tools 26from pydantic import BaseModel, Field 27 28from airbyte_ops_mcp.cloud_admin.registry_lookup import ( 29 resolve_canonical_name_to_definition_id, 30) 31from airbyte_ops_mcp.constants import OrganizationAliasEnum, WorkspaceAliasEnum 32from airbyte_ops_mcp.prod_db_access.queries import ( 33 is_source_connector, 34 query_actor_population_by_org, 35 query_actors_pinned_to_version, 36 query_connection_sync_activity_from_prod, 37 query_connections_by_connector, 38 query_connections_by_destination_connector, 39 query_connections_by_stream, 40 query_connector_rollouts, 41 query_connector_versions, 42 query_dataplanes_list, 43 query_destination_connection_stats, 44 query_failed_sync_attempts_for_connector, 45 query_new_connector_releases, 46 query_org_connector_pins, 47 query_org_pin_stats, 48 query_recent_syncs_for_connector, 49 query_source_connection_stats, 50 query_syncs_for_connector_version, 51 query_version_actor_health, 52 query_versions_with_pins, 53 query_workspace_info, 54 query_workspaces_by_email_domain, 55 resolve_version_id_by_tag, 56 resolve_version_info, 57 search_organizations, 58 search_workspaces, 59) 60from airbyte_ops_mcp.tier_cache import ( 61 TierFilter, 62 TierSummary, 63 enrich_rows_by_org, 64 filter_rows_by_tier, 65 get_org_tiers, 66) 67from airbyte_ops_mcp.version_summaries import ( 68 summarize_population, 69 summarize_version_health, 70) 71 72 73class StatusFilter(StrEnum): 74 """Filter for job status in sync queries.""" 75 76 ALL = "all" 77 SUCCEEDED = "succeeded" 78 FAILED = "failed" 79 80 81# Cloud UI base URL for building connection URLs 82CLOUD_UI_BASE_URL = "https://cloud.airbyte.com" 83 84 85def _validate_sync_activity_scope( 86 *, 87 organization_id: str | None, 88 workspace_id: str | None, 89 connection_ids: list[str] | None, 90) -> None: 91 """Require at least one explicit scope filter for sync activity queries.""" 92 if organization_id or workspace_id or connection_ids: 93 return 94 raise PyAirbyteInputError( 95 message=( 96 "Provide at least one scope filter: `organization_id`, `workspace_id`, " 97 "or `connection_ids`." 98 ), 99 context={ 100 "organization_id": organization_id, 101 "workspace_id": workspace_id, 102 "connection_ids": connection_ids, 103 }, 104 ) 105 106 107def _validate_sync_activity_window( 108 *, 109 start_at: datetime, 110 end_at: datetime, 111) -> tuple[datetime, datetime]: 112 """Validate that `start_at` and `end_at` describe a usable window. 113 114 Returns the timestamps normalized to UTC. Raises `PyAirbyteInputError` for 115 naive timestamps or inverted ranges. No clock-relative caps are enforced 116 here; the caller is trusted to choose a sensible window. 117 """ 118 if start_at.tzinfo is None or end_at.tzinfo is None: 119 raise PyAirbyteInputError( 120 message="`start_at` and `end_at` must include timezone information.", 121 context={ 122 "start_at": start_at.isoformat(), 123 "end_at": end_at.isoformat(), 124 }, 125 ) 126 127 normalized_start = start_at.astimezone(timezone.utc) 128 normalized_end = end_at.astimezone(timezone.utc) 129 130 if normalized_start >= normalized_end: 131 raise PyAirbyteInputError( 132 message="`start_at` must be earlier than `end_at`.", 133 context={ 134 "start_at": normalized_start.isoformat(), 135 "end_at": normalized_end.isoformat(), 136 }, 137 ) 138 return normalized_start, normalized_end 139 140 141# ============================================================================= 142# Pydantic Models for MCP Tool Responses 143# ============================================================================= 144 145 146class OrganizationSearchHit(BaseModel): 147 """A single organization returned by a name/email search.""" 148 149 organization_id: str = Field(description="The organization UUID") 150 organization_name: str = Field(description="The name of the organization") 151 email: str | None = Field( 152 default=None, description="The email address associated with the organization" 153 ) 154 customer_tier: str | None = Field( 155 default=None, 156 description="Customer tier (TIER_0, TIER_1, TIER_2, or UNKNOWN). Enriched from the GCS tier cache.", 157 ) 158 159 160class OrganizationSearchResult(BaseModel): 161 """Result of searching organizations by name substring.""" 162 163 name_contains: str = Field(description="The search substring that was used") 164 total_found: int = Field(description="Total number of organizations matching") 165 organizations: list[OrganizationSearchHit] = Field( 166 description="List of matching organizations" 167 ) 168 169 170class WorkspaceInfo(BaseModel): 171 """Information about a workspace.""" 172 173 organization_id: str = Field(description="The organization UUID") 174 workspace_id: str = Field(description="The workspace UUID") 175 workspace_name: str = Field(description="The name of the workspace") 176 slug: str | None = Field( 177 default=None, description="The workspace slug (URL-friendly identifier)" 178 ) 179 email: str | None = Field( 180 default=None, description="The email address associated with the workspace" 181 ) 182 dataplane_group_id: str | None = Field( 183 default=None, description="The dataplane group UUID (region)" 184 ) 185 dataplane_name: str | None = Field( 186 default=None, description="The name of the dataplane (e.g., 'US', 'EU')" 187 ) 188 created_at: datetime | None = Field( 189 default=None, description="When the workspace was created" 190 ) 191 customer_tier: str | None = Field( 192 default=None, 193 description="Customer tier (TIER_0, TIER_1, TIER_2, or UNKNOWN). Enriched from the GCS tier cache.", 194 ) 195 is_eu: bool | None = Field( 196 default=None, 197 description="Whether the workspace is in the EU region (derived from dataplane_name).", 198 ) 199 200 201class WorkspaceSearchResult(BaseModel): 202 """Result of searching workspaces by name or email domain.""" 203 204 name_contains: str | None = Field( 205 default=None, description="The name substring that was searched for" 206 ) 207 email_domain: str | None = Field( 208 default=None, 209 description="The email domain that was searched for (e.g., 'motherduck.com')", 210 ) 211 total_workspaces_found: int = Field( 212 description="Total number of workspaces matching" 213 ) 214 unique_organization_ids: list[str] = Field( 215 description="List of unique organization IDs found" 216 ) 217 workspaces: list[WorkspaceInfo] = Field(description="List of matching workspaces") 218 219 220# Keep backward-compatible alias for any external references 221WorkspacesByEmailDomainResult = WorkspaceSearchResult 222 223 224class LatestAttemptBreakdown(BaseModel): 225 """Breakdown of connections by latest attempt status.""" 226 227 succeeded: int = Field( 228 default=0, description="Connections where latest attempt succeeded" 229 ) 230 failed: int = Field( 231 default=0, description="Connections where latest attempt failed" 232 ) 233 cancelled: int = Field( 234 default=0, description="Connections where latest attempt was cancelled" 235 ) 236 running: int = Field( 237 default=0, description="Connections where latest attempt is still running" 238 ) 239 unknown: int = Field( 240 default=0, 241 description="Connections with no recent attempts in the lookback window", 242 ) 243 244 245class VersionPinStats(BaseModel): 246 """Stats for connections pinned to a specific version.""" 247 248 pinned_version_id: str | None = Field( 249 description="The connector version UUID (None for unpinned connections)" 250 ) 251 docker_image_tag: str | None = Field( 252 default=None, description="The docker image tag for this version" 253 ) 254 total_connections: int = Field(description="Total number of connections") 255 enabled_connections: int = Field( 256 description="Number of enabled (active status) connections" 257 ) 258 active_connections: int = Field( 259 description="Number of connections with recent sync activity" 260 ) 261 latest_attempt: LatestAttemptBreakdown = Field( 262 description="Breakdown by latest attempt status" 263 ) 264 265 266class ConnectorConnectionStats(BaseModel): 267 """Aggregate connection stats for a connector.""" 268 269 connector_definition_id: str = Field(description="The connector definition UUID") 270 connector_type: str = Field(description="'source' or 'destination'") 271 canonical_name: str | None = Field( 272 default=None, description="The canonical connector name if resolved" 273 ) 274 total_connections: int = Field( 275 description="Total number of non-deprecated connections" 276 ) 277 enabled_connections: int = Field( 278 description="Number of enabled (active status) connections" 279 ) 280 active_connections: int = Field( 281 description="Number of connections with recent sync activity" 282 ) 283 pinned_connections: int = Field( 284 description="Number of connections with explicit version pins" 285 ) 286 unpinned_connections: int = Field( 287 description="Number of connections on default version" 288 ) 289 latest_attempt: LatestAttemptBreakdown = Field( 290 description="Overall breakdown by latest attempt status" 291 ) 292 by_version: list[VersionPinStats] = Field( 293 description="Stats broken down by pinned version" 294 ) 295 296 297class ConnectorConnectionStatsResponse(BaseModel): 298 """Response containing connection stats for multiple connectors.""" 299 300 sources: list[ConnectorConnectionStats] = Field( 301 default_factory=list, description="Stats for source connectors" 302 ) 303 destinations: list[ConnectorConnectionStats] = Field( 304 default_factory=list, description="Stats for destination connectors" 305 ) 306 lookback_days: int = Field( 307 description="Lookback window used for 'active' connections" 308 ) 309 generated_at: datetime = Field(description="When this response was generated") 310 311 312def _opt_str(value: Any) -> str | None: 313 """Convert a nullable value to str, returning None if the value is None/falsy.""" 314 return str(value) if value else None 315 316 317@mcp_tool( 318 read_only=True, 319 idempotent=True, 320) 321def query_prod_dataplanes() -> list[dict[str, Any]]: 322 """List all dataplane groups with workspace counts. 323 324 Returns information about all active dataplane groups in Airbyte Cloud, 325 including the number of workspaces in each. Useful for understanding 326 the distribution of workspaces across regions (US, US-Central, EU). 327 328 Returns list of dicts with keys: dataplane_group_id, dataplane_name, 329 organization_id, enabled, tombstone, created_at, workspace_count 330 """ 331 return query_dataplanes_list() 332 333 334@mcp_tool( 335 read_only=True, 336 idempotent=True, 337) 338def query_prod_workspace_info( 339 workspace_id: Annotated[ 340 str | WorkspaceAliasEnum, 341 Field( 342 description="Workspace UUID or alias to look up. " 343 "Accepts '@devin-ai-sandbox' as an alias for the Devin AI sandbox workspace." 344 ), 345 ], 346) -> dict[str, Any] | None: 347 """Get workspace information including dataplane group. 348 349 Returns details about a specific workspace, including which dataplane 350 (region) it belongs to. Useful for determining if a workspace is in 351 the EU region for filtering purposes. 352 353 Returns dict with keys: workspace_id, workspace_name, slug, organization_id, 354 dataplane_group_id, dataplane_name, created_at, tombstone 355 Or None if workspace not found. 356 """ 357 # Resolve workspace ID alias (workspace_id is required, so resolved value is never None) 358 resolved_workspace_id = WorkspaceAliasEnum.resolve(workspace_id) 359 assert resolved_workspace_id is not None # Type narrowing: workspace_id is required 360 361 return query_workspace_info(resolved_workspace_id) 362 363 364@mcp_tool( 365 read_only=True, 366 idempotent=True, 367) 368def query_prod_connector_versions( 369 connector_definition_id: Annotated[ 370 str, 371 Field(description="Connector definition UUID to list versions for"), 372 ], 373) -> list[dict[str, Any]]: 374 """List all versions for a connector definition. 375 376 Returns all published versions of a connector, ordered by last_published 377 date descending. Useful for understanding version history and finding 378 specific version IDs for pinning or rollout monitoring. 379 380 Returns list of dicts with keys: version_id, docker_image_tag, docker_repository, 381 release_stage, support_level, cdk_version, language, last_published, release_date 382 """ 383 return query_connector_versions(connector_definition_id) 384 385 386@mcp_tool( 387 read_only=True, 388 idempotent=True, 389) 390def query_prod_new_connector_releases( 391 days: Annotated[ 392 int, 393 Field(description="Number of days to look back (default: 7)", default=7), 394 ] = 7, 395 limit: Annotated[ 396 int, 397 Field(description="Maximum number of results (default: 100)", default=100), 398 ] = 100, 399) -> list[dict[str, Any]]: 400 """List recently published connector versions. 401 402 Returns connector versions published within the specified number of days. 403 Uses last_published timestamp which reflects when the version was actually 404 deployed to the registry (not the changelog date). 405 406 Returns list of dicts with keys: version_id, connector_definition_id, docker_repository, 407 docker_image_tag, last_published, release_date, release_stage, support_level, 408 cdk_version, language, created_at 409 """ 410 return query_new_connector_releases(days=days, limit=limit) 411 412 413@mcp_tool( 414 read_only=True, 415 idempotent=True, 416) 417def query_prod_actors_by_pinned_connector_version( 418 connector_version_id: Annotated[ 419 str, 420 Field(description="Connector version UUID to find pinned instances for"), 421 ], 422) -> list[dict[str, Any]]: 423 """List actors (sources/destinations) effectively pinned to a specific connector version. 424 425 Returns all actors that are effectively pinned to a specific connector version, 426 considering all scope levels: actor-level pins, workspace-level pins, and 427 organization-level pins (with actor > workspace > organization precedence). 428 Useful for monitoring rollouts and understanding which customers are affected. 429 430 The actor_id field is the actor ID (superset of source_id/destination_id). 431 432 Returns list of dicts with keys: actor_id, connector_definition_id, origin_type, 433 origin, description, created_at, expires_at, pin_scope_type, actor_name, 434 workspace_id, workspace_name, organization_id, dataplane_group_id, dataplane_name 435 436 pin_scope_type is 'actor', 'workspace', or 'organization' indicating which scope 437 level the effective pin came from. 438 """ 439 return query_actors_pinned_to_version(connector_version_id) 440 441 442@mcp_tool( 443 read_only=True, 444 idempotent=True, 445) 446def query_prod_recent_syncs_for_connector_version( 447 connector_version_id: Annotated[ 448 str | None, 449 Field( 450 description=( 451 "Connector version UUID. Provide this OR " 452 "connector_name + connector_version." 453 ), 454 default=None, 455 ), 456 ] = None, 457 connector_name: Annotated[ 458 str | None, 459 Field( 460 description=( 461 "Canonical connector name (e.g. `source-pokeapi`, " 462 "`destination-duckdb`). Used with `connector_version` to " 463 "resolve the version UUID." 464 ), 465 default=None, 466 ), 467 ] = None, 468 connector_version: Annotated[ 469 str | None, 470 Field( 471 description=( 472 "Semver version tag (e.g. `0.3.59`). " 473 "Used with `connector_name` to resolve the version UUID." 474 ), 475 default=None, 476 ), 477 ] = None, 478 days: Annotated[ 479 int, 480 Field(description="Number of days to look back (default: 7)", default=7), 481 ] = 7, 482 limit: Annotated[ 483 int, 484 Field(description="Maximum number of results (default: 100)", default=100), 485 ] = 100, 486 successful_only: Annotated[ 487 bool, 488 Field( 489 description="If `True`, only return successful syncs (default: `False`)", 490 default=False, 491 ), 492 ] = False, 493) -> list[dict[str, Any]]: 494 """List sync jobs that were run with a specific connector version. 495 496 Works for both source and destination connectors. Automatically detects 497 the connector type from the version metadata and uses the appropriate 498 query variant. 499 500 Accepts either `connector_version_id` (UUID) or `connector_name` + 501 `connector_version` (e.g. `source-pokeapi` + `0.3.59`). When using 502 name + version, the `docker_repository` is derived from the canonical 503 name (e.g. `source-pokeapi` → `airbyte/source-pokeapi`). 504 505 Filters on the version stamped into `jobs.config` at job-creation time, 506 not the current pin state. This avoids false positives (pre-pin syncs 507 counted as RC) and false negatives (post-unpin syncs missed). 508 509 Pin columns (`pin_origin_type`, `pin_origin`, `pin_scope_type`) are 510 still included as informational output but are not used for filtering. 511 512 Returns list of dicts with keys: `job_id`, `connection_id`, `job_status`, 513 `started_at`, `job_updated_at`, `connection_name`, `actor_id`, `actor_name`, 514 `actor_definition_id`, `source_definition_version_id`, 515 `destination_definition_version_id`, `pin_origin_type`, 516 `pin_origin`, `pin_scope_type`, `workspace_id`, `workspace_name`, 517 `organization_id`, `dataplane_group_id`, `dataplane_name`. 518 """ 519 # Resolve inputs to a version UUID and connector type. 520 if connector_version_id is not None: 521 version_info = resolve_version_info(connector_version_id) 522 docker_repository = version_info["docker_repository"] 523 elif connector_name is not None and connector_version is not None: 524 # Derive docker_repository from canonical name. 525 docker_repository = f"airbyte/{connector_name}" 526 version_info = resolve_version_id_by_tag( 527 docker_repository=docker_repository, 528 docker_image_tag=connector_version, 529 ) 530 connector_version_id = version_info["version_id"] 531 else: 532 raise PyAirbyteInputError( 533 message=( 534 "Provide either `connector_version_id` or both " 535 "`connector_name` and `connector_version`." 536 ), 537 ) 538 539 is_destination = not is_source_connector(docker_repository) 540 return query_syncs_for_connector_version( 541 connector_version_id, 542 is_destination=is_destination, 543 days=days, 544 limit=limit, 545 successful_only=successful_only, 546 ) 547 548 549@mcp_tool( 550 read_only=True, 551 idempotent=True, 552 open_world=True, 553) 554def query_prod_recent_syncs_for_connector( 555 source_definition_id: Annotated[ 556 str | None, 557 Field( 558 description=( 559 "Source connector definition ID (UUID) to search for. " 560 "Provide this OR source_canonical_name OR destination_definition_id " 561 "OR destination_canonical_name (exactly one required). " 562 "Example: 'afa734e4-3571-11ec-991a-1e0031268139' for YouTube Analytics." 563 ), 564 default=None, 565 ), 566 ], 567 source_canonical_name: Annotated[ 568 str | None, 569 Field( 570 description=( 571 "Canonical source connector name to search for. " 572 "Provide this OR source_definition_id OR destination_definition_id " 573 "OR destination_canonical_name (exactly one required). " 574 "Examples: 'source-youtube-analytics', 'YouTube Analytics'." 575 ), 576 default=None, 577 ), 578 ], 579 destination_definition_id: Annotated[ 580 str | None, 581 Field( 582 description=( 583 "Destination connector definition ID (UUID) to search for. " 584 "Provide this OR destination_canonical_name OR source_definition_id " 585 "OR source_canonical_name (exactly one required). " 586 "Example: '94bd199c-2ff0-4aa2-b98e-17f0acb72610' for DuckDB." 587 ), 588 default=None, 589 ), 590 ], 591 destination_canonical_name: Annotated[ 592 str | None, 593 Field( 594 description=( 595 "Canonical destination connector name to search for. " 596 "Provide this OR destination_definition_id OR source_definition_id " 597 "OR source_canonical_name (exactly one required). " 598 "Examples: 'destination-duckdb', 'DuckDB'." 599 ), 600 default=None, 601 ), 602 ], 603 status_filter: Annotated[ 604 StatusFilter, 605 Field( 606 description=( 607 "Filter by job status: 'all' (default), 'succeeded', or 'failed'. " 608 "Use 'succeeded' to find healthy connections with recent successful syncs. " 609 "Use 'failed' to find connections with recent failures." 610 ), 611 default=StatusFilter.ALL, 612 ), 613 ], 614 organization_id: Annotated[ 615 str | OrganizationAliasEnum | None, 616 Field( 617 description=( 618 "Optional organization ID (UUID) or alias to filter results. " 619 "If provided, only syncs from this organization will be returned. " 620 "Accepts '@airbyte-internal' as an alias for the Airbyte internal org." 621 ), 622 default=None, 623 ), 624 ], 625 lookback_days: Annotated[ 626 int, 627 Field(description="Number of days to look back (default: 7)", default=7), 628 ], 629 limit: Annotated[ 630 int, 631 Field(description="Maximum number of results (default: 100)", default=100), 632 ], 633 customer_tier_filter: Annotated[ 634 TierFilter, 635 Field( 636 description=( 637 "Required tier filter: 'TIER_0', 'TIER_1', 'TIER_2', 'UNKNOWN', or 'ALL'. " 638 "Filters results to only include connections belonging to organizations " 639 "in the specified tier. Use 'ALL' to include all tiers." 640 ), 641 ), 642 ] = "TIER_2", 643 *, 644 exclude_pinned: Annotated[ 645 bool, 646 Field( 647 description=( 648 "If True, exclude syncs for actors that are already pinned to a " 649 "specific version (at any scope level: actor, workspace, or organization). " 650 "Useful for 'prove fix' workflows where you want to find unpinned " 651 "connections for live testing. Default: False (include all syncs)." 652 ), 653 default=False, 654 ), 655 ], 656 enabled_schedules_only: Annotated[ 657 bool, 658 Field( 659 description=( 660 "If True, only return syncs for connections that are both active " 661 "(not paused/inactive) and on an automated sync schedule " 662 "(not manual-trigger-only). Useful for canary workflows where " 663 "you need connections that will produce organic syncs during a " 664 "monitoring window. Default: False (include all connections)." 665 ), 666 default=False, 667 ), 668 ], 669) -> list[dict[str, Any]]: 670 """List recent sync jobs for ALL actors using a connector type. 671 672 This tool finds all actors with the given connector definition and returns their 673 recent sync jobs, regardless of whether they have explicit version pins. It filters 674 out deleted actors, deleted workspaces, and deprecated connections. 675 676 Results are always enriched with customer_tier and is_eu fields. 677 The customer_tier_filter parameter is required to ensure tier-aware querying. 678 679 Use this tool to: 680 - Find healthy connections with recent successful syncs (status_filter='succeeded') 681 - Investigate connector issues across all users (status_filter='failed') 682 - Get an overview of all recent sync activity (status_filter='all') 683 684 Set `exclude_pinned=True` to filter out syncs for actors that are already pinned to a 685 specific version. This is useful for 'prove fix' live connection testing workflows 686 where you want to find unpinned connections to test against. 687 688 Set `enabled_schedules_only=True` to restrict results to connections that are both 689 enabled (status='active') and on an automated schedule (not manual-trigger-only). 690 This is useful for canary prerelease workflows where you need connections that 691 will run organically during the monitoring window. 692 693 Supports both SOURCE and DESTINATION connectors. Provide exactly one of: 694 source_definition_id, source_canonical_name, destination_definition_id, 695 or destination_canonical_name. 696 697 Key fields in results: 698 - job_status: 'succeeded', 'failed', 'cancelled', etc. 699 - connection_id, connection_name: The connection that ran the sync 700 - actor_id, actor_name: The source or destination actor 701 - customer_tier: TIER_0, TIER_1, TIER_2, or UNKNOWN 702 - is_eu: Whether the workspace is in the EU region 703 - pin_origin_type, pin_origin, pinned_version_id: Version pin context (NULL if not pinned) 704 - pin_scope_type: 'actor', 'workspace', or 'organization' (NULL if not pinned) 705 """ 706 # Validate that exactly one connector parameter is provided 707 provided_params = [ 708 source_definition_id, 709 source_canonical_name, 710 destination_definition_id, 711 destination_canonical_name, 712 ] 713 num_provided = sum(p is not None for p in provided_params) 714 if num_provided != 1: 715 raise PyAirbyteInputError( 716 message=( 717 "Exactly one of source_definition_id, source_canonical_name, " 718 "destination_definition_id, or destination_canonical_name must be provided." 719 ), 720 ) 721 722 # Determine if this is a destination connector 723 is_destination = ( 724 destination_definition_id is not None or destination_canonical_name is not None 725 ) 726 727 # Resolve canonical name to definition ID if needed 728 resolved_definition_id: str 729 if source_canonical_name: 730 resolved_definition_id = resolve_canonical_name_to_definition_id( 731 canonical_name=source_canonical_name, 732 ) 733 elif destination_canonical_name: 734 resolved_definition_id = resolve_canonical_name_to_definition_id( 735 canonical_name=destination_canonical_name, 736 ) 737 elif source_definition_id: 738 resolved_definition_id = source_definition_id 739 else: 740 # We've validated exactly one param is provided, so this must be set 741 assert destination_definition_id is not None 742 resolved_definition_id = destination_definition_id 743 744 # Resolve organization ID alias 745 resolved_organization_id = OrganizationAliasEnum.resolve(organization_id) 746 747 rows = query_recent_syncs_for_connector( 748 connector_definition_id=resolved_definition_id, 749 is_destination=is_destination, 750 status_filter=status_filter, 751 organization_id=resolved_organization_id, 752 days=lookback_days, 753 limit=limit, 754 exclude_pinned=exclude_pinned, 755 enabled_schedules_only=enabled_schedules_only, 756 ) 757 758 enriched = enrich_rows_by_org( 759 rows=rows, 760 allow_degraded=True, 761 ) 762 return filter_rows_by_tier(enriched, customer_tier_filter) 763 764 765@mcp_tool( 766 read_only=True, 767 idempotent=True, 768 open_world=True, 769) 770def query_prod_failed_sync_attempts_for_connector( 771 source_definition_id: Annotated[ 772 str | None, 773 Field( 774 description=( 775 "Source connector definition ID (UUID) to search for. " 776 "Exactly one of this or source_canonical_name is required. " 777 "Example: 'afa734e4-3571-11ec-991a-1e0031268139' for YouTube Analytics." 778 ), 779 default=None, 780 ), 781 ] = None, 782 source_canonical_name: Annotated[ 783 str | None, 784 Field( 785 description=( 786 "Canonical source connector name to search for. " 787 "Exactly one of this or source_definition_id is required. " 788 "Examples: 'source-youtube-analytics', 'YouTube Analytics'." 789 ), 790 default=None, 791 ), 792 ] = None, 793 organization_id: Annotated[ 794 str | OrganizationAliasEnum | None, 795 Field( 796 description=( 797 "Optional organization ID (UUID) or alias to filter results. " 798 "If provided, only failed attempts from this organization will be returned. " 799 "Accepts '@airbyte-internal' as an alias for the Airbyte internal org." 800 ), 801 default=None, 802 ), 803 ] = None, 804 lookback_days: Annotated[ 805 int, 806 Field(description="Number of days to look back (default: 7)", default=7), 807 ] = 7, 808 limit: Annotated[ 809 int, 810 Field(description="Maximum number of results (default: 100)", default=100), 811 ] = 100, 812 customer_tier_filter: Annotated[ 813 TierFilter, 814 Field( 815 description=( 816 "Required tier filter: 'TIER_0', 'TIER_1', 'TIER_2', 'UNKNOWN', or 'ALL'. " 817 "Filters results to only include connections belonging to organizations " 818 "in the specified tier. Use 'ALL' to include all tiers." 819 ), 820 ), 821 ] = "TIER_2", 822) -> list[dict[str, Any]]: 823 """List failed sync attempts for ALL actors using a source connector type. 824 825 This tool finds all actors with the given connector definition and returns their 826 failed sync attempts, regardless of whether they have explicit version pins. 827 828 Results are always enriched with customer_tier and is_eu fields. 829 The customer_tier_filter parameter is required to ensure tier-aware querying. 830 831 This is useful for investigating connector issues across all users. Use this when 832 you want to find failures for a connector type regardless of which version users 833 are on. 834 835 Note: This tool only supports SOURCE connectors. For destination connectors, 836 a separate tool would be needed. 837 838 Key fields in results: 839 - failure_summary: JSON containing failure details including failureType and messages 840 - customer_tier: TIER_0, TIER_1, TIER_2, or UNKNOWN 841 - is_eu: Whether the workspace is in the EU region 842 - pin_origin_type, pin_origin, pinned_version_id: Version pin context (NULL if not pinned) 843 - pin_scope_type: 'actor', 'workspace', or 'organization' (NULL if not pinned) 844 """ 845 # Validate that exactly one of the two parameters is provided 846 if (source_definition_id is None) == (source_canonical_name is None): 847 raise PyAirbyteInputError( 848 message=( 849 "Exactly one of source_definition_id or source_canonical_name " 850 "must be provided, but not both." 851 ), 852 ) 853 854 # Resolve canonical name to definition ID if needed 855 resolved_definition_id: str 856 if source_canonical_name: 857 resolved_definition_id = resolve_canonical_name_to_definition_id( 858 canonical_name=source_canonical_name, 859 ) 860 else: 861 resolved_definition_id = source_definition_id # ty: ignore[invalid-assignment] 862 863 # Resolve organization ID alias 864 resolved_organization_id = OrganizationAliasEnum.resolve(organization_id) 865 866 rows = query_failed_sync_attempts_for_connector( 867 connector_definition_id=resolved_definition_id, 868 organization_id=resolved_organization_id, 869 days=lookback_days, 870 limit=limit, 871 ) 872 enriched = enrich_rows_by_org( 873 rows=rows, 874 allow_degraded=True, 875 ) 876 return filter_rows_by_tier(enriched, customer_tier_filter) 877 878 879@mcp_tool( 880 read_only=True, 881 idempotent=True, 882 open_world=True, 883) 884def query_prod_connections_by_connector( 885 source_definition_id: Annotated[ 886 str | None, 887 Field( 888 description=( 889 "Source connector definition ID (UUID) to search for. " 890 "Exactly one of source_definition_id, source_canonical_name, " 891 "destination_definition_id, or destination_canonical_name is required. " 892 "Example: 'afa734e4-3571-11ec-991a-1e0031268139' for YouTube Analytics." 893 ), 894 default=None, 895 ), 896 ] = None, 897 source_canonical_name: Annotated[ 898 str | None, 899 Field( 900 description=( 901 "Canonical source connector name to search for. " 902 "Exactly one of source_definition_id, source_canonical_name, " 903 "destination_definition_id, or destination_canonical_name is required. " 904 "Examples: 'source-youtube-analytics', 'YouTube Analytics'." 905 ), 906 default=None, 907 ), 908 ] = None, 909 destination_definition_id: Annotated[ 910 str | None, 911 Field( 912 description=( 913 "Destination connector definition ID (UUID) to search for. " 914 "Exactly one of source_definition_id, source_canonical_name, " 915 "destination_definition_id, or destination_canonical_name is required. " 916 "Example: 'e5c8e66c-a480-4a5e-9c0e-e8e5e4c5c5c5' for DuckDB." 917 ), 918 default=None, 919 ), 920 ] = None, 921 destination_canonical_name: Annotated[ 922 str | None, 923 Field( 924 description=( 925 "Canonical destination connector name to search for. " 926 "Exactly one of source_definition_id, source_canonical_name, " 927 "destination_definition_id, or destination_canonical_name is required. " 928 "Examples: 'destination-duckdb', 'DuckDB'." 929 ), 930 default=None, 931 ), 932 ] = None, 933 organization_id: Annotated[ 934 str | OrganizationAliasEnum | None, 935 Field( 936 description=( 937 "Optional organization ID (UUID) or alias to filter results. " 938 "If provided, only connections in this organization will be returned. " 939 "Accepts '@airbyte-internal' as an alias for the Airbyte internal org." 940 ), 941 default=None, 942 ), 943 ] = None, 944 limit: Annotated[ 945 int, 946 Field(description="Maximum number of results (default: 1000)", default=1000), 947 ] = 1000, 948 customer_tier_filter: Annotated[ 949 TierFilter, 950 Field( 951 description=( 952 "Required tier filter: 'TIER_0', 'TIER_1', 'TIER_2', 'UNKNOWN', or 'ALL'. " 953 "Filters results to only include connections belonging to organizations " 954 "in the specified tier. Use 'ALL' to include all tiers." 955 ), 956 ), 957 ] = "TIER_2", 958 *, 959 exclude_pinned: Annotated[ 960 bool, 961 Field( 962 description=( 963 "If True, exclude connections whose connector is already pinned to a " 964 "specific version (at any scope level: actor, workspace, or organization). " 965 "Useful for 'prove fix' workflows where you want to find unpinned " 966 "connections for live testing. Default: False (include all connections)." 967 ), 968 default=False, 969 ), 970 ], 971 enabled_schedules_only: Annotated[ 972 bool, 973 Field( 974 description=( 975 "If True, only return connections that are both active " 976 "(not paused/inactive) and on an automated sync schedule " 977 "(not manual-trigger-only). Useful for canary workflows where " 978 "you need connections that will produce organic syncs during a " 979 "monitoring window. Default: False (include all connections)." 980 ), 981 default=False, 982 ), 983 ], 984) -> list[dict[str, Any]]: 985 """Search for all connections using a specific source or destination connector type. 986 987 This tool queries the Airbyte Cloud Prod DB Replica directly for fast results. 988 It finds all connections where the source or destination connector matches the 989 specified type, regardless of how the connector is named by users. 990 991 Results are always enriched with customer_tier and is_eu fields. 992 The customer_tier_filter parameter is required to ensure tier-aware querying. 993 994 Optionally filter by organization_id to limit results to a specific organization. 995 Use '@airbyte-internal' as an alias for the Airbyte internal organization. 996 997 Set `exclude_pinned=True` to filter out connections that are already pinned to a 998 specific version. This is useful for 'prove fix' live connection testing workflows 999 where you want to find unpinned connections to test against. 1000 1001 Set `enabled_schedules_only=True` to restrict results to connections that are both 1002 enabled (status='active') and on an automated schedule (not manual-trigger-only). 1003 This is useful for canary prerelease workflows where you need connections that 1004 will run organically during the monitoring window. 1005 1006 Returns a list of connection dicts with workspace context and clickable Cloud UI URLs. 1007 For source queries, returns: connection_id, connection_name, connection_url, source_id, 1008 source_name, source_definition_id, workspace_id, workspace_name, organization_id, 1009 dataplane_group_id, dataplane_name, pin_origin_type, pin_origin, pinned_version_id, 1010 pin_scope_type, customer_tier, is_eu. 1011 For destination queries, returns: connection_id, connection_name, connection_url, 1012 destination_id, destination_name, destination_definition_id, workspace_id, 1013 workspace_name, organization_id, dataplane_group_id, dataplane_name, pin_origin_type, 1014 pin_origin, pinned_version_id, pin_scope_type, customer_tier, is_eu. 1015 1016 pin_scope_type is 'actor', 'workspace', or 'organization' indicating which scope 1017 level the effective pin came from (NULL if not pinned). 1018 """ 1019 # Validate that exactly one of the four connector parameters is provided 1020 provided_params = [ 1021 source_definition_id, 1022 source_canonical_name, 1023 destination_definition_id, 1024 destination_canonical_name, 1025 ] 1026 num_provided = sum(p is not None for p in provided_params) 1027 if num_provided != 1: 1028 raise PyAirbyteInputError( 1029 message=( 1030 "Exactly one of source_definition_id, source_canonical_name, " 1031 "destination_definition_id, or destination_canonical_name must be provided." 1032 ), 1033 ) 1034 1035 # Determine if this is a source or destination query and resolve the definition ID 1036 is_source_query = ( 1037 source_definition_id is not None or source_canonical_name is not None 1038 ) 1039 resolved_definition_id: str 1040 1041 if source_canonical_name: 1042 resolved_definition_id = resolve_canonical_name_to_definition_id( 1043 canonical_name=source_canonical_name, 1044 ) 1045 elif source_definition_id: 1046 resolved_definition_id = source_definition_id 1047 elif destination_canonical_name: 1048 resolved_definition_id = resolve_canonical_name_to_definition_id( 1049 canonical_name=destination_canonical_name, 1050 ) 1051 else: 1052 resolved_definition_id = destination_definition_id # ty: ignore[invalid-assignment] 1053 1054 # Resolve organization ID alias 1055 resolved_organization_id = OrganizationAliasEnum.resolve(organization_id) 1056 1057 # Query the database based on connector type 1058 if is_source_query: 1059 rows = [ 1060 { 1061 "organization_id": str(row.get("organization_id", "")), 1062 "workspace_id": str(row["workspace_id"]), 1063 "workspace_name": row.get("workspace_name", ""), 1064 "connection_id": str(row["connection_id"]), 1065 "connection_name": row.get("connection_name", ""), 1066 "connection_url": ( 1067 f"{CLOUD_UI_BASE_URL}/workspaces/{row['workspace_id']}" 1068 f"/connections/{row['connection_id']}/status" 1069 ), 1070 "source_id": str(row["source_id"]), 1071 "source_name": row.get("source_name", ""), 1072 "source_definition_id": str(row["source_definition_id"]), 1073 "dataplane_group_id": str(row.get("dataplane_group_id", "")), 1074 "dataplane_name": row.get("dataplane_name", ""), 1075 "pin_origin_type": row.get("pin_origin_type"), 1076 "pin_origin": row.get("pin_origin"), 1077 "pinned_version_id": _opt_str(row.get("pinned_version_id")), 1078 "pin_scope_type": row.get("pin_scope_type"), 1079 } 1080 for row in query_connections_by_connector( 1081 connector_definition_id=resolved_definition_id, 1082 organization_id=resolved_organization_id, 1083 limit=limit, 1084 exclude_pinned=exclude_pinned, 1085 enabled_schedules_only=enabled_schedules_only, 1086 ) 1087 ] 1088 else: 1089 # Destination query 1090 rows = [ 1091 { 1092 "organization_id": str(row.get("organization_id", "")), 1093 "workspace_id": str(row["workspace_id"]), 1094 "workspace_name": row.get("workspace_name", ""), 1095 "connection_id": str(row["connection_id"]), 1096 "connection_name": row.get("connection_name", ""), 1097 "connection_url": ( 1098 f"{CLOUD_UI_BASE_URL}/workspaces/{row['workspace_id']}" 1099 f"/connections/{row['connection_id']}/status" 1100 ), 1101 "destination_id": str(row["destination_id"]), 1102 "destination_name": row.get("destination_name", ""), 1103 "destination_definition_id": str(row["destination_definition_id"]), 1104 "dataplane_group_id": str(row.get("dataplane_group_id", "")), 1105 "dataplane_name": row.get("dataplane_name", ""), 1106 "pin_origin_type": row.get("pin_origin_type"), 1107 "pin_origin": row.get("pin_origin"), 1108 "pinned_version_id": _opt_str(row.get("pinned_version_id")), 1109 "pin_scope_type": row.get("pin_scope_type"), 1110 } 1111 for row in query_connections_by_destination_connector( 1112 connector_definition_id=resolved_definition_id, 1113 organization_id=resolved_organization_id, 1114 limit=limit, 1115 exclude_pinned=exclude_pinned, 1116 enabled_schedules_only=enabled_schedules_only, 1117 ) 1118 ] 1119 1120 enriched = enrich_rows_by_org( 1121 rows=rows, 1122 allow_degraded=True, 1123 ) 1124 return filter_rows_by_tier(enriched, customer_tier_filter) 1125 1126 1127@mcp_tool( 1128 read_only=True, 1129 idempotent=True, 1130 open_world=True, 1131) 1132def query_prod_connections_by_stream( 1133 stream_name: Annotated[ 1134 str, 1135 Field( 1136 description=( 1137 "Name of the stream to search for in connection catalogs. " 1138 "This must match the exact stream name as configured in the connection. " 1139 "Examples: 'global_exclusions', 'campaigns', 'users'." 1140 ), 1141 ), 1142 ], 1143 source_definition_id: Annotated[ 1144 str | None, 1145 Field( 1146 description=( 1147 "Source connector definition ID (UUID) to search for. " 1148 "Provide this OR source_canonical_name (exactly one required). " 1149 "Example: 'afa734e4-3571-11ec-991a-1e0031268139' for YouTube Analytics." 1150 ), 1151 default=None, 1152 ), 1153 ], 1154 source_canonical_name: Annotated[ 1155 str | None, 1156 Field( 1157 description=( 1158 "Canonical source connector name to search for. " 1159 "Provide this OR source_definition_id (exactly one required). " 1160 "Examples: 'source-klaviyo', 'Klaviyo', 'source-youtube-analytics'." 1161 ), 1162 default=None, 1163 ), 1164 ], 1165 organization_id: Annotated[ 1166 str | OrganizationAliasEnum | None, 1167 Field( 1168 description=( 1169 "Optional organization ID (UUID) or alias to filter results. " 1170 "If provided, only connections in this organization will be returned. " 1171 "Accepts '@airbyte-internal' as an alias for the Airbyte internal org." 1172 ), 1173 default=None, 1174 ), 1175 ], 1176 limit: Annotated[ 1177 int, 1178 Field(description="Maximum number of results (default: 100)", default=100), 1179 ], 1180 customer_tier_filter: Annotated[ 1181 TierFilter, 1182 Field( 1183 description=( 1184 "Required tier filter: 'TIER_0', 'TIER_1', 'TIER_2', 'UNKNOWN', or 'ALL'. " 1185 "Filters results to only include connections belonging to organizations " 1186 "in the specified tier. Use 'ALL' to include all tiers." 1187 ), 1188 ), 1189 ] = "TIER_2", 1190) -> list[dict[str, Any]]: 1191 """Find connections that have a specific stream enabled in their catalog. 1192 1193 This tool searches the connection's configured catalog (JSONB) for streams 1194 matching the specified name. It's particularly useful when validating 1195 connector fixes that affect specific streams - you can quickly find 1196 customer connections that use the affected stream. 1197 1198 Results are always enriched with customer_tier and is_eu fields. 1199 The customer_tier_filter parameter is required to ensure tier-aware querying. 1200 1201 Use cases: 1202 - Finding connections with a specific stream enabled for regression testing 1203 - Validating connector fixes that affect particular streams 1204 - Identifying which customers use rarely-enabled streams 1205 1206 Returns a list of connection dicts with workspace context and clickable Cloud UI URLs. 1207 """ 1208 provided_params = [source_definition_id, source_canonical_name] 1209 num_provided = sum(p is not None for p in provided_params) 1210 if num_provided != 1: 1211 raise PyAirbyteInputError( 1212 message=( 1213 "Exactly one of source_definition_id or source_canonical_name " 1214 "must be provided." 1215 ), 1216 ) 1217 1218 resolved_definition_id: str 1219 if source_canonical_name: 1220 resolved_definition_id = resolve_canonical_name_to_definition_id( 1221 canonical_name=source_canonical_name, 1222 ) 1223 else: 1224 assert source_definition_id is not None 1225 resolved_definition_id = source_definition_id 1226 1227 resolved_organization_id = OrganizationAliasEnum.resolve(organization_id) 1228 1229 rows = [ 1230 { 1231 "organization_id": str(row.get("organization_id", "")), 1232 "workspace_id": str(row["workspace_id"]), 1233 "workspace_name": row.get("workspace_name", ""), 1234 "connection_id": str(row["connection_id"]), 1235 "connection_name": row.get("connection_name", ""), 1236 "connection_status": row.get("connection_status", ""), 1237 "connection_url": ( 1238 f"{CLOUD_UI_BASE_URL}/workspaces/{row['workspace_id']}" 1239 f"/connections/{row['connection_id']}/status" 1240 ), 1241 "source_id": str(row["source_id"]), 1242 "source_name": row.get("source_name", ""), 1243 "source_definition_id": str(row["source_definition_id"]), 1244 "dataplane_group_id": str(row.get("dataplane_group_id", "")), 1245 "dataplane_name": row.get("dataplane_name", ""), 1246 } 1247 for row in query_connections_by_stream( 1248 connector_definition_id=resolved_definition_id, 1249 stream_name=stream_name, 1250 organization_id=resolved_organization_id, 1251 limit=limit, 1252 ) 1253 ] 1254 enriched = enrich_rows_by_org( 1255 rows=rows, 1256 allow_degraded=True, 1257 ) 1258 return filter_rows_by_tier(enriched, customer_tier_filter) 1259 1260 1261@mcp_tool( 1262 read_only=True, 1263 idempotent=True, 1264) 1265def query_prod_organizations( 1266 name_contains: Annotated[ 1267 str, 1268 Field( 1269 description=( 1270 "Case-insensitive substring to search for in organization name or email. " 1271 "For example, 'acme' will match organizations named 'Acme Corp' or " 1272 "with email 'admin@acme.io'." 1273 ), 1274 ), 1275 ], 1276 limit: Annotated[ 1277 int, 1278 Field( 1279 description="Maximum number of organizations to return (default: 20)", 1280 default=20, 1281 ), 1282 ] = 20, 1283) -> OrganizationSearchResult: 1284 """Search organizations by name or email substring. 1285 1286 Performs a case-insensitive substring match on organization name and email. 1287 Use the returned `organization_id` values with other tools like 1288 `query_prod_connections_by_connector` or `lookup_customer_tiers`. 1289 """ 1290 rows = search_organizations(name_contains=name_contains, limit=limit) 1291 1292 orgs = [ 1293 OrganizationSearchHit( 1294 organization_id=str(row["organization_id"]), 1295 organization_name=row.get("organization_name", ""), 1296 email=row.get("email"), 1297 ) 1298 for row in rows 1299 ] 1300 1301 # Enrich with tier annotation 1302 org_ids = [o.organization_id for o in orgs] 1303 tier_results = { 1304 r.organization_id: r 1305 for r in get_org_tiers( 1306 organization_ids=org_ids, 1307 allow_degraded=True, 1308 ) 1309 } 1310 for org in orgs: 1311 tier_result = tier_results.get(org.organization_id) 1312 if tier_result: 1313 org.customer_tier = tier_result.customer_tier 1314 1315 return OrganizationSearchResult( 1316 name_contains=name_contains, 1317 total_found=len(orgs), 1318 organizations=orgs, 1319 ) 1320 1321 1322@mcp_tool( 1323 read_only=True, 1324 idempotent=True, 1325) 1326def query_prod_workspaces( 1327 name_contains: Annotated[ 1328 str | None, 1329 Field( 1330 description=( 1331 "Case-insensitive substring to search for in workspace name or slug. " 1332 "For example, 'acme' will match workspaces named 'Acme Staging'." 1333 ), 1334 default=None, 1335 ), 1336 ] = None, 1337 email_domain: Annotated[ 1338 str | None, 1339 Field( 1340 description=( 1341 "Email domain to search for (e.g., 'motherduck.com'). " 1342 "Do not include the '@' symbol." 1343 ), 1344 default=None, 1345 ), 1346 ] = None, 1347 limit: Annotated[ 1348 int, 1349 Field( 1350 description="Maximum number of workspaces to return (default: 100)", 1351 default=100, 1352 ), 1353 ] = 100, 1354) -> WorkspaceSearchResult: 1355 """Search workspaces by name substring or email domain. 1356 1357 At least one of `name_contains` or `email_domain` must be provided. 1358 When `name_contains` is given, performs a case-insensitive substring match 1359 on workspace name and slug. When `email_domain` is given, matches 1360 workspaces by user email domain. 1361 1362 The returned organization IDs can be used with other tools like 1363 `query_prod_connections_by_connector` to find connections within 1364 those organizations for safe testing. 1365 """ 1366 if not name_contains and not email_domain: 1367 raise PyAirbyteInputError( 1368 message="At least one of `name_contains` or `email_domain` must be provided.", 1369 ) 1370 1371 if name_contains: 1372 rows = search_workspaces(name_contains=name_contains, limit=limit) 1373 else: 1374 assert email_domain is not None 1375 clean_domain = email_domain.lstrip("@") 1376 rows = query_workspaces_by_email_domain(email_domain=clean_domain, limit=limit) 1377 1378 workspaces = [ 1379 WorkspaceInfo( 1380 organization_id=str(row["organization_id"]), 1381 workspace_id=str(row["workspace_id"]), 1382 workspace_name=row.get("workspace_name", ""), 1383 slug=row.get("slug"), 1384 email=row.get("email"), 1385 dataplane_group_id=_opt_str(row.get("dataplane_group_id")), 1386 dataplane_name=row.get("dataplane_name"), 1387 created_at=row.get("created_at"), 1388 ) 1389 for row in rows 1390 ] 1391 1392 # Enrich with tier annotation (annotation only, no filtering) 1393 unique_org_ids = list(dict.fromkeys(w.organization_id for w in workspaces)) 1394 tier_results = { 1395 r.organization_id: r 1396 for r in get_org_tiers( 1397 organization_ids=unique_org_ids, 1398 allow_degraded=True, 1399 ) 1400 } 1401 for ws in workspaces: 1402 tier_result = tier_results.get(ws.organization_id) 1403 if tier_result: 1404 ws.customer_tier = tier_result.customer_tier 1405 ws.is_eu = ws.dataplane_name == "EU" if ws.dataplane_name else False 1406 1407 return WorkspaceSearchResult( 1408 name_contains=name_contains, 1409 email_domain=email_domain.lstrip("@") if email_domain else None, 1410 total_workspaces_found=len(workspaces), 1411 unique_organization_ids=unique_org_ids, 1412 workspaces=workspaces, 1413 ) 1414 1415 1416# Backward-compatible alias 1417query_prod_workspaces_by_email_domain = query_prod_workspaces 1418 1419 1420def _build_connector_stats( 1421 connector_definition_id: str, 1422 connector_type: str, 1423 canonical_name: str | None, 1424 rows: list[dict[str, Any]], 1425 version_tags: dict[str, str | None], 1426) -> ConnectorConnectionStats: 1427 """Build ConnectorConnectionStats from query result rows.""" 1428 # Aggregate totals across all version groups 1429 total_connections = 0 1430 enabled_connections = 0 1431 active_connections = 0 1432 pinned_connections = 0 1433 unpinned_connections = 0 1434 total_succeeded = 0 1435 total_failed = 0 1436 total_cancelled = 0 1437 total_running = 0 1438 total_unknown = 0 1439 1440 by_version: list[VersionPinStats] = [] 1441 1442 for row in rows: 1443 version_id = row.get("pinned_version_id") 1444 row_total = int(row.get("total_connections", 0)) 1445 row_enabled = int(row.get("enabled_connections", 0)) 1446 row_active = int(row.get("active_connections", 0)) 1447 row_pinned = int(row.get("pinned_connections", 0)) 1448 row_unpinned = int(row.get("unpinned_connections", 0)) 1449 row_succeeded = int(row.get("succeeded_connections", 0)) 1450 row_failed = int(row.get("failed_connections", 0)) 1451 row_cancelled = int(row.get("cancelled_connections", 0)) 1452 row_running = int(row.get("running_connections", 0)) 1453 row_unknown = int(row.get("unknown_connections", 0)) 1454 1455 total_connections += row_total 1456 enabled_connections += row_enabled 1457 active_connections += row_active 1458 pinned_connections += row_pinned 1459 unpinned_connections += row_unpinned 1460 total_succeeded += row_succeeded 1461 total_failed += row_failed 1462 total_cancelled += row_cancelled 1463 total_running += row_running 1464 total_unknown += row_unknown 1465 1466 by_version.append( 1467 VersionPinStats( 1468 pinned_version_id=str(version_id) if version_id else None, 1469 docker_image_tag=version_tags.get(str(version_id)) 1470 if version_id 1471 else None, 1472 total_connections=row_total, 1473 enabled_connections=row_enabled, 1474 active_connections=row_active, 1475 latest_attempt=LatestAttemptBreakdown( 1476 succeeded=row_succeeded, 1477 failed=row_failed, 1478 cancelled=row_cancelled, 1479 running=row_running, 1480 unknown=row_unknown, 1481 ), 1482 ) 1483 ) 1484 1485 return ConnectorConnectionStats( 1486 connector_definition_id=connector_definition_id, 1487 connector_type=connector_type, 1488 canonical_name=canonical_name, 1489 total_connections=total_connections, 1490 enabled_connections=enabled_connections, 1491 active_connections=active_connections, 1492 pinned_connections=pinned_connections, 1493 unpinned_connections=unpinned_connections, 1494 latest_attempt=LatestAttemptBreakdown( 1495 succeeded=total_succeeded, 1496 failed=total_failed, 1497 cancelled=total_cancelled, 1498 running=total_running, 1499 unknown=total_unknown, 1500 ), 1501 by_version=by_version, 1502 ) 1503 1504 1505@mcp_tool( 1506 read_only=True, 1507 idempotent=True, 1508 open_world=True, 1509) 1510def query_prod_connector_connection_stats( 1511 source_definition_ids: Annotated[ 1512 list[str] | None, 1513 Field( 1514 description=( 1515 "List of source connector definition IDs (UUIDs) to get stats for. " 1516 "Example: ['afa734e4-3571-11ec-991a-1e0031268139']" 1517 ), 1518 default=None, 1519 ), 1520 ] = None, 1521 destination_definition_ids: Annotated[ 1522 list[str] | None, 1523 Field( 1524 description=( 1525 "List of destination connector definition IDs (UUIDs) to get stats for. " 1526 "Example: ['94bd199c-2ff0-4aa2-b98e-17f0acb72610']" 1527 ), 1528 default=None, 1529 ), 1530 ] = None, 1531 lookback_days: Annotated[ 1532 int, 1533 Field( 1534 description=( 1535 "Number of days to look back for 'active' connections (default: 7). " 1536 "Connections with sync activity within this window are counted as active." 1537 ), 1538 default=7, 1539 ), 1540 ] = 7, 1541) -> ConnectorConnectionStatsResponse: 1542 """Get aggregate connection stats for multiple connectors. 1543 1544 Returns counts of connections grouped by pinned version for each connector, 1545 including: 1546 - Total, enabled, and active connection counts 1547 - Pinned vs unpinned breakdown 1548 - Latest attempt status breakdown (succeeded, failed, cancelled, running, unknown) 1549 1550 This tool is designed for release monitoring workflows. It allows you to: 1551 1. Query recently released connectors to identify which ones to monitor 1552 2. Get aggregate stats showing how many connections are using each version 1553 3. See health metrics (pass/fail) broken down by version 1554 1555 The `lookback_days` parameter controls the lookback window for: 1556 - Counting 'active' connections (those with recent sync activity) 1557 - Determining 'latest attempt status' (most recent attempt within the window) 1558 1559 Connections with no sync activity in the lookback window will have 1560 'unknown' status in the latest_attempt breakdown. 1561 """ 1562 # Initialize empty lists if None 1563 source_ids = source_definition_ids or [] 1564 destination_ids = destination_definition_ids or [] 1565 1566 if not source_ids and not destination_ids: 1567 raise PyAirbyteInputError( 1568 message=( 1569 "At least one of source_definition_ids or destination_definition_ids " 1570 "must be provided." 1571 ), 1572 ) 1573 1574 sources: list[ConnectorConnectionStats] = [] 1575 destinations: list[ConnectorConnectionStats] = [] 1576 1577 # Process source connectors 1578 for source_def_id in source_ids: 1579 # Get version info for tag lookup 1580 versions = query_connector_versions(source_def_id) 1581 version_tags = { 1582 str(v["version_id"]): v.get("docker_image_tag") for v in versions 1583 } 1584 1585 # Get aggregate stats 1586 rows = query_source_connection_stats(source_def_id, days=lookback_days) 1587 1588 sources.append( 1589 _build_connector_stats( 1590 connector_definition_id=source_def_id, 1591 connector_type="source", 1592 canonical_name=None, 1593 rows=rows, 1594 version_tags=version_tags, 1595 ) 1596 ) 1597 1598 # Process destination connectors 1599 for dest_def_id in destination_ids: 1600 # Get version info for tag lookup 1601 versions = query_connector_versions(dest_def_id) 1602 version_tags = { 1603 str(v["version_id"]): v.get("docker_image_tag") for v in versions 1604 } 1605 1606 # Get aggregate stats 1607 rows = query_destination_connection_stats(dest_def_id, days=lookback_days) 1608 1609 destinations.append( 1610 _build_connector_stats( 1611 connector_definition_id=dest_def_id, 1612 connector_type="destination", 1613 canonical_name=None, 1614 rows=rows, 1615 version_tags=version_tags, 1616 ) 1617 ) 1618 1619 return ConnectorConnectionStatsResponse( 1620 sources=sources, 1621 destinations=destinations, 1622 lookback_days=lookback_days, 1623 generated_at=datetime.now(timezone.utc), 1624 ) 1625 1626 1627# ============================================================================= 1628# Connector Rollout Models and Tools 1629# ============================================================================= 1630 1631 1632class ConnectorRolloutInfo(BaseModel): 1633 """Information about a connector rollout.""" 1634 1635 rollout_id: str = Field(description="The rollout UUID") 1636 actor_definition_id: str = Field(description="The connector definition UUID") 1637 state: str = Field( 1638 description="Rollout state: initialized, workflow_started, in_progress, " 1639 "paused, finalizing, succeeded, errored, failed_rolled_back, canceled" 1640 ) 1641 initial_rollout_pct: int | None = Field( 1642 default=None, description="Initial rollout percentage" 1643 ) 1644 current_target_rollout_pct: int | None = Field( 1645 default=None, description="Current target rollout percentage" 1646 ) 1647 final_target_rollout_pct: int | None = Field( 1648 default=None, description="Final target rollout percentage" 1649 ) 1650 has_breaking_changes: bool = Field( 1651 description="Whether the RC has breaking changes" 1652 ) 1653 max_step_wait_time_mins: int | None = Field( 1654 default=None, description="Maximum wait time between rollout steps in minutes" 1655 ) 1656 rollout_strategy: str | None = Field( 1657 default=None, description="Rollout strategy: manual, automated, overridden" 1658 ) 1659 updated_by_user_id: str | None = Field( 1660 default=None, 1661 description="User ID recorded as last updating the rollout", 1662 ) 1663 updated_by_user_name: str | None = Field( 1664 default=None, 1665 description="Name recorded as last updating the rollout", 1666 ) 1667 updated_by_user_email: str | None = Field( 1668 default=None, 1669 description="Email recorded as last updating the rollout", 1670 ) 1671 workflow_run_id: str | None = Field( 1672 default=None, description="Temporal workflow run ID" 1673 ) 1674 error_msg: str | None = Field(default=None, description="Error message if errored") 1675 failed_reason: str | None = Field( 1676 default=None, description="Reason for failure if failed" 1677 ) 1678 paused_reason: str | None = Field( 1679 default=None, description="Reason for pause if paused" 1680 ) 1681 tag: str | None = Field(default=None, description="Optional tag for the rollout") 1682 created_at: datetime | None = Field( 1683 default=None, description="When the rollout was created" 1684 ) 1685 updated_at: datetime | None = Field( 1686 default=None, description="When the rollout was last updated" 1687 ) 1688 completed_at: datetime | None = Field( 1689 default=None, description="When the rollout completed (if terminal)" 1690 ) 1691 expires_at: datetime | None = Field( 1692 default=None, description="When the rollout expires" 1693 ) 1694 rc_docker_image_tag: str | None = Field( 1695 default=None, description="Docker image tag of the release candidate" 1696 ) 1697 rc_docker_repository: str | None = Field( 1698 default=None, description="Docker repository of the release candidate" 1699 ) 1700 initial_docker_image_tag: str | None = Field( 1701 default=None, description="Docker image tag of the initial version" 1702 ) 1703 initial_docker_repository: str | None = Field( 1704 default=None, description="Docker repository of the initial version" 1705 ) 1706 filters: dict[str, Any] | None = Field( 1707 default=None, 1708 description="Raw rollout filters JSON (e.g., {'tierFilter': {'tier': 'TIER_0'}})", 1709 ) 1710 customer_tier: str | None = Field( 1711 default=None, 1712 description="Customer tier targeted by this rollout (extracted from filters), " 1713 "e.g., 'TIER_0', 'TIER_1'. None if no tier filter is set.", 1714 ) 1715 1716 1717def _parse_rollout_filters(filters_raw: Any) -> dict[str, Any] | None: 1718 """Parse the rollout filters field from a database row. 1719 1720 The filters field may be a JSON string, a dict, or None. 1721 """ 1722 if filters_raw is None: 1723 return None 1724 if isinstance(filters_raw, dict): 1725 return filters_raw 1726 if isinstance(filters_raw, str): 1727 try: 1728 parsed = json.loads(filters_raw) 1729 if isinstance(parsed, dict): 1730 return parsed 1731 except (json.JSONDecodeError, TypeError): 1732 pass 1733 return None 1734 1735 1736def _extract_tier_from_filters(filters_raw: Any) -> str | None: 1737 """Extract customer tier from rollout filters JSON. 1738 1739 Supports two formats: 1740 - Legacy: `{"tierFilter": {"tier": "TIER_0"}}` 1741 - Current: `{"customerTierFilters": [{"name": "TIER", "value": ["TIER_1"], "operator": "IN"}]}` 1742 """ 1743 parsed = _parse_rollout_filters(filters_raw) 1744 if parsed is None: 1745 return None 1746 1747 # Current format: customerTierFilters list 1748 tier_filters = parsed.get("customerTierFilters") 1749 if isinstance(tier_filters, list): 1750 for entry in tier_filters: 1751 if isinstance(entry, dict) and entry.get("name") == "TIER": 1752 values = entry.get("value") 1753 if isinstance(values, list) and len(values) == 1: 1754 return str(values[0]) 1755 if isinstance(values, list) and len(values) > 1: 1756 return ", ".join(str(v) for v in values) 1757 1758 # Legacy format: tierFilter dict 1759 tier_filter = parsed.get("tierFilter") 1760 if isinstance(tier_filter, dict): 1761 tier = tier_filter.get("tier") 1762 if isinstance(tier, str): 1763 return tier 1764 1765 return None 1766 1767 1768def _row_to_connector_rollout_info(row: dict[str, Any]) -> ConnectorRolloutInfo: 1769 """Convert a database row to a ConnectorRolloutInfo model.""" 1770 return ConnectorRolloutInfo( 1771 rollout_id=str(row["rollout_id"]), 1772 actor_definition_id=str(row["actor_definition_id"]), 1773 state=row["state"], 1774 initial_rollout_pct=row.get("initial_rollout_pct"), 1775 current_target_rollout_pct=row.get("current_target_rollout_pct"), 1776 final_target_rollout_pct=row.get("final_target_rollout_pct"), 1777 has_breaking_changes=row["has_breaking_changes"], 1778 max_step_wait_time_mins=row.get("max_step_wait_time_mins"), 1779 rollout_strategy=row.get("rollout_strategy"), 1780 updated_by_user_id=str(row["updated_by_user_id"]) 1781 if row.get("updated_by_user_id") is not None 1782 else None, 1783 updated_by_user_name=row.get("updated_by_user_name"), 1784 updated_by_user_email=row.get("updated_by_user_email"), 1785 workflow_run_id=row.get("workflow_run_id"), 1786 error_msg=row.get("error_msg"), 1787 failed_reason=row.get("failed_reason"), 1788 paused_reason=row.get("paused_reason"), 1789 tag=row.get("tag"), 1790 created_at=row.get("created_at"), 1791 updated_at=row.get("updated_at"), 1792 completed_at=row.get("completed_at"), 1793 expires_at=row.get("expires_at"), 1794 rc_docker_image_tag=row.get("rc_docker_image_tag"), 1795 rc_docker_repository=row.get("rc_docker_repository"), 1796 initial_docker_image_tag=row.get("initial_docker_image_tag"), 1797 initial_docker_repository=row.get("initial_docker_repository"), 1798 filters=_parse_rollout_filters(row.get("filters")), 1799 customer_tier=_extract_tier_from_filters(row.get("filters")), 1800 ) 1801 1802 1803@mcp_tool( 1804 read_only=True, 1805 idempotent=True, 1806) 1807def query_prod_connector_rollouts( 1808 actor_definition_id: Annotated[ 1809 str | None, 1810 Field(description="Connector definition UUID to filter by (optional)"), 1811 ] = None, 1812 rollout_id: Annotated[ 1813 str | None, 1814 Field(description="Specific rollout UUID to look up (optional)"), 1815 ] = None, 1816 active_only: Annotated[ 1817 bool, 1818 Field(description="If true, only return active (non-terminal) rollouts"), 1819 ] = False, 1820 limit: Annotated[ 1821 int, 1822 Field(description="Maximum number of results (default: 100)"), 1823 ] = 100, 1824) -> list[ConnectorRolloutInfo]: 1825 """Query connector rollouts with flexible filtering. 1826 1827 Returns rollouts based on the provided filters. If no filters are specified, 1828 returns all active rollouts. Useful for monitoring rollout status and history. 1829 1830 Filter behavior: 1831 - rollout_id: Returns that specific rollout (ignores other filters) 1832 - active_only: Returns only active (non-terminal) rollouts 1833 - actor_definition_id: Returns rollouts for that specific connector 1834 - No filters: Returns all active rollouts (same as active_only=True) 1835 """ 1836 rows = query_connector_rollouts( 1837 actor_definition_id=actor_definition_id, 1838 rollout_id=rollout_id, 1839 active_only=active_only, 1840 limit=limit, 1841 ) 1842 return [_row_to_connector_rollout_info(row) for row in rows] 1843 1844 1845@mcp_tool( 1846 read_only=True, 1847 idempotent=True, 1848 open_world=True, 1849) 1850def query_prod_connection_sync_activity( 1851 start_at: Annotated[ 1852 datetime, 1853 Field( 1854 description=( 1855 "Inclusive start timestamp for the sync activity window. " 1856 "Must be timezone-aware (ISO 8601 with offset or `Z`)." 1857 ), 1858 ), 1859 ], 1860 end_at: Annotated[ 1861 datetime, 1862 Field( 1863 description=( 1864 "Exclusive end timestamp for the sync activity window. " 1865 "Must be timezone-aware and strictly after `start_at`." 1866 ), 1867 ), 1868 ], 1869 organization_id: Annotated[ 1870 str | OrganizationAliasEnum | None, 1871 Field( 1872 description=( 1873 "Optional organization UUID or alias. At least one of " 1874 "`organization_id`, `workspace_id`, or `connection_ids` is " 1875 "required. Accepts `@airbyte-internal` as an alias for the " 1876 "Airbyte internal org." 1877 ), 1878 default=None, 1879 ), 1880 ] = None, 1881 workspace_id: Annotated[ 1882 str | WorkspaceAliasEnum | None, 1883 Field( 1884 description=( 1885 "Optional workspace UUID or alias. At least one of " 1886 "`organization_id`, `workspace_id`, or `connection_ids` is " 1887 "required. Accepts `@devin-ai-sandbox` as an alias for the " 1888 "Devin AI sandbox workspace." 1889 ), 1890 default=None, 1891 ), 1892 ] = None, 1893 connection_ids: Annotated[ 1894 list[str] | None, 1895 Field( 1896 description=( 1897 "Optional list of connection UUIDs. At least one of " 1898 "`organization_id`, `workspace_id`, or `connection_ids` is " 1899 "required." 1900 ), 1901 default=None, 1902 ), 1903 ] = None, 1904 status_filter: Annotated[ 1905 StatusFilter, 1906 Field( 1907 description=( 1908 "Filter by job status: `all` (default), `succeeded`, or " 1909 "`failed`. Applied to `jobs.status` in the Prod DB Replica." 1910 ), 1911 default=StatusFilter.ALL, 1912 ), 1913 ] = StatusFilter.ALL, 1914 limit: Annotated[ 1915 int, 1916 Field( 1917 description="Maximum number of attempt rows to return.", 1918 default=1000, 1919 ), 1920 ] = 1000, 1921) -> list[dict[str, Any]]: 1922 """List recent sync jobs and attempts from the Prod DB Replica. 1923 1924 Returns one row per `(job, attempt)` pair for sync jobs whose `updated_at` 1925 falls in `[start_at, end_at)`, scoped to the provided organization, 1926 workspace, or connection IDs. Designed for live operational lookups — 1927 e.g. "what happened on this connection in the last hour" — not for 1928 historical analysis. 1929 1930 Each row is enriched with `customer_tier` and `is_eu` for the owning 1931 organization. Tier filtering is intentionally not applied — this is a 1932 read-only observability query. 1933 1934 Input requirements: 1935 - At least one of `organization_id`, `workspace_id`, or `connection_ids` 1936 must be provided (any combination is accepted). 1937 - `start_at` and `end_at` must be timezone-aware and `start_at < end_at`. 1938 1939 Key fields in each row: 1940 - `job_id`, `attempt_id`, `attempt_number` 1941 - `job_status`, `attempt_status` 1942 - `job_started_at`, `job_updated_at`, `attempt_ended_at` 1943 - `failure_summary` (JSON; populated when an attempt failed) 1944 - `connection_id`, `connection_name`, `connection_status` 1945 - `source_actor_id`, `source_actor_name`, `source_actor_definition_id` 1946 - `destination_actor_id`, `destination_actor_name`, 1947 `destination_actor_definition_id` 1948 - `workspace_id`, `workspace_name`, `organization_id` 1949 - `dataplane_group_id`, `dataplane_name` 1950 - `customer_tier`, `is_eu` (added by tier enrichment) 1951 """ 1952 resolved_organization_id = OrganizationAliasEnum.resolve(organization_id) 1953 resolved_workspace_id = WorkspaceAliasEnum.resolve(workspace_id) 1954 _validate_sync_activity_scope( 1955 organization_id=resolved_organization_id, 1956 workspace_id=resolved_workspace_id, 1957 connection_ids=connection_ids, 1958 ) 1959 normalized_start_at, normalized_end_at = _validate_sync_activity_window( 1960 start_at=start_at, 1961 end_at=end_at, 1962 ) 1963 1964 rows = query_connection_sync_activity_from_prod( 1965 start_at=normalized_start_at, 1966 end_at=normalized_end_at, 1967 organization_id=resolved_organization_id, 1968 workspace_id=resolved_workspace_id, 1969 connection_ids=connection_ids, 1970 status_filter=status_filter.value, 1971 limit=limit, 1972 ) 1973 return enrich_rows_by_org( 1974 rows=rows, 1975 allow_degraded=True, 1976 ) 1977 1978 1979# ============================================================================= 1980# Pinned Connector Versions Models and Tools 1981# ============================================================================= 1982 1983 1984class PinnedConnectorVersionInfo(BaseModel): 1985 """A connector version that has at least one scoped configuration pin.""" 1986 1987 version_id: str = Field(description="The actor_definition_version UUID") 1988 connector_definition_id: str = Field(description="The connector definition UUID") 1989 connector_name: str = Field(description="Human-readable connector name") 1990 docker_repository: str = Field(description="Docker repository path") 1991 docker_image_tag: str = Field(description="Docker image tag for this version") 1992 last_published: str | None = Field( 1993 default=None, description="ISO timestamp when this version was last published" 1994 ) 1995 pin_count: int = Field( 1996 description="Total number of scoped_configuration rows pinning to this version" 1997 ) 1998 breaking_change_pins: int = Field( 1999 default=0, 2000 description="Number of actor-scoped pins created by breaking changes", 2001 ) 2002 rollout_pins: int = Field( 2003 default=0, 2004 description="Number of pins created by connector rollouts", 2005 ) 2006 actor_pins: int = Field( 2007 description="Number of actor-scoped pins (excludes breaking change and rollout pins)" 2008 ) 2009 workspace_pins: int = Field(description="Number of workspace-scoped pins") 2010 org_pins: int = Field(description="Number of organization-scoped pins") 2011 2012 2013@mcp_tool( 2014 read_only=True, 2015 idempotent=True, 2016 open_world=True, 2017) 2018def query_connector_pin_stats( 2019 connector_definition_id: Annotated[ 2020 str | None, 2021 Field( 2022 description="Connector definition UUID to filter by (optional). " 2023 "Mutually exclusive with `connector_canonical_name`." 2024 ), 2025 ] = None, 2026 connector_canonical_name: Annotated[ 2027 str | None, 2028 Field( 2029 description="Connector canonical name (e.g. `source-postgres`) to filter by. " 2030 "Resolved to a definition ID via the registry. " 2031 "Mutually exclusive with `connector_definition_id`." 2032 ), 2033 ] = None, 2034) -> list[PinnedConnectorVersionInfo]: 2035 """Query connector versions that have at least one scoped configuration pin. 2036 2037 Returns versions from the prod DB that are referenced by at least one 2038 `scoped_configuration` pin (`key = 'connector_version'`). Each version 2039 appears exactly once with per-scope pin breakdown (actor, workspace, org). 2040 2041 If neither filter is provided, returns the global superset across all connectors. 2042 """ 2043 if connector_definition_id and connector_canonical_name: 2044 raise PyAirbyteInputError( 2045 message=( 2046 "Provide at most one of `connector_definition_id` or " 2047 "`connector_canonical_name`, not both." 2048 ), 2049 ) 2050 2051 resolved_id: str | None = None 2052 if connector_canonical_name: 2053 resolved_id = resolve_canonical_name_to_definition_id( 2054 canonical_name=connector_canonical_name, 2055 ) 2056 elif connector_definition_id: 2057 resolved_id = connector_definition_id 2058 2059 rows = query_versions_with_pins(actor_definition_id=resolved_id) 2060 return [ 2061 PinnedConnectorVersionInfo( 2062 version_id=str(row["version_id"]), 2063 connector_definition_id=str(row["connector_definition_id"]), 2064 connector_name=row["connector_name"], 2065 docker_repository=row["docker_repository"], 2066 docker_image_tag=row["docker_image_tag"], 2067 last_published=( 2068 row["last_published"].isoformat() if row.get("last_published") else None 2069 ), 2070 pin_count=row["pin_count"], 2071 breaking_change_pins=row.get("breaking_change_pins", 0), 2072 rollout_pins=row.get("rollout_pins", 0), 2073 actor_pins=row.get("actor_pins", 0), 2074 workspace_pins=row.get("workspace_pins", 0), 2075 org_pins=row.get("org_pins", 0), 2076 ) 2077 for row in rows 2078 ] 2079 2080 2081# ============================================================================= 2082# Organization-scoped Pin Models and Tools 2083# ============================================================================= 2084 2085 2086class PinOriginFilter(StrEnum): 2087 """How a `scoped_configuration` pin was created, used to filter pins.""" 2088 2089 ALL = "all" 2090 MANUAL = "manual" 2091 CONNECTOR_ROLLOUT = "connector_rollout" 2092 BREAKING_CHANGE = "breaking_change" 2093 2094 2095# Rollout states considered non-terminal ("active"). Kept in sync with the set 2096# used by the rollout-monitoring SQL in `airbyte_ops_mcp.prod_db_access.sql`. 2097_ACTIVE_ROLLOUT_STATES = frozenset( 2098 { 2099 "initialized", 2100 "workflow_started", 2101 "in_progress", 2102 "paused", 2103 "finalizing", 2104 "errored", 2105 } 2106) 2107 2108 2109def _pin_category(origin_type: str | None) -> str: 2110 """Classify a pin as `rollout`, `breaking_change`, or `manual`.""" 2111 if origin_type == "connector_rollout": 2112 return "rollout" 2113 if origin_type == "breaking_change": 2114 return "breaking_change" 2115 return "manual" 2116 2117 2118# Maps a `PinOriginFilter` to the `_pin_category` value it keeps. `origin_filter` 2119# is applied here in Python rather than in SQL — the fetched pin list is small, 2120# so an in-SQL `:origin_filter` OR-chain would only add scan cost. 2121_ORIGIN_FILTER_CATEGORIES: dict[str, str] = { 2122 "manual": "manual", 2123 "connector_rollout": "rollout", 2124 "breaking_change": "breaking_change", 2125} 2126 2127 2128def _resolve_connector_filter_id( 2129 *, 2130 connector_definition_id: str | None, 2131 connector_canonical_name: str | None, 2132) -> str | None: 2133 """Resolve mutually-exclusive connector inputs to a definition id or `None`. 2134 2135 Blank or whitespace-only inputs are treated as absent (`None`) so an 2136 optional filter passed as `""` does not become a real, zero-matching SQL 2137 filter. 2138 """ 2139 connector_definition_id = (connector_definition_id or "").strip() or None 2140 connector_canonical_name = (connector_canonical_name or "").strip() or None 2141 if connector_definition_id and connector_canonical_name: 2142 raise PyAirbyteInputError( 2143 message=( 2144 "Provide at most one of `connector_definition_id` or " 2145 "`connector_canonical_name`, not both." 2146 ), 2147 ) 2148 if connector_canonical_name: 2149 return resolve_canonical_name_to_definition_id( 2150 canonical_name=connector_canonical_name, 2151 ) 2152 return connector_definition_id 2153 2154 2155def _require_organization_id(organization_id: str | OrganizationAliasEnum) -> str: 2156 """Resolve a required organization id to a canonical UUID string. 2157 2158 Accepts an organization UUID or an `OrganizationAliasEnum` alias, resolving 2159 aliases to their UUID. The result is validated as a UUID and returned in 2160 canonical (lowercased) form for consistent logging and comparison. (The 2161 org-pin SQL casts this to native `uuid`, so matching is case-insensitive 2162 either way.) Raises `PyAirbyteInputError` on blank or malformed input rather 2163 than passing an invalid value to SQL and returning a confusing empty result. 2164 """ 2165 resolved = OrganizationAliasEnum.resolve(organization_id) 2166 if not resolved or not resolved.strip(): 2167 raise PyAirbyteInputError( 2168 message="`organization_id` is required (a non-empty organization UUID or alias).", 2169 ) 2170 try: 2171 return str(uuid.UUID(resolved.strip())) 2172 except ValueError as exc: 2173 raise PyAirbyteInputError( 2174 message="`organization_id` is not a valid organization UUID or alias.", 2175 ) from exc 2176 2177 2178def _normalize_optional_version_id(pinned_version_id: str | None) -> str | None: 2179 """Coerce a blank `pinned_version_id` to `None` and validate UUID format. 2180 2181 A blank or whitespace-only value is treated as "no filter" (`None`) rather 2182 than being passed to the SQL `uuid` cast, which would raise 2183 `invalid input syntax for type uuid`. 2184 """ 2185 normalized = (pinned_version_id or "").strip() or None 2186 if normalized is not None: 2187 try: 2188 uuid.UUID(normalized) 2189 except ValueError as exc: 2190 raise PyAirbyteInputError( 2191 message="`pinned_version_id` is not a valid UUID.", 2192 ) from exc 2193 return normalized 2194 2195 2196class OrgVersionPinStats(BaseModel): 2197 """A connector version pinned somewhere under an organization, with counts.""" 2198 2199 version_id: str = Field(description="The actor_definition_version UUID") 2200 connector_definition_id: str = Field(description="The connector definition UUID") 2201 connector_name: str = Field(description="Human-readable connector name") 2202 docker_repository: str = Field(description="Docker repository path") 2203 docker_image_tag: str = Field(description="Docker image tag for this version") 2204 last_published: str | None = Field( 2205 default=None, description="ISO timestamp when this version was last published" 2206 ) 2207 pin_count: int = Field( 2208 description="Total pins under the org targeting this version (all scopes)" 2209 ) 2210 manual_pins: int = Field( 2211 default=0, 2212 description="Pins with no system origin (user-created manual pins), any scope", 2213 ) 2214 rollout_pins: int = Field( 2215 default=0, description="Pins created by connector rollouts" 2216 ) 2217 breaking_change_pins: int = Field( 2218 default=0, description="Pins created by breaking changes" 2219 ) 2220 actor_pins: int = Field( 2221 description="Manual actor-scoped pins (excludes rollout and breaking-change)" 2222 ) 2223 workspace_pins: int = Field(description="Workspace-scoped pins under the org") 2224 org_pins: int = Field(description="Organization-scoped pins") 2225 has_active_rollout: bool = Field( 2226 default=False, 2227 description=( 2228 "`True` if at least one rollout pin is backed by a non-terminal " 2229 "`connector_rollout`" 2230 ), 2231 ) 2232 2233 2234class OrgConnectorPin(BaseModel): 2235 """A single `scoped_configuration` pin discovered under an organization.""" 2236 2237 connector_definition_id: str = Field(description="The connector definition UUID") 2238 connector_name: str = Field(description="Human-readable connector name") 2239 docker_repository: str = Field(description="Docker repository path") 2240 pinned_version_id: str = Field( 2241 description="The pinned actor_definition_version UUID" 2242 ) 2243 pinned_version_tag: str = Field( 2244 description="Docker image tag of the pinned version" 2245 ) 2246 pin_scope_type: str = Field( 2247 description="Scope of the pin: `organization`, `workspace`, or `actor`" 2248 ) 2249 scope_id: str = Field(description="UUID of the scoped entity") 2250 scope_name: str | None = Field( 2251 default=None, description="Display name of the scoped entity, when resolvable" 2252 ) 2253 pin_category: str = Field( 2254 description="Derived pin type: `manual`, `rollout`, or `breaking_change`" 2255 ) 2256 set_by: str | None = Field( 2257 default=None, 2258 description="Email (or name) of the user who set a manual pin, when known", 2259 ) 2260 rollout_id: str | None = Field( 2261 default=None, description="Backing connector_rollout UUID for rollout pins" 2262 ) 2263 rollout_state: str | None = Field( 2264 default=None, description="State of the backing rollout, for rollout pins" 2265 ) 2266 is_active_rollout: bool = Field( 2267 default=False, 2268 description="`True` when `rollout_state` is a non-terminal (active) state", 2269 ) 2270 description: str | None = Field(default=None, description="Free-text pin reason") 2271 reference_url: str | None = Field( 2272 default=None, description="Reference URL attached to the pin, when present" 2273 ) 2274 created_at: str | None = Field( 2275 default=None, description="ISO timestamp when the pin was created" 2276 ) 2277 expires_at: str | None = Field( 2278 default=None, description="ISO timestamp when the pin expires, when set" 2279 ) 2280 2281 2282@mcp_tool( 2283 read_only=True, 2284 idempotent=True, 2285 open_world=True, 2286) 2287def query_prod_pin_stats_for_organization( 2288 organization_id: Annotated[ 2289 str | OrganizationAliasEnum, 2290 Field( 2291 description="Organization UUID (or `@airbyte-internal` alias) to scope pins to. " 2292 "Resolve organization names to an ID first via `search_organizations`." 2293 ), 2294 ], 2295 connector_definition_id: Annotated[ 2296 str | None, 2297 Field( 2298 description="Connector definition UUID to filter by (optional). " 2299 "Mutually exclusive with `connector_canonical_name`." 2300 ), 2301 ] = None, 2302 connector_canonical_name: Annotated[ 2303 str | None, 2304 Field( 2305 description="Connector canonical name (e.g. `source-postgres`) to filter by. " 2306 "Resolved to a definition ID via the registry. " 2307 "Mutually exclusive with `connector_definition_id`." 2308 ), 2309 ] = None, 2310 limit: Annotated[ 2311 int, 2312 Field(description="Maximum number of versions to return (default: 1000)."), 2313 ] = 1000, 2314) -> list[OrgVersionPinStats]: 2315 """Query connector versions pinned anywhere under an organization. 2316 2317 Returns one row per pinned version, aggregating every `connector_version` 2318 pin whose scope belongs to the organization — the org itself, one of its 2319 workspaces, or an actor within one of those workspaces (actor, workspace, 2320 and organization scopes). Each row carries the per-scope pin breakdown, the 2321 manual/rollout/breaking-change split, and a `has_active_rollout` flag. 2322 2323 This powers the first step of the Organization Pins view (pick an org, then 2324 see the versions pinned under it). Use `query_prod_pins_for_organization` 2325 for the individual pins behind a selected version. 2326 """ 2327 resolved_org_id = _require_organization_id(organization_id) 2328 resolved_connector_id = _resolve_connector_filter_id( 2329 connector_definition_id=connector_definition_id, 2330 connector_canonical_name=connector_canonical_name, 2331 ) 2332 rows = query_org_pin_stats( 2333 resolved_org_id, 2334 connector_definition_id=resolved_connector_id, 2335 limit=limit, 2336 ) 2337 return [ 2338 OrgVersionPinStats( 2339 version_id=str(row["version_id"]), 2340 connector_definition_id=str(row["connector_definition_id"]), 2341 connector_name=row["connector_name"], 2342 docker_repository=row["docker_repository"], 2343 docker_image_tag=row["docker_image_tag"], 2344 last_published=( 2345 row["last_published"].isoformat() if row.get("last_published") else None 2346 ), 2347 pin_count=row["pin_count"], 2348 manual_pins=row.get("manual_pins", 0), 2349 rollout_pins=row.get("rollout_pins", 0), 2350 breaking_change_pins=row.get("breaking_change_pins", 0), 2351 actor_pins=row.get("actor_pins", 0), 2352 workspace_pins=row.get("workspace_pins", 0), 2353 org_pins=row.get("org_pins", 0), 2354 has_active_rollout=bool(row.get("has_active_rollout", False)), 2355 ) 2356 for row in rows 2357 ] 2358 2359 2360@mcp_tool( 2361 read_only=True, 2362 idempotent=True, 2363 open_world=True, 2364) 2365def query_prod_pins_for_organization( 2366 organization_id: Annotated[ 2367 str | OrganizationAliasEnum, 2368 Field( 2369 description="Organization UUID (or `@airbyte-internal` alias) to scope pins to. " 2370 "Resolve organization names to an ID first via `search_organizations`." 2371 ), 2372 ], 2373 connector_definition_id: Annotated[ 2374 str | None, 2375 Field( 2376 description="Connector definition UUID to filter by (optional). " 2377 "Mutually exclusive with `connector_canonical_name`." 2378 ), 2379 ] = None, 2380 connector_canonical_name: Annotated[ 2381 str | None, 2382 Field( 2383 description="Connector canonical name (e.g. `source-postgres`) to filter by. " 2384 "Resolved to a definition ID via the registry. " 2385 "Mutually exclusive with `connector_definition_id`." 2386 ), 2387 ] = None, 2388 pinned_version_id: Annotated[ 2389 str | None, 2390 Field( 2391 description="Actor_definition_version UUID to return only pins targeting " 2392 "that version. This is the post-selection filter for the org pins tab." 2393 ), 2394 ] = None, 2395 origin_filter: Annotated[ 2396 PinOriginFilter, 2397 Field( 2398 description="Restrict by how the pin was created: `all` (default), " 2399 "`manual`, `connector_rollout`, or `breaking_change`." 2400 ), 2401 ] = PinOriginFilter.ALL, 2402 limit: Annotated[ 2403 int, 2404 Field(description="Maximum number of pins to return (default: 1000)."), 2405 ] = 1000, 2406) -> list[OrgConnectorPin]: 2407 """List the individual connector-version pins discovered under an organization. 2408 2409 Returns one row per `scoped_configuration` pin whose scope belongs to the 2410 organization (org/workspace/actor), resolving the pinned connector and 2411 version, the scope's display name, the manual author's email, and — for 2412 rollout-origin pins — the backing `connector_rollout` id and state. This 2413 directly answers whether each pin is manual or caused by an active rollout. 2414 2415 This powers the second step of the Organization Pins view: after picking a 2416 version from `query_prod_pin_stats_for_organization`, pass its 2417 `pinned_version_id` here to list the pins behind it. 2418 """ 2419 resolved_org_id = _require_organization_id(organization_id) 2420 resolved_connector_id = _resolve_connector_filter_id( 2421 connector_definition_id=connector_definition_id, 2422 connector_canonical_name=connector_canonical_name, 2423 ) 2424 rows = query_org_connector_pins( 2425 resolved_org_id, 2426 connector_definition_id=resolved_connector_id, 2427 pinned_version_id=_normalize_optional_version_id(pinned_version_id), 2428 limit=limit, 2429 ) 2430 kept_category = _ORIGIN_FILTER_CATEGORIES.get(origin_filter.value) 2431 pins: list[OrgConnectorPin] = [] 2432 for row in rows: 2433 origin_type = row.get("origin_type") 2434 if kept_category is not None and _pin_category(origin_type) != kept_category: 2435 continue 2436 rollout_state = row.get("rollout_state") 2437 set_by = row.get("pinned_by_user_email") or row.get("pinned_by_user_name") 2438 created_at = row.get("created_at") 2439 expires_at = row.get("expires_at") 2440 pins.append( 2441 OrgConnectorPin( 2442 connector_definition_id=str(row["connector_definition_id"]), 2443 connector_name=row["connector_name"], 2444 docker_repository=row["docker_repository"], 2445 pinned_version_id=str(row["pinned_version_id"]), 2446 pinned_version_tag=row["pinned_version_tag"], 2447 pin_scope_type=str(row["pin_scope_type"]), 2448 scope_id=str(row["scope_id"]), 2449 scope_name=row.get("scope_name"), 2450 pin_category=_pin_category(origin_type), 2451 set_by=str(set_by) if set_by else None, 2452 rollout_id=str(row["rollout_id"]) if row.get("rollout_id") else None, 2453 rollout_state=rollout_state, 2454 is_active_rollout=rollout_state in _ACTIVE_ROLLOUT_STATES, 2455 description=row.get("description"), 2456 reference_url=row.get("reference_url"), 2457 created_at=created_at.isoformat() if created_at else None, 2458 expires_at=expires_at.isoformat() if expires_at else None, 2459 ) 2460 ) 2461 return pins 2462 2463 2464# ============================================================================= 2465# Health and Population Summary Models and Tools 2466# ============================================================================= 2467 2468 2469def _resolve_connector_target( 2470 *, 2471 connector_version_id: str | None, 2472 connector_name: str | None, 2473 connector_version: str | None, 2474 connector_definition_id: str | None, 2475 connector_canonical_name: str | None, 2476) -> tuple[str | None, str, str, str | None]: 2477 """Resolve mixed connector inputs to a common target tuple. 2478 2479 Returns `(version_id, definition_id, docker_repository, docker_image_tag)`. 2480 `version_id` and `docker_image_tag` are `None` when only a definition-level 2481 identifier was supplied. 2482 """ 2483 if connector_version_id is not None: 2484 info = resolve_version_info(connector_version_id) 2485 return ( 2486 connector_version_id, 2487 str(info["actor_definition_id"]), 2488 info["docker_repository"], 2489 info.get("docker_image_tag"), 2490 ) 2491 if connector_name is not None and connector_version is not None: 2492 docker_repository = f"airbyte/{connector_name}" 2493 info = resolve_version_id_by_tag( 2494 docker_repository=docker_repository, 2495 docker_image_tag=connector_version, 2496 ) 2497 return ( 2498 str(info["version_id"]), 2499 str(info["actor_definition_id"]), 2500 docker_repository, 2501 connector_version, 2502 ) 2503 2504 definition_id: str | None = None 2505 if connector_definition_id is not None: 2506 definition_id = connector_definition_id 2507 elif connector_canonical_name is not None: 2508 definition_id = resolve_canonical_name_to_definition_id( 2509 canonical_name=connector_canonical_name, 2510 ) 2511 if definition_id is None: 2512 raise PyAirbyteInputError( 2513 message=( 2514 "Provide one of: `connector_version_id`, " 2515 "`connector_name` + `connector_version`, " 2516 "`connector_definition_id`, or `connector_canonical_name`." 2517 ), 2518 ) 2519 versions = query_connector_versions(definition_id) 2520 if not versions: 2521 raise PyAirbyteInputError( 2522 message=f"No connector versions found for definition: {definition_id}", 2523 ) 2524 return (None, definition_id, versions[0]["docker_repository"], None) 2525 2526 2527class ConnectorPopulationSummary(BaseModel): 2528 """Applied vs potential pinning audience for a connector, split by tier.""" 2529 2530 connector_definition_id: str = Field(description="The connector definition UUID") 2531 connector_version_id: str | None = Field( 2532 default=None, 2533 description="The version UUID, when a specific version was requested", 2534 ) 2535 docker_repository: str = Field(description="Docker repository path") 2536 docker_image_tag: str | None = Field( 2537 default=None, description="Docker image tag, when a version was requested" 2538 ) 2539 customer_tier_filter: str = Field( 2540 description="Tier filter applied to the counts (`TIER_0`/`TIER_1`/`TIER_2`/`UNKNOWN`/`ALL`)" 2541 ) 2542 active: TierSummary = Field( 2543 description=( 2544 "Potential audience: enabled actors of the definition (those with at " 2545 "least one active connection, `status = 'active'`), by tier" 2546 ) 2547 ) 2548 pinned_any: TierSummary = Field( 2549 description="Active actors already pinned to any version, by tier" 2550 ) 2551 eligible: TierSummary = Field( 2552 description="Active actors not pinned to any version (available to pin), by tier" 2553 ) 2554 pinned_to_version: TierSummary | None = Field( 2555 default=None, 2556 description=( 2557 "Applied audience: actors pinned to the requested version, by tier. " 2558 "`None` when no specific version was requested." 2559 ), 2560 ) 2561 2562 2563class ConnectorVersionHealthSummary(BaseModel): 2564 """Four-bucket health rollup for the actors running a connector version.""" 2565 2566 connector_version_id: str = Field(description="The connector version UUID") 2567 connector_definition_id: str = Field(description="The connector definition UUID") 2568 docker_repository: str = Field(description="Docker repository path") 2569 docker_image_tag: str | None = Field( 2570 default=None, description="Docker image tag for this version" 2571 ) 2572 days: int = Field(description="Lookback window in days") 2573 customer_tier_filter: str = Field( 2574 description="Tier filter applied to the counts (`TIER_0`/`TIER_1`/`TIER_2`/`UNKNOWN`/`ALL`)" 2575 ) 2576 healthy: int = Field(description="Actors with at least one successful sync") 2577 unhealthy: int = Field( 2578 description="Actors with failures and no successes in the window" 2579 ) 2580 awaiting: int = Field( 2581 description="Actors that ran but produced only non-terminal jobs (no result yet)" 2582 ) 2583 disabled: int = Field( 2584 description=( 2585 "Actors pinned to the version that produced no jobs in the window — " 2586 "the dormant/inactive audience" 2587 ) 2588 ) 2589 total_actors: int = Field(description="Total actors counted across all states") 2590 healthy_by_tier: TierSummary = Field(description="Healthy actors by tier") 2591 unhealthy_by_tier: TierSummary = Field(description="Unhealthy actors by tier") 2592 awaiting_by_tier: TierSummary = Field(description="Awaiting-results actors by tier") 2593 disabled_by_tier: TierSummary = Field(description="Disabled actors by tier") 2594 2595 2596@mcp_tool( 2597 read_only=True, 2598 idempotent=True, 2599 open_world=True, 2600) 2601def query_connector_population_summary( 2602 connector_version_id: Annotated[ 2603 str | None, 2604 Field( 2605 description=( 2606 "Connector version UUID. When provided, the applied audience " 2607 "(`pinned_to_version`) is included. Provide this OR " 2608 "`connector_name` + `connector_version` OR a definition-level " 2609 "identifier." 2610 ), 2611 ), 2612 ] = None, 2613 connector_name: Annotated[ 2614 str | None, 2615 Field( 2616 description=( 2617 "Canonical connector name (e.g. `source-postgres`). Used with " 2618 "`connector_version` to resolve the version UUID." 2619 ), 2620 ), 2621 ] = None, 2622 connector_version: Annotated[ 2623 str | None, 2624 Field( 2625 description=( 2626 "Semver version tag (e.g. `0.3.59`). Used with `connector_name`." 2627 ), 2628 ), 2629 ] = None, 2630 connector_definition_id: Annotated[ 2631 str | None, 2632 Field( 2633 description=( 2634 "Connector definition UUID for a definition-level summary " 2635 "(no `pinned_to_version` breakdown)." 2636 ), 2637 ), 2638 ] = None, 2639 connector_canonical_name: Annotated[ 2640 str | None, 2641 Field( 2642 description=( 2643 "Canonical connector name resolved to a definition ID via the " 2644 "registry, for a definition-level summary." 2645 ), 2646 ), 2647 ] = None, 2648 customer_tier_filter: Annotated[ 2649 TierFilter, 2650 Field( 2651 description=( 2652 "Which customer tiers to count. Defaults to `TIER_2`; pass " 2653 "`ALL` to include TIER_0/TIER_1 (revenue-critical) customers." 2654 ), 2655 ), 2656 ] = "TIER_2", 2657) -> ConnectorPopulationSummary: 2658 """Summarize the applied vs potential pinning audience for a connector, by tier. 2659 2660 Answers "how many actors are pinned and how many are eligible for pinning, 2661 split by tier" — the population view analogous to a rollout's audience. 2662 2663 - `active`: the potential audience — non-tombstoned actors of the 2664 definition that have at least one *active* connection 2665 (`connection.status = 'active'`). Inactive/disabled and deprecated 2666 connections are excluded, so this reflects the enabled, rollout-touchable 2667 population rather than every actor ever created. 2668 - `pinned_any`: active actors that already have an effective 2669 `connector_version` pin at any scope (actor/workspace/org). 2670 - `eligible`: `active` minus `pinned_any` — actors available to pin. 2671 - `pinned_to_version`: the applied audience for the requested version 2672 (only when a version identifier was provided). 2673 2674 Backed by `scoped_configuration` + actor/connection tables, so it is cheap 2675 to compute. Accepts a version identifier (preferred, adds 2676 `pinned_to_version`) or a definition-level identifier. 2677 """ 2678 version_id, definition_id, docker_repository, docker_image_tag = ( 2679 _resolve_connector_target( 2680 connector_version_id=connector_version_id, 2681 connector_name=connector_name, 2682 connector_version=connector_version, 2683 connector_definition_id=connector_definition_id, 2684 connector_canonical_name=connector_canonical_name, 2685 ) 2686 ) 2687 is_destination = not is_source_connector(docker_repository) 2688 2689 population_rows = query_actor_population_by_org( 2690 actor_definition_id=definition_id, 2691 is_destination=is_destination, 2692 ) 2693 pinned_version_rows = ( 2694 query_actors_pinned_to_version(version_id) if version_id is not None else None 2695 ) 2696 summary = summarize_population( 2697 population_rows, 2698 pinned_version_rows=pinned_version_rows, 2699 tier_filter=customer_tier_filter, 2700 # The population query above is run without a `target_version_id`, so the 2701 # version-aware summaries do not apply (the per-version audience comes 2702 # from `pinned_version_rows` instead). 2703 has_target_version=False, 2704 ) 2705 return ConnectorPopulationSummary( 2706 connector_definition_id=definition_id, 2707 connector_version_id=version_id, 2708 docker_repository=docker_repository, 2709 docker_image_tag=docker_image_tag, 2710 customer_tier_filter=customer_tier_filter, 2711 active=summary.active_by_tier, 2712 pinned_any=summary.pinned_any_by_tier, 2713 eligible=summary.eligible_by_tier, 2714 pinned_to_version=summary.pinned_to_version_by_tier, 2715 ) 2716 2717 2718@mcp_tool( 2719 read_only=True, 2720 idempotent=True, 2721 open_world=True, 2722) 2723def query_connector_version_health_summary( 2724 connector_version_id: Annotated[ 2725 str | None, 2726 Field( 2727 description=( 2728 "Connector version UUID. Provide this OR " 2729 "`connector_name` + `connector_version`." 2730 ), 2731 ), 2732 ] = None, 2733 connector_name: Annotated[ 2734 str | None, 2735 Field( 2736 description=( 2737 "Canonical connector name (e.g. `source-postgres`). Used with " 2738 "`connector_version` to resolve the version UUID." 2739 ), 2740 ), 2741 ] = None, 2742 connector_version: Annotated[ 2743 str | None, 2744 Field( 2745 description=( 2746 "Semver version tag (e.g. `0.3.59`). Used with `connector_name`." 2747 ), 2748 ), 2749 ] = None, 2750 days: Annotated[ 2751 int, 2752 Field( 2753 description="Number of days to look back (default: 7, max: 30)", 2754 ge=1, 2755 le=30, 2756 ), 2757 ] = 7, 2758 include_pinned_disabled: Annotated[ 2759 bool, 2760 Field( 2761 description=( 2762 "If `True` (default), actors pinned to the version that ran no " 2763 "jobs in the window are counted as `disabled`." 2764 ), 2765 ), 2766 ] = True, 2767 customer_tier_filter: Annotated[ 2768 TierFilter, 2769 Field( 2770 description=( 2771 "Which customer tiers to count. Defaults to `TIER_2`; pass " 2772 "`ALL` to include TIER_0/TIER_1 (revenue-critical) customers." 2773 ), 2774 ), 2775 ] = "TIER_2", 2776) -> ConnectorVersionHealthSummary: 2777 """Summarize actor health for a connector version into four buckets. 2778 2779 Answers "how many actors on a version are healthy / unhealthy / awaiting / 2780 disabled". Classification per actor over the lookback window: 2781 2782 - `healthy`: at least one successful sync (the same success signal the 2783 autopilot health gate uses). 2784 - `unhealthy`: failures and no successes. 2785 - `awaiting`: ran but produced only non-terminal jobs (no result yet). 2786 - `disabled`: (when `include_pinned_disabled`) pinned to the version with no 2787 jobs at all in the window — the dormant/inactive audience. 2788 2789 Built on the attempt/version primitive — the version stamped into 2790 `jobs.config` at job-creation time — not the current pin state, so it 2791 reflects actors that actually ran this version. This scans jobs over the 2792 window and is more expensive than the population summary; keep `days` 2793 bounded and query per-version. 2794 """ 2795 if connector_version_id is None and not ( 2796 connector_name is not None and connector_version is not None 2797 ): 2798 raise PyAirbyteInputError( 2799 message=( 2800 "Provide either `connector_version_id` or both " 2801 "`connector_name` and `connector_version`." 2802 ), 2803 ) 2804 version_id, definition_id, docker_repository, docker_image_tag = ( 2805 _resolve_connector_target( 2806 connector_version_id=connector_version_id, 2807 connector_name=connector_name, 2808 connector_version=connector_version, 2809 connector_definition_id=None, 2810 connector_canonical_name=None, 2811 ) 2812 ) 2813 assert version_id is not None 2814 is_destination = not is_source_connector(docker_repository) 2815 2816 health_rows = query_version_actor_health( 2817 version_id, 2818 is_destination=is_destination, 2819 days=days, 2820 ) 2821 pinned_actor_rows = ( 2822 query_actors_pinned_to_version(version_id) if include_pinned_disabled else None 2823 ) 2824 summary = summarize_version_health( 2825 health_rows, 2826 pinned_actor_rows=pinned_actor_rows, 2827 tier_filter=customer_tier_filter, 2828 ) 2829 return ConnectorVersionHealthSummary( 2830 connector_version_id=version_id, 2831 connector_definition_id=definition_id, 2832 docker_repository=docker_repository, 2833 docker_image_tag=docker_image_tag, 2834 days=days, 2835 customer_tier_filter=customer_tier_filter, 2836 healthy=summary.healthy, 2837 unhealthy=summary.unhealthy, 2838 awaiting=summary.awaiting, 2839 disabled=summary.disabled, 2840 total_actors=summary.total_actors, 2841 healthy_by_tier=summary.healthy_by_tier, 2842 unhealthy_by_tier=summary.unhealthy_by_tier, 2843 awaiting_by_tier=summary.awaiting_by_tier, 2844 disabled_by_tier=summary.disabled_by_tier, 2845 ) 2846 2847 2848def register_prod_db_ops_tools(app: FastMCP) -> None: 2849 """Register prod DB query tools with the FastMCP app.""" 2850 register_mcp_tools(app, mcp_module=__name__)