> This page is for version 0.8.0.
> For other versions, use one of these documentation indexes:
> - Latest (default): https://docs.nvidia.com/nemo-helix/latest/llms.txt
> - 0.8.0: https://docs.nvidia.com/nemo-helix/v0.8.0/llms.txt
> - 0.7.3: https://docs.nvidia.com/nemo-helix/v0.7.3/llms.txt
> - 0.7.2: https://docs.nvidia.com/nemo-helix/v0.7.2/llms.txt
> - 0.7.1: https://docs.nvidia.com/nemo-helix/v0.7.1/llms.txt
> - 0.7.0: https://docs.nvidia.com/nemo-helix/v0.7.0/llms.txt
> - 0.6.0: https://docs.nvidia.com/nemo-helix/v0.6.0/llms.txt
> - 0.5.1: https://docs.nvidia.com/nemo-helix/v0.5.1/llms.txt
> - 0.5.0: https://docs.nvidia.com/nemo-helix/v0.5.0/llms.txt
> - 0.4.0: https://docs.nvidia.com/nemo-helix/v0.4.0/llms.txt
> - 0.3.0: https://docs.nvidia.com/nemo-helix/v0.3.0/llms.txt
> - 0.2.0: https://docs.nvidia.com/nemo-helix/v0.2.0/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo-helix/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo-helix/_mcp/server.

# Register Agents

> Register an agent on NeMo Helix from code, a container image, a remote endpoint, or its traces.

Registering an agent creates an `agent` entity in a workspace. Choose the method that matches what you have:

