Skip to main content
Glama

Senaro Personal Finance

Debt Consolidation Comparison

compare_debt_consolidation
Read-onlyIdempotent

Calculation, not advice. Verify with a professional before acting. Compares keeping cards vs. consolidation loan vs. optional balance transfer offers (single offer or head-to-head multi-offer comparison via bt_offers[]).

Supports partial balance transfers via bt_transfer_limit: transfers only up to that dollar amount (choosing cards by highest APR, highest balance, or manually), then runs a combined simulation of the BT card + remaining original-card balances together, so freed minimum payments are correctly redistributed.

Shows total cost, interest saved, monthly payment change, origination fee breakeven, hidden risks (reracking), promo-trap detection per offer, and what-if scenarios. Works with multiple cards including cash advance balances.

Pick this to weigh a consolidation loan (required input), plus any balance-transfer offers, against keeping current cards; pick calculate_cc_payoff for a single payoff timeline with no consolidation option, and pick compare_payoff_strategies to compare avalanche against snowball ordering on the cards as they stand.

The response includes chart_hints with rendering directives any client can use.

HEAVY tool: use output='summary' (default) for the headline comparison or output='inline' for the full payload.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
cardsYesCredit cards to include, 1 to 20. Required: omitting the field answers contract_error MISSING_REQUIRED_FIELD, while an explicit JSON null answers parse_error ("cards must be a JSON array."); the two are not the same rejection. segments and stop_spend_month are not supported by this tool and are rejected; a non-zero monthly_spend, annual_fee, or plan_fees_monthly is rejected too, but zero (including an explicit 0) is accepted and dropped for all three: this tool always reads the flat purchase_balance / cash_advance_balance fields on each card below, never segments[] balances, and card-level fees and ongoing spend are not modeled here. Those five fields are supported by calculate_cc_payoff and compare_payoff_strategies instead.
outputNoValid values: 'summary' (default), 'inline'. summary: compact response with a data_preview block; no heavy array exists on this response today, so summary and inline are currently identical in content. inline: full payload (currently identical to summary; will diverge once a heavy array is added for chart rendering).
bt_offersNoBalance-transfer offers to compare head-to-head, 1 to 10, preferred over the four scalar bt_* fields above when comparing two or more offers: when supplied, bt_offers overrides bt_apr_pct, bt_promo_months, bt_regular_apr_pct, and bt_fee_pct, and their range checks are skipped. The response includes a balance_transfer_offers block with per-offer simulation results, selected_offer_index, selected_offer_label, selected_offer_reason, and all_offers_trap. Optional; a JSON null is rejected, unlike bt_manual_transfers and windfalls below, where a JSON null is treated as omitted.
windfallsNoOne-time principal payments, at most 12, same shape as calculate_cc_payoff. Optional; a JSON null is treated as omitted, the same as leaving the field out. When non-empty, the response adds windfalls_applied[] and windfalls_unused[] on keep_cards, on each balance_transfer scenario (and on each offer in balance_transfer_offers.offers[]), on consolidation_loan (single-row per windfall since the loan is a single-balance instrument), and on optimized_consolidation.keep_subset. All scenarios use with-windfalls totals so cross-option ranking stays apples-to-apples, except what_if.same_budget_accelerated, a windfall-free hypothetical about extra-payment behavior, not your actual lump-sum schedule.
bt_apr_pctNoBalance-transfer APR as a percentage, 0-100, e.g. 0 for a 0% promo. Required when include_balance_transfer is true and bt_offers is omitted. bt_offers, when supplied, overrides this and the other three bt_* scalars below. The 0-100 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.
bt_fee_pctNoBalance-transfer fee as a percentage of the transferred balance, 0-10. Optional; defaults to 3.0 when omitted. bt_offers, when supplied, overrides this. The 0-10 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.
chart_titleNoOverride for the chart title. Optional; must not contain an em dash or en dash. Max 120 characters.
full_scheduleNoWhether to return the full month-by-month amortization schedule instead of the compact default. Optional; defaults to false when omitted.
bt_promo_monthsNoBalance-transfer promo period in months, 1-60. Optional; defaults to 18 when omitted. bt_offers, when supplied, overrides this. The 1-60 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.
current_strategyNoYour current payoff strategy, compared against the consolidation loan / balance-transfer alternative: 'avalanche' or 'snowball'. Optional; defaults to 'avalanche' when omitted. Case-sensitive.
bt_transfer_limitNoCap on the total dollar amount transferred to the balance-transfer card, at least $0.01. When set, only this amount moves to the BT card; remaining balances stay on original cards, and a combined simulation runs both halves together, correctly redistributing freed minimum payments. Optional; when omitted, the entire balance is transferred (legacy behavior). Needs include_balance_transfer or bt_offers.
bt_regular_apr_pctNoAPR that applies after the promo period ends, as a percentage, 0-100. Optional; defaults to 25.20 when omitted. bt_offers, when supplied, overrides this. The 0-100 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.
consolidation_loanYesLoan terms for the consolidation option. Required: omitting the field answers contract_error MISSING_REQUIRED_FIELD, while an explicit JSON null answers parse_error ("consolidation_loan must be an object."); the two are not the same rejection.
bt_manual_transfersNoExact per-card transfer amounts. Required when bt_transfer_strategy is 'manual'; each entry's card_name must match a name in cards[]. Optional otherwise; a JSON null is treated as omitted, the same as leaving the field out.
bt_transfer_strategyNoHow to choose which balances move when bt_transfer_limit is less than your total debt: 'highest_apr_first' (transfer from highest-APR segments first, maximizes interest savings), 'highest_balance_first' (transfer largest balances first), or 'manual' (use bt_manual_transfers to specify exact amounts per card). Optional; defaults to 'highest_apr_first' when omitted. Needs bt_transfer_limit.
extra_monthly_paymentNoExtra monthly payment in dollars, $0 to $1,000,000,000, applied on top of the required minimums for keep-cards and any balance transfer, and on top of the loan's own required payment for consolidation. Optional; defaults to 0 when omitted. fixed_payments is not a parameter of this tool, unlike calculate_cc_payoff: the keep-cards baseline is always simulated under the canonical constant rolled-forward payment (see comparison_basis in the response); supplying fixed_payments returns an unknown_parameter error.
include_balance_transferNoWhether to run a single-offer balance-transfer scenario using the four scalar bt_* fields below. Optional; defaults to false when omitted. Ignored once bt_offers is supplied; use bt_offers when comparing two or more offers.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / consolidation_loan / properties / annual_rate_pct / description
      Previous value: -"Annual interest rate for the consolidation loan, as a percentage, 0-36, e.g. 10.99. Required."New value: +"Annual interest rate for the consolidation loan, as a percentage, 0-36, e.g. 10.99. This is the loan's note interest rate, not the disclosed APR. The APR already reflects the origination fee, so entering it here counts the fee twice. Required."
  2. Changed13 schema fields changed
    • addedInput schema / properties / bt_manual_transfers / items / properties / card_name / maxLength
      Added value: +120
    • addedInput schema / properties / bt_offers / items / properties / apr_pct / maximum
      Added value: +100
    • addedInput schema / properties / bt_offers / items / properties / apr_pct / minimum
      Added value: +0
    • addedInput schema / properties / bt_offers / items / properties / label / maxLength
      Added value: +120
    • addedInput schema / properties / bt_offers / maxItems
      Added value: +10
    • addedInput schema / properties / bt_transfer_limit / minimum
      Added value: +0.01
    • changedInput schema / properties / cards / description
      Previous value: -"Credit cards to include, 1 to 20. Required: omitting the field answers contract_error MISSING_REQUIRED_FIELD, while an explicit JSON null answers parse_error (\"cards must be a JSON array.\"); the two are not the same rejection. segments and stop_spend_month are not supported by this tool and are rejected; a non-zero monthly_spend, annual_fee, or plan_fees_monthly is rejected too, but zero (including an explicit 0) is accepted and dropped for all three: this tool always reads the flat purchase_balance / cash_advance_balance fields on each card below, never segments[] balances, and card-level fees and ongoing spend are not modeled here. Those five fields are supported by calculate_cc_payoff and compare_strategies instead."New value: +"Credit cards to include, 1 to 20. Required: omitting the field answers contract_error MISSING_REQUIRED_FIELD, while an explicit JSON null answers parse_error (\"cards must be a JSON array.\"); the two are not the same rejection. segments and stop_spend_month are not supported by this tool and are rejected; a non-zero monthly_spend, annual_fee, or plan_fees_monthly is rejected too, but zero (including an explicit 0) is accepted and dropped for all three: this tool always reads the flat purchase_balance / cash_advance_balance fields on each card below, never segments[] balances, and card-level fees and ongoing spend are not modeled here. Those five fields are supported by calculate_cc_payoff and compare_payoff_strategies instead."
    • addedInput schema / properties / cards / items / properties / name / maxLength
      Added value: +120
    • addedInput schema / properties / chart_title / maxLength
      Added value: +120
    • addedInput schema / properties / current_strategy / enum
      Added value: +[
      +  "avalanche",
      +  "snowball",
      +  null
      +]
    • changedInput schema / properties / output / enum
      Previous value: -[
      -  "summary",
      -  "inline"
      -]New value: +[
      +  "summary",
      +  "inline",
      +  null
      +]
    • changedInput schema / properties / output / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • addedInput schema / properties / windfalls / items / properties / label / maxLength
      Added value: +120
  3. Changed6 schema fields changed
    • changedInput schema / properties / extra_monthly_payment / description
      Previous value: -"Extra monthly payment in dollars, $0 to $1,000,000,000, applied on top of the required minimums. Optional; defaults to 0 when omitted. fixed_payments is not a parameter of this tool, unlike calculate_cc_payoff: the keep-cards baseline is always simulated under the canonical constant rolled-forward payment (see comparison_basis in the response); supplying fixed_payments returns an unknown_parameter error."New value: +"Extra monthly payment in dollars, $0 to $1,000,000,000, applied on top of the required minimums for keep-cards and any balance transfer, and on top of the loan's own required payment for consolidation. Optional; defaults to 0 when omitted. fixed_payments is not a parameter of this tool, unlike calculate_cc_payoff: the keep-cards baseline is always simulated under the canonical constant rolled-forward payment (see comparison_basis in the response); supplying fixed_payments returns an unknown_parameter error."
    • removedInput schema / properties / output / default
      Removed value: -null
    • changedInput schema / properties / output / description
      Previous value: -"Response verbosity: 'summary' (default) | 'inline' | 'capture'. summary: compact response with a data_preview block; no heavy array exists on this response today, so summary and inline are currently identical in content. inline: full payload (currently identical to summary; will diverge once a heavy array is added for chart rendering). capture: full payload written to this server's local disk for the chart-render pipeline; capture_ref URI returned. Available on the local stdio transport only; the hosted HTTP transport rejects 'capture' with a structured error naming 'summary' and 'inline' as the valid alternatives. Optional; defaults to 'summary' when omitted."New value: +"Valid values: 'summary' (default), 'inline'. summary: compact response with a data_preview block; no heavy array exists on this response today, so summary and inline are currently identical in content. inline: full payload (currently identical to summary; will diverge once a heavy array is added for chart rendering)."
    • addedInput schema / properties / output / enum
      Added value: +[
      +  "summary",
      +  "inline"
      +]
    • changedInput schema / properties / output / type
      Previous value: -[
      -  "string",
      -  "null"
      -]New value: +"string"
    • changedInput schema / properties / windfalls / description
      Previous value: -"One-time principal payments, at most 12, same shape as calculate_cc_payoff. Optional; a JSON null is treated as omitted, the same as leaving the field out. When non-empty, the response adds windfalls_applied[] and windfalls_unused[] on keep_cards, on each balance_transfer scenario (and on each offer in balance_transfer_offers.offers[]), on consolidation_loan (single-row per windfall since the loan is a single-balance instrument), and on optimized_consolidation.keep_subset. All scenarios use with-windfalls totals so cross-option ranking stays apples-to-apples."New value: +"One-time principal payments, at most 12, same shape as calculate_cc_payoff. Optional; a JSON null is treated as omitted, the same as leaving the field out. When non-empty, the response adds windfalls_applied[] and windfalls_unused[] on keep_cards, on each balance_transfer scenario (and on each offer in balance_transfer_offers.offers[]), on consolidation_loan (single-row per windfall since the loan is a single-balance instrument), and on optimized_consolidation.keep_subset. All scenarios use with-windfalls totals so cross-option ranking stays apples-to-apples, except what_if.same_budget_accelerated, a windfall-free hypothetical about extra-payment behavior, not your actual lump-sum schedule."
  4. Changed19 schema fields changed
    • addedInput schema / properties / bt_apr_pct
      Added value: +{
      +  "default": null,
      +  "description": "Balance-transfer APR as a percentage, 0-100, e.g. 0 for a 0% promo. Required when include_balance_transfer is true and bt_offers is omitted. bt_offers, when supplied, overrides this and the other three bt_* scalars below. The 0-100 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / bt_fee_pct
      Added value: +{
      +  "default": null,
      +  "description": "Balance-transfer fee as a percentage of the transferred balance, 0-10. Optional; defaults to 3.0 when omitted. bt_offers, when supplied, overrides this. The 0-10 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / bt_manual_transfers
      Added value: +{
      +  "default": null,
      +  "description": "Exact per-card transfer amounts. Required when bt_transfer_strategy is 'manual'; each entry's card_name must match a name in cards[]. Optional otherwise; a JSON null is treated as omitted, the same as leaving the field out.",
      +  "items": {
      +    "properties": {
      +      "amount": {
      +        "description": "Dollar amount to transfer from this card, greater than $0, up to $1,000,000,000. Required per entry.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "card_name": {
      +        "description": "Card name; must match a name in cards[]. Required per entry. Max 120 characters.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      }
      +    },
      +    "type": [
      +      "object",
      +      "null"
      +    ]
      +  },
      +  "type": [
      +    "array",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / bt_offers
      Added value: +{
      +  "default": null,
      +  "description": "Balance-transfer offers to compare head-to-head, 1 to 10, preferred over the four scalar bt_* fields above when comparing two or more offers: when supplied, bt_offers overrides bt_apr_pct, bt_promo_months, bt_regular_apr_pct, and bt_fee_pct, and their range checks are skipped. The response includes a balance_transfer_offers block with per-offer simulation results, selected_offer_index, selected_offer_label, selected_offer_reason, and all_offers_trap. Optional; a JSON null is rejected, unlike bt_manual_transfers and windfalls below, where a JSON null is treated as omitted.",
      +  "items": {
      +    "properties": {
      +      "apr_pct": {
      +        "description": "Offer APR as a percentage, 0-100, e.g. 0 for a 0% promo. Required per offer.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "fee_pct": {
      +        "description": "Balance-transfer fee for this offer, as a percentage of the transferred balance, 0-10. Optional; defaults to 3.0 when omitted.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "label": {
      +        "description": "Label for this offer. Optional; defaults to '<apr_pct>% / <promo_months>mo' when omitted. Max 120 characters.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "promo_months": {
      +        "description": "This offer's promo period in months, 1-60. Optional; defaults to 18 when omitted.",
      +        "type": [
      +          "integer",
      +          "null"
      +        ]
      +      },
      +      "regular_apr_pct": {
      +        "description": "APR that applies after this offer's promo period ends, as a percentage, 0-100. Optional; defaults to 25.20 when omitted.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      }
      +    },
      +    "type": [
      +      "object",
      +      "null"
      +    ]
      +  },
      +  "type": [
      +    "array",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / bt_promo_months
      Added value: +{
      +  "default": null,
      +  "description": "Balance-transfer promo period in months, 1-60. Optional; defaults to 18 when omitted. bt_offers, when supplied, overrides this. The 1-60 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.",
      +  "type": [
      +    "integer",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / bt_regular_apr_pct
      Added value: +{
      +  "default": null,
      +  "description": "APR that applies after the promo period ends, as a percentage, 0-100. Optional; defaults to 25.20 when omitted. bt_offers, when supplied, overrides this. The 0-100 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / bt_transfer_limit
      Added value: +{
      +  "default": null,
      +  "description": "Cap on the total dollar amount transferred to the balance-transfer card, at least $0.01. When set, only this amount moves to the BT card; remaining balances stay on original cards, and a combined simulation runs both halves together, correctly redistributing freed minimum payments. Optional; when omitted, the entire balance is transferred (legacy behavior). Needs include_balance_transfer or bt_offers.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / bt_transfer_strategy
      Added value: +{
      +  "default": null,
      +  "description": "How to choose which balances move when bt_transfer_limit is less than your total debt: 'highest_apr_first' (transfer from highest-APR segments first, maximizes interest savings), 'highest_balance_first' (transfer largest balances first), or 'manual' (use bt_manual_transfers to specify exact amounts per card). Optional; defaults to 'highest_apr_first' when omitted. Needs bt_transfer_limit.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / cards
      Added value: +{
      +  "description": "Credit cards to include, 1 to 20. Required: omitting the field answers contract_error MISSING_REQUIRED_FIELD, while an explicit JSON null answers parse_error (\"cards must be a JSON array.\"); the two are not the same rejection. segments and stop_spend_month are not supported by this tool and are rejected; a non-zero monthly_spend, annual_fee, or plan_fees_monthly is rejected too, but zero (including an explicit 0) is accepted and dropped for all three: this tool always reads the flat purchase_balance / cash_advance_balance fields on each card below, never segments[] balances, and card-level fees and ongoing spend are not modeled here. Those five fields are supported by calculate_cc_payoff and compare_strategies instead.",
      +  "items": {
      +    "properties": {
      +      "cash_advance_apr_pct": {
      +        "description": "Cash advance APR as a percentage, greater than 0, up to 100. Required when cash_advance_balance is greater than 0.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "cash_advance_balance": {
      +        "description": "Cash advance balance in dollars, $0 to $1,000,000,000. Optional; defaults to 0 when omitted.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "minimum_payment": {
      +        "description": "Minimum payment in dollars, $0 to $1,000,000,000. Optional; 0 or omitted auto-calculates the bank minimum. Used as the locked floor for the constant keep-cards payment: each card pays max(your minimum, the bank minimum), held constant and rolled forward as cards clear.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "name": {
      +        "description": "Card label, e.g. 'Chase Sapphire'. Optional; a card without a name is auto-numbered ('Card 1', 'Card 2', ...). Max 120 characters.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "purchase_apr_pct": {
      +        "description": "Purchase APR as a percentage, 0-100, e.g. 22.99. Required per card.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "purchase_balance": {
      +        "description": "Purchase balance in dollars, $0 to $1,000,000,000. Required per card.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      }
      +    },
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / chart_title
      Added value: +{
      +  "default": null,
      +  "description": "Override for the chart title. Optional; must not contain an em dash or en dash. Max 120 characters.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / consolidation_loan
      Added value: +{
      +  "description": "Loan terms for the consolidation option. Required: omitting the field answers contract_error MISSING_REQUIRED_FIELD, while an explicit JSON null answers parse_error (\"consolidation_loan must be an object.\"); the two are not the same rejection.",
      +  "properties": {
      +    "annual_rate_pct": {
      +      "description": "Annual interest rate for the consolidation loan, as a percentage, 0-36, e.g. 10.99. Required.",
      +      "type": [
      +        "number",
      +        "null"
      +      ]
      +    },
      +    "include_fee_in_principal": {
      +      "description": "Whether the origination fee is rolled into the loan principal rather than paid upfront. Optional; defaults to true when omitted. A JSON null is rejected; omit the field instead of sending null.",
      +      "type": [
      +        "boolean",
      +        "null"
      +      ]
      +    },
      +    "origination_fee_flat": {
      +      "description": "Flat-dollar origination fee, $0 to $10,000. Optional; defaults to 0 when omitted, and takes precedence over origination_fee_pct when it produces a larger fee. A JSON null is rejected; omit the field instead of sending null.",
      +      "type": [
      +        "number",
      +        "null"
      +      ]
      +    },
      +    "origination_fee_pct": {
      +      "description": "Origination fee as a percentage of loan principal, 0-10. Optional; defaults to 0 when omitted. A JSON null is rejected, unlike every other optional field on this tool; omit the field instead of sending null.",
      +      "type": [
      +        "number",
      +        "null"
      +      ]
      +    },
      +    "term_months": {
      +      "description": "Consolidation loan term in months, 12-84. Required.",
      +      "type": [
      +        "integer",
      +        "null"
      +      ]
      +    }
      +  },
      +  "type": "object"
      +}
    • addedInput schema / properties / current_strategy
      Added value: +{
      +  "default": null,
      +  "description": "Your current payoff strategy, compared against the consolidation loan / balance-transfer alternative: 'avalanche' or 'snowball'. Optional; defaults to 'avalanche' when omitted. Case-sensitive.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / extra_monthly_payment
      Added value: +{
      +  "default": null,
      +  "description": "Extra monthly payment in dollars, $0 to $1,000,000,000, applied on top of the required minimums. Optional; defaults to 0 when omitted. fixed_payments is not a parameter of this tool, unlike calculate_cc_payoff: the keep-cards baseline is always simulated under the canonical constant rolled-forward payment (see comparison_basis in the response); supplying fixed_payments returns an unknown_parameter error.",
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / full_schedule
      Added value: +{
      +  "default": null,
      +  "description": "Whether to return the full month-by-month amortization schedule instead of the compact default. Optional; defaults to false when omitted.",
      +  "type": [
      +    "boolean",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / include_balance_transfer
      Added value: +{
      +  "default": null,
      +  "description": "Whether to run a single-offer balance-transfer scenario using the four scalar bt_* fields below. Optional; defaults to false when omitted. Ignored once bt_offers is supplied; use bt_offers when comparing two or more offers.",
      +  "type": [
      +    "boolean",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / output
      Added value: +{
      +  "default": null,
      +  "description": "Response verbosity: 'summary' (default) | 'inline' | 'capture'. summary: compact response with a data_preview block; no heavy array exists on this response today, so summary and inline are currently identical in content. inline: full payload (currently identical to summary; will diverge once a heavy array is added for chart rendering). capture: full payload written to this server's local disk for the chart-render pipeline; capture_ref URI returned. Available on the local stdio transport only; the hosted HTTP transport rejects 'capture' with a structured error naming 'summary' and 'inline' as the valid alternatives. Optional; defaults to 'summary' when omitted.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • removedInput schema / properties / toolArguments
      Removed value: -{
      -  "description": "JSON object with these parameters:\n\ncards (REQUIRED array, max 20):\n  - name: string (optional)\n  - purchase_balance: decimal >= 0 (REQUIRED)\n  - purchase_apr_pct: decimal 0-100 as percentage, e.g. 22.99 (REQUIRED)\n  - cash_advance_balance: decimal >= 0 (optional, default 0)\n  - cash_advance_apr_pct: decimal > 0, <= 100 (required if cash_advance_balance > 0)\n  - minimum_payment: decimal >= 0 (optional, 0 = auto-calculate). Used as the locked floor for the constant keep-cards payment: each card pays max(your minimum, the bank minimum), held constant and rolled forward as cards clear.\n  - segments: NOT SUPPORTED by this tool (rejected with a parse_error if supplied). This tool always reads the flat purchase_balance / cash_advance_balance fields above, never segments[] balances; supply those instead. segments[] input is supported by calculate_cc_payoff and compare_strategies.\n  - monthly_spend / stop_spend_month: NOT SUPPORTED by this tool (rejected with a validation error if supplied). Ongoing spend on cards a consolidation loan or transfer just paid off is not modeled by any arm here; supported by calculate_cc_payoff and compare_strategies.\n\nconsolidation_loan (REQUIRED object):\n  - annual_rate_pct: decimal 0-36 as percentage, e.g. 10.99 (REQUIRED)\n  - term_months: int 12-84 (REQUIRED)\n  - origination_fee_pct: decimal 0-10 (optional, default 0)\n  - origination_fee_flat: decimal (optional, default 0, takes precedence if > pct-based fee)\n  - include_fee_in_principal: bool (optional, default true)\n\nextra_monthly_payment: decimal >= 0 (optional, default 0)\ncurrent_strategy: 'avalanche' | 'snowball' (optional, default 'avalanche')\n(Note: fixed_payments is NOT a parameter of this tool, unlike calculate_cc_payoff. The keep-cards baseline is always simulated under the canonical constant rolled-forward payment, see comparison_basis in the response. Passing fixed_payments returns an unknown_parameter error.)\n\nBalance transfer, SINGLE OFFER (legacy, all optional):\ninclude_balance_transfer: bool (default false)\nbt_apr_pct: decimal 0-100 (required if include_balance_transfer: true, use 0 for 0% promo)\nbt_promo_months: int 1-60 (optional, default 18)\nbt_regular_apr_pct: decimal 0-100 (optional, default 25.20)\nbt_fee_pct: decimal 0-10 (optional, default 3.0)\n\nBalance transfer, MULTI-OFFER (preferred when comparing two or more offers):\nbt_offers: array of objects (max 10), when supplied, takes precedence over the scalar bt_* fields\n  Each object:\n  - apr_pct: decimal 0-100 (REQUIRED)\n  - promo_months: int 1-60 (optional, default 18)\n  - regular_apr_pct: decimal 0-100 (optional, default 25.20)\n  - fee_pct: decimal 0-10 (optional, default 3.0)\n  - label: string (optional, defaults to \"<apr_pct>% / <months>mo\")\nThe response includes a balance_transfer_offers block with per-offer simulation\nresults, selected_offer_index, selected_offer_label, selected_offer_reason, and all_offers_trap.\n\nPartial balance transfer (use when the BT offer has a transfer limit < your total debt):\nbt_transfer_limit: decimal >= 0.01 (optional), cap on total transferred amount.\n  When set, only this amount moves to the BT card; remaining balances stay on original cards.\n  A combined simulation runs both halves together, correctly redistributing freed minimum payments.\n  When omitted, the entire balance is transferred (legacy behavior).\nbt_transfer_strategy: 'highest_apr_first' | 'highest_balance_first' | 'manual' (optional, default 'highest_apr_first')\n  highest_apr_first: transfer from highest-APR segments first (maximizes interest savings)\n  highest_balance_first: transfer largest balances first\n  manual: use bt_manual_transfers to specify exact amounts per card\nbt_manual_transfers: array of objects (required when bt_transfer_strategy='manual')\n  Each object:\n  - card_name: string (must match a card name in cards[])\n  - amount: decimal > 0\n\nfull_schedule: bool (optional, default false, compact schedule by default)\n\nwindfalls: array of one-time principal payments (optional, default empty, max 12). Same shape as calculate_cc_payoff. Each item:\n  - month: int >= 0 (REQUIRED). 0 means applied before month 1's interest. N >= 1 applies at the END of calendar month N.\n  - amount: decimal > 0 (REQUIRED).\n  - label: string (optional). e.g. 'Tax refund', 'Year-end bonus'.\nWhen non-empty the response adds windfalls_applied[] and windfalls_unused[] on keep_cards, on each balance_transfer scenario (and on each offer in balance_transfer_offers.offers[]), on consolidation_loan (single-row per windfall since the loan is a single-balance instrument), and on optimized_consolidation.keep_subset. All scenarios use with-windfalls totals so cross-option ranking stays apples-to-apples.\n\nchart_title: string (optional) override for the chart title. Must not contain em-dashes or en-dashes. Max 120 characters.\n\nENVELOPE:\n  output: 'summary' (default) | 'inline' | 'capture'\n  summary: compact response with a data_preview block. No heavy array exists on this response today, so summary and inline are currently identical in content; the envelope is wired ahead of the future chart-render pipeline.\n  inline: full payload (currently identical to summary; will diverge once a heavy array is added for chart rendering).\n  capture: full payload written to ~/.senaro/captures/; capture_ref URI returned.\n    Available on the local stdio transport only; the hosted HTTP transport rejects 'capture'\n    with a structured error naming 'summary' and 'inline' as the valid alternatives."
      -}
    • addedInput schema / properties / windfalls
      Added value: +{
      +  "default": null,
      +  "description": "One-time principal payments, at most 12, same shape as calculate_cc_payoff. Optional; a JSON null is treated as omitted, the same as leaving the field out. When non-empty, the response adds windfalls_applied[] and windfalls_unused[] on keep_cards, on each balance_transfer scenario (and on each offer in balance_transfer_offers.offers[]), on consolidation_loan (single-row per windfall since the loan is a single-balance instrument), and on optimized_consolidation.keep_subset. All scenarios use with-windfalls totals so cross-option ranking stays apples-to-apples.",
      +  "items": {
      +    "properties": {
      +      "amount": {
      +        "description": "Dollar amount of the windfall, greater than 0. Required per entry.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "label": {
      +        "description": "Optional label for this windfall, e.g. 'Tax refund' or 'Year-end bonus'. Max 120 characters.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "month": {
      +        "description": "Month index the windfall is applied, 0 or more. 0 means applied before month 1's interest; N >= 1 applies at the end of calendar month N. Required per entry.",
      +        "type": [
      +          "integer",
      +          "null"
      +        ]
      +      }
      +    },
      +    "type": [
      +      "object",
      +      "null"
      +    ]
      +  },
      +  "type": [
      +    "array",
      +    "null"
      +  ]
      +}
    • changedInput schema / required
      Previous value: -[
      -  "toolArguments"
      -]New value: +[
      +  "cards",
      +  "consolidation_loan"
      +]
  5. First observed

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare a safe, idempotent, closed-world read, so the safety profile needs no restating. The description adds real behavioral context beyond that: it is a calculation with an explicit non-advice disclaimer, it is flagged HEAVY with a summary/inline output switch, it discloses promo-trap detection and reracking risk analysis, and it notes the response carries chart_hints. It stops short of describing pagination or result size limits.

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?

Six short paragraphs, front-loaded with the comparison and the required-input constraint, then sibling routing, then output modes. Dense but each paragraph carries distinct information; the disclaimer line and the output-mode note are the only near-redundant portions given the depth of the schema.

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?

No output schema exists and the tool is large (17 parameters, nested objects), so the description must orient the agent on results, which it does by listing the headline metrics, scenario comparisons, and the balance_transfer_offers/selection blocks that the schema details further. Some response structure is only documented in schema descriptions, but the combination is complete enough to call the tool correctly.

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?

Schema coverage is 100%, so the baseline is 3; the description still earns above it by explaining behavior the schema does not: bt_transfer_limit triggers a combined simulation of the BT card plus remaining original-card balances with freed minimum payments redistributed, and bt_offers supersedes the scalar bt_* fields. These are semantic interactions, not parameter restatements.

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 opening sentence names the exact comparison performed (keeping cards vs. a consolidation loan vs. optional balance-transfer offers) and specifies both the single-offer and head-to-head multi-offer modes. It then explicitly distinguishes itself from two named siblings, so an agent can route correctly without opening schemas.

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?

It gives an explicit selection rule with alternatives and their conditions: use this tool to weigh a consolidation loan (declared required) plus BT offers against keeping cards, use `calculate_cc_payoff` for a single payoff timeline, and `compare_payoff_strategies` for avalanche-vs-snowball on cards as they stand. Exclusions and the required input are stated outright.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources