# Registry
URL: /docs/cli/registry

Publish an AgentSpec JSON file so others can fetch it with a single command.



An alineo "registry item" is just a URL that returns an `AgentSpec` JSON object (the same spec type used by [`alineo`](/docs/agent)). Any URL works — a GitHub raw file, a Gist, your own server, or the small curated set of examples alineo hosts at [registry.alineo.tech](https://registry.alineo.tech) — there's no requirement to publish through a central service.

<Cards>
  <Card href="/docs/cli/registry/schema" title="AgentSpec schema" description="All fields, types, and constraints for a valid agent spec." />
</Cards>

## Publishing a spec [#publishing-a-spec]

An agent spec is a static JSON file. Hosting it is as simple as pushing it to a public GitHub repository and sharing the raw URL:

```
https://raw.githubusercontent.com/your-org/your-repo/main/agents/node-toolchain.json
```

Anyone can then fetch it into their own project with:

```bash
bunx alineo-cli add https://raw.githubusercontent.com/your-org/your-repo/main/agents/node-toolchain.json
```

This only saves the spec locally — it doesn't run anything. See [Running an agent spec](/docs/cli/using-sandboxes) for how to actually load and run it with `Alineo.start()`.

## Minimal example [#minimal-example]

Every spec runs inside a `node:22` sandbox (there's no `image` field — the base image is fixed) and requires `harness: "pi"`:

```json
{
  "name": "node-toolchain",
  "harness": "pi",
  "setup": [{ "name": "install tools", "run": "npm install -g typescript eslint prettier" }]
}
```

## Composition with `registryDependencies` [#composition-with-registrydependencies]

A spec can declare dependencies on other specs by URL. `alineo add` fetches and saves them first, depth-first, before saving the top-level spec — it does not merge or run them, each dependency just ends up as its own separate spec file in `agentsDir`:

```json
{
  "name": "ts-reviewer",
  "harness": "pi",
  "registryDependencies": ["https://example.com/agents/node-toolchain.json"],
  "setup": [{ "name": "install linter", "run": "npm install -g @typescript-eslint/parser" }]
}
```

There's no cycle detection — avoid dependency chains that reference each other.