| Method                                              | You provide                             | Use when                                                                |
| --------------------------------------------------- | --------------------------------------- | ----------------------------------------------------------------------- |
| [Code](#register-with-code)                         | An `agent.yaml` and the files beside it | NeMo Helix should run the agent.                                        |
| [Container image](#register-with-a-container-image) | An `agent.yaml` and an image            | The agent is already packaged, or the image runs its own server.        |
| [Remote endpoint](#register-a-remote-endpoint)      | An `agent.yaml` that points at a URL    | The agent runs elsewhere behind an OpenAI- or Anthropic-compatible API. |
| [Traces](#register-from-traces)                     | A name                                  | You only want to analyze traces the agent already sends.                |

Agent names must start with a lowercase letter, be 2–63 characters long, and use lowercase letters,
digits, hyphens, and dots, with no consecutive hyphens and no trailing hyphen.

The CLI and Python SDK connect to the deployment in your current CLI context. To connect to a local or remote deployment, see [Connect with CLI Contexts](/documentation/reference/cli-reference/connect-to-deployments).

#### CLI

```bash
# Confirm the deployment and workspace in the current context
nemo config view
```

#### Python SDK

```python
from nemo_helix_plugin.client.client import NemoClient

client = NemoClient.from_config()
```

> **Note**
>
> These examples use the `default` workspace. If your current CLI context uses a different workspace, run `nemo config set --workspace default` first. To check, run `nemo config view`.

## Register with Code

An agent is defined by an `agent.yaml` in the `nemo-agents-spec-v1` format. This calculator agent ships with the source checkout:

```yaml
config_format: nemo-agents-spec-v1
name: calculator-agent
description: Calculator agent executed with DeepAgents

instructions:
  system:
    content: |
      You are a concise calculator agent. Solve arithmetic and numeric
      comparison requests yourself and return only the answer.

default_harness: deepagents
harnesses:
  deepagents:
    kind: deepagents

models:
  default:
    provider: nvidia
    model: ${NEMO_DEFAULT_MODEL}
```

Register it:

#### CLI

```bash
nemo agents create \
  --name calculator-agent \
  --agent-config plugins/nemo-agents/examples/nemo-agent-config/calculator-agent/agent.yaml
```

#### Python SDK

```python
import yaml
from nemo_agents_plugin.sdk import AgentsResource
from nemo_helix_plugin.client.client import NemoClient

agents = AgentsResource(NemoClient.from_config())

with open("plugins/nemo-agents/examples/nemo-agent-config/calculator-agent/agent.yaml") as f:
    config = yaml.safe_load(f)

agents.create(name="calculator-agent", config=config, config_format=config["config_format"])
```

#### Studio

Open **Agents**, select **Register Agent**, and choose one of:

* **Register with code upload**: drop the folder that contains `agent.yaml`.
* **Register from GitHub**: enter `github.com/owner/repo`, optionally with `@branch` and
  `#sub/directory`. Studio reads the files from GitHub on demand. Select an access-token secret
  for a private repository.

The CLI validates the config, replaces `${NEMO_DEFAULT_MODEL}` with the default model from
`nemo setup`, creates the agent, and uploads the text files in the config's directory (skills,
prompts, MCP server scripts) to the `<name>-ethos` fileset, up to 500 files and 900 KB.
Deployments and evaluations stage that fileset beside `agent.yaml`, so relative paths keep
working. The Python SDK registers the config only; use the CLI or Studio when the agent has other
files.

### `agent.yaml` Reference

| Field                          | Purpose                                                                                                                                                                                             |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `config_format`                | Always `nemo-agents-spec-v1`.                                                                                                                                                                       |
| `name`, `description`          | Agent metadata.                                                                                                                                                                                     |
| `default_harness`, `harnesses` | The harness that runs the agent. Each entry sets a `kind` (`deepagents`, `claude`, `codex`, `hermes`, `nooa-bench-agent`, `remote-agent`), plus optional `settings` and a harness-specific `model`. |
| `models`                       | Named model bindings. A harness uses `models.default` unless it sets its own `model`.                                                                                                               |
| `instructions.system.content`  | The system prompt, shared by every harness.                                                                                                                                                         |
| `skills.paths`                 | Skill directories relative to `agent.yaml`; each must contain a `SKILL.md`.                                                                                                                         |
| `mcp.servers`                  | MCP servers that expose tools to the harness.                                                                                                                                                       |
| `tools.blocked`                | Tool names the harness must not call.                                                                                                                                                               |
| `runtime`                      | `timeout_seconds` and `max_turns`.                                                                                                                                                                  |
| `environment`                  | Workspace and artifacts directories, and environment variables.                                                                                                                                     |
| `telemetry`                    | Relay telemetry settings. When unset, deployments and execute jobs export ATIF trajectories to Intake for every harness that supports it (not `remote-agent`); set `enabled: false` to opt out.     |

See the [examples directory](https://github.com/NVIDIA-NeMo/nemo-helix/tree/main/plugins/nemo-agents/examples/nemo-agent-config)
for a config per harness.

> **Note**
>
> `nemo agents create` also accepts legacy NeMo Agent Toolkit (NAT) workflow configs
> (`config_format: nat-workflow-v1`, the default when `config_format` is omitted). Use
> `nemo-agents-spec-v1` for new agents; registered-agent evaluation targets and the optimization
> strategies require it.

### Bring Your Own Harness

The built-in harnesses build the agent from `agent.yaml`. To run agent code you wrote yourself, such
as your own LangGraph or Deep Agents graph, wrap it in a
[Fabric adapter](https://github.com/NVIDIA/NeMo-Fabric/tree/v0.4.0/docs/adapter-contract): a Python
runtime that Fabric starts, plus a descriptor that registers it. NeMo Helix then registers, deploys,
and invokes the agent like any other.

**1. Implement the runtime.** Fabric calls `start` once with the agent's config, `invoke` for each
request, and `stop` on shutdown. Return the reply text as `output["response"]`.

```python
from nemo_fabric_adapter_contract.models import (
    AgentConfig,
    AgentRunRequest,
    AgentRunResult,
    AgentRunStatus,
    RuntimeContext,
)
from nemo_fabric_adapters.common import lifecycle

from acme_agent.graph import build_agent  # your agent code


class AcmeRuntime:
    async def start(self, payload: dict) -> None:
        config: AgentConfig = payload["config"]
        model = config.models["default"]
        system = config.instructions.system if config.instructions else None
        self.agent = build_agent(
            model=model.model,
            base_url=model.base_url,  # the Inference Gateway, filled in by NeMo Helix
            system_prompt=system.content if system else None,
        )

    async def invoke(self, request: AgentRunRequest, context: RuntimeContext) -> AgentRunResult:
        reply = await self.agent.run(request.input)
        return AgentRunResult(status=AgentRunStatus.SUCCEEDED, output={"response": reply})

    async def stop(self) -> None:
        self.agent = None


def main() -> None:
    lifecycle.serve(AcmeRuntime, config_loader=AgentConfig.from_mapping)


if __name__ == "__main__":  # Fabric starts the runner with `python -m`
    main()
```

**2. Describe it** in `acme-agent.fabric-adapter.json`. `config.accepts` lists the `agent.yaml` fields
the runtime applies; Fabric rejects a config that sets anything else. NeMo Helix accepts only adapter
IDs that start with `nvidia.fabric.`.

```json
{
  "contract_version": "fabric.adapter/v1alpha2",
  "adapter_id": "nvidia.fabric.acme-agent",
  "adapter_kind": "python",
  "runner": {"module": "acme_agent.fabric_adapter"},
  "config": {
    "accepts": ["models", "models.base_url", "instructions.system"],
    "system_instruction_modes": ["replace"]
  }
}
```

**3. Package the descriptor with your code,** so Fabric discovers it wherever the package is installed:

```toml
[project]
name = "acme-agent"
version = "0.1.0"
dependencies = ["nemo-fabric-adapters-common>=0.4.0,<0.5.0"]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["src/acme_agent"]

[tool.hatch.build.targets.wheel.shared-data]
"acme-agent.fabric-adapter.json" = "share/nemo-fabric/adapters/acme-agent/acme-agent.fabric-adapter.json"
```

**4. Select it** in `agent.yaml`:

```yaml
default_harness: acme
harnesses:
  acme:
    kind: nvidia.fabric.acme-agent
```

**5. Install the package everywhere the agent is validated or runs:**

* The environment where you run `nemo agents create` and `nemo agents package`, which validate the
  agent against its adapter.
* The platform's Python environment, for subprocess deployments. If you installed NeMo Helix with
  `uv tool install`, add your package to that tool environment with `--with`.
* The agent image, for Docker and Kubernetes deployments. Package with `--pyproject` so the image
  installs your project; the `nemo agents package-agent` platform job cannot.

Automatic trace export and streaming depend on what the descriptor declares; see the
[adapter contract](https://github.com/NVIDIA/NeMo-Fabric/tree/v0.4.0/docs/adapter-contract). The
Insights plugin's
[`nvidia.fabric.insights-analyst`](https://github.com/NVIDIA-NeMo/nemo-helix/tree/main/plugins/nemo-insights)
adapter is a complete example.

### Model Access

Platform-routed models go through the [Inference Gateway](/documentation/models-and-inference),
which holds the provider credentials:

* Set `provider` to `nvidia`, `openai`, or `openai-compatible`, and leave `base_url` unset. NeMo
  Helix fills in the gateway URL when it runs the agent.
* Set `model` to a model entity from `nemo models list` (for example,
  `nvidia-nemotron-3-5-lightning-30b-a3b`) or a
  [virtual model](/documentation/models-and-inference/virtual-models) in the same workspace.
* `api_key_env` is optional. The platform supplies a placeholder for gateway-routed models.

To route a model to a provider directly instead, set `base_url` and name the environment variable
that holds its key in `api_key_env`.

### Install Harness Support

The Agents plugin includes Fabric and every harness adapter, but not the third-party harness
packages. Install the extra for the harness you use:

| Harness                 | Package                                     | Source checkout                                           |
| ----------------------- | ------------------------------------------- | --------------------------------------------------------- |
| DeepAgents              | `nemo-helix[nemo-agents-plugin-deepagents]` | `uv sync --package nemo-agents-plugin --extra deepagents` |
| Claude Code             | `nemo-helix[nemo-agents-plugin-claude]`     | `uv sync --package nemo-agents-plugin --extra claude`     |
| Codex                   | `nemo-helix[nemo-agents-plugin-codex]`      | `uv sync --package nemo-agents-plugin --extra codex`      |
| NOOA (Python 3.12–3.13) | `nemo-helix[nemo-agents-plugin-nooa]`       | `uv sync --package nemo-agents-plugin --extra nooa`       |
| Remote agent            | `nemo-helix[nemo-agents-plugin]`            | Included                                                  |

```bash
uv tool install "nemo-helix[nemo-agents-plugin-deepagents]"
```

Hermes conflicts with NeMo Helix's dependencies, so it runs from a separate Python 3.14
environment. From a source checkout, run `script/dev-install-hermes.sh` and export the
`ADAPTER_PYTHON` it prints before starting NeMo Helix. Otherwise, follow the
[Hermes Agent installation guide](https://hermes-agent.nousresearch.com/docs/installation) and
install the matching `nemo-fabric[relay]` and `nemo-fabric-adapters-hermes` versions into that
environment.

## Register with a Container Image

The image is chosen when you deploy, so register the agent's `agent.yaml` as in
[Register with Code](#register-with-code), then deploy it with `--image`:

```bash
nemo agents deploy --agent calculator-agent --mode docker --image calculator-agent:local
```

`nemo agents package` builds an image from an `agent.yaml`; see
[Build and Publish Agent Images](/documentation/agents/deploy-agents#build-and-publish-agent-images).

For an image that already runs its own server, add `--use-image-entrypoint` so the deployment keeps
the image's `ENTRYPOINT` and `CMD`. The server must:

* Listen on `0.0.0.0:$PORT`.
* Serve `GET /health`.
* Serve `POST /v1/chat/completions` to work with `nemo agents invoke` and `nemo agents chat`.

The deployment writes the stored config into the container and sets `AGENT_CONFIG_PATH` to its path
(`NAT_CONFIG_PATH` for legacy NAT workflow configs).

## Register a Remote Endpoint

The `remote-agent` harness forwards each request to an agent that runs elsewhere. The endpoint
must stream Server-Sent Events (SSE) and speak OpenAI Responses (`openai-responses`, the default),
OpenAI Chat Completions (`openai-completions`), or Anthropic Messages (`anthropic-messages`).

```yaml
config_format: nemo-agents-spec-v1
name: support-agent
default_harness: remote-agent
harnesses:
  remote-agent:
    kind: remote-agent
    settings:
      base_url: https://agent.example.com/v1   # API root, including /v1
      api_type: openai-responses
models:
  default:
    provider: remote
    model: support-agent                      # model name the endpoint expects
    api_key_env: REMOTE_AGENT_API_KEY          # omit for an unauthenticated endpoint
telemetry:
  enabled: false
```

Register and deploy it like any other agent. Skills, MCP servers, tool policy, and tracing stay
configured on the remote agent; tag its traces with the agent's name so they match. For live streaming and sessions, see the
[Remote Agent example](https://github.com/NVIDIA-NeMo/nemo-helix/tree/main/plugins/nemo-agents/examples/nemo-agent-config#remote-agent).

## Register from Traces

To analyze an agent that already sends traces to Intake, register its name with an empty config.
The name must match the agent name on its traces (`agent.name` in ATIF, `gen_ai.agent.name` in
OTLP); see [Collect Agent Traces](/documentation/agents/traces-and-insights/collect-agent-traces).

#### CLI

```bash
nemo agents create --name support-agent --agent-config <(echo '{}')
```

#### Python SDK

```python
from nemo_agents_plugin.sdk import AgentsResource
from nemo_helix_plugin.client.client import NemoClient

agents = AgentsResource(NemoClient.from_config())
agents.create(name="support-agent", config={})
```

#### Studio

Open **Agents**, select **Register Agent** > **Register from traces**, and choose an unregistered
agent name found in ingested traces.

A trace-only agent works with [Insights](/documentation/agents/traces-and-insights/insights-from-traces),
but has nothing to deploy or evaluate. To run it on NeMo Helix, delete it and register it again
under the same name with a config.

## Manage Registered Agents

```bash
nemo agents list
nemo agents get calculator-agent
nemo agents delete calculator-agent
```

An agent's config cannot be edited in place. To change it, register a new agent, or use
`nemo agents redeploy` to replace a deployed agent; see
[Update a Deployed Agent](/documentation/agents/deploy-agents#update-a-deployed-agent).