feat: make the skills verification catalog budget configurable per server (#2294)

Adds a Skills section to Server Settings with Maximum Number of Skills and
Maximum Catalog Size fields, defaulting to SKILL_MAX_CATALOG_SKILLS (256) and
SKILL_MAX_CATALOG_BYTES (64 MiB). The values persist as skillCatalogMaxSkills /
skillCatalogMaxBytes on the server's mcp.json entry (omitted at the default),
are validated as positive integers by the /api/servers routes, and are read by
verifySkills through getServerSettings(), so the CLI's --verify and the TUI
Skills pane both honor them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P6i1HBSdSS9kL4npZ2dDSe
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-09-13 23:54:29 -04:00
commit eb41185c37

View file

@ -679,6 +679,27 @@ describe("ServerSettingsModal", () => {
expect(typeof call.maxFetchRequests).toBe("number");
});
it("calls onSettingsChange when changing a skills catalog limit (#2294)", async () => {
const user = userEvent.setup();
const onSettingsChange = vi.fn();
renderWithMantine(
<ServerSettingsModal
opened
settings={{ ...emptySettings, skillCatalogMaxSkills: 3 }}
serverType="streamable-http"
isStdio={false}
onClose={vi.fn()}
onSettingsChange={onSettingsChange}
/>,
);
await user.click(screen.getByRole("button", { name: "Skills" }));
await user.type(screen.getByLabelText(/Maximum Number of Skills/), "0");
expect(onSettingsChange).toHaveBeenLastCalledWith({
...emptySettings,
skillCatalogMaxSkills: 30,
});
});
it("preserves sibling rows when editing one of several headers", async () => {
const user = userEvent.setup();
const onSettingsChange = vi.fn();