Skip to main content
Glama
vendurehq

Vendure MCP Server

Official
by vendurehq

vendure_add

Extend Vendure projects by adding API extensions, entities, services, job queues, or custom plugins. Specify plugin, entity, or service details to integrate new features seamlessly into your e-commerce setup.

Instructions

Add features to your Vendure project.

IMPORTANT USAGE PATTERNS:

  • For API Extension: Requires apiExtension="plugin-name", plus queryName OR mutationName, plus selectedService

  • For Entity: Requires entity="EntityName" and selectedPlugin="plugin-name"

  • For Service: Requires service="ServiceName" and selectedPlugin="plugin-name"

  • For Job Queue: Requires jobQueue="plugin-name", name="queue-name", and selectedService="service-name"

EXAMPLES:

  • Add API extension: {apiExtension: "my-plugin", queryName: "customProducts", selectedService: "ProductService"}

  • Add entity: {entity: "CustomProduct", selectedPlugin: "my-plugin"}

  • Add service: {service: "CustomService", selectedPlugin: "my-plugin"}

  • Create new plugin: {plugin: "MyNewPlugin"}

Use list_plugins tool first to see available plugin names.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
apiExtensionNoAdd an API extension scaffold to the specified plugin. Provide the plugin name. Example: "my-plugin". Requires queryName or mutationName and selectedService.
codegenNoAdd GraphQL codegen configuration to the specified plugin. Provide the plugin name. Example: "my-plugin"
configNoSpecify the path to a custom Vendure config file. Example: "./custom-vendure-config.ts"
customFieldsNoAdd custom fields support to the entity (boolean flag)
entityNoAdd a new entity with the specified class name. Example: "Product" or "Customer". Requires selectedPlugin to be specified.
jobQueueNoAdd job-queue support to the specified plugin. Provide the plugin name. Example: "my-plugin"
mutationNameNoName for the GraphQL mutation (used with apiExtension). Example: "createCustomOrder" or "updateSpecialPrice"
nameNoName for the job queue (required with jobQueue). Example: "email-queue" or "product-import-queue"
pluginNoCreate a new plugin with the specified name. Example: "MyNewPlugin"
projectPathYesPath to the Vendure project directory (required)
queryNameNoName for the GraphQL query (used with apiExtension). Example: "customProducts" or "getSpecialOffers"
selectedEntityNoName of the entity for entity service (automatically sets type to entity). Example: "Product"
selectedPluginNoName of the plugin to add the entity/service/api-extension to. Must be an existing plugin name. Example: "my-plugin" or "test-plugin"
selectedServiceNoName of the service to add the job queue or API extension to. Must be an existing service. Example: "ProductService"
serviceNoAdd a new service with the specified class name. Example: "ProductService" or "OrderService". Requires selectedPlugin to be specified.
translatableNoMake the entity translatable (boolean flag)
typeNoType of service: "basic" or "entity" (default: basic). Use "entity" when working with database entities.
uiExtensionsNoAdd Admin UI extensions setup to the specified plugin. Provide the plugin name. Example: "my-plugin"

