Skip to main content
Glama

search_components

Search for PC components like processors, graphics cards, and memory on meupc.net to compare prices across Brazilian stores and check specifications.

Instructions

Busca componentes de PC por texto no meupc.net (processadores, placas de vídeo, memórias, etc.)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesTexto para buscar componentes (ex: 'rtx 4070', 'ryzen 7')
limitNoNúmero máximo de resultados

Implementation Reference

  • Main handler function that searches for PC components on meupc.net. It fetches the search results page, parses HTML to extract component data (name, category, price, URL, image), and returns results as JSON string.
    export async function searchComponents(params: SearchComponentsParams): Promise<string> { const { query, limit } = params; const encoded = encodeURIComponent(query); const $ = await fetchPage(`/pesquisar?q=${encoded}`); const results: ComponentResult[] = []; $("div.media").each((_, el) => { if (results.length >= limit) return false; const $el = $(el); const nameEl = $el.find("div.media-content a h4"); const name = nameEl.text().trim(); if (!name) return; const url = $el.find("div.media-content > a").attr("href") ?? ""; const image = $el.find("div.media-left figure img").attr("src") ?? null; // Extrair categoria do link "Add na build" (ex: /processadores/add/HASH) const addLink = $el.find("a.button.is-link").attr("href") ?? ""; const categoryMatch = addLink.match(/meupc\.net\/([^/]+)\/add\//); const category = categoryMatch ? categoryMatch[1] : null; // Extrair preço do parágrafo de preço const priceText = $el.find("div.media-content > p").filter((_, p) => { return $(p).text().includes("R$"); }).first().text(); // Tentar pegar preço PIX primeiro, senão preço normal const pixMatch = priceText.match(/R\$\s*([\d.,]+)\s*no PIX/); const normalMatch = priceText.match(/R\$\s*([\d.,]+)/); const priceStr = pixMatch ? pixMatch[1] : normalMatch ? normalMatch[1] : null; const price = parsePrice(priceStr); results.push({ name, category, price, url: absoluteUrl(url), image: image && !image.includes("placeholder") ? absoluteUrl(image) : null, }); }); return JSON.stringify(results, null, 2); }
  • Input validation schema using Zod that defines the tool parameters: 'query' (string, required) for the search text, and 'limit' (number, optional, default 10) for maximum results.
    export const searchComponentsSchema = z.object({ query: z.string().describe("Texto para buscar componentes (ex: 'rtx 4070', 'ryzen 7')"), limit: z.number().int().positive().default(10).describe("Número máximo de resultados"), }); export type SearchComponentsParams = z.infer<typeof searchComponentsSchema>;
  • src/index.ts:16-23 (registration)
    MCP server tool registration that registers 'search_components' with its schema shape and handler function, including description in Portuguese.
    server.tool( "search_components", "Busca componentes de PC por texto no meupc.net (processadores, placas de vídeo, memórias, etc.)", searchComponentsSchema.shape, async (params) => ({ content: [{ type: "text", text: await searchComponents(params) }], }) );
  • Type definition for ComponentResult that the handler returns - includes name, category, price, URL, and image fields.
    export interface ComponentResult { name: string; category: string | null; price: number | null; url: string; image: string | null; }
  • Helper utility functions used by the handler: fetchPage() for web scraping, absoluteUrl() for URL resolution, and parsePrice() for extracting numeric prices from text.
    export async function fetchPage(path: string): Promise<CheerioAPI> { const url = path.startsWith("http") ? path : `${BASE_URL}${path.startsWith("/") ? "" : "/"}${path}`; const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT); try { const response = await fetch(url, { headers: { "User-Agent": USER_AGENT, "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7", }, signal: controller.signal, }); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText} — ${url}`); } const html = await response.text(); return cheerio.load(html); } finally { clearTimeout(timeout); } } export function absoluteUrl(path: string | undefined | null): string { if (!path) return ""; if (path.startsWith("http")) return path; return `${BASE_URL}${path.startsWith("/") ? "" : "/"}${path}`; } export function parsePrice(text: string | undefined | null): number | null { if (!text) return null; const cleaned = text.replace(/[R$\s.]/g, "").replace(",", "."); const num = parseFloat(cleaned); return isNaN(num) ? null : num; }

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/leosebben/mcp-meupc'

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