Documentation Index
Fetch the complete documentation index at: https://docs.argentos.ai/llms.txt
Use this file to discover all available pages before exploring further.
Prerequisites
- Python 3.11+
- Target vendor API docs reviewed
- ArgentOS repo cloned (
tools/aos/ directory available)
Directory Structure
Every connector lives at tools/aos/aos-{name}/:
tools/aos/aos-{name}/
├── connector.json <- Authoritative metadata
├── README.md <- Operator docs
└── agent-harness/
├── permissions.json <- Mode-gate map
├── pyproject.toml <- Python config + CLI entry point
├── cli_aos/
│ └── {name}/
│ ├── __init__.py <- Version marker
│ ├── constants.py <- Env var names, API base URLs
│ ├── errors.py <- CliError dataclass
│ ├── output.py <- JSON/text helpers
│ ├── config.py <- Auth resolution from env vars
│ ├── client.py <- HTTP client (actual API calls)
│ ├── runtime.py <- Command functions + health
│ └── cli.py <- Click CLI wiring
└── tests/
├── conftest.py <- sys.path setup
└── test_cli.py <- FakeClient mocking
Step 1: Copy the Reference Template
cp -r tools/aos/templates/python-click-tool tools/aos/aos-{name}
cd tools/aos/aos-{name}
Or copy from an existing connector as a reference:
cp -r tools/aos/aos-twilio tools/aos/aos-{name}
Rename all internal references from the source connector to your new name.
Step 2: Write connector.json
This is the authoritative manifest. It tells ArgentOS what your connector does, what commands it supports, what auth it needs, and how to render it in the dashboard.
{
"tool": "aos-{name}",
"backend": "{vendor}-api",
"manifest_schema_version": "1.0.0",
"connector": {
"label": "My Vendor",
"category": "category-name",
"categories": ["primary-category", "secondary"],
"resources": ["resource1", "resource2"]
},
"auth": {
"kind": "service-key",
"required": true,
"service_keys": ["VENDOR_API_KEY"],
"interactive_setup": [
"Get an API key from vendor.com/settings",
"Add VENDOR_API_KEY in API Keys settings"
]
},
"commands": [
{
"id": "items.list",
"summary": "List items",
"required_mode": "readonly",
"supports_json": true,
"resource": "items",
"action_class": "read"
},
{
"id": "items.create",
"summary": "Create a new item",
"required_mode": "write",
"supports_json": true,
"resource": "items",
"action_class": "write"
}
]
}
Step 3: Write permissions.json
Map every CLI command to a permission tier:
{
"commands": {
"health": "readonly",
"config.show": "readonly",
"capabilities": "readonly",
"items.list": "readonly",
"items.get": "readonly",
"items.create": "write",
"items.update": "write",
"items.delete": "admin"
}
}
Step 4: Implement client.py
This is the core — the HTTP client that calls the actual vendor API.
import json
import urllib.request
import urllib.error
class Client:
def __init__(self, api_key: str, base_url: str = "https://api.vendor.com/v1"):
self.api_key = api_key
self.base_url = base_url
def _request(self, method: str, path: str, data=None):
url = f"{self.base_url}{path}"
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json",
}
body = json.dumps(data).encode() if data else None
req = urllib.request.Request(url, data=body, headers=headers, method=method)
try:
with urllib.request.urlopen(req) as resp:
return json.loads(resp.read().decode())
except urllib.error.HTTPError as e:
raise RuntimeError(f"API error {e.code}: {e.read().decode()}")
def list_items(self, limit=30):
return self._request("GET", f"/items?limit={limit}")
def create_item(self, title: str, description: str = ""):
return self._request("POST", "/items", {"title": title, "description": description})
Guidelines:
- Use stdlib
urllib (no external HTTP dependencies)
- One method per command
- Return structured dicts, not raw responses
- Auth resolved from constructor params (injected by
config.py)
Step 5: Implement runtime.py
Command result functions and the three required contracts:
from .client import Client
from .config import resolve_config
from .output import success, error
def health():
cfg = resolve_config()
if not cfg.get("api_key"):
return {"status": "needs_setup", "checks": {"auth": False}, "next_steps": ["Set VENDOR_API_KEY"]}
try:
client = Client(cfg["api_key"])
client.list_items(limit=1)
return {"status": "healthy", "checks": {"auth": True, "api": True}}
except Exception as e:
return {"status": "degraded", "checks": {"auth": True, "api": False}, "detail": str(e)}
def items_list(mode, limit=30):
cfg = resolve_config()
client = Client(cfg["api_key"])
return success("items.list", client.list_items(limit))
Step 6: Implement cli.py
Wire commands to runtime functions using Click:
import click
from .runtime import health, items_list
from .output import format_output
@click.group()
@click.option("--json", "use_json", is_flag=True)
@click.option("--mode", default="readonly")
@click.option("--verbose", is_flag=True)
@click.pass_context
def cli(ctx, use_json, mode, verbose):
ctx.ensure_object(dict)
ctx.obj["json"] = use_json
ctx.obj["mode"] = mode
@cli.command()
@click.pass_context
def health_cmd(ctx):
"""Report connector health."""
click.echo(format_output(health(), ctx.obj["json"]))
# ... more commands
Entry point in pyproject.toml:
[project.scripts]
aos-{name} = "cli_aos.{name}.cli:cli"
Step 7: Write Tests
cd agent-harness
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
python -m pytest tests/ -v
Required test coverage:
- Commands match
connector.json manifest
- Health: missing creds returns
needs_setup, valid creds returns healthy
- Read commands return expected data shapes (use FakeClient)
- Write commands respect mode gating (calling write in readonly mode fails)
Step 8: Verify End-to-End
# Check capabilities
aos-{name} --json capabilities | python -m json.tool
# Check health
aos-{name} --json health | python -m json.tool
# Run tests
python -m pytest tests/ -v
Certification Gates
Before a connector is production-ready:
| Gate | Requirement |
|---|
| Contract | Valid connector.json, working capabilities, health, config show |
| Safety | Write actions classified, destructive actions gated at admin mode |
| Audit | Tool calls preserve evidence, failures return understandable errors |
| Docs | README exists with setup instructions and known limitations |
| Tests | All required test categories pass |
Risk Tiers
| Tier | Access Level | Examples | Review Required |
|---|
| 1: Read-heavy | Queries only | Search tickets, list contacts | Minimal |
| 2: Bounded write | Scoped mutations | Reply to message, create event | Standard |
| 3: Business mutation | Business state changes | CRM stage change, invoice creation | Thorough |
| 4: Destructive/admin | Irreversible operations | Delete records, revoke access | Explicit approval |