airbyte-agent-mcp 0.1.60__py3-none-any.whl → 0.1.68__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.
@@ -519,13 +519,14 @@ def _parse_oauth2_config(scheme: Any) -> dict[str, str]:
519
519
  config["refresh_url"] = refresh_url
520
520
 
521
521
  # Extract custom refresh configuration from x-airbyte-token-refresh extension
522
+ # Note: x_token_refresh is a Dict[str, Any], not a Pydantic model, so use .get()
522
523
  x_token_refresh = getattr(scheme, "x_token_refresh", None)
523
524
  if x_token_refresh:
524
- auth_style = getattr(x_token_refresh, "auth_style", None)
525
+ auth_style = x_token_refresh.get("auth_style")
525
526
  if auth_style:
526
527
  config["auth_style"] = auth_style
527
528
 
528
- body_format = getattr(x_token_refresh, "body_format", None)
529
+ body_format = x_token_refresh.get("body_format")
529
530
  if body_format:
530
531
  config["body_format"] = body_format
531
532
 
@@ -495,6 +495,14 @@ class LocalExecutor:
495
495
  print(result.data)
496
496
  """
497
497
  try:
498
+ # Check for hosted-only actions before converting to Action enum
499
+ if config.action == "search":
500
+ raise NotImplementedError(
501
+ "search is only available in hosted execution mode. "
502
+ "Initialize the connector with external_user_id, airbyte_client_id, "
503
+ "and airbyte_client_secret to use this feature."
504
+ )
505
+
498
506
  # Convert config to internal format
499
507
  action = Action(config.action) if isinstance(config.action, str) else config.action
500
508
  params = config.params or {}
@@ -1214,15 +1222,22 @@ class LocalExecutor:
1214
1222
  def _extract_metadata(
1215
1223
  self,
1216
1224
  response_data: dict[str, Any],
1225
+ response_headers: dict[str, str],
1217
1226
  endpoint: EndpointDefinition,
1218
1227
  ) -> dict[str, Any] | None:
1219
1228
  """Extract metadata from response using meta extractor.
1220
1229
 
1221
- Each field in meta_extractor dict is independently extracted using JSONPath.
1230
+ Each field in meta_extractor dict is independently extracted using JSONPath
1231
+ for body extraction, or special prefixes for header extraction:
1232
+ - @link.{rel}: Extract URL from RFC 5988 Link header by rel type
1233
+ - @header.{name}: Extract raw header value by header name
1234
+ - Otherwise: JSONPath expression for body extraction
1235
+
1222
1236
  Missing or invalid paths result in None for that field (no crash).
1223
1237
 
1224
1238
  Args:
1225
1239
  response_data: Full API response (before record extraction)
1240
+ response_headers: HTTP response headers
1226
1241
  endpoint: Endpoint with optional meta extractor configuration
1227
1242
 
1228
1243
  Returns:
@@ -1233,11 +1248,15 @@ class LocalExecutor:
1233
1248
  Example:
1234
1249
  meta_extractor = {
1235
1250
  "pagination": "$.records",
1236
- "request_id": "$.requestId"
1251
+ "request_id": "$.requestId",
1252
+ "next_page_url": "@link.next",
1253
+ "rate_limit": "@header.X-RateLimit-Remaining"
1237
1254
  }
1238
1255
  Returns: {
1239
1256
  "pagination": {"cursor": "abc", "total": 100},
1240
- "request_id": "xyz123"
1257
+ "request_id": "xyz123",
1258
+ "next_page_url": "https://api.example.com/data?cursor=abc",
1259
+ "rate_limit": "99"
1241
1260
  }
