airbyte-internal-ops 0.6.1__py3-none-any.whl → 0.7.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. {airbyte_internal_ops-0.6.1.dist-info → airbyte_internal_ops-0.7.1.dist-info}/METADATA +6 -1
  2. {airbyte_internal_ops-0.6.1.dist-info → airbyte_internal_ops-0.7.1.dist-info}/RECORD +33 -30
  3. airbyte_ops_mcp/_sentry.py +101 -0
  4. airbyte_ops_mcp/cli/app.py +1 -1
  5. airbyte_ops_mcp/cli/{repo.py → local.py} +131 -8
  6. airbyte_ops_mcp/connector_ops/__init__.py +17 -0
  7. airbyte_ops_mcp/connector_ops/utils.py +859 -0
  8. airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/checks/assets.py +4 -5
  9. airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/checks/documentation/__init__.py +1 -1
  10. airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/checks/documentation/documentation.py +23 -22
  11. airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/checks/documentation/models.py +7 -7
  12. airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/checks/metadata.py +15 -15
  13. airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/checks/packaging.py +11 -9
  14. airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/checks/security.py +16 -20
  15. airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/checks/version.py +94 -18
  16. airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/cli.py +6 -8
  17. airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/models.py +7 -8
  18. airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/utils.py +2 -2
  19. airbyte_ops_mcp/mcp/_guidance.py +37 -0
  20. airbyte_ops_mcp/mcp/cloud_connector_versions.py +46 -9
  21. airbyte_ops_mcp/mcp/server.py +5 -0
  22. {airbyte_internal_ops-0.6.1.dist-info → airbyte_internal_ops-0.7.1.dist-info}/WHEEL +0 -0
  23. {airbyte_internal_ops-0.6.1.dist-info → airbyte_internal_ops-0.7.1.dist-info}/entry_points.txt +0 -0
  24. /airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/README.md +0 -0
  25. /airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/__init__.py +0 -0
  26. /airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/checks/__init__.py +0 -0
  27. /airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/checks/documentation/helpers.py +0 -0
  28. /airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/checks/documentation/templates/documentation_headers_check_description.md.j2 +0 -0
  29. /airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/checks/documentation/templates/section_content_description.md.j2 +0 -0
  30. /airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/checks/documentation/templates/template.md.j2 +0 -0
  31. /airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/consts.py +0 -0
  32. /airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/templates/__init__.py +0 -0
  33. /airbyte_ops_mcp/{_legacy/airbyte_ci/connector_qa → connector_qa}/templates/qa_checks.md.j2 +0 -0
@@ -7,21 +7,21 @@ import asyncclick as click
7
7
  import asyncer
8
8
  from jinja2 import Environment, PackageLoader, select_autoescape
9
9
 
