/** * defineTool() — High-Level Tool Definition (Vercel/Stripe Style) * * The recommended entry point for building MCP tools. Write a plain * JSON-like config object — zero Zod imports, zero builder patterns. * The framework converts everything to Zod schemas internally. * * @example * ```typescript * import { defineTool, success } from '@vinkius-core/mcp-fusion'; * * export const projects = defineTool('projects', { * description: 'Manage workspace projects', * shared: { workspace_id: 'string' }, * actions: { * list: { readOnly: true, handler: async (ctx, args) => success([]) }, * create: { params: { name: 'string' }, handler: async (ctx, args) => success(args.name) }, * }, * }); * ``` * * @see {@link createTool} for the power-user builder API * @see {@link ToolRegistry} for registering tools * * @module */ import { type ZodObject, type ZodRawShape } from 'zod'; import { GroupedToolBuilder } from './GroupedToolBuilder.js'; import { type ToolResponse, type MiddlewareFn } from '../types.js'; import { type MiddlewareDefinition } from '../middleware/ContextDerivation.js'; import { type Presenter } from '../../presenter/Presenter.js'; import { type ParamsMap, type InferParams } from './ParamDescriptors.js'; /** * Action definition within a `defineTool()` config. * * When `params` is provided as a `ParamsMap`, the handler's `args` are * automatically typed as `InferParams & TSharedArgs`. * When `params` is a ZodObject, use `z.infer` for manual typing. * * @typeParam TContext - Application context type * @typeParam TSharedArgs - Shared args inherited from ToolConfig.shared * @typeParam TParams - Action-specific params (inferred from the params field) */ export interface ActionDef, TParams extends ParamsMap = ParamsMap> { /** Human-readable description for the LLM */ description?: string; /** Parameter definitions (JSON descriptors or Zod schema) */ params?: TParams | ZodObject; /** Mark as read-only (no side effects) */ readOnly?: boolean; /** Mark as destructive (irreversible) */ destructive?: boolean; /** Mark as idempotent (safe to retry) */ idempotent?: boolean; /** Common schema fields to omit for this action */ omitCommon?: string[]; /** MVA Presenter — when set, handler returns raw data instead of ToolResponse */ returns?: Presenter; /** The handler function — args are fully typed when params is specified */ handler: (ctx: TContext, args: TParams extends ParamsMap ? (keyof TParams extends never ? TSharedArgs & Record : InferParams & TSharedArgs) : TSharedArgs & Record) => Promise; } /** * Group definition within a `defineTool()` config. * * @typeParam TContext - Application context type * @typeParam TSharedArgs - Inferred shared args type */ export interface GroupDef> { /** Human-readable group description */ description?: string; /** Common schema fields to omit for all actions in this group */ omitCommon?: string[]; /** Group-scoped middleware (accepts both MiddlewareFn and MiddlewareDefinition) */ middleware?: (MiddlewareFn | MiddlewareDefinition>)[]; /** Actions within this group — each action's params are inferred independently */ actions: { [K in string]: ActionDef; }; } /** * Full `defineTool()` configuration. * * @typeParam TContext - Application context type * @typeParam TShared - Shared params map type */ export interface ToolConfig { /** Tool description for the LLM */ description?: string; /** Capability tags for filtering */ tags?: string[]; /** Discriminator field name (default: 'action') */ discriminator?: string; /** Use TOON-formatted descriptions */ toonDescription?: boolean; /** Parameters shared across all actions */ shared?: TShared | ZodObject; /** Global middleware applied to all actions (accepts both MiddlewareFn and MiddlewareDefinition) */ middleware?: (MiddlewareFn | MiddlewareDefinition>)[]; /** MCP tool annotations (e.g. `{ readOnlyHint: true, openWorldHint: true }`) */ annotations?: Record; /** Flat actions — each action's params are inferred independently */ actions?: { [K in string]: ActionDef>; }; /** Hierarchical groups (mutually exclusive with `actions`) */ groups?: { [K in string]: GroupDef>; }; } /** Expected return type for handlers */ export type ExpectedHandlerReturnType = Promise | AsyncGenerator; /** * Utility type to force a readable, localized TypeScript error if a handler * does not return exactly `ToolResponse` or `AsyncGenerator<..., ToolResponse, ...>`. */ export type ValidateActionDef = TAction extends { handler: (...args: unknown[]) => infer R; } ? [R] extends [ExpectedHandlerReturnType] ? TAction : Omit & { handler: "❌ Type Error: handler must return ToolResponse. Use return success(data) or return error(msg)."; } : TAction; /** * Deep validation of the tool config to intercept handler return types * and provide readable errors without causing 50-line RecursiveBuilder issues. */ export type ValidateConfig = C extends ToolConfig ? { [K in keyof C]: K extends 'actions' ? { [A in keyof C['actions']]: ValidateActionDef; } : K extends 'groups' ? { [G in keyof C['groups']]: { [GK in keyof C['groups'][G]]: GK extends 'actions' ? { [A in keyof NonNullable[G]['actions']]: ValidateActionDef[G]['actions'][A]>; } : NonNullable[G][GK]; }; } : C[K]; } : C; /** * Define a tool using a high-level JSON-like config. * * This is the recommended entry point for most developers. * The framework handles all Zod schema creation, validation, * and MCP protocol details internally. * * @example * ```typescript * const echo = defineTool('echo', { * actions: { * say: { * params: { message: 'string' }, * handler: async (ctx, args) => success(args.message), * }, * }, * }); * * // Tool with shared params + groups + middleware * const platform = defineTool('platform', { * description: 'Platform management', * tags: ['admin'], * shared: { workspace_id: { type: 'string', description: 'Workspace ID' } }, * middleware: [requireAuth], * groups: { * users: { * description: 'User management', * actions: { * list: { readOnly: true, handler: listUsers }, * ban: { destructive: true, params: { user_id: 'string' }, handler: banUser }, * }, * }, * }, * }); * * // Register normally * const registry = new ToolRegistry(); * registry.register(platform); * ``` * * @see {@link createTool} for the power-user builder API * @see {@link ToolRegistry.register} for registration */ export declare function defineTool(name: string, config: ToolConfig): GroupedToolBuilder; //# sourceMappingURL=defineTool.d.ts.map