import { CanActivate, SetMetadata, Type } from '@nestjs/common'; import { z } from 'zod'; import { ToolAnnotations as SdkToolAnnotations } from '@modelcontextprotocol/sdk/types.js'; import { MCP_TOOL_METADATA_KEY } from './constants'; /** * Security scheme type for MCP tools */ export type SecurityScheme = | { type: 'noauth' } | { type: 'oauth2'; scopes?: string[] }; export interface ToolMetadata { name: string; description: string; parameters?: z.ZodType; outputSchema?: z.ZodType; annotations?: SdkToolAnnotations; _meta?: Record; // Security-related metadata securitySchemes?: SecurityScheme[]; isPublic?: boolean; requiredScopes?: string[]; requiredRoles?: string[]; guards?: Type[]; } // eslint-disable-next-line @typescript-eslint/no-empty-object-type export interface ToolAnnotations extends SdkToolAnnotations {} export interface ToolOptions { name?: string; description?: string; parameters?: z.ZodType; outputSchema?: z.ZodType; annotations?: ToolAnnotations; _meta?: Record; } /** * Decorator that marks a controller method as an MCP tool. * @param {Object} options - The options for the decorator * @param {string} options.name - The name of the tool * @param {string} options.description - The description of the tool * @param {z.ZodType} [options.parameters] - The parameters of the tool * @param {z.ZodType} [options.outputSchema] - The output schema of the tool * @returns {MethodDecorator} - The decorator */ export const Tool = (options: ToolOptions) => { if (options.parameters === undefined) { options.parameters = z.object({}); } return SetMetadata(MCP_TOOL_METADATA_KEY, options); };