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

# aion-api-client

> API client package for authentication, GraphQL, model service, and control-plane addressing.

`aion-api-client` is the low-level package for connecting Python agents and tools to Aion platform
APIs. It owns HTTP authentication, typed GraphQL access, model-service configuration, and the shared
control-plane addressing models used by Aion MCP helpers.

Use this package directly when you need to construct Aion API clients, build capability URLs, or pass
typed capability references into framework-specific packages.

## Install

```bash theme={null}
pip install aion-api-client
```

The package is also installed through the framework extras in `aion-sdk`.

## Authentication

The client reads Aion API credentials from environment variables:

| Variable             | Required | Purpose                                                   |
| -------------------- | -------- | --------------------------------------------------------- |
| `AION_CLIENT_ID`     | yes      | API client identifier.                                    |
| `AION_CLIENT_SECRET` | yes      | API client secret.                                        |
| `AION_API_HOST`      | no       | Aion API host. Defaults to the SDK's production API host. |

Authentication is handled by the SDK JWT manager. Higher-level packages such as `aion-mcp`,
`aion-authoring-langgraph`, and `aion-authoring-adk` reuse that token manager when building authenticated
requests.

## Control-plane addressing

The control-plane models describe how to address Aion capabilities without hard-coding URL strings.
The core shape is:

```python theme={null}
CapabilityReference(
    subject=CapabilitySubject | None,
    kind=CapabilityKind,
    key=CapabilityKey,
)
```

Use a subjectless reference for application-owned surfaces such as the global Aion MCP server. Use a
subject-qualified reference for capabilities attached to distributions, environments, or agent
identities.

```python theme={null}
from aion.api import (
    AION_CONTROL_PLANE_MCP_CAPABILITY_KEY,
    AionControlPlanePaths,
    CapabilityReference,
    CapabilitySubject,
)

paths = AionControlPlanePaths("https://api.aion.to")

control_plane = CapabilityReference.global_mcp()
keyed_control_plane = CapabilityReference.global_mcp(
    key=AION_CONTROL_PLANE_MCP_CAPABILITY_KEY
)
distribution_mcp = CapabilityReference.primary_mcp(
    CapabilitySubject.distribution("distribution-id")
)
concrete_distribution_mcp = CapabilityReference.mcp(
    CapabilitySubject.distribution("distribution-id"),
    key="mcp.twitter.distribution",
)

assert paths.capability_path(control_plane) == "/mcp"
assert (
    paths.capability_path(keyed_control_plane)
    == "/mcp/mcp.aion.control_plane"
)
assert paths.capability_path(distribution_mcp) == "/distributions/distribution-id/mcp"
assert (
    paths.capability_path(concrete_distribution_mcp)
    == "/distributions/distribution-id/mcp/mcp.twitter.distribution"
)
```

## Capability subjects

| Subject constructor                                   | Route prefix                         |
| ----------------------------------------------------- | ------------------------------------ |
| `CapabilitySubject.distribution(distribution_id)`     | `/distributions/{distributionId}`    |
| `CapabilitySubject.environment(agent_environment_id)` | `/environments/{agentEnvironmentId}` |
| `CapabilitySubject.agent_identity(agent_identity_id)` | `/agents/{agentIdentityId}`          |
| `CapabilitySubject.agent_at_name(agent_at_name)`      | `/agents/@{agentAtName}`             |

## Capability kinds and keys

`CapabilityKind` identifies the protocol surface. HTTP-addressable values include
`CapabilityKind.MCP_SERVER` and `CapabilityKind.A2A_ENDPOINT`.

Subjectless keyed references are reserved for system-owned capabilities. Today, that means the
built-in control-plane MCP server can be addressed either as the primary global MCP route
`/mcp` or as `/mcp/mcp.aion.control_plane`.

Subject-qualified keyed references use the same path shape across endpoint kinds:
`/{subject}/{kind}/{capabilityKey}`. For REST-style A2A calls, protocol operation
segments follow the capability key, for example
`/{subject}/a2a/a2a.daemon/message:send`.

`CapabilityKey` identifies either:

* the primary capability of that kind for the addressed subject
* one concrete capability key declared by the behavior

```python theme={null}
from aion.api import CapabilityKey, CapabilityReference, CapabilitySubject

primary = CapabilityReference.mcp(
    CapabilitySubject.distribution("distribution-id"),
    key=CapabilityKey.primary(),
)

concrete = CapabilityReference.mcp(
    CapabilitySubject.distribution("distribution-id"),
    key=CapabilityKey.concrete("mcp.twitter.distribution"),
)
```

Omitting `key` selects the primary capability.

## Runtime capability references

`RuntimeCapabilityReference` is a template for resolving a reference after an
`AionRuntimeContext` exists. It does not read from thread-local or ambient state. The framework
adapter must pass the current request context explicitly, or extract it from the framework's
per-request context object.

```python theme={null}
from aion.api import CapabilitySubjectSource, RuntimeCapabilityReference

incoming_request_distribution_mcp = RuntimeCapabilityReference.primary_mcp(
    CapabilitySubjectSource.INCOMING_DISTRIBUTION
)

resolved = incoming_request_distribution_mcp.resolve(runtime_context)
```

`CapabilitySubjectSource.INCOMING_DISTRIBUTION` means the distribution from the current incoming
request's Aion Distribution extension payload. It is request-scoped, not a global default.

| Source                  | Runtime accessor                           |
| ----------------------- | ------------------------------------------ |
| `ACTIVE_ENVIRONMENT`    | `runtime_context.get_environment()`        |
| `INCOMING_DISTRIBUTION` | `runtime_context.get_distribution()`       |
| `PRINCIPAL_IDENTITY`    | `runtime_context.get_principal_identity()` |

## Principal selectors

`PrincipalSelector` is request metadata used to tell Aion which runtime principal the call is being
made as. It is not a credential by itself; the API still validates the bearer token and the selected
principal.

For behavior-originated calls back to the control plane, such as MCP or A2A access,
`AionRuntimeContext.get_principal_selector()` derives this metadata from the active request. It
prefers the environment's daemon identity when available and falls back to the environment id. Omitting
the selector can make the request look like the broader authenticated subject, which may be denied even
when the runtime daemon or environment would be allowed.

```python theme={null}
from aion.api import PrincipalSelector

selector = PrincipalSelector.agent_environment("environment-id")
headers = selector.to_headers()
graphql_principal = selector.to_gql_value()
```

The MCP helpers derive the selector from `AionRuntimeContext.get_principal_selector()` when no
explicit selector is supplied.

## Related pages

* [aion-mcp](/sdk/python/packages/aion-mcp)
* [LangGraph MCP Guide](/sdk/langgraph/guides/mcp)
* [Google ADK MCP Guide](/sdk/google-adk/guides/mcp)
