@airctrl/mcp
v0.1.0
Published
AIRCTRL MCP server — expose the AI gateway to MCP-compatible agents (Claude Code, Cursor). Runs local/self-hosted.
Readme
@airctrl/mcp
MCP server that exposes the AIRCTRL AI gateway to MCP-compatible agents (Claude Code, Cursor, Warp, and any client that speaks the Model Context Protocol). It lets an agent set up and manage gateways, bring your own provider keys (BYOK), mint connection tokens, and read usage — from a single natural-language instruction.
Runs local / self-hosted — never hosted by us
This server is designed to run on your machine (via your MCP client) or on
your own infrastructure. We never host it. It only talks to the AIRCTRL
control plane over HTTPS with your Personal Access Token; it never receives,
stores, or returns provider plaintext keys. Provider keys you add via BYOK are
validated and encrypted server-side and are never returned by any tool. The
only secret a tool ever returns is a gateway connection token you explicitly
mint (create_gateway_token / setup_gateway), shown once.
Install
Published (intended usage):
npx -y @airctrl/mcpFrom the monorepo (local dev):
cd packages/mcp
npm ci
npm run build # emits dist/
node dist/index.js # started by your MCP client, not directlyConfiguration
The server reads its config from environment variables (your MCP client
passes them), namespaced AIRCTRL_MCP_* — the same convention as the official
MongoDB MCP server (MDB_MCP_*). Secrets go in the environment, never in a
prompt or a tool argument.
| Variable | Required | Description |
| --------------------- | -------- | ------------------------------------------------------------- |
| AIRCTRL_MCP_API_URL | no | Control-plane base URL. Default http://localhost:54330. |
| AIRCTRL_MCP_API_TOKEN | yes | Your Personal Access Token (sk-actrl-pat-…). Never logged. |
| AIRCTRL_MCP_KEY_* | as needed | Your BYOK provider keys (see below). One per line. |
Provider keys — AIRCTRL_MCP_KEY_* (never in the prompt)
Your provider API keys (Anthropic, OpenAI, …) go in environment variables whose
name must start with AIRCTRL_MCP_KEY_. You name them; the suffix is free,
so you can keep as many as you want:
AIRCTRL_MCP_KEY_ANTHROPIC_PROD = sk-ant-...
AIRCTRL_MCP_KEY_ANTHROPIC_TEST = sk-ant-...
AIRCTRL_MCP_KEY_OPENAI = sk-...In the prompt you reference a key by the name of its variable, never by its
value — e.g. "…use the key in AIRCTRL_MCP_KEY_ANTHROPIC_PROD". The server
reads that variable and uses its value. For safety it only reads variables with
the AIRCTRL_MCP_KEY_ prefix (so a prompt can't make it read AWS_SECRET_*,
PATH, or anything outside that namespace).
Getting a Personal Access Token (PAT)
A PAT is your user credential for the control plane (distinct from a gateway token). Create one from the AIRCTRL app (Settings → Developer → Create token) or via the API:
curl -X POST "$AIRCTRL_MCP_API_URL/v1/pats" \
-H "authorization: Bearer <your-session-or-existing-pat>" \
-H "content-type: application/json" \
-d '{"name":"my-laptop","scopes":{"readOnly":false}}'
# → { "ok": true, "data": { "pat": {...}, "plaintext": "sk-actrl-pat-…" } }The plaintext is shown once — store it in your MCP client config. Scope it
to specific projects and/or readOnly: true when you want a narrower token.
Client setup
Claude Code
Add to your .mcp.json (project) or run claude mcp add:
{
"mcpServers": {
"airctrl": {
"command": "npx",
"args": ["-y", "@airctrl/mcp"],
"env": {
"AIRCTRL_MCP_API_URL": "https://api.airctrl.dev",
"AIRCTRL_MCP_API_TOKEN": "sk-actrl-pat-…",
"AIRCTRL_MCP_KEY_ANTHROPIC_PROD": "sk-ant-…"
}
}
}
}Cursor
Add to ~/.cursor/mcp.json (global) or .cursor/mcp.json (project) — same
shape as above.
Warp
Warp configures MCP servers globally (Settings → Agents → MCP servers → Add), not
via a project file. It supports the same command/args/env shape (plus an
optional working_directory).
Local dev (unpublished build)
Point command/args at your built dist (works from any directory, no npm
publish needed):
{
"mcpServers": {
"airctrl": {
"command": "node",
"args": ["/absolute/path/to/airctrl/packages/mcp/dist/index.js"],
"env": {
"AIRCTRL_MCP_API_URL": "http://localhost:54330",
"AIRCTRL_MCP_API_TOKEN": "sk-actrl-pat-…",
"AIRCTRL_MCP_KEY_ANTHROPIC_TEST": "sk-ant-…"
}
}
}
}Tools
| Tool | What it does |
| ----------------------- | --------------------------------------------------------------------------------------------- |
| setup_gateway | One-shot: read a key from an AIRCTRL_MCP_KEY_* var, store it (BYOK), create a gateway with it, mint a token, return config. |
| list_providers | List supported providers (OpenAI, Anthropic, Gemini, …) with their ids. |
| list_gateways | List the gateways in a project. |
| create_gateway | Create a bare gateway (prefer setup_gateway when connecting a key). |
| add_provider_key | Store a provider key (from an AIRCTRL_MCP_KEY_* var), validated + encrypted; never returned. |
| rotate_provider_key | Replace the key of an existing credential (re-validated + re-encrypted). |
| set_routing | Set a gateway's default provider/model and/or attach a credential. |
| create_gateway_token | Mint a gateway connection token (sk-actrl-*), returned once. |
| read_usage | Read a gateway's request logs (provider, model, status, tokens, cost, latency). |
| get_connection_config | Compose the copy-paste connection config for a gateway. |
| airctrl_status | Report how this server is configured (API URL + whether a PAT is set). |
Example
First put your key in an AIRCTRL_MCP_KEY_* variable (in the client config
above), then ask your agent — referencing the variable name, not the key:
"With the AIRCTRL tools, call
setup_gatewayfor project97eccaf5-…, provideranthropic, using the key in the env varAIRCTRL_MCP_KEY_ANTHROPIC_PROD. Give me the connection config."
The agent calls setup_gateway once and gets back the gateway, a fresh
connection token, and the base URLs to point the OpenAI SDK or Claude Code at.
If a credential for that variable already exists, it is reused (no duplicates).
Connecting a client to the gateway
setup_gateway / get_connection_config return data-plane base URLs. Pair them
with the gateway token:
- OpenAI SDK:
base_url = <gateway>/compat,api_key = <gateway token>. - OpenAI-native:
POST <gateway>/openai/v1/chat/completions. - Claude Code:
ANTHROPIC_BASE_URL=<gateway>/anthropic,ANTHROPIC_AUTH_TOKEN=<gateway token>.
