Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion docs/agent-profile.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ portable and make profile listings useful.

### Provider configuration

- `mcpServers` (object): MCP server definitions.
- `mcpServers` (object): MCP server definitions. Each entry defines either
`command` (with optional `args`, `env`, `timeout`) for a server CAO launches,
or `url` for a remote one, with `type` naming its transport (for example
`http` or `sse`). An entry defining neither is invalid.
- `tools` (array), `toolAliases` (object), and `toolsSettings` (object):
provider tool configuration.
- `resources` (array), `hooks` (object), and `useLegacyMcpJson` (boolean):
Expand Down
62 changes: 62 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,68 @@ See [AG-UI](agui.md) for enablement, event shapes, and privacy boundaries.
client can render create and edit forms from the server's definition instead
of duplicating the field list.
- `POST /agents/profiles/install` installs a profile.
- `POST /agents/profiles` creates a profile in the local store from a supplied
document. Named distinctly from `install`, which takes a bare profile name or
an https:// URL rather than the document itself. The request carries `name`
and `content`; the two identities of a profile, its storage key and its
frontmatter `name`, must agree, so a mismatch is a 400 rather than a silent
rename. A conflicting name returns 409. Requires `cao:write` or `cao:admin`.
- `PUT /agents/profiles/{name}` replaces an existing local-store profile and
never creates one. A request naming a built-in or provider-managed profile
returns 404 rather than writing a local file that would shadow the original.
Requires `cao:write` or `cao:admin`.
- `DELETE /agents/profiles/{name}` removes a profile from the local store.
Requires `cao:write` or `cao:admin`, the same guard as create and replace, so
one credential covers the whole create/edit/delete cycle. Scopes are a flat
set rather than a hierarchy, so requiring admin here would 403 a caller
holding exactly `cao:write`. Built-ins are not deletable, for the same reason
they are not replaceable.
- Both write routes run the profile validator on the exact submitted document
before persisting anything, so an invalid profile never reaches disk. Errors
reject the request with 400 and the findings attached; warnings do not block
the write and are returned in the response so a client can surface them after
a successful save.
- The validator rejects non-string mapping keys. A profile is written as YAML,
which allows any scalar as a key, but the format is described by JSON Schema,
where object keys are strings. Without this rule `mcpServers: {1: {...}}`
validates clean and persists, then fails to load, since the model requires
string keys. Note YAML also auto-types an unquoted date, so `2026-01-01:` is a
date key rather than a string; quote such keys.
- That key check walks the parsed document, and a document is rejected up front if
it is too large to inspect, because YAML anchors make a document's value graph
arbitrarily larger than its bytes: each alias resolves to another reference to
the same object, so chained anchors give a sub-kilobyte body an exponential
expansion. Two ceilings, both far above real input, which for the largest
bundled profile is 23 expanded values nested 3 deep: a document may expand to at
most 20,000 values (~870x) and nest at most 64 levels (~21x). Exceeding either
is itself an error, and nothing further runs, since the later steps are what
such a document is expensive in. Within the ceilings, containers already visited
are skipped, so each offending key is reported once, at the first path that
reaches it. Note that differs from the schema step, which does not memoize and
so reports a shared invalid value once per referencing path.
- An `mcpServers` entry must define either `command`, for a server CAO launches,
or `url`, for a remote one whose `type` names its transport. The schema
previously required `command` unconditionally, which made the write routes
reject url-based servers that the runtime accepts and passes through to the
provider unchanged. An entry defining neither is still rejected. `url` is the
spelling `resolve_mcp_server_config` documents; an entry naming its endpoint
under any other key satisfies neither branch and is rejected.
- Every 400 from the profile write and source routes uses one `detail` shape,
`{"message", "errors"}`, so a client never has to switch on the type of
`detail`. `errors` is empty for a failure that is not attributable to a field,
but the key is always present. This covers rejected names as well as schema
findings. 404 and 409 keep FastAPI's conventional bare-string `detail`, since
the status code already discriminates and there are no findings to attach.
- `GET /agents/profiles/{name}/source` returns a profile's document exactly as
stored. Use this, not `GET /agents/profiles/{name}`, when the document is
going to be edited and written back: that route returns the *resolved*
profile, having applied `${VAR}` substitution from the managed environment
file to the raw text before parsing. Round-tripping a resolved document
through a write would persist substituted values into a plaintext profile.
Requires `cao:read`, `cao:write`, or `cao:admin`, the same guard the profile
reads beside it now carry. Gating matters at least as much here as on the parsed
route, because this one returns the stored bytes verbatim from every configured
store, including documents that fail to parse.
- Template validation and preview require the selected template to include a
`schema.json` file.
- `/agents/providers` reports provider availability.
Expand Down
Loading
Loading