1242
1261
  """
1243
1262
  # Check if endpoint has meta extractor
@@ -1247,26 +1266,96 @@ class LocalExecutor:
1247
1266
  extracted_meta: dict[str, Any] = {}
1248
1267
 
1249
1268
  # Extract each field independently
1250
- for field_name, jsonpath_expr_str in endpoint.meta_extractor.items():
1269
+ for field_name, extractor_expr in endpoint.meta_extractor.items():
1251
1270
  try:
1252
- # Parse and apply JSONPath expression
1253
- jsonpath_expr = parse_jsonpath(jsonpath_expr_str)
1254
- matches = [match.value for match in jsonpath_expr.find(response_data)]
1255
-
1256
- if matches:
1257
- # Return first match (most common case)
1258
- extracted_meta[field_name] = matches[0]
1271
+ if extractor_expr.startswith("@link."):
1272
+ # RFC 5988 Link header extraction
1273
+ rel = extractor_expr[6:]
1274
+ extracted_meta[field_name] = self._extract_link_url(response_headers, rel)
1275
+ elif extractor_expr.startswith("@header."):
1276
+ # Raw header value extraction (case-insensitive lookup)
1277
+ header_name = extractor_expr[8:]
1278
+ extracted_meta[field_name] = self._get_header_value(response_headers, header_name)
1259
1279
  else:
1260
- # Path not found - set to None
1261
- extracted_meta[field_name] = None
1280
+ # JSONPath body extraction
1281
+ jsonpath_expr = parse_jsonpath(extractor_expr)
1282
+ matches = [match.value for match in jsonpath_expr.find(response_data)]
1283
+
1284
+ if matches:
1285
+ # Return first match (most common case)
1286
+ extracted_meta[field_name] = matches[0]
1287
+ else:
1288
+ # Path not found - set to None
1289
+ extracted_meta[field_name] = None
1262
1290
 
1263
1291
  except Exception as e:
1264
1292
  # Log error but continue with other fields
1265
- logging.warning(f"Failed to apply meta extractor for field '{field_name}' with path '{jsonpath_expr_str}': {e}. Setting to None.")
1293
+ logging.warning(f"Failed to apply meta extractor for field '{field_name}' with expression '{extractor_expr}': {e}. Setting to None.")
1266
1294
  extracted_meta[field_name] = None
1267
1295
 
1268
1296
  return extracted_meta
1269
1297
 
1298
+ @staticmethod
1299
+ def _extract_link_url(headers: dict[str, str], rel: str) -> str | None:
1300
+ """Extract URL from RFC 5988 Link header by rel type.
1301
+
1302
+ Parses Link header format: <url>; param1="value1"; rel="next"; param2="value2"
1303
+
1304
+ Supports:
1305
+ - Multiple parameters per link in any order
1306
+ - Both quoted and unquoted rel values
1307
+ - Multiple links separated by commas
1308
+
1309
+ Args:
1310
+ headers: Response headers dict
1311
+ rel: The rel type to extract (e.g., "next", "prev", "first", "last")
1312
+
1313
+ Returns:
1314
+ The URL for the specified rel type, or None if not found
1315
+ """
1316
+ link_header = headers.get("Link") or headers.get("link", "")
1317
+ if not link_header:
1318
+ return None
1319
+
1320
+ for link_segment in re.split(r",(?=\s*<)", link_header):
1321
+ link_segment = link_segment.strip()
1322
+
1323
+ url_match = re.match(r"<([^>]+)>", link_segment)
1324
+ if not url_match:
1325
+ continue
1326
+
1327
+ url = url_match.group(1)
1328
+ params_str = link_segment[url_match.end() :]
1329
+
1330
+ rel_match = re.search(r';\s*rel="?([^";,]+)"?', params_str, re.IGNORECASE)
1331
+ if rel_match and rel_match.group(1).strip() == rel:
1332
+ return url
1333
+
1334
+ return None
1335
+
1336
+ @staticmethod
1337
+ def _get_header_value(headers: dict[str, str], header_name: str) -> str | None:
1338
+ """Get header value with case-insensitive lookup.
1339
+
1340
+ Args:
1341
+ headers: Response headers dict
1342
+ header_name: Header name to look up
1343
+
1344
+ Returns:
1345
+ Header value or None if not found
1346
+ """
1347
+ # Try exact match first
1348
+ if header_name in headers:
1349
+ return headers[header_name]
1350
+
1351
+ # Case-insensitive lookup
1352
+ header_name_lower = header_name.lower()
1353
+ for key, value in headers.items():
1354
+ if key.lower() == header_name_lower:
1355
+ return value
1356
+
1357
+ return None
1358
+
1270
1359
  def _validate_required_body_fields(self, endpoint: Any, params: dict[str, Any], action: Action, entity: str) -> None:
1271
1360
  """Validate that required body fields are present for CREATE/UPDATE operations.
1272
1361
 
@@ -1394,7 +1483,7 @@ class _StandardOperationHandler:
1394
1483
  request_kwargs = self.ctx.determine_request_format(endpoint, body)
1395
1484
 
1396
1485
  # Execute async HTTP request
