{"_id":"@airctrl/mcp","name":"@airctrl/mcp","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@airctrl/mcp","version":"0.1.0","type":"module","description":"AIRCTRL MCP server — expose the AI gateway to MCP-compatible agents (Claude Code, Cursor). Runs local/self-hosted.","license":"UNLICENSED","homepage":"https://airctrl.dev","bin":{"airctrl-mcp":"dist/index.js"},"main":"dist/index.js","publishConfig":{"access":"public"},"scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","lint":"eslint src","start":"node dist/index.js"},"dependencies":{"@airctrl/sdk":"0.1.0","@modelcontextprotocol/sdk":"1.29.0","zod":"4.4.3"},"devDependencies":{"@types/node":"22.20.0"},"gitHead":"cc62d4b10ea2268f94fa964fc7b4a683d6b1a35d","_id":"@airctrl/mcp@0.1.0","_nodeVersion":"22.19.0","_npmVersion":"11.12.0","dist":{"integrity":"sha512-3OrFI/1wJc7G2Y5SEdHIGV2VeuIQjFHPDlekUCfyHytKuLsWEKyuB5c/hitsstFy3xO5/K+QMrCHpfFordUYKQ==","shasum":"7de8c25a857c75f9ac816a7b120467415826a590","tarball":"https://registry.npmjs.org/@airctrl/mcp/-/mcp-0.1.0.tgz","fileCount":6,"unpackedSize":31150,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAYiH6A98V6VXuHP86udjkcnj4a+oBfYN30d3+UhIdrnAiEAr/K8wJ2imuDkvCXYI/uLaBvZbKs1Vf2roe6Y9UHyDGI="}]},"_npmUser":{"name":"david.theovex","email":"david@theovex.com"},"directories":{},"maintainers":[{"name":"david.theovex","email":"david@theovex.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp_0.1.0_1783614357714_0.7960219054299691"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-09T16:25:57.471Z","0.1.0":"2026-07-09T16:25:57.885Z","modified":"2026-07-09T16:25:58.146Z"},"maintainers":[{"name":"david.theovex","email":"david@theovex.com"}],"description":"AIRCTRL MCP server — expose the AI gateway to MCP-compatible agents (Claude Code, Cursor). Runs local/self-hosted.","homepage":"https://airctrl.dev","license":"UNLICENSED","readme":"# @airctrl/mcp\n\nMCP server that exposes the **AIRCTRL AI gateway** to MCP-compatible agents\n(Claude Code, Cursor, Warp, and any client that speaks the [Model Context\nProtocol](https://modelcontextprotocol.io)). It lets an agent set up and manage\ngateways, bring your own provider keys (BYOK), mint connection tokens, and read\nusage — from a single natural-language instruction.\n\n## Runs local / self-hosted — never hosted by us\n\nThis server is designed to run **on your machine** (via your MCP client) or on\n**your own infrastructure**. We never host it. It only talks to the AIRCTRL\ncontrol plane over HTTPS with your Personal Access Token; it never receives,\nstores, or returns provider plaintext keys. Provider keys you add via BYOK are\nvalidated and encrypted server-side and are **never** returned by any tool. The\nonly secret a tool ever returns is a **gateway connection token** you explicitly\nmint (`create_gateway_token` / `setup_gateway`), shown once.\n\n## Install\n\nPublished (intended usage):\n\n```bash\nnpx -y @airctrl/mcp\n```\n\nFrom the monorepo (local dev):\n\n```bash\ncd packages/mcp\nnpm ci\nnpm run build      # emits dist/\nnode dist/index.js # started by your MCP client, not directly\n```\n\n## Configuration\n\nThe server reads its config from **environment variables** (your MCP client\npasses them), namespaced `AIRCTRL_MCP_*` — the same convention as the official\nMongoDB MCP server (`MDB_MCP_*`). Secrets go in the environment, **never** in a\nprompt or a tool argument.\n\n| Variable              | Required | Description                                                   |\n| --------------------- | -------- | ------------------------------------------------------------- |\n| `AIRCTRL_MCP_API_URL` | no       | Control-plane base URL. Default `http://localhost:54330`.     |\n| `AIRCTRL_MCP_API_TOKEN` | yes    | Your Personal Access Token (`sk-actrl-pat-…`). Never logged.  |\n| `AIRCTRL_MCP_KEY_*`   | as needed | Your BYOK provider keys (see below). One per line.           |\n\n### Provider keys — `AIRCTRL_MCP_KEY_*` (never in the prompt)\n\nYour provider API keys (Anthropic, OpenAI, …) go in environment variables whose\nname **must** start with `AIRCTRL_MCP_KEY_`. You name them; the suffix is free,\nso you can keep as many as you want:\n\n```\nAIRCTRL_MCP_KEY_ANTHROPIC_PROD = sk-ant-...\nAIRCTRL_MCP_KEY_ANTHROPIC_TEST = sk-ant-...\nAIRCTRL_MCP_KEY_OPENAI         = sk-...\n```\n\nIn the prompt you reference a key by the **name of its variable**, never by its\nvalue — e.g. *\"…use the key in `AIRCTRL_MCP_KEY_ANTHROPIC_PROD`\"*. The server\nreads that variable and uses its value. For safety it only reads variables with\nthe `AIRCTRL_MCP_KEY_` prefix (so a prompt can't make it read `AWS_SECRET_*`,\n`PATH`, or anything outside that namespace).\n\n### Getting a Personal Access Token (PAT)\n\nA PAT is your **user** credential for the control plane (distinct from a gateway\ntoken). Create one from the AIRCTRL app (Settings → Developer → Create token) or\nvia the API:\n\n```bash\ncurl -X POST \"$AIRCTRL_MCP_API_URL/v1/pats\" \\\n  -H \"authorization: Bearer <your-session-or-existing-pat>\" \\\n  -H \"content-type: application/json\" \\\n  -d '{\"name\":\"my-laptop\",\"scopes\":{\"readOnly\":false}}'\n# → { \"ok\": true, \"data\": { \"pat\": {...}, \"plaintext\": \"sk-actrl-pat-…\" } }\n```\n\nThe `plaintext` is shown **once** — store it in your MCP client config. Scope it\nto specific `projects` and/or `readOnly: true` when you want a narrower token.\n\n## Client setup\n\n### Claude Code\n\nAdd to your `.mcp.json` (project) or run `claude mcp add`:\n\n```json\n{\n  \"mcpServers\": {\n    \"airctrl\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@airctrl/mcp\"],\n      \"env\": {\n        \"AIRCTRL_MCP_API_URL\": \"https://api.airctrl.dev\",\n        \"AIRCTRL_MCP_API_TOKEN\": \"sk-actrl-pat-…\",\n        \"AIRCTRL_MCP_KEY_ANTHROPIC_PROD\": \"sk-ant-…\"\n      }\n    }\n  }\n}\n```\n\n### Cursor\n\nAdd to `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (project) — same\nshape as above.\n\n### Warp\n\nWarp configures MCP servers globally (Settings → Agents → MCP servers → Add), not\nvia a project file. It supports the same `command`/`args`/`env` shape (plus an\noptional `working_directory`).\n\n### Local dev (unpublished build)\n\nPoint `command`/`args` at your built `dist` (works from any directory, no npm\npublish needed):\n\n```json\n{\n  \"mcpServers\": {\n    \"airctrl\": {\n      \"command\": \"node\",\n      \"args\": [\"/absolute/path/to/airctrl/packages/mcp/dist/index.js\"],\n      \"env\": {\n        \"AIRCTRL_MCP_API_URL\": \"http://localhost:54330\",\n        \"AIRCTRL_MCP_API_TOKEN\": \"sk-actrl-pat-…\",\n        \"AIRCTRL_MCP_KEY_ANTHROPIC_TEST\": \"sk-ant-…\"\n      }\n    }\n  }\n}\n```\n\n## Tools\n\n| Tool                    | What it does                                                                                  |\n| ----------------------- | --------------------------------------------------------------------------------------------- |\n| `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. |\n| `list_providers`        | List supported providers (OpenAI, Anthropic, Gemini, …) with their ids.                       |\n| `list_gateways`         | List the gateways in a project.                                                               |\n| `create_gateway`        | Create a bare gateway (prefer `setup_gateway` when connecting a key).                          |\n| `add_provider_key`      | Store a provider key (from an `AIRCTRL_MCP_KEY_*` var), validated + encrypted; never returned. |\n| `rotate_provider_key`   | Replace the key of an existing credential (re-validated + re-encrypted).                       |\n| `set_routing`           | Set a gateway's default provider/model and/or attach a credential.                            |\n| `create_gateway_token`  | Mint a gateway connection token (`sk-actrl-*`), returned once.                                 |\n| `read_usage`            | Read a gateway's request logs (provider, model, status, tokens, cost, latency).               |\n| `get_connection_config` | Compose the copy-paste connection config for a gateway.                                        |\n| `airctrl_status`        | Report how this server is configured (API URL + whether a PAT is set).                         |\n\n## Example\n\nFirst put your key in an `AIRCTRL_MCP_KEY_*` variable (in the client config\nabove), then ask your agent — referencing the **variable name**, not the key:\n\n> \"With the AIRCTRL tools, call `setup_gateway` for project\n> `97eccaf5-…`, provider `anthropic`, using the key in the env var\n> `AIRCTRL_MCP_KEY_ANTHROPIC_PROD`. Give me the connection config.\"\n\nThe agent calls `setup_gateway` once and gets back the gateway, a fresh\nconnection token, and the base URLs to point the OpenAI SDK or Claude Code at.\nIf a credential for that variable already exists, it is reused (no duplicates).\n\n## Connecting a client to the gateway\n\n`setup_gateway` / `get_connection_config` return data-plane base URLs. Pair them\nwith the gateway token:\n\n- **OpenAI SDK**: `base_url = <gateway>/compat`, `api_key = <gateway token>`.\n- **OpenAI-native**: `POST <gateway>/openai/v1/chat/completions`.\n- **Claude Code**: `ANTHROPIC_BASE_URL=<gateway>/anthropic`, `ANTHROPIC_AUTH_TOKEN=<gateway token>`.\n","readmeFilename":"README.md","_rev":"1-e60531966ebd14d3220e575a24183193"}