Skip to main content
Glama

get_command_info

Retrieve detailed information about a specific Drush command, including its usage and parameters, by specifying the command name and optional version for accurate results.

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

  • Tool handler case for 'get_command_info': validates input, calls fetchCommandInfo, returns JSON response or error.
    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; }
  • Main implementation of fetching and parsing Drush command information from drush.org using web scraping with axios and cheerio.
    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 registration including name, description, and input schema definition.
    { 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 Drush command information (output schema).
    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; }
  • src/index.ts:59-82 (registration)
    Registration of the tool in the MCP server's listTools handler.
    this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ { 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"], }, }, ], }));

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

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