Tool inventory and discovery
The Tools tab is where AuthSec's view of your MCP server lives. Discovery populates it; scope mapping (the next step) acts on it.
What the UI does
The Tools tab shows every tool AuthSec knows about your server, with badges per tool (mapped, public, unmapped, admin-override). The big button is Scan now, which triggers POST /authsec/resource-servers/:id/rescan.
How the scan works
AuthSec opens an HTTP connection to your public_base_url + protected_base_path (e.g. https://your-mcp.example.com/mcp) and issues a synthetic JSON-RPC request:
{"jsonrpc":"2.0","id":1,"method":"tools/list"}
It parses the response, then for each tool extracts:
name(required, unique per resource server)descriptioninputSchema(stored as JSONB)annotations(MCP standard —readOnlyHint,destructiveHint, etc.)
Each tool is upserted into mcp_tools with inventory_source = 'mcp_scan' and the current scan_generation bumped by one. Tools that were in the previous generation but are not in the new one stay in the table — they're marked stale but not deleted, so audit history is preserved.
scan_generation
A monotonically increasing integer on resource_servers. Every successful scan bumps it. Per-tool records carry the scan_generation they were last seen in, which lets the UI distinguish "discovered in the most recent scan" from "carried over from an older scan".
The activation preview only counts tools whose scan_generation equals last_successful_generation — i.e. tools confirmed in the most recent successful scan. Tools left over from an old scan don't block activation but also aren't enforced; they're effectively in limbo until the next scan picks them up or you delete them.
Inventory sources
Three ways a tool can get into mcp_tools:
| Source | How | Notes |
|---|---|---|
mcp_scan | POST /rescan enumeration | The normal path. |
sdk_manifest | PUT /sdk-manifest from the Go SDK on startup | Use this when synthetic enumeration fails (e.g. your server requires auth on tools/list). Set PublishManifest: true in Config. |
manual | Admin-created via UI / API | Escape hatch for tools that exist conceptually but don't show up in tools/list. |
The SDK manifest source is preferred when available because the SDK knows the tool inventory authoritatively without needing a network round-trip.
Troubleshooting
Scan returns 401. Your MCP server requires authentication on tools/list. You have two options:
- Loosen
tools/listto unauthenticated. The SDK will protect it once installed (the SDK adds OAuth in front;tools/listitself never carried sensitive data in normal MCP usage). - Use the Go SDK's
ToolInventoryProviderescape hatch to publish the manifest from inside your process, skipping the network scan entirely. See Go SDK reference.
Scan times out. The discovery client has a hard timeout. If your tools/list enumeration is slow (lots of tools, lots of schema content), use the SDK manifest path instead. State will flip to scan_failed; the last_scan_error column tells you which timeout fired.
Scan returns a non-MCP response. Your /mcp route is serving HTML or a different JSON shape. AuthSec will fail with a parse error in last_scan_error. Check that the URL you registered actually serves JSON-RPC.
Tool count looks wrong. Tools that were in the previous scan but not the latest one stick around in mcp_tools (as stale). The activation preview filters them out. To get rid of them entirely, edit per-tool from the Tools tab.
Re-scanning after schema changes
When you change your tool surface (add a tool, remove one, change an inputSchema), re-scan. Existing scope mappings to unchanged tool names are preserved across scans — admin overrides survive. A removed tool stays in the inventory (marked stale); a renamed tool shows up as new.
What this populates
- The Tools tab listing (this page).
- The "TOOLS / 101" counter on the Launch tab's activation preview.
- The
tools/listresponse your SDK serves —mcp_toolsrows withscan_generation = last_successful_generationare what's visible to callers (filtered further by their granted scopes).
Related
- Map tools to scopes — the next step
- Launch the application — where the activation preview lives
- Go SDK reference — the SDK manifest path