catalog is the optional fourth part of an AgentUIServer. Attach
it and the settings UI appears; omit it and those surfaces stay hidden.
get*Catalog) alongside a list of what they have already configured
(list*). And public read shapes never carry secrets — apiKey is accepted on writes and
never returned.
Model providers
Model providers
ProviderType is a string. The literal "custom" is reserved for user-defined
providers; any other value denotes a builtin such as "openai" or "anthropic".
baseUrl is present exactly when type is "custom" — builtins resolve their own
endpoint.Writes carry the key: CreateModelProviderRequest is
{ type, name, baseUrl?, apiKey, models }, and the update form is the same plus a required
id. Updates are a full replace keyed by id, not a patch — send the complete
models array, since omitted entries are dropped.ModelProviderCatalogEntry is discovery-only —
{ type, name, models, supportedReasoningEfforts?, logo? } — with no id and no key. Its
type is never "custom", because a custom provider is created through the custom form
rather than picked from a catalog.supportedReasoningEfforts lists the effort levels the provider’s models accept, which the
custom-provider form offers when configuring a model. logo is an optional image for the
provider card.
The custom-provider form these types back, in the Models settings panel.
Connectors (MCP servers)
Connectors (MCP servers)
requiresAuth: false tells the UI to hide the Disconnect action. authenticated drives the
connected/disconnected state shown to the user.Auth comes in two parallel unions — one for writes, one for public reads:The write union accepts an
apiKey; the public union has no such field, which is what keeps
secrets out of read paths. For dcr, authUrl is required on the public shape because the
UI needs somewhere to send the user.authenticateConnector starts the OAuth flow. It takes
{ id, redirectURL? } — redirectURL being the callback page your application owns — and
its return type is a union:ConnectorBase when the connector is already authenticated or when
auth.authUrl carries the authorize URL. Return the result object when the popup flow needs
an authorization_endpoint. Handle both when consuming it.disconnectConnector clears auth and returns the updated connector, so the UI can re-render
from the response. As with providers, updateConnector is a full replace keyed by id.Skills
Skills
SelectRegistrySkillRequest, which adds a catalogId
recording the SkillCatalogEntry it came from. Importing a repository directly sends
ImportGithubSkillRequest, which carries only the git fields. The distinction persists into
the read shape: a RegistrySkill has catalogId, a GithubSkill does not.There is no updateSkill — skills are created and deleted rather than edited. Deletion is
asymmetric between the two kinds: removing a registry skill returns it to the catalog as
selectable again, while removing a GitHub-imported skill is permanent.
Importing a skill from a GitHub repository in the Skills settings panel.
Sandbox providers
Sandbox providers
execTimeoutMs caps a single execution rather than the sandbox’s
lifetime.SandboxProviderBase extends that config with { id, name, catalogId, isConnected }. Note
it carries the last-saved config rather than omitting it, so an update form can show current
values without a second fetch. SandboxProviderCatalogEntry adds { id, name, type }.
SandboxProviderListEntry pairs each configured provider with the current snapshot sync
status. A failed status may include statusReason with a human-readable failure detail.CreateSandboxProviderRequest adds catalogId, name, type, and a required apiKey.
UpdateSandboxProviderRequest takes id plus the config, with an optional apiKey —
omit it to keep the existing key, send one to rotate. That is the one place a catalog write
is not a straight full replace.
Configuring a sandbox provider (Daytona) in the Sandbox providers settings panel.
Accessing the catalog
useCatalogServer() throws when no catalog is attached, so use it only where one is
guaranteed. useOptionalCatalogServer() returns null instead — prefer it in components that
must render either way.
Widening
Every catalog interface is generic over its row and request types, following the same pattern as the chat and builder ports:ConnectorCatalogServer’s first type parameter is TTool extends ToolBase, so a
host that surfaces per-connector tool metadata widens there.
Auth branches are widened by intersecting a branch and re-forming the union, so you can add
fields to one variant without loosening the others: