> ## Documentation Index
> Fetch the complete documentation index at: https://docs.airctrl.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Combine AIRCTRL tools

> Use the dashboard, CLI, SDK and MCP together without duplicating credentials or adding secret files to your repository.

export function AirctrlWordmark() {
  return <span className="airctrl-wordmark" aria-label="AIRCTRL">
      <span aria-hidden="true" className="airctrl-wordmark-air">AIR</span>
      <span aria-hidden="true" className="airctrl-wordmark-ctrl">CTRL</span>
    </span>;
}

You do not need to choose one <AirctrlWordmark /> tool for an entire project. Use each tool for the part it handles best.

* Use the **dashboard** for security decisions that require a person, such as membership, roles, Personal Access Tokens and Service Account credentials.
* Use the **CLI** for interactive terminal work and to start local processes with decrypted records in memory.
* Use the **SDK** when your application or script needs to call <AirctrlWordmark /> directly.
* Use **MCP** when an agent needs to inspect or change <AirctrlWordmark /> resources under an approved identity.
* Use the raw **API** when another language or platform cannot use the TypeScript SDK.

All surfaces enforce the same API permissions. Their local configuration is separate.

## What the tools share

The tools can use the same <AirctrlWordmark /> account, project and record IDs. A human PAT can also represent the same person across API, SDK, CLI and MCP. A Service Account bundle can represent the same machine across SDK, CLI and MCP.

They do not automatically read each other's configuration:

| Configuration                                       | Who reads it                              |
| --------------------------------------------------- | ----------------------------------------- |
| `~/.airctrl/config.json` created by `airctrl login` | CLI only                                  |
| `AIRCTRL_API_URL` and `AIRCTRL_TOKEN`               | Your SDK application                      |
| `AIRCTRL_MCP_*` variables                           | The local MCP server                      |
| Active Service Account bundle                       | Only the process where you map its fields |

Do not make an application read the CLI configuration file. That file belongs to the CLI and its shape is not an application integration contract.
The SDK does not read the CLI login file, and MCP does not inherit it.

## Local development without environment files

This is the simplest way to use <AirctrlWordmark /> records in a local application that already reads environment variables.

### Prepare the records

Create a project in the dashboard and store the values your application needs. Give records names that produce clear environment keys. The CLI trims each name, converts it to uppercase and replaces characters outside `A-Z`, `0-9` and `_` with `_`. For example, `Database URL` becomes `DATABASE_URL`.

Choose names that remain unique after conversion. Names such as `API URL` and `API-URL` both become `API_URL`. An injected record also replaces an existing child-process variable with the same key.

### Sign in to the CLI

```bash theme={}
airctrl login
```

The CLI stores the API URL, human PAT and optional default project in `~/.airctrl/config.json`, outside your repository. It asks for the vault passphrase when it needs to decrypt records unless your approved runtime supplies `AC_VAULT_PASSWORD`.

Confirm the project before launching the application:

```bash theme={}
airctrl record list --project "$PROJECT_ID" --limit 25
```

### Start the application

```bash theme={}
airctrl run --project "$PROJECT_ID" -- npm run dev
```

The CLI decrypts accessible records locally and injects them only into the child process. Your application continues to use normal environment access:

```ts theme={}
const databaseUrl = process.env.DATABASE_URL

if (!databaseUrl) {
  throw new Error('DATABASE_URL is required')
}
```

No `.env` file is created. When a value changes in <AirctrlWordmark />, restart the command to launch a new process with the current values.

<Note>
  `airctrl run` removes <AirctrlWordmark /> control variables such as `AC_TOKEN` and `AC_VAULT_PASSWORD` before starting the child. The application receives the selected project records, not the CLI credential that fetched them.
</Note>

## Use the CLI for setup and the SDK in code

The CLI is useful for finding IDs and checking access before you write integration code:

```bash theme={}
airctrl project accounts
airctrl project list --account "$AIRCTRL_ACCOUNT_ID"
airctrl record list --project "$PROJECT_ID" --limit 25
```

The SDK still needs its own explicit configuration:

```ts theme={}
import { createClient } from '@airctrl/sdk'

const airctrl = createClient({
  baseUrl: process.env.AIRCTRL_API_URL!,
  auth: process.env.AIRCTRL_TOKEN!,
})
```

Load those values through your operating system, deployment platform or approved secret storage. Do not copy them from the CLI file at runtime.

Use this combination when the CLI helps a developer prepare or inspect <AirctrlWordmark />, while the application must call <AirctrlWordmark /> after it starts. If the application only needs ordinary environment values, use `airctrl run` and omit the SDK.

## Use the CLI to discover context for MCP

The CLI can help you find an account, project, record or gateway ID before asking an agent to work with it:

```bash theme={}
airctrl project list --account "$AIRCTRL_ACCOUNT_ID"
airctrl gateway list --project "$PROJECT_ID"
```