Implementation Reference

  • Registers vendure_add and other Vendure CLI commands as MCP tools by iterating over cliCommands and calling server.registerTool with name `vendure_${command.name}` (e.g. vendure_add for command 'add')
    export function registerCliCommandTools(server: McpServer): void {
        for (const command of cliCommands) {
            const commandSchema = commandSchemas[command.name];
    
            // Register main command
            server.registerTool(
                `vendure_${command.name}`,
                {
                    description: command.description,
                    ...(command.options &&
                        command.options.length > 0 && { inputSchema: commandSchema.mainCommand.shape }),
                },
                async (args: Record<string, any>) => {
                    const { projectPath } = getProjectContext();
                    const result = await executeMcpOperation(command.name, args, projectPath);
                    return {
                        content: [{ type: 'text' as const, text: result }],
                    };
                },
            );
    
            // Register sub-commands
            if (commandSchema.subCommands) {
                for (const subCommandName of Object.keys(commandSchema.subCommands)) {
                    const subCommandSchema = commandSchema.subCommands[subCommandName];
                    const subCommandOption = command.options?.find(
                        o => convertToParameterName(o.long) === subCommandName,
                    );
    
                    server.registerTool(
                        `vendure_${command.name}_${convertCamelToSnakeCase(subCommandName)}`,
                        {
                            description: `${subCommandOption?.description} (used in "vendure ${command.name}")`,
                            inputSchema: subCommandSchema.shape,
                        },
                        async (args: Record<string, any>) => {
                            const { projectPath } = getProjectContext();
                            // Handle both 'name' and 'value' as the main parameter (in case of naming conflicts)
                            const mainParamValue = args.name ?? args.value;
                            const transformedArgs = { [subCommandName]: mainParamValue, ...args };
                            const result = await executeMcpOperation(command.name, transformedArgs, projectPath);
                            return {
                                content: [{ type: 'text' as const, text: result }],
                            };
                        },
                    );
                }
            }
        }
    }
  • Dynamically generates Zod schemas for input validation of vendure_add (and all CLI tools) from the Vendure CLI command definitions
    export const commandSchemas: Record<string, any> = cliCommands.reduce(
        (acc, command) => {
            acc[command.name] = generateSchemaFromCommand(command);
            return acc;
        },
        {} as Record<string, any>,
    );
  • Core handler logic for vendure_add: formats arguments, spawns the Vendure CLI binary with 'add' command, captures output, and returns result (called from tool handler)
    export async function executeMcpOperation(
        commandName: string,
        options: Record<string, any>,
        projectPath: string,
    ): Promise<string> {
        try {
            const cliArgs = [commandName, ...formatOptionsForCli(options)];
            const result = await executeVendureCommand(cliArgs, projectPath);
            return `${commandName} operation completed successfully.\n\nOutput:\n${result}`;
        } catch (error) {
            throw new Error(
                `Failed to execute ${commandName}: ${error instanceof Error ? error.message : String(error)}`,
            );
        }
  • Helper to convert tool input parameters (camelCase) to kebab-case CLI flags for vendure add command
    function formatOptionsForCli(options: Record<string, any>): string[] {
        const args: string[] = [];
    
        for (const [key, value] of Object.entries(options)) {
            if (value === undefined || value === false) continue;
    
            const kebabKey = key.replace(/([A-Z])/g, '-$1').toLowerCase();
            const flag = `--${kebabKey}`;
    
            if (typeof value === 'boolean' && value === true) {
                args.push(flag);
            } else if (typeof value === 'string' || typeof value === 'number') {
                args.push(flag, String(value));
            }
        }
    
        return args;
    }
  • Low-level helper that spawns the vendure CLI process and captures stdout/stderr for the add command execution
    async function executeVendureCommand(args: string[], projectPath: string): Promise<string> {
        return new Promise((resolve, reject) => {
            const vendureBin = path.join(projectPath, 'node_modules', '.bin', 'vendure');
    
            if (!fs.existsSync(projectPath)) {
                reject(new Error(`Project directory does not exist: ${projectPath}`));
                return;
            }
    
            if (!fs.existsSync(vendureBin)) {
                reject(
                    new Error(
                        `Vendure CLI not found at: ${vendureBin}. Make sure @vendure/cli is installed in the project.`,
                    ),
                );
                return;
            }
    
            const child = spawn(vendureBin, args, {
                cwd: projectPath,
                stdio: ['pipe', 'pipe', 'pipe'],
                env: { ...process.env },
            });
    
            let stdout = '';
            let stderr = '';
    
            child.stdout?.on('data', data => {
                stdout += data.toString();
            });
    
            child.stderr?.on('data', data => {
                stderr += data.toString();
            });
    
            child.on('close', code => {
                if (code === 0) {
                    resolve(stdout);
                } else {
                    reject(new Error(stderr || stdout || `Command exited with code ${code}`));
                }
            });
    
            child.on('error', err => {
                reject(err);
            });
        });
    }

Tool Definition Quality

Score is being calculated. Check back soon.

Install Server

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/vendurehq/mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server