The agent-discover dashboard is a single-page web application served at http://localhost:3424.
The dashboard provides a visual interface for managing MCP servers. It connects to the backend via WebSocket for real-time updates -- when servers are installed, activated, or deactivated, the UI updates automatically without manual refresh.
The default view. Shows all MCP servers registered in the local database as cards. This is a merged view -- both installed and active servers appear together with their current status.
An Add Server button in the panel header opens a collapsible form for manual server registration. The form adapts to the selected transport:
- Local (stdio): Name, Command, Args (comma-separated), Description, Env vars, Tags.
- Remote URL: Name, URL, Description, Env vars, Tags.
Each server card displays:
- Server name.
- Health dot indicating the server's health status (green for healthy, red for unhealthy, gray for unknown).
- Error count (if greater than 0), shown as a badge with a clear button (x) to reset via
POST /api/servers/:id/reset-errors. Error count also auto-resets on a successful health probe. - Active/Inactive status indicator (green/gray dot with label).
- Description and tags as small badges.
- Source (local, registry, smithery, manual) and transport (stdio, sse, streamable-http).
- Tools list with name and description (if the server has been activated at least once).
- Action buttons: Activate/Deactivate, Check Health, Delete.
- Test drawer (active servers only): seven subtabs — Tools, Info, Resources, Prompts, Events, Export, Diagnostics — plus a pop-out button that re-parents the drawer into a floating panel for side-by-side debugging. See Test Panel below for full detail.
- Expandable sections:
- Secrets: Lists stored secrets with masked values. Provides a form to add new secrets (key + value). Each secret has a delete button.
- Metrics: Shows a table of per-tool call counts, error counts, and average latency. Data is loaded on expand.
- Config: Editable fields for description, command, args (comma-separated), and env vars (KEY=VALUE per line). Save button persists changes via
PUT /api/servers/:id.
When no servers are registered, a placeholder message is shown with a hint to use registry_install or browse the marketplace.
The badge in the sidebar navigation shows the total count of servers.
Federated search across the official MCP registry, npm, and PyPI. Enter a search term to find MCP servers available for installation. Results appear after a 400ms debounce delay.
Each card shows:
- Server name, description, and version
- Runtime tag (
node,python,streamable-http,sse,docker) - Repository link (clickable, opens in new tab)
- Install button: Registers the server in the local database with the right command for its runtime —
npx -y <pkg>for node,uvx <pkg>for python, the remote URL for sse/streamable-http. Shows a checkmark if already installed. Shows a spinner during install and an error indicator on failure.
A prereqs banner is rendered above the result list when a package manager that the host needs (npx, uvx, docker) is missing — fed by GET /api/prereqs which probes each tool with <tool> --version. The banner explains which tool is missing and how to install it.
Installing a server from Browse adds it to the Servers tab.
Real-time call log of all proxied MCP tool calls. Each row shows timestamp, server name, tool name, success/fail badge, and latency.
- Click any row to expand full-width Args and Response panels below it (stacked vertically).
- Filter bar: dropdown to filter by server, dropdown for success/fail status.
- Clear All button removes all log entries (calls
DELETE /api/logs). - Real-time: new entries stream in via WebSocket (
log_entrymessages) without page refresh. - Badge: sidebar navigation shows the current log entry count.
- Retention: entries older than 30 days are auto-pruned (configurable via
AGENT_DISCOVER_LOG_RETENTION_DAYSenv var). In-memory ring buffer capped at 500 entries.
The sidebar contains:
- Header: Widgets icon (Material Symbols
widgets) and "agent-discover" title with version number. - Navigation: Three tab buttons -- Servers (with count badge), Browse, and Logs (with count badge).
- Footer: Theme toggle button (moon/sun icon).
The page uses an inline SVG favicon -- four rounded rectangles in the accent color (#5d8da8) at varying opacities.
The dashboard supports light and dark themes, toggled via the theme button in the sidebar footer.
- Dark theme (default): Dark backgrounds with light text
- Light theme: Light backgrounds with dark text
Both themes use the same accent color (#5d8da8) and Material Design 3 design tokens.
- Icons: Material Symbols Outlined (Google Fonts)
- Body font: Inter (400, 500, 600, 700 weights)
- Monospace font: JetBrains Mono (400, 500 weights)
- Border radius: 12px for cards, 16px for panels, 8px for small elements
- Section headers: Uppercase, 13px, weight 600, 0.5px letter-spacing
The dashboard supports bidirectional theme sync with the agent-desk shell:
- Inbound: Listens for
postMessageevents withtype: "theme-sync"and applies custom CSS variables (colors, shadows) from the parent frame. Also watches for external body class mutations viaMutationObserver. - Outbound: Emits theme changes via
console.log('__agent_desk_theme__:dark')for reverse sync. - When theme sync is active from a parent, the local theme toggle button is hidden.
Actions like saving config, setting secrets, and running health checks show brief toast notifications at the bottom of the screen. Toasts auto-dismiss after 3 seconds.
The dashboard maintains a persistent WebSocket connection. State is synchronized via:
- Full state snapshot on initial connection
- DB fingerprint polling every 2 seconds
- Automatic re-sync when the fingerprint changes
- Manual refresh available via the
{ "type": "refresh" }WebSocket message
The dashboard uses morphdom for efficient DOM diffing when applying state updates.
Each active server card exposes a Test expandable section that provides MCP-Inspector-grade debugging inside the dashboard itself — no second process, no second port. All network calls hit agent-discover's existing dashboard HTTP port (AGENT_DISCOVER_PORT, default 3424) and are restricted to loopback origins unless AGENT_DISCOVER_ALLOW_REMOTE_TEST=1 is set.
- Tools — list of
tools/listentries. Selecting one renders a schema-driven form from the tool'sinputSchema(supportsstring,number,integer,boolean,enum→<select>,arraywith add/remove rows, nestedobject, format-aware inputs fordate-time/date/email/uri, and a raw JSON textarea fallback foroneOf/anyOf/patternProperties). Submit calls the tool viaPOST /api/servers/:id/call. The result pane has three view modes:- Pretty — walks the MCP content array:
textas markdown,image/audioas embedded media (base64 data URL),resource/resource_linkas tagged blocks. - Raw — JSON-highlighted payload.
- cURL — copy-pasteable
curlcommand that reproduces the call outside the UI. - Latency pill (ms) and a success/fail badge sit above the body.
- Pretty — walks the MCP content array:
- Info —
getServerInfo()— server name, version, instructions (rendered as markdown), and a readable capabilities dump. - Resources —
resources/listpaginated vianextCursor(Load morebutton). Selecting a resource exposes Read, Subscribe, and Unsubscribe actions. Subscribed resources'resources/updatednotifications flow through the WebSocketnotificationstream and appear in the Events subtab. - Prompts —
prompts/listpaginated. Selecting a prompt renders its declared arguments as a mini form. Get prompt callsprompts/getand renders the resulting message chain inline (roles + markdown bodies). - Events — live feed of every server-sent notification and progress update since the drawer opened, scoped to the currently selected server.
- Export — one-click copy of the server's config in four formats:
mcp.json— standard MCP client shape (Claude Desktop, Cursor, Windsurf).claude-code— same{ mcpServers: { ... } }shape scoped to Claude Code.cursor— Cursor.cursor/mcp.jsonshape.agent-discover— the declarative setup-file format used byAGENT_DISCOVER_SETUP_FILE.
- Diagnostics —
pinground-trip (RTT in ms) andlogging/setLevelselector.
Every Test drawer has a pop-out button (top-right of the tab bar). Pop-out reparents the tester into a floating panel anchored to the top-right of the viewport. Multiple floating panels can coexist, so you can test two servers side-by-side.
Below the tool form, the drawer offers a Save as preset button and a preset dropdown. Presets are scoped by (serverName, toolName, presetName) and persisted to localStorage — they survive page refresh but are not synced across browsers or machines.
The Test ad-hoc button in the Servers tab header opens a floating panel backed by a transient MCP server — one that's activated just for this test session and never written to the registry. Transient servers get a 15-minute TTL, auto-disconnect on release or tab close, and their tools are not exposed to the host MCP catalog (getAllProxiedTools skips them). Ideal for paste-and-test flows during local MCP server development without polluting the registry.
agent-discover advertises the following client capabilities to every child server it activates:
roots.listChanged— the list of roots is configurable via theAGENT_DISCOVER_ROOTSenv var (comma-separated URIs) and exposed atGET /api/roots.elicitation— servers that request user confirmation viaelicitation/createare not blocked at the protocol level; interactive UI support lands in v1.5.
The Test panel can execute arbitrary tool calls and dump server capabilities — the trust boundary is "localhost only". The REST endpoints powering it refuse requests with non-loopback remoteAddress or suspicious Origin headers (DNS-rebinding protection). The AGENT_DISCOVER_ALLOW_REMOTE_TEST=1 escape hatch exists for controlled reverse-proxy deployments but prints a warning at startup.
The dashboard can be run independently of any MCP client:
node dist/server.js
# or with custom options:
node dist/server.js --port 3425 --db /path/to/discover.db