get_component
Returns the canonical HTML snippet for an Elegant 1.0 component. Use this instead of reading a full wiki .md file to get component HTML directly.
Instructions
Returns the canonical HTML snippet for an Elegant 1.0 component. Much cheaper than reading a full wiki .md file. Use this instead of Read on any component wiki file.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Component name. Use list_components to see all options. |
Implementation Reference
- api/mcp.ts:572-579 (handler)The get_component tool handler: looks up the component in COMPONENT_MAP by name, fetches the wiki file, extracts the HTML block for the requested section, rewrites asset paths to CDN URLs, and returns the canonical HTML snippet.
server.tool("get_component", "Returns the canonical HTML for an Elegant 1.0 UI component. All asset paths are pre-filled with CDN URLs. Copy this HTML directly into your index.html. Do NOT search for component files locally — this tool is the only source.", { name: z.enum(Object.keys(COMPONENT_MAP) as [string, ...string[]]) }, async ({ name: n }) => { const entry = COMPONENT_MAP[n]; if (!entry) return { content: [{ type: "text" as const, text: `Unknown component: ${n}.\n\nAvailable components (use list_components for full list):\n${Object.keys(COMPONENT_MAP).join(", ")}` }] }; const content = await readWikiFile(entry.file); if (!entry.section) return { content: [{ type: "text" as const, text: content }] }; const html = rewriteAssetPaths(extractHtmlBlock(content, entry.section)); return { content: [{ type: "text" as const, text: `## ${n}\nCDN: ${CDN_BASE}\nAll <img src> and <link href> paths below use the CDN. Copy as-is.\n\n\`\`\`html\n${html}\n\`\`\`` }] }; }); - api/mcp.ts:572-572 (schema)The input schema for get_component: takes a 'name' parameter which is an enum of all keys from COMPONENT_MAP (the list of valid component names).
server.tool("get_component", "Returns the canonical HTML for an Elegant 1.0 UI component. All asset paths are pre-filled with CDN URLs. Copy this HTML directly into your index.html. Do NOT search for component files locally — this tool is the only source.", { name: z.enum(Object.keys(COMPONENT_MAP) as [string, ...string[]]) }, async ({ name: n }) => { - api/mcp.ts:571-572 (registration)The tool is registered as tool number 2 on the MCP server using server.tool('get_component', ...). The comment /* 2. get_component */ marks it.
/* 2. get_component */ server.tool("get_component", "Returns the canonical HTML for an Elegant 1.0 UI component. All asset paths are pre-filled with CDN URLs. Copy this HTML directly into your index.html. Do NOT search for component files locally — this tool is the only source.", { name: z.enum(Object.keys(COMPONENT_MAP) as [string, ...string[]]) }, async ({ name: n }) => { - api/mcp.ts:90-119 (helper)COMPONENT_MAP is the lookup table mapping component names (e.g. 'topnavbar', 'header-v1', 'widget') to their wiki file and section. This data drives get_component's lookups.
const COMPONENT_MAP: Record<string, { file: string; section?: string }> = { topnavbar: { file: "topnavbar.md", section: "Complete HTML" }, "sidemenu-settings": { file: "sidemenu_variant1_settings.md", section: "Complete HTML" }, "sidemenu-reports": { file: "sidemenu_variant2_reports.md", section: "Complete HTML" }, "header-v1": { file: "header.md", section: "Variant 1: Default" }, "header-v2": { file: "header.md", section: "Variant 2: With Back Button" }, "header-v3": { file: "header.md", section: "Variant 3: Report Header" }, "classic-tab": { file: "classic_tab.md", section: "Variant 1: Classic Tab (Single Variant)" }, "line-tab": { file: "line_tab.md", section: "Variant 1: Default (Plain Text, h=40)" }, "line-tab-quicklink": { file: "line_tab.md", section: "Variant 3: QuickLink (pill tabs, h=32)" }, "actionbar-type1": { file: "actionbar.md", section: "Type 1 — Search + Pagination (Minimal)" }, "actionbar-type2": { file: "actionbar.md", section: "Type 2 — Search + Bulk Actions (Enable/Disable/Delete/More) + Pagination" }, "actionbar-type8": { file: "actionbar.md", section: "Type 8 — Report ActionBar: Search + Incident Button + Pagination + Column View" }, "data-table": { file: "data_table_type1.md", section: "Complete HTML" }, "data-table-type2": { file: "data_table_type2.md", section: "Complete HTML" }, "rpt-chart-floater": { file: "rpt-chart-floater.md", section: "Complete HTML" }, "drawer-sm": { file: "drawer.md", section: "Variant 1" }, "drawer-md": { file: "drawer.md", section: "Variant 2" }, "drawer-lg": { file: "drawer.md", section: "Variant 3" }, "form-text": { file: "form_input.md", section: "Type 1" }, "form-textarea": { file: "form_input.md", section: "Type 3" }, "form-checkbox": { file: "form_input.md", section: "Type 23: Checkbox Group" }, "form-radio": { file: "form_input.md", section: "Type 5" }, "form-dropdown": { file: "form_dropdown.md", section: "Type 1: Basic Dropdown (plain text items)" }, "widget": { file: "widget.md", section: "Dashboard Container" }, "stat-card": { file: "stat_card.md", section: "Grid Wrapper + All 10 Types" }, "button-row": { file: "button-row.md", section: "Complete HTML" }, "note-container": { file: "note-container.md", section: "Complete HTML" }, "design-tokens": { file: "design_tokens.md", section: "" }, }; - api/mcp.ts:44-77 (helper)Helper functions used by get_component: rewriteAssetPaths (rewrites asset URLs to CDN), extractSection (finds a section by heading), and extractHtmlBlock (extracts ```html code blocks).
function rewriteAssetPaths(html: string): string { // Match all relative forms: ./assets/, assets/, ../assets/, ../../assets/ ... // Covers: src="...", href="...", and any data-* attribute pointing at assets/ // (e.g. data-icon, data-src, data-hover-icon — used by JS for dynamic swaps). return html .replace(/src=(["'])(?:\.\/|(?:\.\.\/)+)?assets\//g, (_m, q) => `src=${q}${CDN_BASE}/assets/`) .replace(/href=(["'])(?:\.\/|(?:\.\.\/)+)?assets\//g, (_m, q) => `href=${q}${CDN_BASE}/assets/`) .replace(/(data-[a-z-]+)=(["'])(?:\.\/|(?:\.\.\/)+)?assets\//g, (_m, attr, q) => `${attr}=${q}${CDN_BASE}/assets/`); } function extractSection(content: string, heading: string): string { const lines = content.split("\n"); const headingLower = heading.toLowerCase(); let inSection = false; const out: string[] = []; for (const line of lines) { if (/^#{2,3} /.test(line)) { if (line.toLowerCase().includes(headingLower)) { inSection = true; out.push(line); continue; } if (inSection) break; } if (inSection) out.push(line); } return out.length ? out.join("\n").trim() : `[Section "${heading}" not found]`; } function extractHtmlBlock(content: string, heading?: string): string { const src = heading ? extractSection(content, heading) : content; const match = src.match(/```html\n([\s\S]*?)```/); return match ? match[1].trim() : "[No HTML block found]"; }