`airctrl login` does not sign MCP in. This separation prevents an agent from silently inheriting a developer's terminal session. Configure MCP separately with `AIRCTRL_MCP_*` variables. Then make a natural-language request with the exact scope you found:

```text theme={}
Show the active records in project "00000000-0000-4000-8000-000000000010".
Return names, formats and IDs only. Do not decrypt values or change anything.
```

<div className="technical-reference">
  **MCP tool used:** `list_records`
</div>

## Use a Service Account in CI or a server

Do not use a human CLI login for an unattended workload.

1. Create the Service Account in the dashboard.
2. Assign the smallest custom role and project access it needs.
3. Share the required records with it when direct record access is needed.
4. Provision its credential in the dashboard.
5. Save the complete bundle in the deployment platform's secret storage.
6. Map the same bundle into the SDK, CLI or MCP process that performs the work.

Use only one identity mode in each process. Do not combine a human PAT, human vault passphrase and Service Account capability fields.

For the SDK, map the bundle directly:

```ts theme={}
const airctrl = createClient({
  baseUrl: bundle.baseUrl,
  auth: bundle.bearer,
  credential: {
    credentialId: bundle.credentialId,
    capPrivateKeyB64: bundle.capPrivateKeyB64,
  },
})
```

For the CLI, map the bundle to `AC_API_BASE_URL`, `AC_TOKEN`, `AC_SA_CREDENTIAL_ID` and `AC_SA_CAP_PRIVATE_KEY_B64`. For MCP, use the matching `AIRCTRL_MCP_*` variables described in [Authentication](/getting-started/authentication).

Service Account creation, role assignment and credential lifecycle remain dashboard-only. SDK, CLI and MCP use an active credential; they do not administer it.

## Separate control-plane and application credentials

<AirctrlWordmark /> credentials and application credentials have different jobs:

* A human PAT or Service Account token authenticates calls to the <AirctrlWordmark /> control plane.
* A vault passphrase or Service Account capability decrypts <AirctrlWordmark /> records locally.
* A gateway token authenticates an application to an <AirctrlWordmark /> gateway.
* A provider credential lets that gateway call the selected AI provider.

Do not substitute one for another. For example, an OpenAI client receives a gateway token and gateway URL. It does not receive your <AirctrlWordmark /> PAT or stored OpenAI provider key.

## Avoid these combinations

* Do not assume `airctrl login` configures the SDK or MCP.
* Do not parse `~/.airctrl/config.json` from application code.
* Do not expect `airctrl run` to pass <AirctrlWordmark /> control credentials to its child process.
* Do not commit a `.env` file, PAT, Service Account bundle, vault passphrase or provider key.
* Do not use a human PAT for CI when a least-privilege Service Account can perform the supported operation.
* Do not ask an agent to search neighboring accounts, projects or IDs after a `403` or `404`.

## Troubleshoot a combined workflow

| Problem                                    | What it means                                                                                               | What to do                                                                                         |
| ------------------------------------------ | ----------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `cli_not_authenticated`                    | The CLI has no human login, complete Service Account environment or selected machine profile.               | Run `airctrl login` for local human work, or supply one complete approved machine identity.        |
| `cli_project_required`                     | The CLI cannot choose a project safely.                                                                     | Pass `--project` or save a default project during human login.                                     |
| `sa_run_requires_project`                  | A Service Account tried to rely on a human default project.                                                 | Pass the assigned project ID explicitly.                                                           |
| A variable is missing in the child process | The record is unavailable, its name produced a different key, or another normalized name collided with it.  | List the project records and compare their normalized names before restarting the process.         |
| `no_wrapper_for_caller`                    | The identity can reach the record metadata but cannot decrypt its data key.                                 | Grant that human or Service Account access to the record in <AirctrlWordmark />.                   |
| `sa_env_bundle_incomplete`                 | Only part of a Service Account credential was supplied, or fields from different identity modes were mixed. | Replace the environment with fields from one complete active bundle.                               |
| MCP reports the wrong identity type        | MCP received a different variable set than expected.                                                        | Check <AirctrlWordmark /> MCP status, then correct the MCP client's `AIRCTRL_MCP_*` configuration. |
| `403` or `not_authorized`                  | Authentication worked, but RBAC or resource access denied the action.                                       | Request the required role or project grant in the dashboard. Do not retry unchanged.               |

## Choose your next guide

* [Authentication](/getting-started/authentication) explains human and machine identities.
* [Records and secrets](/guides/records) covers decryption, injection, creation and sharing.
* [SDK overview](/sdk/overview) shows direct application integration.
* [CLI overview](/cli/overview) explains terminal and process-injection behavior.
* [MCP setup](/mcp/setup) connects an approved agent identity.
* [Feature availability](/reference/availability) shows which operations each identity can use.
