Stage 1 added the schema + service predicate. This stage threads the
filter through every surface that lists or fetches Llms/Agents:
- mcpd routes: viewerFromRequest helper builds a Viewer from the
request's RBAC scope. List endpoints rely on the existing
preSerialization hook (now two-phase: name-scope first, visibility
second). get-by-id/get-by-name routes pass the viewer to the service
which 404s on hidden rows.
- RBAC: AllowedScope gains `isAdmin` to distinguish a `*` cross-resource
grant (admins skip visibility) from a plain `view:llms` grant
(wildcard for RBAC, but visibility still applies). FastifyRequest
augmentation updated.
- VirtualLlmService.register accepts ownerId and stamps it on freshly
created virtual rows; defaults visibility to 'private' on first
create, leaves existing rows untouched on sticky reconnect.
- AgentService.registerVirtualAgents mirrors the same defaults.
- mcplocal: LlmProviderFileEntry / AgentFileEntry / RegistrarPublishedX
carry visibility through to the register payload (default 'private').
- CLI: VISIBILITY column on `mcpctl get llm` and `mcpctl get agent`,
`--visibility` flag on `mcpctl create llm` / `create agent`. YAML
round-trip works because visibility passes through stripInternalFields
unchanged (ownerId is already stripped). Completions regenerated.
Tests: mcpd 908/908, mcplocal 731/731, cli 437/437.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>