import { type ConcurrencyConfig, type RateLimitConfig, type TimeoutConfig } from '@frontmcp/guard'; import { z } from '@frontmcp/lazy-zod'; import { type EntryAvailability } from '@frontmcp/utils'; import { type ToolInputOf, type ToolOutputOf } from '../decorators'; import { type OutputPolicy } from './output-policy'; import { type ToolUIConfig } from './tool-ui.metadata'; /** * Auth provider mapping for tool metadata. * Used in @Tool({ authProviders: [...] }) decorator. */ export interface ToolAuthProviderMapping { /** Provider name */ name: string; /** Whether credential is required (default: true) */ required?: boolean; /** Required scopes for OAuth providers */ scopes?: string[]; /** Alias to use when injecting (for multiple providers) */ alias?: string; } /** * Auth provider reference - can be a string (provider name) or full mapping */ export type ToolAuthProviderRef = string | ToolAuthProviderMapping; /** * Auth provider ref with all defaults applied — the shape the call-tool * credential gate and PRM scope advertising consume. */ export interface NormalizedToolAuthProvider { /** Provider name (must match a registered credential provider). */ name: string; /** Whether the credential is required to run the tool (default: true). */ required: boolean; /** Required OAuth scopes (advertised via PRM `scopes_supported`). */ scopes?: string[]; /** Local alias used when injecting (defaults to `name`). */ alias: string; } /** * Normalize the raw `authProviders` metadata (a mix of string shorthand and * `{ name, required?, scopes?, alias? }` objects) into a uniform list with * defaults applied: * - string `'github'` → `{ name: 'github', required: true, alias: 'github' }` * - object → `required` defaults to `true`, `alias` defaults to `name`. * * Centralizes the "default required = true" contract so the call-tool gate and * PRM advertising agree on what each ref means. Unknown/invalid entries are * skipped defensively (metadata is validated at decoration time, but this is * also called against `unknown` metadata in the flow). */ export declare function normalizeToolAuthProviders(refs: unknown): NormalizedToolAuthProvider[]; declare global { /** * Declarative metadata extends to the an McpTool decorator. */ interface ExtendFrontMcpToolMetadata { } } /** * Example input/output pair for a tool, used in documentation and describe output. */ export interface ToolExample { /** * Description of what this example demonstrates. */ description: string; /** * Example input values for the tool. */ input: Record; /** * Optional expected output for the example. */ output?: unknown; } export interface ToolAnnotations { [x: string]: unknown; /** * A human-readable title for the tool. */ title?: string; /** * If true, the tool does not modify its environment. * * Default: false */ readOnlyHint?: boolean; /** * If true, the tool may perform destructive updates to its environment. * If false, the tool performs only additive updates. * * (This property is meaningful only when `readOnlyHint == false`) * * Default: true */ destructiveHint?: boolean; /** * If true, calling the tool repeatedly with the same arguments * will have no additional effect on the its environment. * * (This property is meaningful only when `readOnlyHint == false`) * * Default: false */ idempotentHint?: boolean; /** * If true, this tool may interact with an "open world" of external * entities. If false, the tool's domain of interaction is closed. * For example, the world of a web search tool is open, whereas that * of a memory tool is not. * * Default: true */ openWorldHint?: boolean; } /** * Tool response type text: include if outputSchema is zod primitive types */ type PrimitiveOutputType = 'string' | 'number' | 'date' | 'boolean' | z.ZodString | z.ZodNumber | z.ZodBoolean | z.ZodBigInt | z.ZodDate; /** * Tool response type image, will use the ImageContentSchema from MCP types */ type ImageOutputType = 'image'; export declare const ImageOutputSchema: import("@frontmcp/lazy-zod").ZodObject<{ type: import("@frontmcp/lazy-zod").ZodLiteral<"image">; data: import("@frontmcp/lazy-zod").ZodString; mimeType: import("@frontmcp/lazy-zod").ZodString; annotations: import("@frontmcp/lazy-zod").ZodOptional>>; priority: import("@frontmcp/lazy-zod").ZodOptional; lastModified: import("@frontmcp/lazy-zod").ZodOptional; }, import("zod/v4/core").$strip>>; _meta: import("@frontmcp/lazy-zod").ZodOptional>; }, import("zod/v4/core").$strip>; export type ImageOutput = z.output; /** * Tool response type audio, will use the AudioContentSchema from MCP types */ type AudioOutputType = 'audio'; export declare const AudioOutputSchema: import("@frontmcp/lazy-zod").ZodObject<{ type: import("@frontmcp/lazy-zod").ZodLiteral<"audio">; data: import("@frontmcp/lazy-zod").ZodString; mimeType: import("@frontmcp/lazy-zod").ZodString; annotations: import("@frontmcp/lazy-zod").ZodOptional>>; priority: import("@frontmcp/lazy-zod").ZodOptional; lastModified: import("@frontmcp/lazy-zod").ZodOptional; }, import("zod/v4/core").$strip>>; _meta: import("@frontmcp/lazy-zod").ZodOptional>; }, import("zod/v4/core").$strip>; export type AudioOutput = z.output; /** * Tool response type resource, will use the EmbeddedResourceSchema from MCP types */ type ResourceOutputType = 'resource'; export declare const ResourceOutputSchema: import("@frontmcp/lazy-zod").ZodObject<{ type: import("@frontmcp/lazy-zod").ZodLiteral<"resource">; resource: import("@frontmcp/lazy-zod").ZodUnion; _meta: import("@frontmcp/lazy-zod").ZodOptional>; text: import("@frontmcp/lazy-zod").ZodString; }, import("zod/v4/core").$strip>, import("@frontmcp/lazy-zod").ZodObject<{ uri: import("@frontmcp/lazy-zod").ZodString; mimeType: import("@frontmcp/lazy-zod").ZodOptional; _meta: import("@frontmcp/lazy-zod").ZodOptional>; blob: import("@frontmcp/lazy-zod").ZodString; }, import("zod/v4/core").$strip>]>; annotations: import("@frontmcp/lazy-zod").ZodOptional>>; priority: import("@frontmcp/lazy-zod").ZodOptional; lastModified: import("@frontmcp/lazy-zod").ZodOptional; }, import("zod/v4/core").$strip>>; _meta: import("@frontmcp/lazy-zod").ZodOptional>; }, import("zod/v4/core").$strip>; export type ResourceOutput = z.output; /** * Tool response type resource_link, will use the ResourceLinkSchema from MCP types */ type ResourceLinkOutputType = 'resource_link'; export declare const ResourceLinkOutputSchema: import("@frontmcp/lazy-zod").ZodObject<{ uri: import("@frontmcp/lazy-zod").ZodString; description: import("@frontmcp/lazy-zod").ZodOptional; mimeType: import("@frontmcp/lazy-zod").ZodOptional; size: import("@frontmcp/lazy-zod").ZodOptional; annotations: import("@frontmcp/lazy-zod").ZodOptional>>; priority: import("@frontmcp/lazy-zod").ZodOptional; lastModified: import("@frontmcp/lazy-zod").ZodOptional; }, import("zod/v4/core").$strip>>; _meta: import("@frontmcp/lazy-zod").ZodOptional>; icons: import("@frontmcp/lazy-zod").ZodOptional; sizes: import("@frontmcp/lazy-zod").ZodOptional>; theme: import("@frontmcp/lazy-zod").ZodOptional>; }, import("zod/v4/core").$strip>>>; name: import("@frontmcp/lazy-zod").ZodString; title: import("@frontmcp/lazy-zod").ZodOptional; type: import("@frontmcp/lazy-zod").ZodLiteral<"resource_link">; }, import("zod/v4/core").$strip>; export type ResourceLinkOutput = z.output; /** * Tool response type json, ZodRawShape for fast usage */ type StructuredOutputType = z.ZodRawShape | z.ZodObject | z.ZodArray | z.ZodUnion<[z.ZodObject, ...z.ZodObject[]]> | z.ZodDiscriminatedUnion<[z.ZodObject, ...z.ZodObject[]]>; export type ToolSingleOutputType = PrimitiveOutputType | ImageOutputType | AudioOutputType | ResourceOutputType | ResourceLinkOutputType | StructuredOutputType; /** * Default default tool schema is {} */ export type ToolOutputType = ToolSingleOutputType | ToolSingleOutputType[] | undefined; export type ToolInputType = z.ZodRawShape; /** * Tool visibility states. See `ToolMetadata.visibility` for full semantics. * * Symmetric with `SkillVisibility` in `skill.metadata.ts`. */ export type ToolVisibility = 'public' | 'hidden' | 'internal'; /** * Resolve a tool's effective visibility, honoring the deprecated * `hideFromDiscovery` alias. Used by the registry and call-tool flow. */ export declare function resolveToolVisibility(metadata: { visibility?: ToolVisibility; hideFromDiscovery?: boolean; }): ToolVisibility; /** * Declarative metadata describing what an McpTool contributes. */ export interface ToolMetadata extends ExtendFrontMcpToolMetadata { /** * Optional unique identifier for the tool. * If omitted, a consumer may derive an ID from the class or file name. */ id?: string; /** * Human‑readable name of the tool, used in UIs, logs, and discovery. */ name: string; /** * Short summary describing what the tool does and when to use it. */ description?: string; /** * Zod schema describing the expected input payload for the tool. * Used for validation and for generating automatic docs/UX. */ inputSchema: InSchema; /** * Zod schema describing the structure of the tool's successful output. */ outputSchema?: OutSchema; /** * Optional list of tags/labels that categorize the tool for discovery and filtering. */ tags?: string[]; /** * MCP tool annotations (behavioral hints) surfaced in `tools/list` — e.g. * `title`, `readOnlyHint`, `destructiveHint`, `idempotentHint`, * `openWorldHint`. Advisory only; clients use them for display and safety UX. */ annotations?: ToolAnnotations; /** * Visibility of this tool to external MCP clients vs internal SDK callers. * * - `'public'` (default): listed in `tools/list` and callable via `tools/call`. * - `'hidden'`: NOT listed in `tools/list`, but still callable via `tools/call` * when the client knows the name (parity with the legacy `hideFromDiscovery` * behavior — used e.g. by `send-elicitation-result.tool.ts`). * - `'internal'`: NOT listed AND NOT callable via external `tools/call` — * only invocable from within the SDK via `ExecutionContextBase.callTool(name, args)`. * Other tools, skill actions, agents (when allow-listed), CodeCall scripts, * and jobs can compose with it; an external MCP client request for this tool * is rejected with method-not-found. * * @default 'public' */ visibility?: ToolVisibility; /** * @deprecated Use `visibility: 'hidden'` instead. When `visibility` is unset, * `hideFromDiscovery: true` is treated as `visibility: 'hidden'` for * backwards compatibility. This alias will be removed in a future major. */ hideFromDiscovery?: boolean; /** * Optional usage examples for the tool. * These are used by codecall:describe to provide accurate usage examples. * If provided, these take precedence over auto-generated examples. */ examples?: ToolExample[]; /** * Interactive widget UI for this tool's result (MCP-UI / ext-apps). * * Prefer the file-based form — point at a `.tsx`/`.html` widget file and the * build bundles it; the widget's input/output types are inferred from this * tool's `inputSchema`/`outputSchema`. * * @example * ```typescript * @Tool({ name: 'chart', inputSchema: { points: z.array(z.number()) }, ui: { file: './chart.widget.tsx' } }) * ``` */ ui?: ToolUIConfig, ToolOutputOf>; /** * Auth providers required by this tool. * Credentials will be loaded before tool execution. * * @example Single provider (shorthand) * ```typescript * @Tool({ name: 'create-issue', authProviders: ['github'] }) * ``` * * @example Single provider with options * ```typescript * @Tool({ * name: 'deploy', * authProviders: [{ * name: 'github', * required: true, * scopes: ['repo', 'workflow'] * }] * }) * ``` * * @example Multiple providers * ```typescript * @Tool({ * name: 'sync-data', * authProviders: ['github', 'jira'] * }) * ``` * * @example Multiple providers with options * ```typescript * @Tool({ * name: 'multi-sync', * authProviders: [ * { name: 'github', required: true }, * { name: 'jira', required: false } * ] * }) * ``` */ authProviders?: ToolAuthProviderRef[]; /** * Rate limiting configuration for this tool. * Controls how many requests are allowed within a time window. * * @example * ```typescript * @Tool({ * name: 'search', * inputSchema: { query: z.string() }, * rateLimit: { maxRequests: 100, windowMs: 60_000, partitionBy: 'userId' }, * }) * ``` */ rateLimit?: RateLimitConfig; /** * Concurrency control configuration for this tool. * Limits the number of simultaneous executions. * * @example * ```typescript * @Tool({ * name: 'deploy', * inputSchema: { env: z.string() }, * concurrency: { maxConcurrent: 1 }, * }) * ``` */ concurrency?: ConcurrencyConfig; /** * Timeout configuration for this tool's execution. * Wraps the execute stage with a deadline. * * @example * ```typescript * @Tool({ * name: 'long-task', * inputSchema: { query: z.string() }, * timeout: { executeMs: 30_000 }, * }) * ``` */ timeout?: TimeoutConfig; /** * Environment availability constraint. * When set, the tool is only discoverable and executable in matching environments. * Fields are AND-ed (all must match), values within a field are OR-ed (any can match). * Omitted fields are unconstrained. * * @example macOS only * ```typescript * @Tool({ name: 'apple_notes', availableWhen: { platform: ['darwin'] } }) * ``` * * @example Node.js production only * ```typescript * @Tool({ name: 'deploy', availableWhen: { runtime: ['node'], env: ['production'] } }) * ``` */ availableWhen?: EntryAvailability; /** * Execution hints reported in `tools/list` items per MCP 2025-11-25. * * `taskSupport` controls whether clients may invoke this tool as a background task * (see https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/tasks): * - `'required'`: clients MUST invoke the tool as a task (the server will reject * non-task-augmented calls with `-32601`). * - `'optional'`: clients MAY invoke the tool as a task or as a normal request. * - `'forbidden'` or absent (default): clients MUST NOT task-augment the call. * * @example * ```typescript * @Tool({ name: 'long_report', execution: { taskSupport: 'optional' } }) * ``` */ execution?: { taskSupport?: 'required' | 'optional' | 'forbidden'; }; /** * Output policy for this tool — overrides `@App` and `@FrontMcp`. Controls * non-finite handling (`allowNonFinite`) and how `outputSchema` is exposed in * `tools/list` (`schemaMode`: `'definition'` (default) / `'description'` / `'both'` / * `'none'`; `schemaDescriptionFormat`: `'summary'` (default) / `'jsonSchema'`). */ output?: OutputPolicy; } export declare const frontMcpToolMetadataSchema: import("@frontmcp/lazy-zod").ZodObject<{ id: import("@frontmcp/lazy-zod").ZodOptional; name: import("@frontmcp/lazy-zod").ZodString; description: import("@frontmcp/lazy-zod").ZodOptional; inputSchema: import("zod").ZodCustom; outputSchema: import("@frontmcp/lazy-zod").ZodOptional, import("@frontmcp/lazy-zod").ZodEnum<{ image: "image"; audio: "audio"; resource: "resource"; resource_link: "resource_link"; }>]>, import("zod").ZodCustom>, import("@frontmcp/lazy-zod").ZodType>>, import("@frontmcp/lazy-zod").ZodRecord>, import("@frontmcp/lazy-zod").ZodType>>>]>, import("@frontmcp/lazy-zod").ZodArray, import("@frontmcp/lazy-zod").ZodEnum<{ image: "image"; audio: "audio"; resource: "resource"; resource_link: "resource_link"; }>]>, import("zod").ZodCustom>, import("@frontmcp/lazy-zod").ZodType>>, import("@frontmcp/lazy-zod").ZodRecord>, import("@frontmcp/lazy-zod").ZodType>>>]>>]>>; tags: import("@frontmcp/lazy-zod").ZodOptional>; annotations: import("@frontmcp/lazy-zod").ZodOptional; readOnlyHint: import("@frontmcp/lazy-zod").ZodOptional; destructiveHint: import("@frontmcp/lazy-zod").ZodOptional; idempotentHint: import("@frontmcp/lazy-zod").ZodOptional; openWorldHint: import("@frontmcp/lazy-zod").ZodOptional; }, import("zod/v4/core").$loose>>; visibility: import("@frontmcp/lazy-zod").ZodOptional>; hideFromDiscovery: import("@frontmcp/lazy-zod").ZodDefault>; examples: import("@frontmcp/lazy-zod").ZodOptional; output: import("@frontmcp/lazy-zod").ZodOptional; }, import("zod/v4/core").$strip>>>; ui: import("@frontmcp/lazy-zod").ZodOptional>; authProviders: import("@frontmcp/lazy-zod").ZodOptional>; scopes: import("@frontmcp/lazy-zod").ZodOptional>; alias: import("@frontmcp/lazy-zod").ZodOptional; }, import("zod/v4/core").$strict>]>>>; rateLimit: import("@frontmcp/lazy-zod").ZodOptional>; partitionBy: import("@frontmcp/lazy-zod").ZodDefault, import("zod").ZodCustom<(ctx: { sessionId: string; clientIp?: string; userId?: string; }) => string, (ctx: { sessionId: string; clientIp?: string; userId?: string; }) => string>]>>>; }, import("zod/v4/core").$strip>>; concurrency: import("@frontmcp/lazy-zod").ZodOptional>; partitionBy: import("@frontmcp/lazy-zod").ZodDefault, import("zod").ZodCustom<(ctx: { sessionId: string; clientIp?: string; userId?: string; }) => string, (ctx: { sessionId: string; clientIp?: string; userId?: string; }) => string>]>>>; }, import("zod/v4/core").$strip>>; timeout: import("@frontmcp/lazy-zod").ZodOptional>; availableWhen: import("@frontmcp/lazy-zod").ZodOptional>; platform: import("@frontmcp/lazy-zod").ZodOptional>; runtime: import("@frontmcp/lazy-zod").ZodOptional>; deployment: import("@frontmcp/lazy-zod").ZodOptional>; provider: import("@frontmcp/lazy-zod").ZodOptional>; target: import("@frontmcp/lazy-zod").ZodOptional>; surface: import("@frontmcp/lazy-zod").ZodOptional>>; env: import("@frontmcp/lazy-zod").ZodOptional>; }, import("zod/v4/core").$strict>>; execution: import("@frontmcp/lazy-zod").ZodOptional>; }, import("zod/v4/core").$strip>>; output: import("@frontmcp/lazy-zod").ZodOptional; schemaMode: import("@frontmcp/lazy-zod").ZodOptional>; schemaDescriptionFormat: import("@frontmcp/lazy-zod").ZodOptional>; }, import("zod/v4/core").$strip>>; }, import("zod/v4/core").$loose>; export {}; //# sourceMappingURL=tool.metadata.d.ts.map