diff --git a/packages/fiori-mcp-server/src/tools/functionalities/generate-fiori-ui-app/command.ts b/packages/fiori-mcp-server/src/tools/functionalities/generate-fiori-ui-app/command.ts index b0073f1b2b2..f136c29b78b 100644 --- a/packages/fiori-mcp-server/src/tools/functionalities/generate-fiori-ui-app/command.ts +++ b/packages/fiori-mcp-server/src/tools/functionalities/generate-fiori-ui-app/command.ts @@ -33,7 +33,7 @@ const exec = promisify(execAsync); * @returns Application generation execution output. */ export async function command(params: ExecuteFunctionalityInput): Promise { - const generatorConfigCAP: GeneratorConfigCAP = validateWithSchema(GeneratorConfigSchemaCAP, params?.parameters); + const generatorConfigCAP: GeneratorConfigCAP = validateWithSchema(GeneratorConfigSchemaCAP(), params?.parameters); const generatorConfig: GeneratorConfigCAPWithAPI = { ...PREDEFINED_GENERATOR_VALUES, ...generatorConfigCAP, diff --git a/packages/fiori-mcp-server/src/tools/functionalities/generate-fiori-ui-app/generate-fiori-ui-app.ts b/packages/fiori-mcp-server/src/tools/functionalities/generate-fiori-ui-app/generate-fiori-ui-app.ts index e11a188f11e..20f06b3544e 100644 --- a/packages/fiori-mcp-server/src/tools/functionalities/generate-fiori-ui-app/generate-fiori-ui-app.ts +++ b/packages/fiori-mcp-server/src/tools/functionalities/generate-fiori-ui-app/generate-fiori-ui-app.ts @@ -5,6 +5,7 @@ import type { ExecuteFunctionalityInput, ExecuteFunctionalityOutput, FunctionalityHandlers, + GetFunctionalityDetailsInput, GetFunctionalityDetailsOutput } from '../../../types'; import { convertToSchema } from '../../utils'; @@ -18,16 +19,21 @@ export const GENERATE_FIORI_UI_APP: GetFunctionalityDetailsOutput = { The data obtained from either method must then be formatted into a JSON object and passed as the parameters. The configuration **MUST** be a valid JSON object corresponding to the inputSchema of the tool. The configuration **MUST** be based on the project files in the projectPath.`, - parameters: convertToSchema(GeneratorConfigSchemaCAP) + parameters: convertToSchema(GeneratorConfigSchemaCAP()) }; /** * Retrieves the details of the Generate SAP Fiori UI Application functionality. * + * @param input * @returns A promise that resolves to the functionality details output. */ -async function getFunctionalityDetails(): Promise { - return GENERATE_FIORI_UI_APP; +async function getFunctionalityDetails(input: GetFunctionalityDetailsInput): Promise { + const details = GENERATE_FIORI_UI_APP; + return { + ...details, + parameters: convertToSchema(GeneratorConfigSchemaCAP(input.appPath)) + }; } /** diff --git a/packages/fiori-mcp-server/src/tools/functionalities/generate-fiori-ui-app/schema.ts b/packages/fiori-mcp-server/src/tools/functionalities/generate-fiori-ui-app/schema.ts index 1fe45d0fccf..92753d1f532 100644 --- a/packages/fiori-mcp-server/src/tools/functionalities/generate-fiori-ui-app/schema.ts +++ b/packages/fiori-mcp-server/src/tools/functionalities/generate-fiori-ui-app/schema.ts @@ -1,70 +1,74 @@ import { LATEST_UI5_VERSION } from '../../../constant'; import * as z from 'zod'; -export const GeneratorConfigSchemaCAP = z.object({ - floorplan: z - .literal(['FE_LROP', 'FE_FEOP', 'FE_FPM', 'FE_OVP', 'FE_ALP', 'FE_WORKLIST', 'FF_SIMPLE']) - .describe('SAP Fiori Elements floor plan type.'), - project: z.object({ - name: z - .string() - .describe("Must be lowercase with dashes, e.g., 'sales-order-management'.") - .regex(/^[a-z0-9-]+$/), - targetFolder: z.string().describe('Absolute path to the CAP project folder (projectPath).'), - namespace: z.optional(z.string()), - title: z.optional(z.string()), - description: z.string(), - ui5Theme: z.optional(z.string()), - ui5Version: z.string().default(LATEST_UI5_VERSION), - localUI5Version: z.optional(z.string()).default(LATEST_UI5_VERSION) - }), - service: z.object({ - servicePath: z - .string() - .describe( - 'The odata endpoint as provided by the cds mcp or as fallback in case that tool is not available from the service cds file.' - ) - .meta({ - examples: [ - '/odata/v4//', - '/odata/v4/MyRiskService/', - '/odata/v2/MyOdataV2Service/', - '/odata/v4/MyOdataV4Service/', - "/odata/v4//", - "/", - '/myAbsolutePathFromServiceCdsFile/' - ] - }), - capService: z.object({ - projectPath: z.string(), - serviceName: z.string(), - serviceCdsPath: z +export const GeneratorConfigSchemaCAP = (projectPath?: string) => { + return z.object({ + floorplan: z + .literal(['FE_LROP', 'FE_FEOP', 'FE_FPM', 'FE_OVP', 'FE_ALP', 'FE_WORKLIST', 'FF_SIMPLE']) + .describe('SAP Fiori Elements floor plan type.'), + project: z.object({ + name: z + .string() + .describe("Must be lowercase with dashes, e.g., 'sales-order-management'.") + .regex(/^[a-z0-9-]+$/), + targetFolder: z .string() - .describe('The path to the service cds file') + .describe(`Absolute path to the CAP project folder (${projectPath ?? 'project path'}).`), + namespace: z.optional(z.string()), + title: z.optional(z.string()), + description: z.string(), + ui5Theme: z.optional(z.string()), + ui5Version: z.string().default(LATEST_UI5_VERSION), + localUI5Version: z.optional(z.string()).default(LATEST_UI5_VERSION) + }), + service: z.object({ + servicePath: z + .string() + .describe( + 'The odata endpoint as provided by the cds mcp or as fallback in case that tool is not available from the service cds file.' + ) .meta({ examples: [ - 'srv/service.cds', - 'srv/my-service.cds', - 'path/to/srv/service.cds', - 'path/to/srv/my-service.cds' + '/odata/v4//', + '/odata/v4/MyRiskService/', + '/odata/v2/MyOdataV2Service/', + '/odata/v4/MyOdataV4Service/', + "/odata/v4//", + "/", + '/myAbsolutePathFromServiceCdsFile/' ] }), - capType: z.optional(z.literal(['Node.js', 'Java'])) - }) - }), - entityConfig: z.object({ - mainEntity: z.object({ - entityName: z - .string() - .describe('The name of the main entity') - .meta({ - examples: ["'SalesOrder'", "'PurchaseOrderHeader'", "'MyEntity'"] - }) + capService: z.object({ + projectPath: z.string(), + serviceName: z.string(), + serviceCdsPath: z + .string() + .describe('The path to the service cds file') + .meta({ + examples: [ + 'srv/service.cds', + 'srv/my-service.cds', + 'path/to/srv/service.cds', + 'path/to/srv/my-service.cds' + ] + }), + capType: z.optional(z.literal(['Node.js', 'Java'])) + }) }), - generateFormAnnotations: z.boolean(), - generateLROPAnnotations: z.boolean() - }) -}); + entityConfig: z.object({ + mainEntity: z.object({ + entityName: z + .string() + .describe('The name of the main entity') + .meta({ + examples: ["'SalesOrder'", "'PurchaseOrderHeader'", "'MyEntity'"] + }) + }), + generateFormAnnotations: z.boolean(), + generateLROPAnnotations: z.boolean() + }) + }); +}; // Input type for generator config -export type GeneratorConfigCAP = z.infer; +export type GeneratorConfigCAP = z.infer>;