Skip to main content
Glama

compare_insurers

Compare health insurance premiums from multiple Swiss insurers based on canton, year, age group, and franchise to identify cost-effective options.

Instructions

Vergleicht mehrere Versicherer für ein bestimmtes Profil.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
insurer_namesYesListe von Versicherer-Namen (z.B. ['CSS', 'Helsana', 'Swica'])
cantonYesKanton (2-Buchstaben-Code)
yearYesJahr (2016-2026)
age_bandYesAltersgruppe
franchise_chfYesFranchise in CHF

Implementation Reference

  • The main handler function executing the tool logic: resolves insurer names to IDs using helper functions, queries the premiums table in Supabase for matching criteria, selects the cheapest model per insurer, sorts by price, and returns a formatted markdown table comparison with price difference and disclaimer.
    async function compareInsurers(params: { insurer_names: string[]; canton: string; year: number; age_band: string; franchise_chf: number; }): Promise<string> { const db = getSupabase(); const { insurer_names, canton, year, age_band, franchise_chf } = params; // Finde ALLE Versicherer-IDs für jeden Namen (z.B. Helsana hat 0312, 1322, 1479, 1568) const matchedInsurers: { searchName: string; ids: string[]; primaryId: string | undefined }[] = insurer_names.map(searchName => ({ searchName, ids: findAllInsurerIds(searchName), primaryId: findInsurerIdByName(searchName) })); // Sammle alle IDs und tracke welche zu welchem Namen gehören const allIds: string[] = []; const idToSearchName = new Map<string, string>(); for (const m of matchedInsurers) { for (const id of m.ids) { allIds.push(id); idToSearchName.set(id, m.searchName); } } const notFound = matchedInsurers.filter(m => m.ids.length === 0).map(m => m.searchName); if (allIds.length === 0) { return `⚠️ Keine der Versicherer gefunden: ${insurer_names.join(", ")}\n\nVerfügbare Versicherer: CSS, Helsana, Swica, Assura, Concordia, Sanitas, KPT, ÖKK, Visana, Groupe Mutuel, Sympany, Atupri, EGK, Aquilana, Galenos`; } // Hole Prämien für ALLE IDs const { data: premiums, error } = await db .from("premiums") .select("insurer_id, monthly_premium_chf, model_type") .eq("canton", canton.toUpperCase()) .eq("year", year) .eq("age_band", age_band) .eq("franchise_chf", franchise_chf) .in("insurer_id", allIds); if (error || !premiums || premiums.length === 0) { return `❌ Keine Prämien gefunden für: ${canton}, ${year}\n\nGesuchte IDs: ${allIds.join(", ")}`; } // Gruppiere nach SUCHNAME (nimm günstigsten Tarif pro Versicherer) const bestByName = new Map<string, { premium: number; model: string; id: string }>(); for (const p of premiums) { const searchName = idToSearchName.get(p.insurer_id) || p.insurer_id; const existing = bestByName.get(searchName); if (!existing || p.monthly_premium_chf < existing.premium) { bestByName.set(searchName, { premium: p.monthly_premium_chf, model: p.model_type, id: p.insurer_id }); } } // Formatiere Ergebnis let result = `📊 Versicherungsvergleich\n`; result += `📍 ${canton} | ${year} | ${age_band} | CHF ${franchise_chf} Franchise\n\n`; const sorted = [...bestByName.entries()] .sort((a, b) => a[1].premium - b[1].premium); sorted.forEach(([searchName, data], index) => { const displayName = getInsurerName(data.id); result += `${index + 1}. ${displayName}: CHF ${data.premium.toFixed(2)}/Monat (${data.model})\n`; }); if (notFound.length > 0) { result += `\n⚠️ Nicht gefunden: ${notFound.join(", ")}\n`; } if (sorted.length >= 2) { const diff = sorted[sorted.length - 1][1].premium - sorted[0][1].premium; result += `\n💰 Differenz günstigste/teuerste: CHF ${diff.toFixed(2)}/Monat\n`; } result += DISCLAIMER; return result; }
  • Input schema for validating tool parameters: requires array of insurer names, canton code, year, age band, and franchise amount.
    inputSchema: { type: "object" as const, properties: { insurer_names: { type: "array", items: { type: "string" }, description: "Liste von Versicherer-Namen (z.B. ['CSS', 'Helsana', 'Swica'])" }, canton: { type: "string", description: "Kanton (2-Buchstaben-Code)" }, year: { type: "number", description: "Jahr (2016-2026)" }, age_band: { type: "string", enum: ["child", "young_adult", "adult"], description: "Altersgruppe" }, franchise_chf: { type: "number", description: "Franchise in CHF" } }, required: ["insurer_names", "canton", "year", "age_band", "franchise_chf"] }
  • src/index.ts:159-173 (registration)
    Tool registration in the TOOLS array used for ListToolsRequestSchema response, defining name, description, and inputSchema.
    { name: "compare_insurers", description: "Vergleicht mehrere Versicherer für ein bestimmtes Profil.", inputSchema: { type: "object" as const, properties: { insurer_names: { type: "array", items: { type: "string" }, description: "Liste von Versicherer-Namen (z.B. ['CSS', 'Helsana', 'Swica'])" }, canton: { type: "string", description: "Kanton (2-Buchstaben-Code)" }, year: { type: "number", description: "Jahr (2016-2026)" }, age_band: { type: "string", enum: ["child", "young_adult", "adult"], description: "Altersgruppe" }, franchise_chf: { type: "number", description: "Franchise in CHF" } }, required: ["insurer_names", "canton", "year", "age_band", "franchise_chf"] } },
  • src/index.ts:498-500 (registration)
    Dispatch registration in the switch statement within CallToolRequestSchema handler, mapping tool name to the compareInsurers function call.
    case "compare_insurers": result = await compareInsurers(args as any); break;
  • Helper function to find all insurer IDs matching a search name (handles multiple IDs per insurer), crucially used in the handler for comprehensive comparison.
    function findAllInsurerIds(searchName: string): string[] { const search = searchName.toLowerCase().trim(); const ids: string[] = []; for (const [id, name] of Object.entries(INSURER_NAMES)) { if (name.toLowerCase().includes(search) || search.includes(name.toLowerCase())) { ids.push(id); } } return ids; }

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/remoprinz/swiss-health-mcp'

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