airanks-acp-zed
v0.1.0
Published
AI optimization rankings inside your editor: an Agent Client Protocol (ACP) agent that wraps AIR (airanks) so Zed can answer "what's the AI rank / AI visibility of <site>?" — same shared auth as every AIR client.
Maintainers
Readme
🪁 airanks-acp-zed
AIR inside your editor. An Agent Client Protocol (ACP) agent that wraps AIR — AI optimization made visible — so Zed (or any other ACP-speaking editor) can answer, right in the chat pane:
💬 "What's the AI rank / AI visibility of stripe.com?"
🌐 What is AIR?
AIR (Artificial Intelligence Ranking) by airanks makes AI optimization visible: how often, and how well, an AI assistant like ChatGPT cites a given domain when answering real questions. Check any site's AI Rank free at airanks.net — or install the browser toolbar to see it everywhere you browse.
This package is that same data, without leaving your editor: it's a small ACP agent that speaks
JSON-RPC over stdio to Zed, calls the same public airanks API the toolbar, the air CLI, and
every other AIR client use, and streams a readable Markdown answer back into the chat pane as it
arrives. Built on the official
@zed-industries/agent-client-protocol
TypeScript SDK.
📚 Table of contents
- What it does
- How a prompt turn flows
- Install
- Wire it into Zed
- Env vars
- Shared authentication
- Development
- Source layout
- Other AIR / airanks repos
- License
🎯 What it does
Ask it about a domain, a brand, or a phrase and it will:
| Step | What happens |
|---|---|
| 1️⃣ Extract | Pulls a domain-shaped token or a search phrase out of your free-form prompt (src/extract.ts). |
| 2️⃣ Call AIR | GET /v1/domains/{host} for a domain, GET /v1/search?q= for anything else. |
| 3️⃣ Hydrate | First-ever sight of a domain triggers server-side hydration — the agent polls while ai_files.status == "pending", streaming "still gathering…" chunks back to the editor instead of hanging silently, and honors 429 Retry-After. |
| 4️⃣ Stream | Renders a Markdown answer: AIR score (0–10), percentile, tracked occurrences/phrases/brands, llms.txt / llms-full.txt / ai.txt / robots.txt / JSON-LD presence, AI-crawler verdicts, and a summary, with a link to the full report on airanks.net. |
Ask "whoami" / "who am I" / "am I logged in" and it calls GET /user to report your AIR login
status instead. Anything that isn't domain-shaped is treated as a search query against domains,
brands, and phrases.
🔀 How a prompt turn flows
sequenceDiagram
autonumber
participant Zed as Zed (editor)
participant Agent as airanks-acp-zed
participant AIR as AIR API (airanks.net)
Zed->>Agent: prompt("what's the AI rank of stripe.com?")
Agent->>Agent: extractIntent() -> {type: "domain", host: "stripe.com"}
Agent-->>Zed: agent_message_chunk "Looking up stripe.com on AIR…"
Agent->>AIR: GET /v1/domains/stripe.com (Bearer? see auth)
alt ai_files.status == "pending"
AIR-->>Agent: 200, status: pending
Agent-->>Zed: agent_message_chunk "still gathering…"
Agent->>AIR: poll again after AIR_POLL_MS
else 429 rate limited
AIR-->>Agent: 429 Retry-After: n
Agent-->>Zed: agent_message_chunk "rate limited — retrying in ns…"
Agent->>AIR: retry after n seconds
end
AIR-->>Agent: 200, status: ready, data
Agent-->>Zed: agent_message_chunk (rendered Markdown report)📦 Install
npm install -g airanks-acp-zed
# or, from this directory:
npm install && npm run build🔌 Wire it into Zed
Add an entry under agent_servers in Zed's settings.json
(Zed > Settings > Open Settings or ~/.config/zed/settings.json):
{
"agent_servers": {
"AIR": {
"command": "airanks-acp",
"args": [],
"env": {}
}
}
}Point command at the built entrypoint directly:
{
"agent_servers": {
"AIR": {
"command": "node",
"args": ["/absolute/path/to/acp-zed/dist/index.js"]
}
}
}{
"agent_servers": {
"AIR": {
"command": "airanks-acp",
"env": { "AIR_API_KEY": "your-air-api-key" }
}
}
}Then open Zed's Agent panel, pick AIR as the agent, and ask it about a site. 🎉
⚙️ Env vars
| Var | Default | Purpose |
|---|---|---|
| AIR_API_KEY | — | Bearer token, always attaches (explicit intent). |
| AIR_API_BASE | https://airanks.net/api/v1 | Override the API host. |
| AIR_POLL_MS | 4000 | Poll interval while a domain is pending. |
| AIR_POLL_MAX_MS | 45000 | Give-up deadline for one prompt turn's poll loop. |
🔐 Shared authentication
Log in once, and every AIR client — this agent, the air CLI, the toolbar, the SDKs — picks it
up. This agent never prompts for a login itself; it just resolves a token, same order as every
other AIR client:
flowchart LR
A["AIR_API_KEY env var"] -->|set| T["✅ use it — always attaches"]
A -->|unset| B["~/.config/air/auth.json"]
B -->|found & host matches| T2["✅ use it — file-scoped to its saved host"]
B -->|missing| C["🕶️ anonymous, rate-limited tier"]AIR_API_KEYenv var — always attaches.~/.config/air/auth.json— written byair loginin any AIR client (a file-sourced token only rides to the host it was minted for).- Anonymous, rate-limited tier.
Run air login once (from node-cli or any other AIR
client) and this agent picks up the saved token automatically. Full contract:
../API-CONTRACT.md.
🛠️ Development
npm install
npm run build # tsc -> dist/
npm run dev # tsc --watch
node dist/index.js # run the agent directly, speaks ACP JSON-RPC over stdin/stdout🗂️ Source layout
| File | Role |
|---|---|
| src/index.ts | stdio wiring (ndJsonStream + AgentSideConnection). |
| src/agent.ts | the Agent implementation: initialize, newSession, authenticate, prompt, cancel. |
| src/air-client.ts | the shared AIR API + auth contract — hostname normalization, token resolution, domain/search/user fetches, pending-poll loop. |
| src/extract.ts | pulls a domain or search phrase out of a free-form prompt. |
| src/format.ts | renders API responses as Markdown for agent_message_chunk updates. |
🔗 Other AIR / airanks repos
| Repo | What it is |
|---|---|
| air-toolbar | The AIR browser toolbar — AI Rank + AI files, everywhere you browse. |
| air-cli (node) | Reference air CLI — the auth/API contract this agent implements. |
| air-cli (rust) · air-cli (go) | Native air CLIs, same shared login. |
| api-client (PHP) | Composer package for the AIR API. |
| js-sdk · python-sdk | Node/browser and Python SDKs. |
| mcp-server | AIR over Model Context Protocol, for any MCP agent. |
| acp-agent | AIR as a BeeAI Agent Communication Protocol agent (different ACP — not this Zed one). |
| agent-toolkit | Wiring AIR into Claude, Codex, Cursor & friends. |
📄 License
MIT — see LICENSE.
Built by airanks — AI optimization, measured. 🪁
