Managing registries
Registries are catalogs of skills and plugins beyond a single owner/repo URL. Each registry is an adapter capa stores in its database and materializes under ~/.capa/registries-managed/<slug>/. You browse and install from the CLI or the Web UI.
Supported source types: github, gitlab, url, and claude-marketplace.
Mental model
Section titled “Mental model”- Add a registry once (
capa registry add …). - Search / browse items (
capa registry searchor Web UI). - Install with
capa add <slug>:<itemId>, thencapa install(unless you used--passthrough/--install).
The adapter decides whether an item is a skill or a plugin. See Registries for the resource-focused reference and CLI: registry for every flag.
Lifecycle commands
Section titled “Lifecycle commands”capa registry # same as listcapa registry listcapa registry path # ~/.capa/registries-managed/
capa registry add <source> [slug] [--type <type>] [--no-cache]capa registry refresh <slug> [--no-cache]capa registry enable <slug>capa registry disable <slug>capa registry remove <slug>
capa registry search [slug] [query]capa registry search -q design --capability skills| Action | Effect |
|---|---|
add | Fetch, validate, and install the adapter; derive or set a slug |
refresh | Re-fetch from the stored source (updates resolved ref) |
disable / enable | Hide or restore without deleting |
remove | Delete the DB row and materialized adapter files |
search | Query one registry or all enabled registries |
Add a registry
Section titled “Add a registry”-
Pick a source form
Form Example GitHub search infragate/capa@skills-shGitHub exact path owner/repo::registries/internalGitLab owner/repo::path --type gitlab(or agitlab.com/…style source)HTTPS adapter URL https://example.com/adapter.ts(HTTPS required except localhost)Claude marketplace owner/repo --type claude-marketplace -
Install the adapter
Terminal window capa registry add infragate/capa@skills-shcapa registry add anthropics/claude-plugins-official marketplace --type claude-marketplacePass a second argument when you want an explicit slug.
-
Verify
Terminal window capa registry listConfirm status is healthy and the registry is enabled.
-
Install an item
Terminal window capa add skills-sh:vercel-labs/skills/find-skillscapa install
Claude marketplace
Section titled “Claude marketplace”Claude marketplace registries point at a repo that publishes marketplace.json. Set the type explicitly when auto-detect is ambiguous:
capa registry add anthropics/claude-plugins-official my-marketplace --type claude-marketplaceThen install with the usual slug:itemId form. You can also manage marketplaces from Registries → Manage registries in the Web UI.
Write your own adapter
Section titled “Write your own adapter”An adapter is a single self-contained adapter.ts (or .js / .mjs) file. capa fetches it, dynamic-imports it to validate the shape, then materializes a copy under ~/.capa/registries-managed/<slug>/. There is no compile step — Bun transpiles TypeScript on the fly inside the server process.
Contract
Section titled “Contract”interface RegistryAdapter { manifest: RegistryManifest; search(args: RegistrySearchArgs): Promise<RegistrySearchResult>; view(args: RegistryViewArgs): Promise<RegistryItemDetail>;}| Piece | Role |
|---|---|
manifest | id, name, optional description / homepage / icon, and capabilities: ['skills' | 'plugins', …] |
search | Fast, lightweight listings (debounced UI search / capa registry search) |
view | Full detail for one item: markdown preview plus installSnippet pasted into capabilities.yaml |
installSnippet for a skill typically looks like:
{ id: 'my-skill', type: 'github', def: { repo: 'owner/repo@my-skill' },}Keep type definitions inline in the file so the adapter has no external imports.
Minimal example
Section titled “Minimal example”Save as my-registry/adapter.ts (folder name becomes the search basename when you use owner/repo@my-registry):
type RegistryCapability = 'skills' | 'plugins';
interface RegistryManifest { id: string; name: string; description?: string; homepage?: string; icon?: string; capabilities: RegistryCapability[];}
interface RegistryItemSummary { id: string; capability: RegistryCapability; title: string; description?: string; author?: string; version?: string; icon?: string; tags?: string[]; homepage?: string;}
interface RegistryItemDetail extends RegistryItemSummary { preview: string; installSnippet: Record<string, unknown>; files?: string[];}
interface RegistryAdapter { manifest: RegistryManifest; search(args: { capability: RegistryCapability; query?: string; limit?: number; }): Promise<{ items: RegistryItemSummary[]; total?: number }>; view(args: { capability: RegistryCapability; id: string; }): Promise<RegistryItemDetail>;}
const adapter: RegistryAdapter = { manifest: { id: 'acme-skills', name: 'Acme Skills', description: 'Internal skill catalog', homepage: 'https://registry.example.com', capabilities: ['skills'], },
async search({ capability, query, limit }) { if (capability !== 'skills') return { items: [] };
const url = new URL('https://registry.example.com/api/search'); if (query) url.searchParams.set('q', query); url.searchParams.set('limit', String(limit ?? 20));
const res = await fetch(url); if (!res.ok) throw new Error(`search failed: ${res.status}`); const data = await res.json();
return { items: (data.results ?? []).map((r: any) => ({ id: r.id, capability: 'skills' as const, title: r.name, description: r.summary, author: r.author, })), total: data.total, }; },
async view({ capability, id }) { if (capability !== 'skills') { throw new Error(`Unsupported capability: ${capability}`); }
const res = await fetch(`https://registry.example.com/api/items/${id}`); if (!res.ok) throw new Error(`view failed: ${res.status}`); const data = await res.json();
return { id, capability: 'skills', title: data.name, description: data.summary, author: data.author, preview: data.readme, // markdown shown in the Web UI installSnippet: { id: data.slug, type: 'github', def: { repo: `${data.owner}/${data.repo}@${data.slug}` }, }, }; },};
export default adapter;Publish and register
Section titled “Publish and register”-
Host the file in a git repo (recommended) or at an HTTPS URL.
my-org/internal-tools/└── registries/└── acme-skills/└── adapter.ts -
Add it to capa
Terminal window # Exact path in a GitHub repocapa registry add my-org/internal-tools::registries/acme-skills# Or search by folder basenamecapa registry add my-org/internal-tools@acme-skills# Or a direct HTTPS URL (HTTPS required except localhost)capa registry add https://raw.example.com/acme-skills/adapter.ts acme-skills -
Verify and use
Terminal window capa registry listcapa registry search acme-skills "checkout"capa add acme-skills:<itemId>capa install
manifest.idmust be unique across loaded adapters. Collisions skip the second adapter and show as failed oncapa registry list.- Return early for unsupported capabilities (
{ items: [] }fromsearch, throw fromview). search/viewtime out after 15 seconds. Cache slow upstream responses in memory when needed.previewis Markdown (sanitized in the Web UI). Returning fullSKILL.mdcontent works well.- Refresh after edits:
capa registry refresh <slug>re-fetches the source; restart the server for a fully clean reload. - Reference adapters in the capa repo:
registries/skills-sh,registries/cursor-marketplace.
Web UI
Section titled “Web UI”With the server running, open the local UI:
- Browse enabled registries and install items
- Manage registries (
/ui/registries/settings) to add, preview, refresh, enable/disable, or remove adapters
See Web UI.