Skip to main content
Glama

bereken_hypotheek_doorstromer

Calculate maximum mortgage for home movers to determine new loan amount, monthly payments, and equity indication based on income, property value, and existing mortgage details.

Instructions

Berekent de maximale hypotheek voor doorstromers. Output: nieuw leenbedrag, maandlast en overwaarde-indicatie.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
inkomen_aanvragerYesBruto jaarinkomen hoofdaanvrager in euro's.
geboortedatum_aanvragerYesGeboortedatum hoofdaanvrager (YYYY-MM-DD).
heeft_partnerYesGeeft aan of een partner mee leent.
inkomen_partnerNoOptioneel partnerinkomen in euro's.
geboortedatum_partnerNoOptionele geboortedatum partner (YYYY-MM-DD).
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).
session_idNoOptioneel sessie-ID vanuit n8n (voor logging).

Implementation Reference

  • Main handler function: normalizes and validates input, constructs API payload, calls Replit backend API for doorstromer hypotheek calculation, formats doorstromer-specific output.
    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 and tool description provided in MCP 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)
    Maps tool name to handler function in TOOL_HANDLERS object used by CallToolRequestHandler.
    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,
    };
  • Normalizes doorstromer input arguments, mapping variant field names (e.g. 'restschuld' -> 'huidige_schuld') and restructuring leningdelen array.
    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;
    }
  • Validates doorstromer-specific inputs: woningwaarde range, leningdelen structure, counts, rentevast <= looptijd, etc.
    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);
    }
Behavior2/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 only states what the tool calculates (maximum mortgage) and lists output fields (new loan amount, monthly payment, equity indication). It doesn't disclose whether this is a read-only calculation or has side effects, doesn't mention rate limits, error conditions, or authentication requirements, and provides no context about what 'doorstromer' specifically entails beyond the general term.

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

Conciseness4/5

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

The description is efficiently structured in two sentences: one stating the purpose and one listing the output. There's no wasted language, and it's appropriately sized for a calculation tool. However, it could be slightly more front-loaded by integrating the output information into the main purpose statement.

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?

For a complex mortgage calculation tool with 9 parameters (including nested objects), no annotations, and no output schema, the description is inadequate. It doesn't explain the calculation methodology, doesn't clarify what 'doorstromer' means operationally, doesn't mention data sources or assumptions, and provides minimal context about the three output values. The description should do more to compensate for the lack of structured metadata.

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?

The description provides no parameter information beyond what's already in the schema. Since schema description coverage is 100%, the baseline score is 3. The description doesn't add any additional context about parameter relationships, dependencies, or usage examples that would enhance understanding beyond the comprehensive schema descriptions.

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: 'Berekent de maximale hypotheek voor doorstromers' (Calculates the maximum mortgage for movers). It specifies the verb (calculates), resource (maximum mortgage), and target audience (doorstromers/movers). However, it doesn't explicitly differentiate from sibling tools like 'bereken_hypotheek_starter' or 'bereken_hypotheek_uitgebreid' beyond the audience mention.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention sibling tools like 'bereken_hypotheek_starter' (for starters) or 'bereken_hypotheek_uitgebreid' (extended), nor does it specify prerequisites or scenarios where this tool is appropriate versus others in the mortgage calculation family.

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/Test'

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