import type { ToolAnnotations } from "@modelcontextprotocol/sdk/types.js"; import type { ConnectionConfig } from "../../config/models.js"; import type { BaseClientManager } from "../../confluent/base-client-manager.js"; import { CallToolResult } from "../../confluent/schema.js"; import { ConnectionPredicate, PredicateResult } from "../../confluent/tools/connection-predicates.js"; import { ToolName } from "../../confluent/tools/tool-name.js"; import { ServerRuntime } from "../../server-runtime.js"; import { ZodRawShape } from "zod"; /** * Standard MCP tool annotations. * Tools should reference these constants rather than creating ad-hoc instances. */ export declare const READ_ONLY: ToolAnnotations; export declare const CREATE_UPDATE: ToolAnnotations; export declare const DESTRUCTIVE: ToolAnnotations; export interface ToolHandler { handle(runtime: ServerRuntime, toolArguments: Record | undefined, sessionId?: string): Promise | CallToolResult; getToolConfig(): ToolConfig; /** * The connection predicate that gates this tool's enablement. Lifted onto * the interface so the MCP tool-call wrapper can compare it against * `alwaysEnabled` to skip the OAuth login gate for tools that don't touch * the client manager (currently the doc-lookup tools). See * {@linkcode BaseToolHandler.predicate} for the rules around setting it. */ readonly predicate: ConnectionPredicate; /** * IDs of connections that satisfy this tool's service requirements. A * non-empty result enables the tool; an empty result disables it. Always a * subset of `runtime.config.connections` keys. * * Implementations that extend {@linkcode BaseToolHandler} (the standard * path for every tool in this codebase) must not override this — declare * a {@linkcode BaseToolHandler.predicate} property and let the base class * derive the result. */ enabledConnectionIds(runtime: ServerRuntime): string[]; /** * Per-connection verdict map for this tool: `{ enabled: true }` for * connections that satisfy its requirements, `{ enabled: false; reason }` * for those that don't. Powers startup-log grouping and the * `describe-tool-availability` diagnostic tool. */ connectionVerdicts(runtime: ServerRuntime): Map; } export interface ToolConfig { name: ToolName; description: string; inputSchema: ZodRawShape; annotations: ToolAnnotations; } export declare abstract class BaseToolHandler implements ToolHandler { abstract handle(runtime: ServerRuntime, toolArguments: Record | undefined, sessionId?: string): Promise | CallToolResult; abstract getToolConfig(): ToolConfig; /** * The connection predicate that gates this tool. The single customization * seam for tool enablement — declared as a one-line readonly property: * * readonly predicate = hasKafka; // base predicate * readonly predicate = kafkaBootstrapOrOAuth; // named composite * readonly predicate = alwaysEnabled; // no requirement * * **Must reference a named export from `connection-predicates.ts`.** Do * not compose with `allOf(...)` or `widenForOAuth(...)` at the use site. * If no existing named export expresses the gate you need, add one — * with a per-predicate test in `connection-predicates.test.ts` matching * the depth of the existing `hasKafka` / `flinkWithTelemetry` blocks — * and reference that. Enforced mechanically: the `predicate property` * block in `tool-registry.test.ts` maintains an explicit * `Readonly>` (`EXPECTED_PREDICATES`) * pinning every tool to its expected predicate. The `Record` over * `ToolName` makes exhaustiveness a compile-time check (a missing tool * is a `tsc` error, not a runtime one), and the value type rejects * combinators at compile time. The `it.each` over the record fails with * the offending tool name in the row label whenever a handler's * `predicate` drifts from the table. New tools or rewires are a one-line * table edit. * * Both {@linkcode enabledConnectionIds} and {@linkcode connectionVerdicts} * are derived from this property and are marked `@final`; never override * either method. The retired iteration helpers `connectionIdsWhere` and * `connectionReasonsWhere` are no longer exported — the base class walks * `runtime.config.connections` for you. */ abstract readonly predicate: ConnectionPredicate; /** * IDs of connections that satisfy this tool's {@linkcode predicate}. A * non-empty result enables the tool; an empty result disables it. * * Customize tool gating by declaring {@linkcode predicate}, never by * replacing this derivation. * * @final — concrete on `BaseToolHandler`; subclasses must not override. */ enabledConnectionIds(runtime: ServerRuntime): string[]; /** * Per-connection verdict map for this tool, derived from * {@linkcode predicate}. Powers grouped startup logging and * the diagnostic-tool surface. * * Customize tool gating by declaring {@linkcode predicate}, never by * replacing this derivation. * * @final — concrete on `BaseToolHandler`; subclasses must not override. */ connectionVerdicts(runtime: ServerRuntime): Map; /** * Resolves the single connection enabled for this tool, returning the * connection id, its config, and the matching client manager. Designed * for handlers that look up `runtime.clientManagers[connId]` (multi- * connection-ready shape). * * Selects `enabledConnectionIds(runtime)[0]` — current runtime is single- * connection, so this is unambiguous; if multi-connection support lands * later, handlers can switch to iterating ids. */ protected resolveSoleConnection(runtime: ServerRuntime): { connId: string; conn: ConnectionConfig; clientManager: BaseClientManager; }; /** * Resolves a required string from an explicit tool argument, falling back to * a connection-config value. Throws if neither is present. * `label` is the human-readable field name (e.g. `"Organization ID"`); * the thrown message is `"${label} is required"`. * The returned value is always trimmed. */ protected resolveParam(argValue: string | undefined, configValue: string | undefined, label: string): string; /** Like resolveParam but returns undefined instead of throwing when both are absent or blank. The returned value is always trimmed. */ protected resolveOptionalParam(argValue: string | undefined, configValue: string | undefined): string | undefined; createResponse(message: string, isError?: boolean, _meta?: Record): CallToolResult; } //# sourceMappingURL=base-tools.d.ts.map