Skip to main content

What the Agent Hub is

The Agent Hub is GAIA’s catalog of installable agents — think of it as an app store for agents that run on your own machine. Behind the scenes it’s a storage bucket of published files plus a small web service (the “Worker”) that serves a catalog file, index.json. Publishing your agent to the Hub does two things:
  1. Anyone can install it with uv pip install gaia-agent-<id> (or from the Agent UI’s Hub panel).
  2. It auto-creates the agent’s page on the Hub website (amd-gaia.ai/hub). The website is generated entirely from the Hub’s catalog, so publishing is the website update — there’s no separate web page to write.
This guide takes you from an empty folder to a published agent, and then shows how to ship updates. No prior packaging experience assumed.
New to building agents? Start with Custom Agents to write the agent itself, then come back here to publish it. Using Claude Code in the GAIA repo? The gaia-build-agent skill builds and the agent-hub-release skill cuts a frozen-binary + npm sidecar release (like the email agent) — invoke them with the Skill tool.

Two ways to publish

To publish to the Hub you normally need a publish token — a secret credential that proves you’re allowed to publish. There are two routes, and they decide whether you need a token:
  1. Contribute via a Pull Request — no token needed (recommended). You add your agent’s folder under hub/agents/<id>/python/ and open a PR to amd/gaia. Automated checks run, a maintainer reviews your code, and after it’s merged a maintainer publishes it for you using AMD’s credentials. You never touch a token. This is the path for community authors, and the review is what earns your agent its trust level (its “security tier”).
  2. Direct publish with your own token. You run gaia agent publish from your own machine. This needs a Hub token scoped to your name. Self-serve tokens aren’t open yet — by design, agents are curated through the PR route while the Hub builds momentum, so every early agent is reviewed and quality stays high. Self-publishing opens up as the ecosystem matures. Today tokens are handed out manually by the maintainers (mostly AMD-internal).
You build the exact same package either way — Steps 1–7 below are identical; only the final publish step (Step 8) differs.
The Hub is a curated channel: the Worker only accepts a publish if the token is scoped to the agent’s author, and the PR route adds human review on top. Separately, anyone can always distribute their agent openly on PyPI or npm — the Hub is the reviewed channel, not the only one.

The four parts of an agent package

Every agent you publish is a normal Python package with four pieces. Keep these in mind — the steps below fill each one in:

Prerequisites

  • GAIA installed — check with gaia -v. See Install.
  • Packaging tools (only needed for the direct-publish route): uv pip install "amd-gaia[publish]" — this adds build (makes the package file) and twine (uploads to PyPI).
  • A Hub token only if you’re using the direct-publish route (Step 8, Path 2).

Part A — Create a new publishable agent

Step 1 — Generate a starter package

“Scaffolding” means generating a ready-to-edit starter package so you don’t write the boilerplate by hand:
This creates a folder with the four parts above already wired together. Flags: --language python|cpp (default python), --output <dir> / -o to choose where it’s created (default: current folder), --layout flat|hub (default flat), and --force to overwrite an existing folder. If you’re contributing the agent to the amd/gaia repo rather than shipping it standalone, scaffold straight into the hub tree with --layout hub, which nests the code under a language directory the way every hub package is arranged:
Prefer to learn from a working example? The repo ships tiny, heavily commented agents made to be copy-pasted — read them in order; each adds exactly one new idea:
  • hello-world/ — the smallest agent possible (a system prompt, no tools).
  • word-count/ — adds one tool with the @tool decorator.
  • doc-search/ — reuses a built-in toolset (RAGToolsMixin) for document Q&A.
Each is a complete, publishable package (manifest + code + README + tests that fake the model, so they run without a model server). See the examples index. The email agent is a full-featured, real-world reference.

Step 2 — Tour the files

Step 3 — Fill in the manifest (and understand the entry point)

The manifest (gaia-agent.yaml) is the description card the Hub stores and indexes. Each field below feeds the catalog and your auto-generated page. To validate your manifest locally, run gaia agent test --lint (the author-side parser; the manifest.schema.json in the repo is the Hub’s server-side aggregate schema and includes fields you never write by hand, like versions). A real example is the email agent’s manifest.
download_size_bytes is not yours to set — the server measures it when you publish. permissions is optional.security_tier is read from your manifest, and it matters. Omit it and you get the most restrictive tier (experimental), which means users can only install your agent by passing an explicit --trust opt-in. The value you write is what the hub publishes for whatever version becomes the new latest; publishing an older version leaves the displayed tier alone. What stops you from simply claiming verified is the review gate, not the parser — publishing goes through a maintainer, and the tier you declare is part of what gets reviewed. The example agents declare experimental because that is genuinely their tier.The website turns all of these into the install switcher, platform badges, and requirement/permission/tier cards automatically — you don’t build any of that.
How GAIA actually finds your agent. After someone installs your package, GAIA has to discover it. That happens through a Python entry point — a standard way for a package to advertise something to a host program. gaia agent init already wrote it into pyproject.toml:
This says: “under the group gaia.agent, my agent is registered by calling build_registration() in this package.” That function (in __init__.py) returns a small AgentRegistration object describing your agent. You rarely edit it by hand — the scaffold and the examples set it up for you — but that’s the wiring that makes gaia <id> work after install.

Step 4 — Write the agent

An agent is a Python class that extends GAIA’s base Agent. At minimum you give it a system prompt (its instructions) and optionally tools (functions it can call). See Agent System and Tools for the full picture:

Step 5 — Write the README

Your README.md becomes your agent’s page on the website, so write it for users. Keep it to plain Markdown (headings, lists, fenced code, bold, inline code, links, blockquotes). For safety the site strips raw HTML and scripts and ignores images, so don’t rely on them. Lead with what the agent does and how to use it — you don’t need to write install instructions, because the website adds the install commands and requirement cards around your text automatically.

Step 6 — Get a token (direct-publish route only)

Skip this entirely if you’re using the PR route (Path 1) — the maintainers publish for you. For direct publishing, store your token once in your operating system’s secure keychain:
On a server or CI machine with no keychain, pass tokens as environment variables instead:
A Hub token is scoped to an author. The author in your manifest must match that scope, or the Hub refuses the publish with a 403 error — this is what stops anyone from publishing under someone else’s name. Never commit a token or type it directly on the command line.

Step 7 — Test it locally

Step 8 — Publish

Path 1 — via PR (no token): commit your package under hub/agents/<id>/python/ and open a PR to amd/gaia. Once the automated checks pass and a maintainer approves and merges it, a maintainer publishes it for you. You’re done — jump to Verify. Path 2 — direct (your own token): from inside your package folder, run:
A wheel is just the standard Python package file (.whl); publish builds it for you. Handy flags:
  • --skip-pypi — publish to the Hub only.
  • --skip-r2 — publish to PyPI only (skip the Hub).
  • --hub-url <url> — point at a different Hub (defaults to GAIA_HUB_URL or https://hub.amd-gaia.ai).
When you publish, the server checks your manifest, confirms your token is allowed to publish under that author, fingerprints the file (a SHA-256 checksum) so it can’t be tampered with, stores it so it can never be overwritten, attaches your README.md, and rebuilds the catalog index.json.

Step 9 — Verify

Your page appears at https://amd-gaia.ai/hub/my-agent the next time the website rebuilds (it regenerates from the catalog on each deploy). For the email agent that redeploy is triggered automatically by its release workflow; a generic auto-redeploy for every agent is still being wired, so for now a maintainer may trigger the website deploy after your publish.

Part B — Update an existing agent

You can’t change a version once it’s published (more on why under Versioning). To ship a change you publish a new version:
1

Make your changes

Edit your code, gaia-agent.yaml, and/or README.md. Manifest and README changes flow to your website page on the next publish.
2

Bump the version number

This rewrites version in gaia-agent.yaml and keeps pyproject.toml and the package’s __init__.py in sync automatically. If your package also ships a non-Python version file (for example an npm package.json), update that one to match — the release tooling checks they agree.
3

Test, then publish again

The server rebuilds the catalog, so the Hub and your website page reflect the new version, README, and manifest.

Keep a changelog

As your agent evolves, record what changed in each version in a CHANGELOG.md (the Keep a Changelog format is a good default). It isn’t required by the publish process, but it’s the cheapest way to make your version bumps reviewable. If your agent also ships an npm package, @changesets/cli can automate version bumps and changelog entries.

Standalone sidecars

The api_server and mcp_server interfaces in your manifest let your agent run as a sidecar — a small local web server that another application talks to over a REST API or MCP, instead of a person using it directly. This is how an app embeds a GAIA agent. For a sidecar to actually serve those interfaces, its package must depend on the REST server pieces. Declare that in pyproject.toml by asking for the [api] extra (the example agents do this):
The email agent goes one step further and ships a frozen native binary plus an npm package (@amd-gaia/agent-email) so JavaScript apps can run it with no Python installed. That packaging is currently hand-built per agent; reusable tooling to make any agent an npm sidecar is on the roadmap.

Publishing a skill instead of an agent

A skill is a reusable capability any agent composes, not a package that runs on its own — so it is a separate hub lane with a separate publish contract (#2467). Skills are contributed by pull request, and only by pull request. Like agents, there is no self-serve publish: the Hub’s publish endpoint is gated on a maintainer-held token secret, so a contributor never handles one. Unlike the agent route, there is not even a direct-publish option to choose from — gaia skill publish is the mechanism maintainers and CI run after your PR merges.
1

Put your skill in skills/community/

One directory per skill: skills/community/<your-skill-name>/SKILL.md, plus tools.py and scripts/ if it ships code. (skills/starter/ is the AMD starter pack — worked examples to copy, not a place to submit.) See skills/community/README.md.
2

Audit it locally

Exit 0 (ALLOW) is what merges cleanly. This is the same engine CI runs, so a clean local run is the whole requirement — no guessing.
3

Open a PR

Automated checks run and a maintainer reviews. The Skill Audit (deterministic gate) check is required: BLOCK or an unparseable skill fails it outright, and REVIEW holds the PR until a maintainer applies the skill-audit-reviewed label. Findings appear as counts and rule ids in a PR comment, with the detail in the repository’s private Security tab.
4

Publication happens after merge

A maintainer publishes from AMD’s credentials. You never touch a token.
Merging is not a tier promotion. A skill’s security_tier is earned by the audit verdict plus publisher signing — verified additionally needs a human AMD audit that no automated scan grants. A maintainer signing off on a REVIEW verdict unblocks your PR; it does not change the verdict on record, and publishing still refuses a skill that has not earned ALLOW.This differs from the agent route above, where review is what sets the trust level. For skills the gate owns the tier, not the reviewer.
The rest of this section is the publish contract that runs after merge — useful to understand, but not something a contributor executes. If what you have is a SKILL.md folder, the differences from an agent package are: Everything else carries over: the same token and publisher scope, the same SemVer + immutability rules, the same security_tier vocabulary, and the same index.json (a skill is a type: "skill" entry). Two skill-only rules:
  • A version is required, and 0.0.0 is rejected — that value is the format’s “unversioned” sentinel, so it can never become an immutable release. Bump it in your PR when you change a skill; each version re-earns its verdict.
  • community and verified need a cleared security audit. Produce the report with gaia skill audit ./<skill>/ --json (#2468) and attach it as the audit form part. The publish call refuses those tiers without one; an experimental skill may publish without a report and is recorded as unaudited rather than stamped as passing. Two consequences that also shape what the PR gate tells you:
    • You cannot claim a tier the audit did not clear. The report lists the tiers your findings actually cleared and the hub checks the claim against it. Check before you claim with gaia skill audit ./<skill>/ --tier community. verified is never cleared by the automated scan — it needs the AMD audit on top of a passing one, so a spotless skill claiming it earns REVIEW.
    • Every version re-earns its verdict. The report is bound to the skill, the version, and a digest of the SKILL.md you audited, so re-run the audit after any edit. Publishing a bumped version with the previous report fails with audit_stale, and editing the manifest after auditing fails with audit_digest_mismatch.
Skill names share one namespace with agent ids, so a name already taken by a published agent is rejected (and vice versa).

How your agent shows up on the website

There is no hand-maintained list of agents — the site is built from the Hub’s index.json. From your manifest and README, the website generates:
  • your listing card and the page at /hub/<id>;
  • an install-method switcher (GAIA / pip / source) with copy buttons;
  • platform badges (from requirements.platforms) and requirement / permission / security-tier cards;
  • your README, rendered as sanitized Markdown inside that frame.
So you maintain only the manifest and README; the page updates itself on each publish.

Versioning rules

Versions follow SemVerMAJOR.MINOR.PATCH (e.g. 2.4.1). Which number you bump signals what changed:
  • PATCH (0.1.0 → 0.1.1) — bug fixes and tweaks; no new features, nothing breaks.
  • MINOR (0.1.1 → 0.2.0) — new features that are backward-compatible (existing usage still works).
  • MAJOR (0.2.0 → 1.0.0) — breaking changes (you removed/renamed something users relied on).
Use gaia agent version patch|minor|major to bump it. Two rules the Hub enforces:
  • Published versions are immutable. Re-publishing the same id@version is rejected with a 409 error — this guarantees that what someone installed can never silently change underneath them. Always bump the version to ship a change.
  • latest_version in the catalog tracks the highest published version automatically; you don’t set it.

Troubleshooting

See also