1397
- response = await self.ctx.http_client.request(
1486
+ response_data, response_headers = await self.ctx.http_client.request(
1398
1487
  method=endpoint.method,
1399
1488
  path=path,
1400
1489
  params=query_params if query_params else None,
@@ -1403,10 +1492,10 @@ class _StandardOperationHandler:
1403
1492
  )
1404
1493
 
1405
1494
  # Extract metadata from original response (before record extraction)
1406
- metadata = self.ctx.executor._extract_metadata(response, endpoint)
1495
+ metadata = self.ctx.executor._extract_metadata(response_data, response_headers, endpoint)
1407
1496
 
1408
1497
  # Extract records if extractor configured
1409
- response = self.ctx.extract_records(response, endpoint)
1498
+ response = self.ctx.extract_records(response_data, endpoint)
1410
1499
 
1411
1500
  # Assume success with 200 status code if no exception raised
1412
1501
  status_code = 200
@@ -1532,7 +1621,7 @@ class _DownloadOperationHandler:
1532
1621
  request_format = self.ctx.determine_request_format(operation, request_body)
1533
1622
  self.ctx.validate_required_body_fields(operation, params, action, entity)
1534
1623
 
1535
- metadata_response = await self.ctx.http_client.request(
1624
+ metadata_response, _ = await self.ctx.http_client.request(
1536
1625
  method=operation.method,
1537
1626
  path=path,
1538
1627
  params=query_params,
@@ -1547,7 +1636,7 @@ class _DownloadOperationHandler:
1547
1636
  )
1548
1637
 
1549
1638
  # Step 3: Stream file from extracted URL
1550
- file_response = await self.ctx.http_client.request(
1639
+ file_response, _ = await self.ctx.http_client.request(
1551
1640
  method="GET",
1552
1641
  path=file_url,
1553
1642
  headers=headers,
@@ -1555,7 +1644,7 @@ class _DownloadOperationHandler:
1555
1644
  )
1556
1645
  else:
1557
1646
  # One-step direct download: stream file directly from endpoint
1558
- file_response = await self.ctx.http_client.request(
1647
+ file_response, _ = await self.ctx.http_client.request(
1559
1648
  method=operation.method,
1560
1649
  path=path,
1561
1650
  params=query_params,
@@ -421,10 +421,14 @@ class HTTPClient:
421
421
  headers: dict[str, str] | None = None,
422
422
  *,
423
423
  stream: bool = False,
424
- ):
424
+ ) -> tuple[dict[str, Any], dict[str, str]]:
425
425
  """Execute a single HTTP request attempt (no retries).
426
426
 
427
427
  This is the core request logic, separated from retry handling.
428
+
429
+ Returns:
430
+ Tuple of (response_data, response_headers) for non-streaming requests.
431
+ For streaming requests, returns (response_object, response_headers).
428
432
  """
429
433
  # Ensure auth credentials are initialized (proactive refresh if needed)
430
434
  await self._ensure_auth_initialized()
@@ -475,7 +479,7 @@ class HTTPClient:
475
479
  status_code=status_code,
476
480
  response_body=f"<binary content, {response.headers.get('content-length', 'unknown')} bytes>",
477
481
  )
478
- return response
482
+ return response, dict(response.headers)
479
483
 
480
484
  # Parse response - handle non-JSON responses gracefully
481
485
  content_type = response.headers.get("content-type", "")
@@ -501,7 +505,7 @@ class HTTPClient:
501
505
  status_code=status_code,
502
506
  response_body=response_data,
503
507
  )
504
- return response_data
508
+ return response_data, dict(response.headers)
505
509
 
506
510
  except AuthenticationError as e:
507
511
  # Auth error (401, 403) - handle token refresh
@@ -631,7 +635,7 @@ class HTTPClient:
631
635
  *,
632
636
  stream: bool = False,
633
637
  _auth_retry_attempted: bool = False,
634
- ):
638
+ ) -> tuple[dict[str, Any], dict[str, str]]:
635
639
  """Make an async HTTP request with optional streaming and automatic retries.
636
640
 
637
641
  Args:
@@ -644,8 +648,9 @@ class HTTPClient:
644
648
  stream: If True, do not eagerly read the body (useful for downloads)
645
649
 
646
650
  Returns:
647
- - If stream=False: Parsed JSON (dict) or empty dict
648
- - If stream=True: Response object suitable for streaming
651
+ Tuple of (response_data, response_headers):
652
+ - If stream=False: (parsed JSON dict or empty dict, response headers dict)
653
+ - If stream=True: (response object suitable for streaming, response headers dict)
649
654
 
650
655
  Raises:
651
656
  HTTPStatusError: If request fails with 4xx/5xx status after all retries
@@ -152,6 +152,7 @@ class Server(BaseModel):
152
152
  url: str
153
153
  description: str | None = None
154
154
  variables: Dict[str, ServerVariable] = Field(default_factory=dict)
155
+ x_airbyte_replication_user_config_mapping: Dict[str, str] | None = Field(default=None, alias="x-airbyte-replication-user-config-mapping")
155
156
 
156
157
  @field_validator("url")
157
158
  @classmethod
@@ -12,7 +12,7 @@ to Operation, Schema, or other models when their respective features
12
12
  are implemented.
13
13
  """
14
14
 
15
- from typing import Literal, Optional
15
+ from typing import Literal
16
16
 
17
17
  from pydantic import BaseModel, ConfigDict, Field
18
18
 
@@ -109,6 +109,30 @@ class RetryConfig(BaseModel):
109
109
  retry_after_format: Literal["seconds", "milliseconds", "unix_timestamp"] = "seconds"
110
110
 
111
111
 
112
+ class CacheFieldProperty(BaseModel):
113
+ """
114
+ Nested property definition for object-type cache fields.
115
+
116
+ Supports recursive nesting to represent complex nested schemas in cache field definitions.
117
+ Used when a cache field has type 'object' and needs to define its internal structure.
118
+
119
+ Example YAML usage:
120
+ - name: collaboration
121
+ type: ['null', 'object']
122
+ description: "Collaboration data"
123
+ properties:
124
+ brief:
125
+ type: ['null', 'string']
126
+ comments:
127
+ type: ['null', 'array']
128
+ """
129
+
130
+ model_config = ConfigDict(populate_by_name=True, extra="forbid")
131
+
132
+ type: str | list[str]
133
+ properties: dict[str, "CacheFieldProperty"] | None = None
134
+
135
+
112
136
  class CacheFieldConfig(BaseModel):
113
137
  """
114
138
  Field configuration for cache mapping.
@@ -116,15 +140,19 @@ class CacheFieldConfig(BaseModel):
116
140
  Defines a single field in a cache entity, with optional name aliasing
117
141
  to map between user-facing field names and cache storage names.
118
142
 
143
+ For object-type fields, supports nested properties to define the internal structure
144
+ of complex nested schemas.
145
+
119
146
  Used in x-airbyte-cache extension for api_search operations.
120
147
  """
121
148
 
122
149
  model_config = ConfigDict(populate_by_name=True, extra="forbid")
123
150
 
124
151
  name: str
125
- x_airbyte_name: Optional[str] = Field(default=None, alias="x-airbyte-name")
152
+ x_airbyte_name: str | None = Field(default=None, alias="x-airbyte-name")
126
153
  type: str | list[str]
127
154
  description: str
155
+ properties: dict[str, CacheFieldProperty] | None = None
128
156
 
129
157
  @property
130
158
  def cache_name(self) -> str:
@@ -145,7 +173,7 @@ class CacheEntityConfig(BaseModel):
145
173
  model_config = ConfigDict(populate_by_name=True, extra="forbid")
146
174
 
147
175
  entity: str
148
- x_airbyte_name: Optional[str] = Field(default=None, alias="x-airbyte-name")
176
+ x_airbyte_name: str | None = Field(default=None, alias="x-airbyte-name")
149
177
  fields: list[CacheFieldConfig]
150
178
 
151
179
  @property
@@ -186,7 +214,7 @@ class CacheConfig(BaseModel):
186
214
 
187
215
  entities: list[CacheEntityConfig]
188
216
 
189
- def get_entity_mapping(self, user_entity: str) -> Optional[CacheEntityConfig]:
217
+ def get_entity_mapping(self, user_entity: str) -> CacheEntityConfig | None:
190
218
  """
191
219
  Get entity config by user-facing name.
192
220
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: airbyte-agent-mcp
3
- Version: 0.1.60
3
+ Version: 0.1.68
4
4
  Summary: MCP server that exposes Airbyte Connector SDK as MCP tools
5
5
  Author-email: Airbyte Support <support@airbyte.io>
6
6
  Requires-Python: >=3.13
@@ -10,11 +10,11 @@ airbyte_agent_mcp/_vendored/__init__.py,sha256=ILl7AHXMui__swyrjxrh9yRa4dLiwBvV6
10
10
  airbyte_agent_mcp/_vendored/connector_sdk/__init__.py,sha256=T5o7roU6NSpH-lCAGZ338sE5dlh4ZU6i6IkeG1zpems,1949
11
11
  airbyte_agent_mcp/_vendored/connector_sdk/auth_strategies.py,sha256=BdjAzFRTwXCmLFqYWqZ4Dx9RsqtI7pAkw-8NynSK4sQ,39914
12
12
  airbyte_agent_mcp/_vendored/connector_sdk/auth_template.py,sha256=nju4jqlFC_KI82ILNumNIyiUtRJcy7J94INIZ0QraI4,4454
13
- airbyte_agent_mcp/_vendored/connector_sdk/connector_model_loader.py,sha256=Cx9wPhKwWfzkc8i63IevL0EsN3iWUl_OA-_jA9EKNcE,34877
13
+ airbyte_agent_mcp/_vendored/connector_sdk/connector_model_loader.py,sha256=b88aoMynHxtG2dhzclkWrLiJbefTiKMzReyj3lOiwJI,34940
14
14
  airbyte_agent_mcp/_vendored/connector_sdk/constants.py,sha256=AtzOvhDMWbRJgpsQNWl5tkogHD6mWgEY668PgRmgtOY,2737
15
15
  airbyte_agent_mcp/_vendored/connector_sdk/exceptions.py,sha256=ss5MGv9eVPmsbLcLWetuu3sDmvturwfo6Pw3M37Oq5k,481
16
16
  airbyte_agent_mcp/_vendored/connector_sdk/extensions.py,sha256=XWRRoJOOrwUHSKbuQt5DU7CCu8ePzhd_HuP7c_uD77w,21376
17
- airbyte_agent_mcp/_vendored/connector_sdk/http_client.py,sha256=NdccrrBHI5rW56XnXcP54arCwywIVKnMeSQPas6KlOM,27466
17
+ airbyte_agent_mcp/_vendored/connector_sdk/http_client.py,sha256=S0eECrPVkjjro9xOhGA3QEwi2H0aWOwwoNZdfXd8OkE,27882
18
18
  airbyte_agent_mcp/_vendored/connector_sdk/introspection.py,sha256=2CyKXZHT74-1Id97uw1RLeyOi6TV24_hoNbQ6-6y7uI,10335
19
19
  airbyte_agent_mcp/_vendored/connector_sdk/secrets.py,sha256=J9ezMu4xNnLW11xY5RCre6DHP7YMKZCqwGJfk7ufHAM,6855
20
20
  airbyte_agent_mcp/_vendored/connector_sdk/types.py,sha256=CStkOsLtmZZdXylkdCsbYORDzughxygt1-Ucma0j-qE,8287
@@ -24,7 +24,7 @@ airbyte_agent_mcp/_vendored/connector_sdk/cloud_utils/__init__.py,sha256=4799Hv9
24
24
  airbyte_agent_mcp/_vendored/connector_sdk/cloud_utils/client.py,sha256=YxdRpQr9XjDzih6csSseBVGn9kfMtaqbOCXP0TPuzFY,7189
25
25
  airbyte_agent_mcp/_vendored/connector_sdk/executor/__init__.py,sha256=EmG9YQNAjSuYCVB4D5VoLm4qpD1KfeiiOf7bpALj8p8,702
26
26
  airbyte_agent_mcp/_vendored/connector_sdk/executor/hosted_executor.py,sha256=ydHcG-biRS1ITT5ELwPShdJW-KYpvK--Fos1ipNgHho,6995
27
- airbyte_agent_mcp/_vendored/connector_sdk/executor/local_executor.py,sha256=CMuknflYNY6_f83xrxvqewfI52MLYdPin3Rvz6HS3wU,67610
27
+ airbyte_agent_mcp/_vendored/connector_sdk/executor/local_executor.py,sha256=_RQXpBVXMlyvI2sL-F5N82nBKq7osZIn6H27Q1fse0g,71225
28
28
  airbyte_agent_mcp/_vendored/connector_sdk/executor/models.py,sha256=lYVT_bNcw-PoIks4WHNyl2VY-lJVf2FntzINSOBIheE,5845
29
29
  airbyte_agent_mcp/_vendored/connector_sdk/http/__init__.py,sha256=y8fbzZn-3yV9OxtYz8Dy6FFGI5v6TOqADd1G3xHH3Hw,911
30
30
  airbyte_agent_mcp/_vendored/connector_sdk/http/config.py,sha256=6J7YIIwHC6sRu9i-yKa5XvArwK2KU60rlnmxzDZq3lw,3283
@@ -45,16 +45,16 @@ airbyte_agent_mcp/_vendored/connector_sdk/performance/__init__.py,sha256=Sp5fSd1
45
45
  airbyte_agent_mcp/_vendored/connector_sdk/performance/instrumentation.py,sha256=_dXvNiqdndIBwDjeDKNViWzn_M5FkSUsMmJtFldrmsM,1504
46
46
  airbyte_agent_mcp/_vendored/connector_sdk/performance/metrics.py,sha256=FRff7dKt4iwt_A7pxV5n9kAGBR756PC7q8-weWygPSM,2817
47
47
  airbyte_agent_mcp/_vendored/connector_sdk/schema/__init__.py,sha256=Uymu-QuzGJuMxexBagIvUxpVAigIuIhz3KeBl_Vu4Ko,1638
48
- airbyte_agent_mcp/_vendored/connector_sdk/schema/base.py,sha256=RcsVLrO0L57g4kWfpDWjfc9gelvecplmoy43Zi-7GEY,4944
48
+ airbyte_agent_mcp/_vendored/connector_sdk/schema/base.py,sha256=4RYTkCWgyS5Z75z9TKj9vXySfO00HJ03QDtbdVYeHYM,5086
49
49
  airbyte_agent_mcp/_vendored/connector_sdk/schema/components.py,sha256=x3YCM1p2n_xHi50fMeOX0mXUiPqjGlLHs3Go8jXokb0,7895
50
50
  airbyte_agent_mcp/_vendored/connector_sdk/schema/connector.py,sha256=mSZk1wr2YSdRj9tTRsPAuIlCzd_xZLw-Bzl1sMwE0rE,3731
51
- airbyte_agent_mcp/_vendored/connector_sdk/schema/extensions.py,sha256=YuA40iwQeioPYIxJRM7VBY6CrbtT9AKYFoJrF3lFN3M,6239
51
+ airbyte_agent_mcp/_vendored/connector_sdk/schema/extensions.py,sha256=f7VhHrcIYxaPOJHMc4g0lpy04pZTbx5nlroNzAu5B9Q,7135
52
52
  airbyte_agent_mcp/_vendored/connector_sdk/schema/operations.py,sha256=RpzGtAI4yvAtMHAfMUMcUwgHv_qJojnKlNb75_agUF8,5729
53
53
  airbyte_agent_mcp/_vendored/connector_sdk/schema/security.py,sha256=zQ9RRuF3LBgLQi_4cItmjXbG_5WKlmCNM3nCil30H90,8470
54
54
  airbyte_agent_mcp/_vendored/connector_sdk/telemetry/__init__.py,sha256=RaLgkBU4dfxn1LC5Y0Q9rr2PJbrwjxvPgBLmq8_WafE,211
55
55
  airbyte_agent_mcp/_vendored/connector_sdk/telemetry/config.py,sha256=tLmQwAFD0kP1WyBGWBS3ysaudN9H3e-3EopKZi6cGKg,885
56
56
  airbyte_agent_mcp/_vendored/connector_sdk/telemetry/events.py,sha256=8Y1NbXiwISX-V_wRofY7PqcwEXD0dLMnntKkY6XFU2s,1328
57
57
  airbyte_agent_mcp/_vendored/connector_sdk/telemetry/tracker.py,sha256=Ftrk0_ddfM7dZG8hF9xBuPwhbc9D6JZ7Q9qs5o3LEyA,5579
58
- airbyte_agent_mcp-0.1.60.dist-info/METADATA,sha256=KRW4oLq5QYG2rUlpeCpSMXtfpytf0BEiVHe5wg7f5nk,3009
59
- airbyte_agent_mcp-0.1.60.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
60
- airbyte_agent_mcp-0.1.60.dist-info/RECORD,,
58
+ airbyte_agent_mcp-0.1.68.dist-info/METADATA,sha256=lm4gWhk2YW_kH_UT1um7uUMhDZY8bhl49jygjPRW4_A,3009
59
+ airbyte_agent_mcp-0.1.68.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
60
+ airbyte_agent_mcp-0.1.68.dist-info/RECORD,,