Execute operations
You can execute operations using either the Python SDK or the Agent Engine API.
With Python
When you expose a connector as a tool for an AI agent, the agent needs to understand what entities and actions are available, what parameters each action requires, and how to paginate through results. Without this information in the tool description, agents make incorrect API calls or require extra discovery calls to understand the API.
Airbyte agent connectors provide two approaches for defining tools: manual docstrings for fine-grained control, and auto-generated descriptions for comprehensive coverage with minimal code. Generally, you want to use auto-generated descriptions unless you have a reason not to. For example, you might specifically want to avoid adding a tool, or autogenerated docstrings could be insufficient for your needs.
Manual docstrings
You can manually define individual tools with hand-written docstrings. This approach works well when you want to expose only specific operations or need custom parameter handling. However, it requires writing and maintaining docstrings for each tool, and the agent only knows about the operations you define.
from pydantic_ai import Agent
from airbyte_agent_github import GithubConnector
agent = Agent("openai:gpt-4o")
connector = GithubConnector(auth_config=...)
@agent.tool_plain
async def list_issues(owner: str, repo: str, limit: int = 10) -> str:
"""List open issues in a GitHub repository."""
result = await connector.issues.list(owner=owner, repo=repo, states=["OPEN"], per_page=limit)
return str(result.data)
The docstring is the tool's description, which helps the LLM understand when to use it. The function parameters become the tool's input schema, so the LLM knows what arguments to provide.
Auto-generated descriptions
For comprehensive tool coverage, use the @Connector.tool_utils decorator. This decorator reads the connector's metadata and automatically generates a detailed docstring that includes all available entities, actions, parameters, and response structures.
from pydantic_ai import Agent
from airbyte_agent_github import GithubConnector
agent = Agent("openai:gpt-4o")
connector = GithubConnector(auth_config=...)
@agent.tool_plain
@GithubConnector.tool_utils
async def github_execute(entity: str, action: str, params: dict | None = None):
return await connector.execute(entity, action, params or {})
The decorator automatically expands the docstring to include all available entities and actions, their required and optional parameters, response structure details, and pagination guidance. This gives the LLM everything it needs to correctly call the connector without additional discovery calls.
Decorator order matters
When using the tool_utils decorator with agent frameworks like Pydantic AI or FastMCP, decorator order matters. The @Connector.tool_utils decorator must be the inner decorator (closest to the function definition) because frameworks capture docstrings at decoration time.
Correct ordering:
@agent.tool_plain # Outer: framework decorator captures __doc__
@GithubConnector.tool_utils # Inner: sets __doc__ before framework sees it
async def github_execute(entity: str, action: str, params: dict | None = None):
...
If you reverse the order, the framework captures the original docstring before tool_utils has a chance to expand it, and the agent won't see the auto-generated documentation.
Custom docstrings
Generally, you should use a connector's default docstrings. Connectors generate useful docstrings automatically. However, there can be cases where autogenerated docstrings aren't ideal for your agent and it misunderstands how to use the tool. In this case, you can supply your own instructions.
Only provide custom docstrings if you need to, and in limited quantities. Doing this may affect connector operations in ways Airbyte didn't intend, and could cause a future connector version to work incorrectly.
@agent.tool_plain
@GithubConnector.tool_utils
async def github_execute(entity: str, action: str, params: dict | None = None):
"""Execute GitHub operations.
IMPORTANT: entity must be a simple name like 'issues', 'repositories', 'pull_requests'.
Action must be 'list', 'get', or 'api_search'.
Owner/repo info goes in params dict, e.g., params={"owner": "airbytehq", "repo": "airbyte"}
"""
return await connector.execute(entity, action, params or {})
Introspection
Connectors provide programmatic introspection methods for runtime discovery. These methods are available in the Python SDK.
list_entities()
Returns structured data about all available entities, their actions, and parameters.
entities = connector.list_entities()
for entity in entities:
print(f"{entity['entity_name']}: {entity['available_actions']}")
# Output: customers: ['list', 'get', 'search']
Each entity description includes the entity name, a description, available actions, and detailed parameter information for each action including parameter names, types, whether they're required, and their location (path, query, or body).
entity_schema()
Returns the JSON schema for a specific entity. This is useful for understanding the structure of returned data.
schema = connector.entity_schema("customers")
if schema:
print(f"Customer properties: {list(schema.get('properties', {}).keys())}")
With the API
You can execute operations directly through the Agent Engine API. This approach is useful when you're not using Python, when building custom integrations, or when you need to execute operations from a backend service.
Authentication
Before making API calls, you need an application token. For details on obtaining tokens, see Token types in the API documentation.
Execute an operation
To execute an operation against a connector, send a POST request to the execute endpoint with the entity, action, and any required parameters.
curl -X POST 'https://api.airbyte.ai/api/v1/integrations/connectors/<connector_id>/execute' \
--header 'Authorization: Bearer <your_application_token>' \
--header 'Content-Type: application/json' \
--data '{
"entity": "<entity_name>",
"action": "<action_name>",
"params": {}
}'
The request body contains three fields:
| Field | Type | Description |
|---|---|---|
entity | string | The entity to operate on, such as users, calls, or issues. |
action | string | The action to perform, such as list, get, or search. |
params | object | Parameters for the action. The required parameters depend on the entity and action. |
Example: List users
This example lists users from a Gong connector.
curl -X POST 'https://api.airbyte.ai/api/v1/integrations/connectors/<connector_id>/execute' \
--header 'Authorization: Bearer <your_application_token>' \
--header 'Content-Type: application/json' \
--data '{
"entity": "users",
"action": "list"
}'
Example: Get a specific record
This example retrieves a specific user by ID.
curl -X POST 'https://api.airbyte.ai/api/v1/integrations/connectors/<connector_id>/execute' \
--header 'Authorization: Bearer <your_application_token>' \
--header 'Content-Type: application/json' \
--data '{
"entity": "users",
"action": "get",
"params": {
"id": "<user_id>"
}
}'
Example: Search with filters
This example searches for records using filter conditions. The search action is available when you have the context store enabled.
curl -X POST 'https://api.airbyte.ai/api/v1/integrations/connectors/<connector_id>/execute' \
--header 'Authorization: Bearer <your_application_token>' \
--header 'Content-Type: application/json' \
--data '{
"entity": "users",
"action": "search",
"params": {
"query": {"filter": {"eq": {"active": true}}},
"limit": 100
}
}'
Response format
Responses include the requested data along with pagination information when applicable.
{
"data": [...],
"meta": {
"pagination": {
"totalRecords": 150,
"currentPageSize": 50,
"currentPageNumber": 1,
"cursor": "<cursor_for_next_page>"
}
}
}
To retrieve additional pages, include the cursor in subsequent requests.
curl -X POST 'https://api.airbyte.ai/api/v1/integrations/connectors/<connector_id>/execute' \
--header 'Authorization: Bearer <your_application_token>' \
--header 'Content-Type: application/json' \
--data '{
"entity": "users",
"action": "list",
"params": {
"cursor": "<cursor_from_previous_response>"
}
}'
Next steps
For detailed information about the entities and actions available for each connector, see the connector's reference documentation in the agent connectors section.