import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import type { DomainName } from "./constants.js"; import type { RegistrationIndex } from "./tools/registration-decorators.js"; /** * Protocol-level icons (SEP-973, spec 2025-11-25) for tools, prompts and * resources. * * ## Scope: one icon per *domain*, not per tool * * 180 hand-picked icons would be unmaintainable and would triple the byte cost * below. Every tool of a domain shares that domain's glyph, which is also what * a client UI wants: the icon groups the catalogue, the name distinguishes * inside the group. * * ## Byte cost * * `icons` rides on every entry of `tools/list`, so it competes with the tool * catalogue itself. Two consequences baked into the format below: * * - inline `data:` SVG only (no network fetch from the client, no asset to * host, no CSP question); * - a deliberately spartan glyph vocabulary — 16×16 viewBox, single ``, * no `mimeType`/`sizes` fields (the data URI already carries the type, and an * SVG is scalable by definition). `descriptions.test.ts` caps both the * per-icon size and the total added to `tools/list`. * * ## Why a response decorator and not a `registerTool` option * * `@modelcontextprotocol/sdk@1.30` types `icons` on `Tool`/`Prompt`/`Resource` * but its `McpServer` never emits them: the `tools/list` and `prompts/list` * handlers build their entries field by field and drop anything else * (`server/mcp.js`). Resources are the exception — their listing spreads the * whole registration config, so `registerResource` can carry `icons` natively * (see `resources/index.ts`). * * So for tools and prompts we decorate the *responses*: `installProtocolIcons` * wraps the handlers the SDK installs, using only the public * `Server.setRequestHandler` API plus schema identity. When the SDK gains * first-class support, this whole shim can be deleted in favour of passing * `icons` in the registration config — `src/icons.test.ts` fails loudly if the * shim ever stops producing icons. */ export interface Icon { src: string; mimeType?: string; sizes?: string[]; } /** * Domain → icons. Every entry of `REGISTERED_DOMAINS` must be present * (asserted in `icons.test.ts`), so adding a domain without an icon fails CI * rather than shipping a half-iconified catalogue. */ export declare const DOMAIN_ICONS: Readonly>; /** * Icons for the dictionary / reference resources (`boond://…`). Resolved * through a function, not a constant, because `registerAllResources` runs at * startup and must honour `BOOND_MCP_ICONS` too. */ export declare function referenceIcons(): Icon[] | undefined; /** Icons for the `current-user` resource. */ export declare function identityIcons(): Icon[] | undefined; export declare function iconsForDomain(domain: DomainName | undefined): Icon[] | undefined; /** * Prompt → icons, from the first domain the prompt orchestrates (its subject: * `factures_a_relancer` → invoices, `synthese_equipe` → resources). */ export declare function iconsForPrompt(name: string): Icon[] | undefined; /** Total byte cost of an icon payload, for the cap test and the docs. */ export declare function iconsByteSize(icons: readonly Icon[] | undefined): number; /** * Attach domain icons to `tools/list` and `prompts/list` responses. * * MUST be called before the first `registerTool` / `registerPrompt` on this * server: it works by intercepting the `setRequestHandler` calls the SDK makes * when it lazily installs those handlers. `index` is read at request time, so * it can still be empty at install time. */ export declare function installProtocolIcons(server: McpServer, index: RegistrationIndex): void; //# sourceMappingURL=icons.d.ts.map