MCP Tool Registry

Pro

Registry for the tools and MCP servers an agent is connected to. Connection lifecycle and health, credential expiry, per-tool parameter schemas, usage and error rates, a scope permission matrix and a recent call log. Four variants — grid, table, permissions and detail.

</>sv-mcp-tool-registry mcptoolsintegrationsagentpermissionsscopesconnections
import { SvMcpToolRegistryComponent } from '@styloviz-pro/mcp-tool-registry';

Demo & usage

Basic usage

Pro

Usage example — open the gallery for the full interactive demo.

Pro

An interactive demo for this component lives in the gallery.

Open live demo

More examples

Scope matrix

Pro

Scopes are ordered, so a policy is a threshold rather than a set.

Audit the transition, not just the result

Pro

Every scope change reports the value it replaced.

Diagnose a failing connection

Pro

The schema says what the tool expects; the call log says what happened.

Read-only audit view

Pro

Keeps the information, removes every control.

When to use

  • Building the integrations page for an agent product — what is connected, what is healthy, what expires soon.
  • Letting an operator narrow what an agent may do, per tool, without editing a config file.
  • Diagnosing why a tool call keeps failing, with the declared schema and the recent call log side by side.
  • Giving a compliance reviewer a read-only view of every connection and granted scope.

Async states

  • loading
  • error
  • retry

Item identity & owned state

Restorable state
  • expandedIds
  • paramsExpandedKeys

Bind these to put a saved view back — the open sections, the hidden columns, the selected rows — and read their Change events to store what the user does.

Inputs

NameTypeDefaultDescription
loadingbooleanfalseTrue while the data is being fetched.
errorSvDataError | string | nullnullLoad failure. Use `toSvDataError()` from `@styloviz/core` to normalize an `HttpErrorResponse`.
serversreadonly McpServer[][]The connected servers.
selectedIdstring | nullnullWhich server the `detail` and `permissions` variants show. Defaults to the first.
variantMcpRegistryVariant'grid'Presentation preset.
showHealthbooleantrueShow the roll-up counts above the list.
showUsagebooleantrueShow per-tool call counts, error rate and latency.
editablebooleantrueLet the reader flip servers and tools on and off.
logLimitnumber8How many call-log entries the `detail` variant shows per page. `0` hides the log. When the log is longer, a notice says how many are hidden and a "Show more" control reveals the next page.
ariaLabelstring'Connected tools'Accessible label for the registry.
nownumberDate.now()Clock used for credential expiry, injectable so a test is not at the mercy of the wall clock.
expandedIdsReadonlySet<string> (two-way)new Set()Server ids whose tool list the viewer expanded (two-way). A `model` so a host can restore or persist which servers were open.
maxServersnumber100How many servers the registry lists at once. `0` = no ceiling. A REGISTRY IS A CATALOGUE, AND CATALOGUES GROW MONOTONICALLY. Nobody removes an MCP server; a platform team's registry passes a hundred entries in its first year and nothing in this component was bounded.
maxToolsPerServernumber50How many of one server's tools are listed when it is expanded. `0` = none. THIS IS THE CEILING THAT ACTUALLY BITES, and it is per SERVER rather than per page. One server exposing a generated API can carry several hundred tools, each with a parameter table — so a registry of six servers renders thousands of rows the moment somebody expands the wrong one, and the count beside the name gave no warning because it is the number the ceiling hides.
maxParamsPerToolnumber8How many of one tool's schema parameters are listed before "Show all". `0` = no ceiling. A GENERATED SCHEMA CAN CARRY A HUNDRED PARAMETERS, and the tool ceiling alone does not bound the page: fifty tools × a hundred rows is still five thousand. The table stops at the ceiling, says how many are hidden, and expands on demand for the one tool being inspected.
paramsExpandedKeysReadonlySet<string> (two-way)new Set()`server::tool` keys whose full parameter table the viewer expanded (two-way). A `model` so a host can restore or persist it.

Outputs

EventPayload typeDescription
retryvoidThe host should re-run the failed load.
serverToggledMcpServerToggleA server's master switch was flipped.
toolToggledMcpToolToggleA single tool was enabled or disabled.
scopeChangedMcpScopeChangeA tool's granted scope changed, with the value it replaced.
reconnectMcpServerThe reader asked to reconnect a server.
credentialActionMcpCredentialActionA credential needs re-authorising or revoking — the host does the work.
serverSelectedMcpServerA server row or card was activated.
revealChangedMcpRevealChangeA viewer revealed or re-hid a server's masked values. Only fires when the privacy policy allows reveal (`provideSvAiPrivacy({ reveal: true })`) — log it to keep an audit trail of who looked at what.
expandedIdsChangeReadonlySet<string>Emits the new `expandedIds` whenever it changes — the output half of `[(expandedIds)]`.
paramsExpandedKeysChangeReadonlySet<string>Emits the new `paramsExpandedKeys` whenever it changes — the output half of `[(paramsExpandedKeys)]`.

