Skip to content

Tool-selection ergonomics: grouped catalog, tier bulk switches, opt-in servers, KV hints - #22

Merged
selic merged 4 commits into
mainfrom
feat/bulk-tool-toggles
Jul 29, 2026
Merged

Tool-selection ergonomics: grouped catalog, tier bulk switches, opt-in servers, KV hints#22
selic merged 4 commits into
mainfrom
feat/bulk-tool-toggles

Conversation

@selic

@selic selic commented Jul 29, 2026

Copy link
Copy Markdown
Member

Three UI complaints after CIPP pushed the catalog to 313 tools, plus the two follow-ups from the same conversation.

What

  • Bulk toggles, one requestPATCH /api/catalog/:upstreamId {enabled, tier?, group?} and the same shape on PUT /api/me/prefs. Per-tool APIs would have meant 225 calls for one click on cipp's read tier, non-atomically. Targets resolve from the live catalog (on /me, from the caller's own envelope), matching on the effective tier so an override moves a tool between switches exactly as displayed.
  • Admin catalog grouped by server — collapsible groups with a server on/off button, per-tier switches with counts, "N of M enabled", a name filter, and a 50-row cap per group. Previously a flat list of everything.
  • Derived categories — servers that prefix descriptions with a path ([Identity > Administration > Users], CIPP) surface the first segment as the group label placeholder, and bulk-by-group matches it, so a category is switchable without typing labels.
  • Secrets hints follow the store/api/secrets/health now reports scheme: Key Vault explains the flat <name>-<field> secret and kv: refs (with cipp-mcp / secret placeholders), OpenBao keeps the KV-v2 wording, and with no store at all the panel says so and points at ${VAR} env refs.
  • Opt-in upstreams — new spec field userDefault: "on" | "off". With "off" a server is listed on /me but contributes nothing until the user opts in (tool, tier, or server-wide); the envelope stays the ceiling, so opting in can never reach a tool the role can't see. /me gained the same tier switches and an "opt-in server" label.
  • CIPP preset now takes a tags param (Identity,Endpoint,Email-Exchange — measured: 26/23/39 tools; all 231 at once doesn't even finish inside the 20s preflight) and ships userDefault: "off".
  • /api/me/access now derives every enabled flag from PolicyService.allowsFor instead of recomputing pref logic locally — the page and the MCP boundary can no longer disagree (they did, for opt-in servers, mid-development).

Tests

227 passing (11 new): transactional repo bulk helpers incl. the opt-in mode; admin bulk route (whole server / tier / effective-tier matching / 404 / viewer 403); bulk prefs narrowing only within the envelope (a viewer's write switch changes nothing); the four userDefault × pref-row combinations, including "per-tool deny still beats a server-wide opt-in"; preset renders the scoped URL and userDefault.

Verified live against the real ndr-mcp-cwpsa upstream in a dev gateway: one click disabled all 8 write tools (31/39, checkboxes struck through), server off/on round-tripped 0↔39, and the opt-in flow went 0/39 → read tier 30 → server-wide 39 → hide destructive 38, with the /me header and tier buttons tracking each step. Both Secrets wordings checked (KV via KEY_VAULT_URI, and the no-store branch).

Release v0.11.0. After deploy: re-install cipp from the preset with scoped tags so prod drops from 313 tools and inherits opt-in.

🤖 Generated with Claude Code

Eugene Samotija and others added 4 commits July 29, 2026 13:11
One click on a tier switch would otherwise be one request per tool — 225 of
them for cipp's read tier, non-atomically. New PATCH /api/catalog/:upstreamId
{enabled, tier?, group?} (no tier/group = the whole server) and the same shape
on PUT /api/me/prefs, both backed by transactional repo helpers returning the
row count. Targets are resolved from the live catalog — and on /me from the
CALLER'S envelope — so a stale UI can never touch a tool the user was never
allowed to see; matching uses the EFFECTIVE tier, so an override moves a tool
between switches exactly as the UI shows it. bulkSetUserPrefs also has the
opt-in mode the upcoming off-by-default upstreams need.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…store-aware secret hints

The Tools tab was a flat list of every tool — unusable once CIPP added 231 of
them, and (unlike /me) with no way to act on one server's set. Now each
upstream is a collapsible group whose header carries a server on/off button,
per-tier bulk switches with counts, and an "N of M enabled" readout; bodies
render at most 50 rows behind a name filter. Bulk clicks go through the new
single-request endpoint.

Tools also gain a derived group: servers that prefix descriptions with a
category path ("[Identity > Administration > Users]" — CIPP) now surface its
first segment as the group-label placeholder, and bulk-by-group matches it, so
a category can be switched even where no label was ever typed.

Secrets-tab hints now follow the configured store, which /api/secrets/health
reports as "scheme": Key Vault explains the flat <name>-<field> secret and kv:
refs, OpenBao keeps the KV-v2 path#field wording, and with no store at all it
says so and points at ${VAR} env references instead of implying one.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rowing

A 231-tool server floods every session it appears in, so upstreams gain
userDefault: "on" | "off". With "off" the server is listed on /me but
contributes nothing until the user opts in — per tool, per tier, or
server-wide — and the role envelope stays the ceiling, so an opt-in can never
reach a tool the role cannot see. On-by-default upstreams behave exactly as
before.

/me grows the same per-tier bulk switches as the admin catalog (one request
per click via the bulk prefs endpoint), shows "N of M active", and labels
opt-in servers so the empty state reads as a choice rather than a bug.

GET /api/me/access now derives each tool's `enabled` from
PolicyService.allowsFor — the same function the MCP boundary calls — instead
of recomputing the pref logic locally, which is what let the page disagree
with reality for opt-in upstreams during development.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Tool-selection ergonomics: bulk tier/group toggles on both the admin catalog
and /me, server-grouped admin catalog, store-aware secret hints, opt-in
upstreams (userDefault), and a CIPP preset that scopes itself with tags.
@selic
selic merged commit 9734ec9 into main Jul 29, 2026
@selic
selic deleted the feat/bulk-tool-toggles branch July 29, 2026 17:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant