Skip to main content
Glama
Cleversoft-IT

Drupal-Modules-MCP MCP Server

get_command_info

Retrieve detailed information about Drush commands to understand their functionality, parameters, and usage within Drupal development workflows.

Instructions

Get detailed information about a specific Drush command

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
command_nameYesName of the Drush command
versionNoDrush version (e.g. '13.x'). Defaults to '13.x'

Implementation Reference

  • Core handler function that implements the logic for 'get_command_info' by fetching the command page from Drush documentation, parsing HTML with Cheerio, extracting structured information (description, arguments, options, examples, aliases), and returning a DrushCommand object.
    private async fetchCommandInfo(commandName: string): Promise<DrushCommand> {
        const url = `${this.baseUrl}/${commandName}/`;
        const response = await axios.get(url);
        const $ = cheerio.load(response.data);
    
        // Get the main content div
        const $content = $("article.md-content__inner");
    
        // Get description (first paragraph after h1)
        const description = $content.find("h1 + p").text().trim();
    
        // Helper function to extract section content
        const extractSection = (title: string): cheerio.Cheerio<Element> => {
            const $section = $content
                .find(`h4[id="${title.toLowerCase()}"]`)
                .next("ul");
            return $section.length ? $section : cheerio.load("")("ul");
        };
    
        // Helper function to process description
        const processDescription = (desc: string): string => {
            // Convert HTML to plain text
            desc = desc.replace(/<\/?[^>]+(>|$)/g, "");
            // Remove leading/trailing periods and spaces
            desc = desc.replace(/^\.?\s*/, "").replace(/\.\s*$/, "");
            // Add note about multiple values if description contains ellipsis
            if (desc.includes("...")) {
                desc += " (accepts multiple values)";
            }
            // Extract default value if present
            const defaultMatch = desc.match(/\(defaults?\s+to\s+([^)]+)\)/i);
            if (defaultMatch) {
                const defaultValue = defaultMatch[1].trim();
                // Move default value to end if it's not already there
                if (!desc.endsWith(defaultMatch[0])) {
                    desc =
                        desc.replace(defaultMatch[0], "") +
                        ` (defaults to ${defaultValue})`;
                }
            }
            // Add period at the end if missing
            if (!desc.endsWith(")") && !desc.endsWith(".")) {
                desc += ".";
            }
            return desc;
        };
    
        // Parse arguments section
        const args: DrushCommand["arguments"] = [];
        const $argsSection = extractSection("Arguments");
        if ($argsSection.length) {
            $argsSection.find("li").each((index: number, li: Element) => {
                // Get the raw HTML and extract argument name and description
                const html = $(li).html() || "";
                const strongMatch = html.match(
                    /<strong>\[?([^\]]+?)\]?<\/strong>\s*(.*)/
                );
                if (strongMatch) {
                    const name = strongMatch[1].replace(/\.$/, "");
                    const description = processDescription(strongMatch[2]);
                    args.push({
                        name,
                        description,
                        required: !html.includes("["),
                    });
                }
            });
        }
    
        // Parse options section
        const options: DrushCommand["options"] = [];
        const $optionsSection = extractSection("Options");
        if ($optionsSection.length) {
            $optionsSection.find("li").each((index: number, li: Element) => {
                const text = $(li).text().trim();
                // Match option name and description
                const match = text.match(
                    /^\*\*\s+--([a-zA-Z0-9-]+)(?:=[^*]+)?\*\*\.?\s*(.*)$/
                );
                if (match) {
                    options.push({
                        name: match[1],
                        description: processDescription(match[2]),
                    });
                }
            });
        }
    
        // Parse examples section
        const examples: string[] = [];
        const $examplesSection = extractSection("Examples");
        if ($examplesSection.length) {
            $examplesSection.find("li").each((index: number, li: Element) => {
                const text = $(li).text().trim();
                if (text) {
                    examples.push(text);
                }
            });
        }
    
        // Parse aliases section
        const aliases: string[] = [];
        const $aliasesSection = extractSection("Aliases");
        if ($aliasesSection.length) {
            $aliasesSection.find("li").each((index: number, li: Element) => {
                const text = $(li).text().trim();
                if (text) {
                    aliases.push(text);
                }
            });
        }
    
        return {
            name: commandName,
            description,
            arguments: args,
            options,
            examples,
            aliases,
            url,
        };
    }
  • Tool dispatch handler in CallToolRequestSchema that validates input parameters and invokes fetchCommandInfo, then formats the response as MCP content.
    case "get_command_info":
        const args = request.params.arguments as {
            command_name: string;
            version?: string;
        };
        if (!args.command_name) {
            throw new McpError(
                ErrorCode.InvalidParams,
                "Command name is required"
            );
        }
    
        try {
            const commandInfo = await this.fetchCommandInfo(
                args.command_name
            );
            return {
                content: [
                    {
                        type: "text",
                        text: JSON.stringify(
                            commandInfo,
                            null,
                            2
                        ),
                    },
                ],
            };
        } catch (error) {
            if (axios.isAxiosError(error)) {
                throw new McpError(
                    ErrorCode.InternalError,
                    `Failed to fetch command info: ${error.message}`
                );
            }
            throw error;
        }
  • Input schema definition for the get_command_info tool, specifying required command_name and optional version parameters.
    inputSchema: {
        type: "object",
        properties: {
            command_name: {
                type: "string",
                description: "Name of the Drush command",
            },
            version: {
                type: "string",
                description:
                    "Drush version (e.g. '13.x'). Defaults to '13.x'",
            },
        },
        required: ["command_name"],
    },
  • src/index.ts:61-82 (registration)
    Registration of the get_command_info tool in the ListToolsRequestSchema response, including name, description, and input schema.
            {
                name: "get_command_info",
                description:
                    "Get detailed information about a specific Drush command",
                inputSchema: {
                    type: "object",
                    properties: {
                        command_name: {
                            type: "string",
                            description: "Name of the Drush command",
                        },
                        version: {
                            type: "string",
                            description:
                                "Drush version (e.g. '13.x'). Defaults to '13.x'",
                        },
                    },
                    required: ["command_name"],
                },
            },
        ],
    }));
  • TypeScript interface defining the structure of the output returned by get_command_info.
    interface DrushCommand {
        name: string;
        description: string;
        usage?: string;
        arguments?: Array<{
            name: string;
            description: string;
            required: boolean;
        }>;
        options?: Array<{
            name: string;
            description: string;
        }>;
        examples?: string[];
        aliases?: string[];
        url: string;
    }
Install Server

Other 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/Cleversoft-IT/drupal-tools-mcp'

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