Skip to main content

AirOps Python SDK for building custom tools that integrate with AirOps Steps API

Project description

AirOps Python SDK

Build custom tools that integrate with AirOps' Steps API.

Installation

Requires Python 3.13+ and uv.

pip install airops

Quick Start

Prerequisites

Docker is required for building and deploying tools.

Install Docker:

  • macOS/Windows: Download Docker Desktop
  • Linux: Install via your package manager:
    # Debian/Ubuntu
    sudo apt-get update && sudo apt-get install docker.io
    
    # Fedora
    sudo dnf install docker
    
    # Arch
    sudo pacman -S docker
    

After installation, verify Docker is running:

docker --version

Create a Tool

Create a new tool project:

airops init my-tool
cd my-tool
cp .env.example .env  # add your AIROPS_API_TOKEN
airops run

This creates a ready-to-run project with:

  • tool.py - Example tool implementation
  • Dockerfile - Container image for deployment
  • .env.example - Environment variable template
  • tests/ - Example test suite

Example

from pydantic import Field
from airops import Tool, ToolOutputs, steps
from airops.inputs import ToolInputs, ShortText, Number


class Inputs(ToolInputs):
    url: ShortText = Field(..., description="Domain or URL to search")
    limit: Number = Field(default=5, description="Maximum results")


class Outputs(ToolOutputs):
    results: list[dict]


tool = Tool(
    name="keyword_extractor",
    description="Extract keywords from a URL using Google Search",
    input_model=Inputs,
    output_model=Outputs,
)


@tool.handler
async def run(inputs: Inputs) -> Outputs:
    # Call AirOps Steps API
    serp = await steps.execute(
        "google_search",
        {"query": f"site:{inputs.url}", "limit": inputs.limit},
    )
    return Outputs(results=serp["results"])


if __name__ == "__main__":
    tool.serve()

Input Types

Use AirOps input types for workflow-compatible schemas:

from airops.inputs import (
    ToolInputs,     # Base class for inputs (required)
    ShortText,      # Single-line text (str)
    LongText,       # Multi-line text (str)
    Number,         # Numeric value (int | float)
    Json,           # JSON value (dict, list, primitives)
    SingleSelect,   # Single choice from options
    MultiSelect,    # Multiple choices from options
    KnowledgeBase,  # Knowledge base ID (int)
    Brandkit,       # Brandkit ID (int)
    Database,       # Database ID (int)
)

class Inputs(ToolInputs):
    query: ShortText = Field(..., description="Search query")
    context: LongText = Field(default="", description="Additional context")
    limit: Number = Field(default=10)
    format: SingleSelect("json", "csv", "xml") = Field(default="json")
    tags: MultiSelect("urgent", "important") = Field(default=[])
    kb_id: KnowledgeBase = Field(..., description="Knowledge base to use")

Get the AirOps workflow schema:

print(tool.airops_inputs_schema)
# [{"name": "query", "interface": "short_text", "label": "Query", ...}, ...]

Configuration

Set the following environment variables:

# Required
export AIROPS_API_TOKEN="your-api-token"

# Optional
export AIROPS_API_BASE_URL="https://api.airops.com"  # default
export AIROPS_DEFAULT_TIMEOUT_S="7200"               # 2 hours default
export AIROPS_POLL_INTERVAL_S="2.0"                  # default

MCP Integration

The AirOps MCP provides tools for discovering available steps, schemas, and workspace secrets.

To use the MCP you will have to configure it with your workspace API key, which can be found in the AirOps app under Settings -> Workspace -> API KEY

Claude Desktop

claude mcp add --transport http airops-sdk-mcp https://app.airops.com/internal_api/sdk/mcp --header "Authorization: Bearer <YOUR_WORKSPACE_TOKEN>"

Cursor

Add to your mcp.json file in Cursor Settings:

{
  "mcpServers": {
    "airops-sdk-mcp": {
      "url": "https://app.airops.com/internal_api/sdk/mcp",
      "headers": {
        "Authorization": "Bearer <YOUR_WORKSPACE_TOKEN>"
      }
    }
  }
}

The MCP exposes:

  • Step discovery and search
  • Input/output schema inspection
  • Workspace secrets listing
  • Tool building guidance at /airops-internal/tool_building_prompt

Usage

Running Locally

uv run tool.py

This starts a local server with:

  • API: http://localhost:8080/runs - Start and poll tool executions
  • UI: http://localhost:8080/ - Browser-based testing interface

Using the Steps API

from airops import steps

# Execute a step and wait for completion
result = await steps.execute("google_search", {"query": "airops"})

# Or use start/poll for more control
handle = await steps.start("google_search", {"query": "airops"})
status = await steps.poll(handle.step_execution_id)

Tool Runtime API

Start a run

POST /runs
Content-Type: application/json

{"inputs": {"url": "example.com"}}

Response (202):

{"run_id": "...", "status": "queued"}

Poll run status

GET /runs/{run_id}

Response:

{
  "run_id": "...",
  "status": "success",
  "outputs": {"results": [...]}
}

Publishing to AirOps

Deploy your tool to AirOps for production use:

airops publish

Options:

  • --name: Override tool name (default: from tool.py)
  • --description: Override description (default: from tool.py)
  • --timeout: Deployment timeout in seconds (default: 600)

The command:

  1. Validates tool.py and Dockerfile exist
  2. Runs type checks with mypy
  3. Builds and exports Docker image
  4. Uploads to AirOps
  5. Monitors deployment until active

Error Handling

from airops import steps
from airops.errors import (
    AiropsError,
    AuthError,
    InvalidInputError,
    RateLimitedError,
    StepFailedError,
    StepTimeoutError,
    UpstreamUnavailableError,
)

try:
    result = await steps.execute("some_step", inputs)
except StepTimeoutError:
    print("Step timed out")
except StepFailedError as e:
    print(f"Step failed: {e.error_details}")
except AiropsError as e:
    print(f"AirOps error: {e}")

Development

# Install dev dependencies
uv sync --dev

# Run tests
uv run pytest

# Type checking
uv run mypy src/airops

# Linting
uv run ruff check src/airops

Using custom tools with agents

The custom tools built and published with the AirOps SDK can be used through the Tool Execution MCP server. This MCP server also requires setting it up with your workspace token and will discover all published tools and serve them as MCP tools your agent can use.

Claude Desktop

claude mcp add --transport http airops-tools-mcp https://app.airops.com/internal_api/tools/mcp --header "Authorization: Bearer <YOUR_WORKSPACE_TOKEN>"

Cursor

Add to your mcp.json file in Cursor Settings:

{
  "mcpServers": {
    "airops-tools-mcp": {
      "url": "https://app.airops.com/internal_api/tools/mcp",
      "headers": {
        "Authorization": "Bearer <YOUR_WORKSPACE_TOKEN>"
      }
    }
  }
}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

airops-0.2.3.tar.gz (93.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

airops-0.2.3-py3-none-any.whl (53.9 kB view details)

Uploaded Python 3

File details

Details for the file airops-0.2.3.tar.gz.

File metadata

  • Download URL: airops-0.2.3.tar.gz
  • Upload date:
  • Size: 93.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.16 {"installer":{"name":"uv","version":"0.9.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for airops-0.2.3.tar.gz
Algorithm Hash digest
SHA256 bcdaa3c9f2ab6981dd6dbcfb85c6c1514f73355cbe4509c3add51d87709efa30
MD5 1cab4cdda561bc2639bacf36f332f0dd
BLAKE2b-256 e983b22c2d746f66dbc6a1170f59017b2da5fc7fda192b63f60934f42c911b44

See more details on using hashes here.

File details

Details for the file airops-0.2.3-py3-none-any.whl.

File metadata

  • Download URL: airops-0.2.3-py3-none-any.whl
  • Upload date:
  • Size: 53.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.16 {"installer":{"name":"uv","version":"0.9.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for airops-0.2.3-py3-none-any.whl
Algorithm Hash digest
SHA256 ef7d57165342b61b7e61411844f7c5e66e0eb16be0f0e6eceeb9a6cad2efd696
MD5 28ab6a10de24604cdbffc9a5af75e1ae
BLAKE2b-256 640b47b6fdcd304a2d0861d84e8476f20a83f1be7f7e18cb7af97cc974cc44b4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page