Wire it to your API

This component is headless about transport: it renders what you give it and reports what the user asks for. Nothing below requires @styloviz/data — drive it from whatever you already use.

Template

Pro

Bound to the names this component actually exposes.

Host class

Pro

Drive the three async inputs from your own fetch.

  • This component does not emit a query, so it renders what you give it. Fetch on your own trigger and bind `servers`, `loading` and `error`.
  • Normalize failures with `toSvDataError()` from `@styloviz/core`. It derives `retryable` from the status, so a 404 does not get a "Try again" button that can only fail again.

Full walkthrough: Connecting to a backend.

Customization & theming

  • Redaction, from the pack-wide policy (`X-2`): the credential LABEL, the server URL, the server error and every call-log error are masked per `provideSvAiPrivacy({ patterns })`. A URL carries a credential without looking like one (`https://user:pass@…`, `…?token=…`) and a failing client echoes it into its error; `SV_AI_COMMON_PATTERNS` includes `url-credentials` and `url-secret-param` for exactly this.
  • Role-gated reveal: with `provideSvAiPrivacy({ reveal: true })` — provided only for the roles allowed to see secrets — each server with something masked on screen gets a Reveal / Hide control, and `(revealChanged)` reports `{ server, revealed }` so you can log who looked. `reveal` is false by default, and it never switches masking off: values stay masked until a viewer asks.
  • `variant` chooses the shape: `grid` for a landing page, `table` when there are more servers than fit, `permissions` for the scope matrix, `detail` for one connection in full.
  • `editable` false turns the whole component into an audit view — switches, radios and actions all disappear.
  • `showHealth` and `showUsage` drop the roll-up counts and the per-tool metrics independently.
  • `logLimit` is the call-log page size: a longer log says how many calls are hidden and offers "Show N more". `0` hides the log. `selectedId` drives which server the single-server variants show.
  • `maxParamsPerTool` (8) bounds a tool's parameter table: a generated schema can carry a hundred parameters, so the table stops at the ceiling, says what it hid, and "Show all N parameters" expands it for the one tool being inspected. `0` turns it off.
  • The `SCOPE_ORDER`, `scopeAtLeast`, `registryHealth` and `credentialExpiry` helpers are exported, so a policy layer can threshold scopes and compute its own roll-ups.
  • Scale ceilings: `[maxServers]` (100) bounds the catalogue and `[maxToolsPerServer]` (50) bounds one server's tool list — the second is the one that bites, because a single server exposing a generated API can carry several hundred tools, each with a parameter table. Both disclose what they left out, and the tool count beside a server name stays the SERVER's count, so the warning does not vanish exactly when it is earned. `0` turns either off.

Best practices

  • Do: Set `risk` on each tool to match the risk you pass to Agent Approval, so the registry and the approval gate agree on severity.
  • Do: Record `previous` from `scopeChanged` in your audit log — knowing a scope became `admin` matters far less than knowing it was `read` an hour ago.
  • Do: Fill in `params` for every tool. The schema is what turns a failing call into a fixable one.
  • Do: Pass `now` in tests so credential-expiry assertions are not at the mercy of the wall clock.
  • Don't: Do not put secrets in `credential`. It carries a kind, a display label and an expiry — `credentialAction` asks the host to do the actual work.
  • Don't: Do not set `expiresAt` on a credential that does not expire. A static key flagged as expiring is how a registry cries wolf until nobody reads it.
  • Don't: Do not reach for this to pick a model — that is AI Model Selector. This manages many stateful connections, not one choice.

Accessibility

  • The permission matrix is a real table: scope columns are `th[scope="col"]`, each tool row is `th[scope="row"]`, and a visually-hidden `caption` names the server.
  • Each radio carries an explicit label ("merge_pull_request: write"), so the cell is meaningful without reading the row and column headers separately.
  • The connected count is `role="status"`, so a connection dropping while the operator is elsewhere is announced.
  • Table rows use proper `aria-expanded` / `aria-controls` disclosures pointing at the revealed tool list.
  • Status is never colour-only — each state carries a text label beside its dot, and a connecting server animates rather than relying on hue alone.
  • Every switch has an explicit `aria-label` naming what it enables, since the visible text belongs to the row rather than the control.
  • The Reveal control is a toggle button with `aria-pressed` and a label naming the server; the parameter "Show all" control carries `aria-expanded` / `aria-controls` pointing at the parameter list.

Feedback on MCP Tool Registry

Spotted a gap in this page, or something that didn't work as described? Comments are GitHub Discussions in the public styloviz/community repo, so posting needs a GitHub account.

Loads giscus.app and GitHub — nothing is fetched until you click.