For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
Use as a plugin marketplace
Expose the agentregistry plugin catalog as a private Claude Code plugin marketplace.
Solo Enterprise for agentregistry can serve its plugin catalog as a Claude Code-compatible plugin marketplace. When enabled, Claude Code and other AI coding assistants can browse and install plugins directly from your private registry, without going through a public marketplace.
The registry exposes a read-only marketplace.json endpoint at:
GET http://localhost:12121/plugin-marketplace/marketplace.jsonAccess control
Every request to the /plugin-marketplace/marketplace.json path goes through the same access control layers as the rest of the registry catalog.
- Layer 1 authentication. A request to the plugin marketplace requires a valid bearer token. Requests with an expired or invalid token get a
401 UnauthorizedHTTP response. - Layer 2: User authorization. The endpoint enforces the AccessPolicy rules that you set up for the registry. Users see only the plugins that they have
registry:readaccess to.
Important
Claude Code sends the Authorization header, including the one that a headersHelper command produces, only to an https:// marketplace URL. If you register the marketplace at an http:// URL, Claude Code cannot authenticate with the plugin marketplace and you see 401 Unauthorized HTTP responses. Expose the registry through an ingress or gateway that terminates HTTPS before you register the marketplace with Claude Code. For more information, see Register the plugin marketplace in Claude Code.
Limitations
- Plugin names in the marketplace are namespaced as
namespace.plugin-name, such asdefault.my-pluginto avoid collisions across namespaces. Plugins that you publish without ametadata.namespacefield are automatically created in thedefaultnamespace. Note thatarctl get pluginsdoes not show the namespace that the plugin was stored in. - Only git-sourced plugins where the registry server was able to resolve the git source and pin it to a commit appear in the marketplace. OCI-sourced plugins are not included in the
marketplace.jsonformat. Plugins that are still resolving or failed to resolve are silently omitted.
Before you begin
Set up an OIDC provider so that users can authenticate with the registry.
Install Solo Enterprise for agentregistry and the
arctlCLI.Port-forward the Solo Enterprise for agentregistry server on port 12121 if you have not done so already. The registry is not exposed externally by default, so you need port-forwarding to reach it from your local machine.
kubectl -n agentregistry-system port-forward svc/agentregistry-enterprise-server 12121:12121
- Publish at least one plugin.
- Create an AccessPolicy that grants
registry:readaccess on the plugins that you want to be visible in the marketplace. For more information about how the registry authenticates and authorizes requests, see About access control. - If you plan to register the marketplace with Claude Code, expose the registry through an ingress gateway that terminates HTTPS in front of it. To test the marketplace without Claude Code, you can run a curl request against the marketplace endpoint on the
localhostaddress that you port-forwarded.
Enable the marketplace endpoint
The marketplace endpoint is disabled by default. Enable it by setting the AGENT_REGISTRY_PLUGIN_MARKETPLACE_COMPAT_ENABLED environment variable to true on the registry server.
Upgrade the Helm release to pass the environment variable to the registry server.
helm upgrade -i agentregistry \ oci://us-docker.pkg.dev/solo-public/agentregistry-enterprise/helm/agentregistry-enterprise \ --namespace agentregistry-system \ --version 2026.9.0 \ --reuse-values \ --set-string "extraEnvVars[0].name=AGENT_REGISTRY_PLUGIN_MARKETPLACE_COMPAT_ENABLED" \ --set-string "extraEnvVars[0].value=true"Warning
The
extraEnvVars[0]syntax writes to the first entry in the list. If your release already sets other extra environment variables, add this variable to your Helm values file instead, so that you do not overwrite an existing entry.Verify that the registry server restarted with the new environment variable.
kubectl -n agentregistry-system get deploy agentregistry-enterprise-server \ -o jsonpath='{.spec.template.spec.containers[0].env[?(@.name=="AGENT_REGISTRY_PLUGIN_MARKETPLACE_COMPAT_ENABLED")].value}'Example output:
trueConfirm that the endpoint now enforces authentication. A request without a bearer token is rejected with a 401 HTTP response.
curl -i http://localhost:12121/plugin-marketplace/marketplace.jsonExample output:
HTTP/1.1 401 UnauthorizedRepeat the request with a bearer token from a user who has
registry:readpermissions on at least one plugin, and confirm that the response lists only the plugins that the role can read.curl -sS -H "Authorization: Bearer $(arctl user info --show-tokens | jq -r '.access_token')" \ http://localhost:12121/plugin-marketplace/marketplace.json | jq -r '.plugins[].name'Example output:
default.hello-plugin
Tip
By default, the registry serves the marketplace at the /plugin-marketplace/marketplace.json path. To mount the endpoint under a base path instead, such as /plugins/plugin-marketplace/marketplace.json, also set the AGENT_REGISTRY_PLUGIN_MARKETPLACE_COMPAT_PATH_PREFIX environment variable to the prefix that you want, such as /plugins. Any prefix that you set here must match the URL that you register with Claude Code later.
Register the plugin marketplace in Claude Code
Because the marketplace endpoint requires a bearer token for authentication, you cannot use the claude plugin marketplace add <url> command to register the plugin in Claude Code as the command does not attach an Authorization header to requests that are sent to the marketplace endpoint. Instead, you must configure the marketplace in the Claude Code settings file directly by using a headersHelper command that supplies a fresh token on each request.
Save the HTTPS URL that Claude Code uses to reach the marketplace endpoint in an environment variable. Use the ingress or gateway host that you set up in Before you begin, not the
localhostaddress that you port-forwarded earlier. Claude Code sends the Authorization header only to anhttps://URL.export AR_MARKETPLACE_URL=https://registry.example.com/plugin-marketplace/marketplace.jsonCreate a script that prints the Authorization header as a JSON object, and make it executable. Claude Code runs this script before it fetches the plugins from the
marketplace.jsonendpoint.mkdir -p ~/.claude/scripts cat > ~/.claude/scripts/agentregistry-marketplace-headers.sh <<'EOF' #!/usr/bin/env bash set -euo pipefail arctl user whoami >/dev/null 2>&1 || true arctl user info --show-tokens | jq -cr '{Authorization: ("Bearer " + .access_token)}' \ || { echo "No valid session. Run 'arctl user login' and try again." >&2; exit 1; } EOF chmod +x ~/.claude/scripts/agentregistry-marketplace-headers.shNote
Claude Code runs the
headersHelpervalue as a shell command, and waits up to 10 seconds for it to print one line of JSON to stdout. Make sure to set theheadersHelperfield to the path of that shell script. Do not add the content of that script to that field as Claude Code caps theheadersHelperfield at 500 characters.Add the marketplace to the
extraKnownMarketplacesblock in your Claude Code settings. Use~/.claude/settings.jsonto make the marketplace available in every project. Do not use a project.claude/settings.jsonfor this entry, because Claude Code honors it only after you accept the workspace trust dialog for that folder, and removes environment variables such asARCTL_TOKEN_FILEfrom theheadersHelpercommand. The following example merges the entry into~/.claude/settings.jsonwithjq, so that an existingextraKnownMarketplacesentry, or any other setting in the file, is preserved. Run these commands in the same shell session as step 1, so that$AR_MARKETPLACE_URLis still set.settings_path=~/.claude/settings.json test -f "$settings_path" || echo '{}' > "$settings_path" tmp=$(mktemp) jq --arg url "$AR_MARKETPLACE_URL" \ '.extraKnownMarketplaces.agentregistry.source = { source: "url", url: $url, headersHelper: "~/.claude/scripts/agentregistry-marketplace-headers.sh" }' "$settings_path" > "$tmp" && mv "$tmp" "$settings_path" jq '.extraKnownMarketplaces.agentregistry' "$settings_path"Example output:
{ "source": { "source": "url", "url": "https://registry.example.com/plugin-marketplace/marketplace.json", "headersHelper": "~/.claude/scripts/agentregistry-marketplace-headers.sh" } }Setting Description sourceThe marketplace source type. Use urlto point Claude Code at amarketplace.jsonfile that the registry serves.urlThe HTTPS URL of the marketplace endpoint. Claude Code sends the Authorization header only to an https://URL.headersHelperThe path to the script that prints the Authorization header. Give an absolute path, or a path relative to ~/.claude, because Claude Code runs the command from its configuration directory.Start or restart Claude Code, then confirm that it registered the marketplace and fetched the catalog.
claude plugin marketplace listExample output:
Configured marketplaces: ❯ agentregistry Source: URL (https://registry.example.com/plugin-marketplace/marketplace.json)If the marketplace does not appear in this list, open an interactive Claude Code session and check the
/pluginpath before you continue troubleshooting. The interactive session triggers a plugin reload.Install a plugin from the catalog. Use the name that the plugin has in the marketplace. Note that you must include the namespace, such as
default.hello-plugin.claude plugin install default.hello-plugin@agentregistryExample output:
✔ Successfully installed plugin: default.hello-plugin@agentregistry (scope: user)Verify that the plugin is installed and enabled.
claude plugin listExample output:
Installed plugins: ❯ default.hello-plugin@agentregistry Version: 1.0.0 Scope: user Status: ✔ enabled
Note
Claude Code caches the catalog when you add the marketplace. If you publish a plugin to the registry afterward, refresh the cache so that the new plugin becomes available to install. Claude Code reruns your headersHelper command as part of the refresh, so the request stays authenticated.
claude plugin marketplace update agentregistry