Marketplace
Discover, inspect, install, authorize, update, and manage skills, extensions, bundles, and MCP servers through one catalog.
- Audience
- Operators running durable agent work
- Focus
- Marketplace guidance shaped for scanability, day-two clarity, and operator context.
This page helps you move from discovery to a managed capability. You will use the Marketplace web page or structured CLI and API surfaces to inspect provenance, install through each kind's owning lifecycle, and complete any required authorization. A catalog record proves where an item came from; it does not prove that the item is safe for every environment.
Browse And Inspect
Open /marketplace to enter the Skills catalog, or go directly to /marketplace/skills,
/marketplace/mcps, /marketplace/extensions, or /marketplace/bundles. Each kind page switches
between Marketplace and Installed scopes; /marketplace/<kind>/<entry-id> opens one catalog record.
An installed skill detail also shows declared capabilities, recent calls, resolver provenance, and
shadow resolution. An installed extension detail keeps its runtime state, health, daemon process,
capabilities, actions, environment requirements, diagnostics, provenance, and provided bundles
together with its management controls.
The CLI returns the same daemon-owned projection:
# Browse every kind. An empty query returns real catalog slices.
agh marketplace search -o json
# Search one kind.
agh marketplace search "linear" --kind mcp -o json
# Continue that exact kind/query/scope from the returned next_cursor.
agh marketplace search "linear" --kind mcp --cursor '<next_cursor>' -o json
# Inspect the stable catalog identity before installing.
agh marketplace info mcp linear -o json
# Disambiguate an installed definition whose local name collides with a catalog entry.
agh marketplace info mcp linear --installed-name custom-linear -o jsonUse the returned entry_id with agh marketplace info. Install commands use the kind-specific
identifier shown by the detail payload, such as an extension or skill install_slug.
--installed-name disambiguates installed MCP, extension, and skill identities; bundle detail
rejects that flag because bundle activation identity is managed through its activation route.
The identifiers in the examples below are illustrative; substitute values returned by your active
catalog.
Single-kind responses return next_cursor when more rows remain. Treat it as opaque and pass it
unchanged with the same kind, query, scope, and workspace; grouped search does not accept a cursor.
Curated and bundle cursors fence the source projection. Remote skill registries do not expose a
snapshot revision, so AGH validates the prior page boundary with one bounded look-behind row. If
that boundary changes, AGH rejects the continuation; restart from the first page instead of
combining shifted pages.
total is the exact filtered total when the source can determine it. A source that cannot determine
an exact total omits it while still returning next_cursor.
JSON preserves the response envelope. Human and TOON output append a Page block; JSONL appends a
type: "page" record after the item records. Read next_cursor from that page metadata in any
output mode before requesting the continuation.
Each kind can fail independently during grouped search. Read the affected kind's stale,
error_class, and error fields instead of treating an empty group as proof that no items exist.
A failed refresh keeps the last successful rows, marks that kind stale, and returns the per-kind
failure report rather than pruning the projection. MCP, extension, and skill rows come from curated
feed documents. Bundle rows are derived from installed extensions, so
agh marketplace refresh --kind bundle is intentionally unavailable.
The launch catalog includes Context7 for current library documentation, Repository Orientation for evidence-backed codebase mapping, and Documentation Writer for project and API documentation. These are ordinary feed entries: inspect the live detail record before installing because curation metadata can change independently of the daemon release.
Install A Skill
Install the detail payload's skill slug through the existing skill lifecycle:
agh skill install documentation-writer -o json
agh skill where documentation-writer -o jsonThe install writes marketplace provenance beside SKILL.md, scans the content, and then verifies
that the effective skill resolver can discover the installed declaration. If a higher-precedence
declaration shadows it, inspect agh skill where <name> and repair the local precedence conflict
before retrying.
Skills do not carry a Marketplace trust badge because the skill source does not expose a trust field. Content scanning and installed provenance are separate runtime checks, not a safety rating.
Install An Extension
Install the detail payload's extension slug, then inspect the persisted provenance:
agh extension install compozy/repository-orientation -o json
agh extension provenance repository-orientation -o jsonFor a curated entry, AGH downloads the feed's exact HTTPS artifact_url, pins its version and
SHA-256 digest, verifies the download before extraction, and records the catalog entry, archive
digest, extracted-tree checksum, registry tier, and trust report separately. Manual registry
installs still resolve GitHub releases. A digest mismatch returns
extension_archive_digest_mismatch; nothing is installed and --allow-unverified cannot bypass
the mismatch. The matching extension.digest.verify event has outcome=success; a mismatch is
persisted with outcome=failure, so failure queries include the rejected archive.
Non-curated side-loads use a two-part gate. The live daemon policy must allow them, and the individual request must confirm the decision:
agh config set extensions.marketplace.allow_unverified true -o json
agh config reload -o json
agh extension install acme/private-extension --allow-unverified --yes -o jsonWhen policy is disabled, the structured diagnostic code is
extension_unverified_policy_blocked; its evidence points to /settings/extensions and the
extensions.marketplace.allow_unverified key. Enabling the policy does not weaken curated digest
verification.
Preview And Activate A Bundle
Bundles are declared by installed extensions. Always preview the selected profile and scope before activation:
agh bundle preview \
--extension linear-bridge \
--bundle incident-response \
--profile default \
--scope workspace \
--workspace <workspace-id> \
-o json
agh bundle activate \
--extension linear-bridge \
--bundle incident-response \
--profile default \
--scope workspace \
--workspace <workspace-id> \
-o jsonPreview is read-only. Activation projects the profile's declared resources only after validation. An active bundle can prevent its owning extension from being disabled or removed until the activation is deactivated.
Install An MCP Server
Catalog entries declare the transport and every required field. The daemon locks those entry-owned fields, validates the submitted values, and writes one complete MCP definition or nothing.
Context7 needs no required values and can be installed globally from the launch catalog:
agh mcp install context7 --scope global -o jsonUse --set KEY to read a field value from stdin or a hidden terminal prompt. To bind an existing
present Vault ref:
printf "%s" "$GITHUB_TOKEN" | \
agh vault put vault:mcp/shared/github-token --kind token --value-stdin
agh mcp install github \
--scope global \
--vault-ref GITHUB_TOKEN=vault:mcp/shared/github-token \
-o jsonWorkspace installs require both selectors:
agh mcp install github \
--scope workspace \
--workspace <workspace-id> \
--vault-ref GITHUB_TOKEN=vault:mcp/shared/github-token \
-o json--set accepts only the field name; the value is never a process argument. The web guided
installer offers the same typed-value or existing-Vault-ref choice. Settings responses return
configured field names and OAuth client-secret presence, never refs or secret values.
For direct HTTP or UDS calls, values is a required nullable property: send null when the entry
needs no operator inputs. Omission is rejected before the settings lifecycle runs.
The install response reports both config apply and next_step. apply.applied,
apply.apply_record_id, apply.active_generation, and apply.next_action tell you whether the
daemon reconciled the new definition into its active configuration or whether repair is required.
next_step=authorize means the structurally valid remote server still needs OAuth; none means
there is no authorization step. Installation does not probe the MCP server and therefore does not
claim runtime readiness.
Authorize A Remote MCP Server
Start the daemon-owned PKCE flow after an OAuth catalog install:
agh mcp authorize linear --scope globalAGH returns a live, copyable authorization URL and may open it in a browser. For a remote operator, or when the daemon HTTP bind is not loopback, use manual completion and paste the authorization code or full redirect URL:
agh mcp authorize linear --scope global --manualWorkspace authorization again requires both selectors:
agh mcp authorize linear --scope workspace --workspace <workspace-id> --manual
agh mcp auth status linear --scope workspace --workspace <workspace-id> -o jsonTreat authorization as complete only when status is authenticated and token_present is true.
A failed or canceled reauthorization preserves the existing token. The automatic HTTP callback is
disabled on non-loopback binds; manual exchange is the supported remote-operator completion path.
Loopback begin responses use the daemon's effective listener host and port, including IPv6, rather
than assuming an IPv4 address.
Manage And Repair MCP Servers
Open /marketplace/mcps?tab=installed. The page combines global definitions with definitions from
the active workspace and keeps four signals independent:
| Signal | Runtime source | What to verify |
|---|---|---|
| Config | Scoped settings entry | The server definition exists. |
| Auth | auth_status.status + token_present | OAuth is absent, needs login, expired, invalid, or confirmed. |
| Runtime | runtime_status.state | The daemon reports ready or a concrete repair state. |
| Probe | runtime_status.probe + tool_count | A probe was skipped, failed, or succeeded with a real tool count. |
A configured row is not automatically ready. OAuth-capable HTTP/SSE servers receive Authorize or Reauthorize only when their reported state needs repair. The editor supports stdio command, args, environment and secret refs, plus remote HTTP/SSE URL and OAuth client/discovery fields. Generic edits clear catalog provenance because the resulting definition is operator-managed.
Agents can inspect redacted state with agh__mcp_status and agh__mcp_auth_status. Management
mutations stay on CLI, HTTP, or UDS:
GET /api/settings/mcp-servers
PUT /api/settings/mcp-servers/{name}
POST /api/settings/mcp-servers/{name}/auth/begin
POST /api/settings/mcp-servers/{name}/auth/exchange
POST /api/settings/mcp-servers/{name}/auth/logoutThe HTTP-only GET /api/mcp/oauth/callback handles loopback browser completion. Use the generated
Settings API reference for exact query and body schemas.
Update Semantics By Kind
Marketplace does not invent one cross-kind update operation.
| Kind | Truthful update signal | Action |
|---|---|---|
| Skill | Installed marketplace version compared with the registry version. | agh skill update <name> --check, then agh skill update <name>. |
| Extension | Installed marketplace version compared with the registry version. | agh extension update <name> --check, then agh extension update <name>. Curated updates re-verify the pinned digest. |
| Bundle | Stored activation spec hash differs from the current installed bundle profile. | Inspect spec_drift, then agh bundle update <activation-id>. |
| MCP | No update comparison or update action in v1. | Manage the installed definition and authorization state; do not infer freshness from a badge. |
Non-semver skill or extension versions do not produce a speculative update badge. Updating a bundle
reapplies its current profile and clears spec_drift after successful reconciliation.
Read Trust As Provenance
Marketplace trust fields answer where an artifact came from and which bytes were checked. They do not guarantee safe behavior.
- Extension
registry_tierrecords the catalog's source tier. checksum_verifiedremains false before download verification and becomes true only after the installed curated archive matches its pinned digest.warningsanddecisionmust be read before installation; do not replace them with a generic verified badge.- MCP catalog provenance identifies the entry and version used to create the settings record. It does not report server reachability or authorization readiness.
- Skills have installed provenance and content verification, but no Marketplace trust tier.
- Bundles inherit their source from the installed extension that declares them.
Configure Catalog Refresh
[marketplace.catalog] controls the curated MCP, extension, and skill feed projection:
[marketplace.catalog]
base_url = "https://raw.githubusercontent.com/compozy/agh/main/catalog"
ttl = "1h"
timeout = "10s"All three keys apply live to the next fetch. Validate a change through the structured lifecycle:
agh config set marketplace.catalog.ttl 30m -o json
agh config reload -o json
agh config apply-history --limit 5 -o jsonA failed refresh preserves the last valid projection and marks that kind stale. A successful
refresh atomically replaces the kind, so entries removed from the feed disappear from discovery.
Installed-item management remains available when the catalog cannot refresh.
Catalog validation rejects OAuth MCP entries unless they declare client_id plus either an absolute
HTTP(S) issuer_url or a complete absolute authorization_url and token_url pair. A rejected
document leaves the last valid projection intact and stale-marked.
Related References
- Marketplace CLI lists exact discovery flags.
- Marketplace API lists browse, detail, and refresh schemas.
- MCP configuration and management covers MCP fields, precedence, status, and authorization.
- Install extensions covers extension lifecycle and policy.
- Bundles covers activation projection and conflicts.
- Configuration lifecycle matrix is generated from the runtime config owner.