10
- from airbyte_ops_mcp._legacy.airbyte_ci.connector_ops.utils import (
10
+ from airbyte_ops_mcp.connector_ops.utils import (
11
11
  Connector, # type: ignore
12
12
  )
13
- from airbyte_ops_mcp._legacy.airbyte_ci.connector_qa.checks import ENABLED_CHECKS
14
- from airbyte_ops_mcp._legacy.airbyte_ci.connector_qa.consts import (
13
+ from airbyte_ops_mcp.connector_qa.checks import ENABLED_CHECKS
14
+ from airbyte_ops_mcp.connector_qa.consts import (
15
15
  CONNECTORS_QA_DOC_TEMPLATE_NAME,
16
16
  )
17
- from airbyte_ops_mcp._legacy.airbyte_ci.connector_qa.models import (
17
+ from airbyte_ops_mcp.connector_qa.models import (
18
18
  Check,
19
19
  CheckCategory,
20
20
  CheckResult,
21
21
  CheckStatus,
22
22
  Report,
23
23
  )
24
- from airbyte_ops_mcp._legacy.airbyte_ci.connector_qa.utils import (
24
+ from airbyte_ops_mcp.connector_qa.utils import (
25
25
  get_all_connectors_in_directory,
26
26
  remove_strict_encrypt_suffix,
27
27
  )
@@ -97,9 +97,7 @@ async def run(
97
97
  if connector_directory:
98
98
  connectors += get_all_connectors_in_directory(connector_directory)
99
99
 
100
- connectors = sorted(
101
- list(connectors), key=lambda connector: connector.technical_name
102
- )
100
+ connectors = sorted(connectors, key=lambda connector: connector.technical_name)
103
101
 
104
102
  if not connectors:
105
103
  raise click.UsageError(
@@ -8,13 +8,12 @@ from dataclasses import dataclass
8
8
  from datetime import datetime
9
9
  from enum import Enum
10
10
  from pathlib import Path
11
- from typing import Dict, List, Optional
12
11
 
13
- from airbyte_ops_mcp._legacy.airbyte_ci.connector_ops.utils import (
12
+ from airbyte_ops_mcp.connector_ops.utils import (
14
13
  Connector,
15
14
  ConnectorLanguage,
16
15
  ) # type: ignore
17
- from airbyte_ops_mcp._legacy.airbyte_ci.connector_qa import consts
16
+ from airbyte_ops_mcp.connector_qa import consts
18
17
 
19
18
  ALL_LANGUAGES = [
20
19
  ConnectorLanguage.JAVA,
@@ -109,7 +108,7 @@ class Check(ABC):
109
108
  )
110
109
 
111
110
  @property
112
- def applies_to_connector_languages(self) -> List[ConnectorLanguage]:
111
+ def applies_to_connector_languages(self) -> list[ConnectorLanguage]:
113
112
  """The connector languages that the QA check applies to
114
113
 
115
114
  Raises:
@@ -121,7 +120,7 @@ class Check(ABC):
121
120
  return ALL_LANGUAGES
122
121
 
123
122
  @property
124
- def applies_to_connector_types(self) -> List[str]:
123
+ def applies_to_connector_types(self) -> list[str]:
125
124
  """The connector types that the QA check applies to
126
125
 
127
126
  Returns:
@@ -154,7 +153,7 @@ class Check(ABC):
154
153
  )
155
154
 
156
155
  @property
157
- def applies_to_connector_support_levels(self) -> Optional[List[str]]:
156
+ def applies_to_connector_support_levels(self) -> list[str] | None:
158
157
  """The connector's support levels that the QA check applies to
159
158
 
160
159
  Returns:
@@ -163,7 +162,7 @@ class Check(ABC):
163
162
  return None
164
163
 
165
164
  @property
166
- def applies_to_connector_cloud_usage(self) -> Optional[List[str]]:
165
+ def applies_to_connector_cloud_usage(self) -> list[str] | None:
167
166
  """The connector's cloud usage level that the QA check applies to
168
167
 
169
168
  Returns:
@@ -270,7 +269,7 @@ class Report:
270
269
  Returns:
271
270
  str: The connectors_report as a JSON string
272
271
  """
273
- connectors_report: Dict[str, Dict] = {}
272
+ connectors_report: dict[str, dict] = {}
274
273
  for check_result in self.check_results:
275
274
  connector = check_result.connector
276
275
  connectors_report.setdefault(
@@ -3,10 +3,10 @@
3
3
  from pathlib import Path
4
4
  from typing import Set
5
5
 
6
- from airbyte_ops_mcp._legacy.airbyte_ci.connector_ops.utils import (
6
+ from airbyte_ops_mcp.connector_ops.utils import (
7
7
  Connector, # type: ignore
8
8
  )
9
- from airbyte_ops_mcp._legacy.airbyte_ci.connector_qa import consts
9
+ from airbyte_ops_mcp.connector_qa import consts
10
10
 
11
11
 
12
12
  def remove_strict_encrypt_suffix(connector_technical_name: str) -> str:
@@ -4,6 +4,43 @@
4
4
  This module contains prompt text constants used by the MCP server's prompt templates.
5
5
  """
6
6
 
7
+ # =============================================================================
8
+ # Server Instructions
9
+ # =============================================================================
10
+ # This text is provided to AI agents via the MCP protocol's "instructions" field.
11
+ # It helps agents understand when to use this server's tools, especially when
12
+ # tool search is enabled. For more context, see:
13
+ # - FastMCP docs: https://gofastmcp.com/servers/overview
14
+ # - Claude tool search: https://www.anthropic.com/news/tool-use-improvements
15
+ # =============================================================================
16
+
17
+ MCP_SERVER_INSTRUCTIONS = """
18
+ Airbyte internal operations server for connector management, cloud administration,
19
+ and production database queries.
20
+
21
+ Use this server for:
22
+ - Publishing connector prereleases and managing version overrides/pins
23
+ - Running connector regression tests (single-version and comparison modes)
24
+ - Querying the Airbyte Cloud production database for workspace, connector, sync,
25
+ and connection diagnostics
26
+ - Triggering and monitoring GitHub Actions CI workflows
27
+ - Looking up Cloud Logging errors for debugging connector issues
28
+ - Performing repository operations on the Airbyte monorepo (for example, listing
29
+ connectors in the repo or inspecting connector definitions)
30
+
31
+ Requirements:
32
+ - GCP credentials for database queries and Cloud Logging access
33
+ - Airbyte Cloud credentials for cloud administration operations
34
+ - GitHub token for workflow dispatch and repository operations
35
+ - Local checkout of the Airbyte repository for repo tools (typically at `../airbyte`)
36
+
37
+ Note: This server is for Airbyte internal use only.
38
+ """.strip()
39
+
40
+ # =============================================================================
41
+ # Prompt Guidance Text
42
+ # =============================================================================
43
+
7
44
  TEST_MY_TOOLS_GUIDANCE = """
8
45
  Test all available tools in this MCP server to confirm they are working properly.
9
46
 
@@ -112,6 +112,15 @@ def get_cloud_connector_version(
112
112
  Literal["source", "destination"],
113
113
  "The type of connector (source or destination)",
114
114
  ],
115
+ config_api_root: Annotated[
116
+ str | None,
117
+ Field(
118
+ description="Optional API root URL override for the Config API. "
119
+ "Defaults to Airbyte Cloud (https://cloud.airbyte.com/api/v1). "
120
+ "Use this to target local or self-hosted deployments.",
121
+ default=None,
122
+ ),
123
+ ] = None,
115
124
  *,
116
125
  ctx: Context,
117
126
  ) -> ConnectorVersionInfo:
@@ -137,7 +146,7 @@ def get_cloud_connector_version(
137
146
  version_data = api_client.get_connector_version(
138
147
  connector_id=actor_id,
139
148
  connector_type=actor_type,
140
- config_api_root=constants.CLOUD_CONFIG_API_ROOT,
149
+ config_api_root=config_api_root or constants.CLOUD_CONFIG_API_ROOT,
141
150
  client_id=auth.client_id,
142
151
  client_secret=auth.client_secret,
143
152
  bearer_token=auth.bearer_token,
@@ -250,7 +259,16 @@ def set_cloud_connector_version_override(
250
259
  "Provides additional auditability for AI-driven operations.",
251
260
  default=None,
252
261
  ),
253
- ],
262
+ ] = None,
263
+ config_api_root: Annotated[
264
+ str | None,
265
+ Field(
266
+ description="Optional API root URL override for the Config API. "
267
+ "Defaults to Airbyte Cloud (https://cloud.airbyte.com/api/v1). "
268
+ "Use this to target local or self-hosted deployments.",
269
+ default=None,
270
+ ),
271
+ ] = None,
254
272
  *,
255
273
  ctx: Context,
256
274
  ) -> VersionOverrideOperationResult:
@@ -363,6 +381,7 @@ def set_cloud_connector_version_override(
363
381
  enhanced_override_reason = " | ".join(audit_parts)
364
382
 
365
383
  # Resolve auth and get current version info
384
+ resolved_config_api_root = config_api_root or constants.CLOUD_CONFIG_API_ROOT
366
385
  try:
367
386
  auth = _resolve_cloud_auth(ctx)
368
387
 
@@ -370,7 +389,7 @@ def set_cloud_connector_version_override(
370
389
  current_version_data = api_client.get_connector_version(
371
390
  connector_id=actor_id,
372
391
  connector_type=actor_type,
373
- config_api_root=constants.CLOUD_CONFIG_API_ROOT,
392
+ config_api_root=resolved_config_api_root,
374
393
  client_id=auth.client_id,
375
394
  client_secret=auth.client_secret,
376
395
  bearer_token=auth.bearer_token,
@@ -391,7 +410,7 @@ def set_cloud_connector_version_override(
391
410
  result = api_client.set_connector_version_override(
392
411
  connector_id=actor_id,
393
412
  connector_type=actor_type,
394
- config_api_root=constants.CLOUD_CONFIG_API_ROOT,
413
+ config_api_root=resolved_config_api_root,
395
414
  client_id=auth.client_id,
396
415
  client_secret=auth.client_secret,
397
416
  workspace_id=resolved_workspace_id,
@@ -407,7 +426,7 @@ def set_cloud_connector_version_override(
407
426
  updated_version_data = api_client.get_connector_version(
408
427
  connector_id=actor_id,
409
428
  connector_type=actor_type,
410
- config_api_root=constants.CLOUD_CONFIG_API_ROOT,
429
+ config_api_root=resolved_config_api_root,
411
430
  client_id=auth.client_id,
412
431
  client_secret=auth.client_secret,
413
432
  bearer_token=auth.bearer_token,
@@ -533,7 +552,16 @@ def set_workspace_connector_version_override(
533
552
  "Provides additional auditability for AI-driven operations.",
534
553
  default=None,
535
554
  ),
536
- ],
555
+ ] = None,
556
+ config_api_root: Annotated[
557
+ str | None,
558
+ Field(
559
+ description="Optional API root URL override for the Config API. "
560
+ "Defaults to Airbyte Cloud (https://cloud.airbyte.com/api/v1). "
561
+ "Use this to target local or self-hosted deployments.",
562
+ default=None,
563
+ ),
564
+ ] = None,
537
565
  *,
538
566
  ctx: Context,
539
567
  ) -> WorkspaceVersionOverrideResult:
@@ -647,7 +675,7 @@ def set_workspace_connector_version_override(
647
675
  workspace_id=resolved_workspace_id,
648
676
  connector_name=connector_name,
649
677
  connector_type=connector_type,
650
- config_api_root=constants.CLOUD_CONFIG_API_ROOT,
678
+ config_api_root=config_api_root or constants.CLOUD_CONFIG_API_ROOT,
651
679
  client_id=auth.client_id,
652
680
  client_secret=auth.client_secret,
653
681
  bearer_token=auth.bearer_token,
@@ -768,7 +796,16 @@ def set_organization_connector_version_override(
768
796
  "Provides additional auditability for AI-driven operations.",
769
797
  default=None,
770
798
  ),
771
- ],
799
+ ] = None,
800
+ config_api_root: Annotated[
801
+ str | None,
802
+ Field(
803
+ description="Optional API root URL override for the Config API. "
804
+ "Defaults to Airbyte Cloud (https://cloud.airbyte.com/api/v1). "
805
+ "Use this to target local or self-hosted deployments.",
806
+ default=None,
807
+ ),
808
+ ] = None,
772
809
  *,
773
810
  ctx: Context,
774
811
  ) -> OrganizationVersionOverrideResult:
@@ -878,7 +915,7 @@ def set_organization_connector_version_override(
878
915
  organization_id=organization_id,
879
916
  connector_name=connector_name,
880
917
  connector_type=connector_type,
881
- config_api_root=constants.CLOUD_CONFIG_API_ROOT,
918
+ config_api_root=config_api_root or constants.CLOUD_CONFIG_API_ROOT,
882
919
  client_id=auth.client_id,
883
920
  client_secret=auth.client_secret,
884
921
  bearer_token=auth.bearer_token,
@@ -22,12 +22,14 @@ from dotenv import load_dotenv
22
22
  from fastmcp import FastMCP
23
23
  from fastmcp_extensions import MCPServerConfigArg, mcp_server
24
24
 
25
+ from airbyte_ops_mcp._sentry import init_sentry_tracking
25
26
  from airbyte_ops_mcp.constants import (
26
27
  HEADER_AIRBYTE_CLOUD_CLIENT_ID,
27
28
  HEADER_AIRBYTE_CLOUD_CLIENT_SECRET,
28
29
  MCP_SERVER_NAME,
29
30
  ServerConfigKey,
30
31
  )
32
+ from airbyte_ops_mcp.mcp._guidance import MCP_SERVER_INSTRUCTIONS
31
33
  from airbyte_ops_mcp.mcp.cloud_connector_versions import (
32
34
  register_cloud_connector_version_tools,
33
35
  )
@@ -59,6 +61,7 @@ def _normalize_bearer_token(value: str) -> str | None:
59
61
  # Create the MCP server with built-in server info resource
60
62
  app = mcp_server(
61
63
  name=MCP_SERVER_NAME,
64
+ instructions=MCP_SERVER_INSTRUCTIONS,
62
65
  package_name="airbyte-internal-ops",
63
66
  advertised_properties={
64
67
  "docs_url": "https://github.com/airbytehq/airbyte-ops-mcp",
@@ -138,6 +141,7 @@ def main() -> None:
138
141
  suitable for direct MCP client connections.
139
142
  """
140
143
  _load_env()
144
+ init_sentry_tracking()
141
145
 
142
146
  print("=" * 60, flush=True, file=sys.stderr)
143
147
  print("Starting Airbyte Admin MCP server (stdio mode).", file=sys.stderr)
@@ -188,6 +192,7 @@ def main_http() -> None:
188
192
  MCP_HTTP_PORT: Port to listen on (default: 8082)
189
193
  """
190
194
  _load_env()
195
+ init_sentry_tracking()
191
196
 
192
197
  host = os.getenv("MCP_HTTP_HOST", DEFAULT_HTTP_HOST)
193
198
  port = _parse_port(os.getenv("MCP_HTTP_PORT"), DEFAULT_HTTP_PORT)