๐ airanks-acp-agent
AIR (Artificial Intelligence Ranking) by airanks โ AI optimization made visible. Check any site's AI Rank free at airanks.net (toolbar: airanks.net/toolbar).
This repo turns AIR into a callable ACP
(Agent Communication Protocol) agent named airank. Any ACP client, hub, or catalog โ
BeeAI included โ can POST /runs and ask airank for a site's AI rank the
same way it would call any other agent. ๐คโ๏ธ๐
๐บ๏ธ Contents
๐ง What it does
AIR measures AI optimization โ how often, and how well, an AI assistant like ChatGPT cites a
given domain when answering real questions. airank is the ACP door into that data:
- ๐ฏ Domain lookup โ send a hostname (
stripe.com), get its AIR score (0โ10), percentile, tracked citation stats, and AI-file posture (llms.txt,ai.txt,robots.txtAI-agent rules). - ๐ Search โ send a phrase (
payment processing), get matching domains, brands, and phrases that airanks tracks. - โณ Graceful hydration โ a domain brand-new to AIR triggers server-side hydration.
airankpolls and streams a "gatheringโฆ" progress message instead of guessing or hanging silently.
๐๏ธ Architecture
Four small modules, one job each:
flowchart LR
subgraph client["๐ฅ Any ACP client"]
C["BeeAI hub / catalog\ncurl / other agent"]
end
subgraph agent_pkg["๐ airanks_acp_agent"]
server["server.py\n@server.agent(name=\"airank\")"]
agentpy["agent.py\nparse โ poll โ format"]
api["api.py\nAirClient (httpx)"]
auth["auth.py\nresolve_token()"]
end
AIR[("โ๏ธ AIR API\nairanks.net/api/v1")]
C -- "POST /runs" --> server
server -- "answer(text)" --> agentpy
agentpy -- "domain() / search()" --> api
api -- "Bearer token?" --> auth
api -- "GET /v1/domains/{host}\nGET /v1/search?q=" --> AIR
AIR -. "JSON" .-> api
agentpy -. "streamed reply chunks" .-> server
server -. "RunYield" .-> C
- ๐
api.pyโ the asynchttpxclient (AirClient):GET /v1/domains/{host},GET /v1/search,GET /user, plusnormalize_hostname(). - ๐
auth.pyโ shared token resolution, identical across every AIR client. - ๐งฉ
agent.pyโ parses the caller's text, polls while a domain is pending, formats the reply. - ๐ช
server.pyโ registers theairankACP agent and runs the server.
๐ A lookup, step by step
The one behavior worth diagramming: a never-before-seen domain. Rather than fake a score,
airank streams a progress chunk and polls until AIR finishes hydrating it (or the ~180s budget
runs out):
sequenceDiagram
autonumber
participant U as ACP caller
participant A as agent.py
participant API as api.py (AirClient)
participant AIR as AIR API
U->>A: "stripe.com"
A->>API: normalize_hostname() โ domain()
API->>AIR: GET /v1/domains/stripe.com
AIR-->>API: data.ai_files.status = "pending"
API-->>A: pending payload
A-->>U: โณ "gathering data now, pollingโฆ"
loop every AIR_POLL_SECONDS (default 20s)
A->>API: domain()
API->>AIR: GET /v1/domains/stripe.com
alt still pending
AIR-->>API: status = "pending"
else ready
AIR-->>API: status = "ready" + score
API-->>A: final payload
A-->>U: "**stripe.com** โ AIR score 8/10 โฆ"
else 429 rate limited
AIR-->>API: 429 + Retry-After
A->>A: sleep(Retry-After)
end
end
๐ฆ Install
pip install -e .
Requires Python 3.10+. Two runtime dependencies: acp-sdk
(the official BeeAI/Linux Foundation Agent Communication Protocol server SDK) and httpx
(uvicorn<0.36 is pinned transitively โ see the comment in pyproject.toml).
๐ Quickstart
airank-acp
# or: python -m airanks_acp_agent.server
Starts an ACP server on http://127.0.0.1:8000 speaking the standard ACP REST contract:
GET /agents, GET /agents/airank, POST /runs, GET /runs/{run_id}, GET /runs/{run_id}/events.
Override the bind address with AIR_ACP_HOST / AIR_ACP_PORT.
Call it like any ACP agent:
curl -s http://127.0.0.1:8000/runs \
-H 'content-type: application/json' \
-d '{"agent_name": "airank", "input": [{"role": "user", "parts": [{"content": "stripe.com"}]}]}'
๐ Behavior reference
| You send | airank does |
Backing call |
|---|---|---|
A single word that parses as a hostname (stripe.com, www.Foo.com) |
Domain lookup โ AIR score, percentile, tracked stats, AI-file summary. Polls while pending. | GET /v1/domains/{host} |
Anything with a space, or a word that isn't a plausible host (payment processing) |
Search across domains, brands, and phrases AIR tracks. | GET /v1/search?q= |
| Empty input | Returns the built-in help string. | โ |
โ๏ธ Environment variables
| Var | Default | Purpose |
|---|---|---|
AIR_API_BASE |
https://airanks.net/api/v1 |
Point at a different API base (staging, a mirror, โฆ). |
AIR_API_KEY |
โ | Bearer token, always attaches (explicit intent). See Shared authentication. |
AIR_ACP_HOST |
127.0.0.1 |
Bind address for the ACP server. |
AIR_ACP_PORT |
8000 |
Bind port for the ACP server. |
AIR_POLL_SECONDS |
20 |
Interval between poll attempts while a domain is hydrating. |
AIR_POLL_MAX_SECONDS |
180 |
Total budget before giving up and telling the caller to retry. |
PLATFORM_URL |
http://127.0.0.1:8333 |
BeeAI platform to self-register with (via acp-sdk). |
PRODUCTION_MODE |
โ | Set true to disable BeeAI auto-registration on startup. |
๐ Registering with a BeeAI / ACP catalog
If a local BeeAI platform is running (PLATFORM_URL, default
http://127.0.0.1:8333), airank-acp self-registers as a provider on startup โ nothing further
to do. To register with a different hub or catalog by hand, point it at this server's base URL and
/agents/airank manifest, e.g.:
beeai agent add http://127.0.0.1:8000
or add a provider entry {"location": "http://<host>:<port>"} via that catalog's own API. Set
PRODUCTION_MODE=true to disable auto-registration (e.g. behind a reverse proxy in prod).
๐ Shared authentication
One login works across every AIR client โ the air CLI, the browser toolbar, the airanks
Python SDK, and this agent. Run air login anywhere and this agent picks it up automatically.
Resolution order:
| Order | Source | Behavior |
|---|---|---|
| 1๏ธโฃ | AIR_API_KEY env var |
Explicit intent โ always attaches. |
| 2๏ธโฃ | ~/.config/air/auth.json |
The file air login writes. A token loaded from here only attaches to requests aimed at the host it was saved for. |
| 3๏ธโฃ | Anonymous | No token โ subject to the anonymous rate limit (honored via Retry-After). |
๐๏ธ Layout
| File | Purpose |
|---|---|
src/airanks_acp_agent/api.py |
Async httpx client for GET /v1/domains/{host}, GET /v1/search, GET /user, plus hostname normalization โ ported from the shared API contract. |
src/airanks_acp_agent/auth.py |
Shared token resolution (AIR_API_KEY > auth file > anonymous). |
src/airanks_acp_agent/agent.py |
Parses the caller's text, polls while pending, formats the reply. |
src/airanks_acp_agent/server.py |
Registers the airank ACP agent and runs the server. |
tests/test_agent.py |
Hostname normalization + response-formatting tests. |
๐งช Testing
pip install -e ".[dev]"
pytest
๐ The airanks family
acp-agent is one door into AIR among many โ same API, same shared login, different front door:
| Repo | What it is |
|---|---|
node-cli |
air โ the reference command-line client. |
rust-cli / go-cli |
Zero-dependency Rust / Go builds of air. |
chrome-extension |
The AIR browser toolbar โ a page's AI Rank while you browse. |
mcp-server |
MCP server exposing air_rank / air_files / air_search tools. |
agent-toolkit |
Wire AIR into Claude, Codex, Cursor, or any MCP-speaking agent. |
acp-zed |
This same idea, wrapped for Zed instead of BeeAI. |
python-sdk / js-sdk / composer-package |
Language SDKs โ no CLI, just a client class. |
homebrew-tap |
brew install for the air CLI. |
claude-skills |
Open-source Claude Code skills built on AIR. |
See ../API-CONTRACT.md for the full wire contract every client shares.
๐ License
MIT โ see LICENSE.
Made with ๐ for the AI-optimization era. Powered by airanks.net.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file airanks_acp_agent-1.0.0.tar.gz.
File metadata
- Download URL: airanks_acp_agent-1.0.0.tar.gz
- Upload date:
- Size: 12.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f7084d058709c00dfcfd2db1273be5155a157631001d634a2d94926354b6f95b
|
|
| MD5 |
04f6c297c9bf7129770a917dd402ef40
|
|
| BLAKE2b-256 |
f6ea1d06294a07202e7576e9f5209a7ebfedc4a24af5e89a883e7cdd978b6a1c
|
Provenance
The following attestation bundles were made for airanks_acp_agent-1.0.0.tar.gz:
Publisher:
release.yml on airanks-net/acp-agent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
airanks_acp_agent-1.0.0.tar.gz -
Subject digest:
f7084d058709c00dfcfd2db1273be5155a157631001d634a2d94926354b6f95b - Sigstore transparency entry: 2482096069
- Sigstore integration time:
-
Permalink:
airanks-net/acp-agent@4a519f57f1f9656213983d30ae29d7c299f7eca6 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/airanks-net
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4a519f57f1f9656213983d30ae29d7c299f7eca6 -
Trigger Event:
push
-
Statement type:
File details
Details for the file airanks_acp_agent-1.0.0-py3-none-any.whl.
File metadata
- Download URL: airanks_acp_agent-1.0.0-py3-none-any.whl
- Upload date:
- Size: 14.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
464c30a4a5e30ff475228c3d7fc31e7218d9fafc89bf5afa269998d7cd85f6f0
|
|
| MD5 |
98f62ecf89f84401ad91833023014b61
|
|
| BLAKE2b-256 |
3a01c823a849b261aaf78687cbb9c81d34c2c0148609d77785bbaf43c86c57a5
|
Provenance
The following attestation bundles were made for airanks_acp_agent-1.0.0-py3-none-any.whl:
Publisher:
release.yml on airanks-net/acp-agent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
airanks_acp_agent-1.0.0-py3-none-any.whl -
Subject digest:
464c30a4a5e30ff475228c3d7fc31e7218d9fafc89bf5afa269998d7cd85f6f0 - Sigstore transparency entry: 2482096153
- Sigstore integration time:
-
Permalink:
airanks-net/acp-agent@4a519f57f1f9656213983d30ae29d7c299f7eca6 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/airanks-net
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4a519f57f1f9656213983d30ae29d7c299f7eca6 -
Trigger Event:
push
-
Statement type: