Skip to main content
Glama

component-builder

Generate UI component code snippets from documentation for integration into Vue.js projects using shadcn-vue library.

Instructions

Retrieve documentation for all filtered components and charts to prepare for component generation, This tool ONLY returns the text snippet for that UI component. After calling this tool, you must edit or add files to integrate the snippet into the codebase.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
iconNoicon module of the componentlucide
componentsYescomponents from components-filter tool
chartsYescharts from components-filter tool

Implementation Reference

  • The execute handler for the 'component-builder' tool. It filters components and charts by necessity, fetches their documentation concurrently using Context7 API via ComponentServices, structures the docs into markdown, and returns a text prompt for generating the component code.
    execute: async (params) => {
      try {
        const necessityFilter = services.ComponentServices.createNecessityFilter("optional");
        // 并发处理所有组件文档
        const componentPromises = params.components
          .filter(necessityFilter)
          .map(async (component) => {
            const processedDoc = await services.ComponentServices.fetchLibraryDocumentation(
              "/unovue/shadcn-vue",
              {
                topic: component.name,
                tokens: 700,
              }
            );
            return {
              name: component.name,
              type: "component",
              doc: JSON.stringify(processedDoc),
            };
          });
    
        // 并发处理所有图表文档
        const chartPromises = params.charts.filter(necessityFilter).map(async (chart) => {
          const processedDoc = await services.ComponentServices.fetchLibraryDocumentation(
            "/unovue/shadcn-vue",
            {
              topic: chart.name,
              tokens: 700,
            }
          );
          return {
            name: chart.name,
            type: "chart",
            doc: JSON.stringify(processedDoc),
          };
        });
    
        // 等待所有文档处理完成
        const [componentResults, chartResults] = await Promise.all([
          Promise.all(componentPromises),
          Promise.all(chartPromises),
        ]);
    
        const filteredComponents = {
          components: componentResults,
          charts: chartResults,
        };
    
        // 转为结构化 markdown 内容
        const structuredMarkdown =
          services.ComponentServices.convertToStructuredMarkdown(filteredComponents);
        const prompt = `${getComponentPrompt(params.icon, structuredMarkdown)}`;
    
        return {
          content: [
            {
              type: "text",
              text: prompt,
            },
          ],
        };
      } catch (error) {
        console.error("Error executing component-builder tool:", error);
        throw error;
      }
    },
  • Input schema for the 'component-builder' tool defining icon preference, list of components, and list of charts from prior filtering step.
    parameters: z.object({
      icon: z
        .enum(["@nuxt/icon", "lucide"])
        .describe("icon module of the component")
        .optional()
        .default("lucide"),
      components: z
        .array(services.ComponentSchema)
        .describe("components from components-filter tool"),
      charts: z.array(services.ComponentSchema).describe("charts from components-filter tool"),
    }),
  • Registration of the 'component-builder' tool on the FastMCP server, including name, description, parameters schema, and execute handler reference.
    // component-builder tool 读取所有组件文档
    server.addTool({
      name: "component-builder",
      description:
        "Retrieve documentation for all filtered components and charts to prepare for component generation, This tool ONLY returns the text snippet for that UI component. After calling this tool, you must edit or add files to integrate the snippet into the codebase.",
      parameters: z.object({
        icon: z
          .enum(["@nuxt/icon", "lucide"])
          .describe("icon module of the component")
          .optional()
          .default("lucide"),
        components: z
          .array(services.ComponentSchema)
          .describe("components from components-filter tool"),
        charts: z.array(services.ComponentSchema).describe("charts from components-filter tool"),
      }),
      execute: async (params) => {
        try {
          const necessityFilter = services.ComponentServices.createNecessityFilter("optional");
          // 并发处理所有组件文档
          const componentPromises = params.components
            .filter(necessityFilter)
            .map(async (component) => {
              const processedDoc = await services.ComponentServices.fetchLibraryDocumentation(
                "/unovue/shadcn-vue",
                {
                  topic: component.name,
                  tokens: 700,
                }
              );
              return {
                name: component.name,
                type: "component",
                doc: JSON.stringify(processedDoc),
              };
            });
    
          // 并发处理所有图表文档
          const chartPromises = params.charts.filter(necessityFilter).map(async (chart) => {
            const processedDoc = await services.ComponentServices.fetchLibraryDocumentation(
              "/unovue/shadcn-vue",
              {
                topic: chart.name,
                tokens: 700,
              }
            );
            return {
              name: chart.name,
              type: "chart",
              doc: JSON.stringify(processedDoc),
            };
          });
    
          // 等待所有文档处理完成
          const [componentResults, chartResults] = await Promise.all([
            Promise.all(componentPromises),
            Promise.all(chartPromises),
          ]);
    
          const filteredComponents = {
            components: componentResults,
            charts: chartResults,
          };
    
          // 转为结构化 markdown 内容
          const structuredMarkdown =
            services.ComponentServices.convertToStructuredMarkdown(filteredComponents);
          const prompt = `${getComponentPrompt(params.icon, structuredMarkdown)}`;
    
          return {
            content: [
              {
                type: "text",
                text: prompt,
              },
            ],
          };
        } catch (error) {
          console.error("Error executing component-builder tool:", error);
          throw error;
        }
      },
    });
  • Base Zod schema for a single component or chart item, used in arrays for 'component-builder' input parameters. Defines name, necessity level, and justification.
    export const ComponentSchema = z.object({
      name: z.string(),
      necessity: z.enum(["critical", "important", "optional"]),
      justification: z.string(),
    });
  • Helper method called by the handler to convert fetched component/chart documentation into a structured Markdown format for the generation prompt.
    static convertToStructuredMarkdown(filteredComponents: {
      components: Array<{ name: string; type: string; doc: string }>;
      charts: Array<{ name: string; type: string; doc: string }>;
    }): string {
      let markdown = "# Shadcn-Vue Components Documentation\n\n";
    
      // 处理组件部分
      if (filteredComponents.components.length > 0) {
        markdown += "## 📦 Components\n\n";
    
        filteredComponents.components.forEach((component, index) => {
          markdown += `### ${index + 1}. ${
            component.name.charAt(0).toUpperCase() + component.name.slice(1)
          } Component\n\n`;
    
          try {
            // 尝试解析 JSON 文档
            const docData = JSON.parse(component.doc);
    
            if (typeof docData === "string") {
              // 如果是字符串,直接使用
              markdown += `${docData}\n\n`;
            } else if (docData && typeof docData === "object") {
              // 如果是对象,格式化显示
              if (docData.content) {
                markdown += `${docData.content}\n\n`;
              } else {
                markdown += `\`\`\`json\n${JSON.stringify(docData, null, 2)}\n\`\`\`\n\n`;
              }
            }
          } catch {
            // 如果解析失败,直接使用原始文档
            markdown += `${component.doc}\n\n`;
          }
    
          markdown += "---\n\n";
        });
      }
    
      // 处理图表部分
      if (filteredComponents.charts.length > 0) {
        markdown += "## 📊 Charts\n\n";
    
        filteredComponents.charts.forEach((chart, index) => {
          markdown += `### ${index + 1}. ${
            chart.name.charAt(0).toUpperCase() + chart.name.slice(1)
          } Chart\n\n`;
    
          try {
            // 尝试解析 JSON 文档
            const docData = JSON.parse(chart.doc);
    
            if (typeof docData === "string") {
              // 如果是字符串,直接使用
              markdown += `${docData}\n\n`;
            } else if (docData && typeof docData === "object") {
              // 如果是对象,格式化显示
              if (docData.content) {
                markdown += `${docData.content}\n\n`;
              } else {
                markdown += `\`\`\`json\n${JSON.stringify(docData, null, 2)}\n\`\`\`\n\n`;
              }
            }
          } catch {
            // 如果解析失败,直接使用原始文档
            markdown += `${chart.doc}\n\n`;
          }
    
          markdown += "---\n\n";
        });
      }
    
      // 添加总结信息
      markdown += "## 📋 Summary\n\n";
      markdown += `- **Total Components**: ${filteredComponents.components.length}\n`;
      markdown += `- **Total Charts**: ${filteredComponents.charts.length}\n`;
      markdown += `- **Total Items**: ${
        filteredComponents.components.length + filteredComponents.charts.length
      }\n\n`;
    
      return markdown;
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the tool retrieves documentation and returns text snippets, but it doesn't disclose critical behavioral traits such as whether this is a read-only operation, potential rate limits, authentication needs, error handling, or what happens if inputs are invalid. The description adds some context about the output being 'text snippets' and the need for subsequent integration, but significant gaps remain for a tool with no annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences and front-loaded with the main purpose, but it includes redundant phrasing ('Retrieve documentation for all filtered components and charts to prepare for component generation, This tool ONLY returns the text snippet for that UI component') that could be more concise. The second sentence adds workflow guidance, which is useful but not strictly necessary for the tool's core function. Overall, it's adequately structured but could be tighter.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (3 parameters, no annotations, no output schema), the description is incomplete. It lacks details on behavioral traits, error handling, and the format or content of the returned text snippets. While it mentions the tool's role in a workflow, it doesn't provide enough context for an AI agent to fully understand how to use it effectively, especially with no output schema to clarify return values.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters (icon, components, charts) with descriptions and enums. The description doesn't add any meaningful semantic details beyond what the schema provides, such as explaining the relationship between components and charts or how the icon parameter affects the output. Baseline 3 is appropriate when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Retrieve documentation for all filtered components and charts to prepare for component generation.' It specifies the verb ('retrieve'), resource ('documentation for components and charts'), and context ('prepare for component generation'). However, it doesn't explicitly differentiate from sibling tools like 'component-usage-doc' or 'components-filter', which likely have related purposes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by stating 'This tool ONLY returns the text snippet for that UI component' and 'After calling this tool, you must edit or add files to integrate the snippet into the codebase,' which suggests it's part of a workflow. However, it doesn't explicitly state when to use this tool versus alternatives like 'component-usage-doc' or 'components-filter,' nor does it provide clear prerequisites or exclusions. The guidance is implied but not comprehensive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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/HelloGGX/shadcn-vue-mcp'

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