Skip to main content
Glama
pace8

mcp-hypotheken-berekenen

bereken_hypotheek_doorstromer

Calculate your maximum mortgage budget for moving to a new home using existing home equity, income details, and current mortgage information.

Instructions

Berekent de maximale hypotheek voor doorstromers (standaard variant). Alle regels uit het doorstromerbeleid gelden ook voor de uitgebreide tool:

Outputvelden (altijd rechtstreeks gebruiken in de terugkoppeling):

  • max_woningbudget → woningbudget inclusief overwaarde en extra leencapaciteit

  • overwaarde_bedrag → vrijvallende winst uit de huidige woning

  • huidige_hypotheek_schuld → resterende schuld die moet worden afgelost

  • extra_leencapaciteit → nieuwe hypotheekruimte bovenop de overwaarde

  • maandlast_nu, maandlast_straks en verschil_maandlast → huidige, toekomstige en delta maandlast

Presentatie richting gebruiker (één compact blok):

  • Toon het woningbudget centraal onder de titel "Uw woningbudget" en licht toe waaruit dit bedrag bestaat in bullets (overwaarde, huidige hypotheek, extra leencapaciteit).

  • Voeg een tweede blok toe "Uw nieuwe maandlast" met maandlast nu, maandlast straks en het verschil (positief/negatief) op eigen regel.

  • Gebruik alleen MCP-waarden; geen eigen herberekeningen behalve eenvoudige weergave/afronding.

Invoerkeuze bestaande hypotheek (verplicht expliciet vragen):

  1. Snelle globale berekening → gebruiker geeft een samenvatting (totale schuld, gemiddelde rente/looptijd, eventuele huidige maandlast). Vul één leningdeel met deze totaalwaarden in.

  2. Detailberekening → gebruiker levert alle leningdelen (hoofdsom, rente, resterende looptijd, hypotheekvorm). Kopieer ze één-op-één in de leningdelen array.

Vraag altijd: "Wilt u een snelle globale berekening (met een samenvatting van uw hypotheek) of een detailberekening waarbij u alle leningdelen invoert?" en volg de gekozen route.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
inkomen_aanvragerYesBruto jaarinkomen hoofdaanvrager in euro's.
geboortedatum_aanvragerYesInterne geboortedatum hoofdaanvrager (ISO). Vraag de gebruiker altijd: "Wat is uw leeftijd of geboortedatum?" en deel bij een leeftijd alleen die leeftijd terug.
heeft_partnerYesGeeft aan of een partner mee leent.
inkomen_partnerNoOptioneel partnerinkomen in euro's.
geboortedatum_partnerNoOptionele interne geboortedatum partner (ISO). Vraag ook hier: "Wat is uw leeftijd of geboortedatum?" en houd de afgeleide datum intern.
verplichtingen_pmNoOptionele maandelijkse verplichtingen in euro's.
waarde_huidige_woningYesHuidige marktwaarde van de bestaande woning.
bestaande_hypotheekYesBestaande leningdelen voor doorstromer (detailuitleg: hypotheek://v4/guide/opzet-intake). VRAAG ALTIJD: "Wilt u een snelle globale berekening (met een samenvatting van uw hypotheek) of een detailberekening waarbij u alle leningdelen invoert?"
session_idNoOptioneel sessie-ID vanuit n8n (voor logging).

Implementation Reference

  • Handler function that processes the tool call: normalizes arguments, validates input, constructs API payload, calls the Replit API for mortgage calculation, logs success, and formats the response specifically for doorstromer scenarios.
    async function handleBerekenDoorstromer(request: any): Promise<ToolResponse> {
      const rawArgs = requireArguments<DoorstromerArguments>(request);
      const normalizedArgs = normalizeDoorstromerArgs(rawArgs) as DoorstromerArguments;
      const logger = createLogger(normalizedArgs.session_id);
    
      validateDoorstromerArguments(normalizedArgs);
      enforceRateLimit(normalizedArgs.session_id);
    
      const payload: any = {
        aanvragers: mapAanvragers(normalizedArgs),
        bestaande_hypotheek: {
          waarde_huidige_woning: normalizedArgs.waarde_huidige_woning,
          leningdelen: normalizedArgs.bestaande_hypotheek.leningdelen,
        },
      };
    
      if (normalizedArgs.session_id) {
        payload.session_id = normalizedArgs.session_id;
      }
    
      const apiClient = getApiClient();
      const { data } = await apiClient.post(
        REPLIT_API_URL_BEREKENEN,
        payload,
        { correlationId: normalizedArgs.session_id }
      );
    
      logger.info('Toolcall succesvol', { tool: 'bereken_hypotheek_doorstromer' });
      return successResponse(formatResponse(data, "bereken_hypotheek_doorstromer"));
    }
  • Input schema definition for the tool, including properties like base intake fields, waarde_huidige_woning, bestaande_hypotheek (with leningdelen), and required fields. Used in ListTools response.
          {
            name: "bereken_hypotheek_doorstromer",
            description: `Maximale hypotheek voor doorstromers ZONDER concrete woning. Gebruik dit wanneer de gebruiker wil weten hoeveel ruimte er is om straks te verhuizen maar er nog geen koopsom of specifieke woning op tafel ligt. Zodra een concreet huis ter sprake komt schakelt u over op de opzet-hypotheek tools. Alle regels uit het doorstromerbeleid gelden ook voor de uitgebreide tool:
    ${DOORSTROMER_OUTPUT_GUIDANCE}`,
            inputSchema: {
              type: "object",
              description: `Gebruik basisintakevelden plus huidige woninginformatie; zie ${OPZET_GUIDE_URI} voor detaildefinities.`,
              properties: {
                ...baseIntakeProperties,
                waarde_huidige_woning: {
                  type: "number",
                  description: "Huidige marktwaarde van de bestaande woning.",
                },
                bestaande_hypotheek: {
                  ...bestaandeHypotheekSchema,
                },
                session_id: {
                  type: "string",
                  description: "Optioneel sessie-ID vanuit n8n (voor logging).",
                },
              },
              required: [
                ...baseIntakeRequired,
                "waarde_huidige_woning",
                "bestaande_hypotheek",
              ],
            },
          },
  • src/index.ts:766-774 (registration)
    TOOL_HANDLERS object registering 'bereken_hypotheek_doorstromer' to its handler function handleBerekenDoorstromer. Used by the CallToolRequestSchema handler to dispatch tool calls.
    const TOOL_HANDLERS: Record<string, ToolHandler> = {
      bereken_hypotheek_starter: handleBerekenStarter,
      bereken_hypotheek_doorstromer: handleBerekenDoorstromer,
      bereken_hypotheek_uitgebreid: handleBerekenUitgebreid,
      haal_actuele_rentes_op: handleActueleRentes,
      opzet_hypotheek_starter: handleOpzetStarter,
      opzet_hypotheek_doorstromer: handleOpzetDoorstromer,
      opzet_hypotheek_uitgebreid: handleOpzetUitgebreid,
    };
  • Helper function to normalize doorstromer-specific arguments, mapping variant field names (e.g., existing_mortgage to bestaande_hypotheek) and normalizing leningdelen structure for consistent API payload.
    export function normalizeDoorstromerArgs(args: any): any {
      if (!args || typeof args !== 'object') {
        logger.warn('Invalid doorstromer args input', { args });
        return args;
      }
      
      const normalized: any = { ...args };
      
      for (const key of Object.keys(normalized)) {
        const lowerKey = key.toLowerCase().trim();
        
        const isBestaandeHypotheek = 
          (lowerKey.includes('bestaande') || lowerKey.includes('existing') || lowerKey.includes('current')) &&
          (lowerKey.includes('hypotheek') || lowerKey.includes('lening') || lowerKey.includes('mortgage') || lowerKey.includes('loan'));
        
        if (isBestaandeHypotheek) {
          logger.debug('Normalizing bestaande_hypotheek', { original_key: key });
          normalized.bestaande_hypotheek = normalizeBestaandeHypotheek(normalized[key]);
          
          if (key !== 'bestaande_hypotheek') {
            delete normalized[key];
          }
        }
        
        const isWoningwaarde = 
          (lowerKey.includes('waarde') && lowerKey.includes('woning')) ||
          (lowerKey.includes('home') && lowerKey.includes('value'));
        
        if (isWoningwaarde && typeof normalized[key] === 'number') {
          logger.debug('Normalizing waarde_huidige_woning', { original_key: key });
          normalized.waarde_huidige_woning = normalized[key];
          
          if (key !== 'waarde_huidige_woning') {
            delete normalized[key];
          }
        }
      }
      
      logger.info('Normalization complete', {
        has_bestaande_hypotheek: !!normalized.bestaande_hypotheek,
        has_leningdelen: !!normalized.bestaande_hypotheek?.leningdelen,
        leningdelen_count: normalized.bestaande_hypotheek?.leningdelen?.length || 0
      });
      
      return normalized;
    }
  • Validation function specific to doorstromer arguments: validates base args, current home value range, and requires/validates bestaande_hypotheek structure including leningdelen.
    export function validateDoorstromerArguments(args: unknown): void {
      // Eerst base arguments valideren
      validateBaseArguments(args);
      
      const input = args as Record<string, unknown>;
      
      // Valideer woningwaarde
      if (typeof input.waarde_huidige_woning !== 'number') {
        throw new ValidationError(
          ErrorCode.INVALID_INPUT,
          'waarde_huidige_woning moet een getal zijn',
          'waarde_huidige_woning'
        );
      }
      
      if (input.waarde_huidige_woning < ValidationConstraints.WONING_WAARDE.MIN || 
          input.waarde_huidige_woning > ValidationConstraints.WONING_WAARDE.MAX) {
        throw new ValidationError(
          ErrorCode.WONING_VALUE_OUT_OF_RANGE,
          `Woningwaarde moet tussen €${ValidationConstraints.WONING_WAARDE.MIN.toLocaleString('nl-NL')} en €${ValidationConstraints.WONING_WAARDE.MAX.toLocaleString('nl-NL')} liggen`,
          'waarde_huidige_woning',
          input.waarde_huidige_woning
        );
      }
      
      // Valideer bestaande hypotheek
      if (!input.bestaande_hypotheek) {
        throw new ValidationError(
          ErrorCode.INVALID_INPUT,
          'bestaande_hypotheek is verplicht voor doorstromers',
          'bestaande_hypotheek'
        );
      }
      
      validateBestaandeHypotheek(input.bestaande_hypotheek);
    }
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It does an excellent job explaining what the tool calculates (max_woningbudget, overwaarde_bedrag, etc.), how to present results to users (two compact blocks with specific formatting), and detailed input handling requirements. However, it doesn't mention potential limitations, error conditions, or performance characteristics that would make it a perfect 5.

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 comprehensive but somewhat lengthy and mixes multiple concerns (output fields, presentation guidelines, input approaches). While all information is valuable, it could be more efficiently structured. The first sentence clearly states the purpose, but subsequent sections could be better organized for quicker comprehension by an AI agent.

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

Completeness4/5

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

For a complex mortgage calculation tool with 9 parameters, nested objects, no annotations, and no output schema, the description does an excellent job covering what's needed. It explains output fields, presentation requirements, and input handling scenarios. The main gap is the lack of explicit error handling or edge case guidance, preventing a perfect score.

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

Parameters4/5

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

With 100% schema description coverage, the baseline is 3. The description adds significant value by explaining the two input approaches for 'bestaande_hypotheek' (quick global calculation vs detailed calculation) and mandating how to ask users about their preference. This provides crucial context beyond the schema's technical parameter definitions, though it doesn't elaborate on all 9 parameters' business logic.

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

Purpose5/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: 'Berekent de maximale hypotheek voor doorstromers (standaard variant)' which translates to 'Calculates the maximum mortgage for movers (standard variant)'. This specifies both the action (calculates maximum mortgage) and the target audience (doorstromers/movers), distinguishing it from sibling tools like bereken_hypotheek_starter and bereken_hypotheek_uitgebreid.

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

Usage Guidelines5/5

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

The description provides explicit guidance on when to use this tool versus alternatives: 'Alle regels uit het doorstromerbeleid gelden ook voor de uitgebreide tool' indicates this is the standard variant for movers, with an extended tool available. It also specifies detailed input scenarios (quick global calculation vs detailed calculation) and mandates asking the user which approach they prefer, providing clear operational guidance.

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/pace8/mcp-hypotheken-berekenen'

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