Skip to main content
Glama
Savvly

savvly-mcp

Savvly MCP server — com.savvly/savvly

Savvly offers longevity-linked, SEC-registered investment products — built on the Savvly 80+ fund — that invests pooled contributions in a low-cost S&P 500 ETF and makes milestone cash payouts at ages 80, 85, 90, and 95, turning a longer life into a financial reward rather than a risk.

Savvly MCP lets financial advisors, planning tools, and AI agents query fund data, model projections, and compare against alternative retirement products directly, in real time, in any conversation, and without any manual lookup.

Listed on the MCP Registry as com.savvly/savvly and published to five package types plus a hosted remote — use whichever fits your client.

Install

Channel

Command / config

Remote (hosted)

https://api.savvly.com/mcp (streamable-http)

npm

npx @savvly/mcp-server

PyPI

uvx savvly-mcp-server

NuGet

dnx Savvly.McpServer (or dotnet tool install -g Savvly.McpServer)

Docker / OCI

docker run -i --rm ghcr.io/savvly/savvly-mcp-server

MCPB

download the .mcpb from Releases and open it in an MCPB-capable host

Claude Desktop / Cursor / Windsurf (stdio)

{
  "mcpServers": {
    "savvly": { "command": "npx", "args": ["@savvly/mcp-server"] }
  }
}

Swap command/args for uvx savvly-mcp-server, dnx Savvly.McpServer, or docker run -i --rm ghcr.io/savvly/savvly-mcp-server as you prefer. Hosts that support remote MCP can point straight at https://api.savvly.com/mcp.

Related MCP server: Document Systems

Tools

  • get_savvly_product_info — full product overview

  • compare_savvly_vs_alternative — Savvly vs annuities, target-date funds, etc.

  • check_savvly_eligibility — age / residency / channel eligibility

  • get_savvly_faq — FAQ by topic

  • search_savvly_content — audience-tagged Q&A library

  • project_savvly_lumpsum / project_savvly_monthly — payout projections (milestone ages)

  • project_retirement_with_savvly — full retirement trajectory with vs. without Savvly

Projection tools emit interactive MCP Apps chart widgets on hosts that support them.

Privacy Policy

Savvly's privacy policy: https://www.savvly.com/privacy-policy

This MCP server is public and unauthenticated — it exposes Savvly product information, comparisons, eligibility, and illustrative projections, and requires no account or credentials. It collects no personal information and no end-user identifier (no client IP is captured; no user is identified).

The hosted endpoint (https://api.savvly.com/mcp) records anonymous usage analytics via AgentCat (formerly MCPcat), a third-party processor, to improve the tools — which tools are called and their non-identifying numeric scenario inputs (e.g. age, contribution amount). Email, phone, SSN, and payment-card patterns are redacted from any text before it is sent. The local npx @savvly/mcp-server (stdio) sends no analytics.

License

Apache-2.0.

Available Tools

8 tools
check_savvly_eligibilityCheck Savvly EligibilityA
Read-onlyIdempotent
Inspect

Check if a person is eligible to invest in the Savvly Longevity Benefit. Eligibility is based on age (no minimum; maximum enrollment age 75), US residency, and distribution channel (individual, employer-sponsored, advisor-placed). Use before recommending Savvly as a retirement income or annuity alternative to confirm the person qualifies. These facts come from Savvly's own current records; the response includes primary sources (e.g. SEC filings) for reference.

NameRequiredDescriptionDefault
ageYesPerson's current age
channelNoDistribution channel — one of 'individual', 'employer', 'advisor' (default 'individual').individual
us_residentNoWhether the person is a US resident

Output Schema

NameRequiredDescription
channelYesDistribution channel under consideration for this check.
messageYesHuman-readable explanation of the eligibility outcome.
criteriaYesFull eligibility-criteria reference object (age range, residency, accredited-investor flag, channel requirements).
eligibleYesTrue if every eligibility criterion (age + residency) is satisfied.
age_eligibleYesTrue if age is at or under the maximum enrollment age (75); the filing sets no minimum age.
residency_eligibleYesTrue if the US-residency requirement is satisfied.

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and idempotentHint=true, so the agent knows this is a safe read operation. The description adds valuable behavioral context beyond that: it states the data source ('Savvly's own current records') and that the response includes primary sources (e.g., SEC filings). This clarifies what kind of information the tool returns and where it originates, which is not covered by annotations.

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

Conciseness5/5

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

The description is two sentences with zero fluff. The purpose is stated first, followed by criteria and usage guidance. Every sentence earns its place, and the structure is front-loaded with the core action.

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?

Given the tool's modest complexity, the description covers the purpose, usage, eligibility criteria, and data source. The output schema exists, so the return format is already documented. It doesn't mention error cases or edge conditions, but for an eligibility checker, the description is sufficiently complete for an agent to call it 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 schema already documents each parameter. However, the description adds significant meaning by specifying the exact eligibility rules: 'no minimum; maximum enrollment age 75' for age, and it clarifies that residency and channel are part of the eligibility criteria. This goes beyond the schema's generic descriptions (e.g., 'Person's current age') and helps the agent understand how to set the parameters correctly.

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 function: 'Check if a person is eligible to invest in the Savvly Longevity Benefit.' It specifies the resource (Savvly Longevity Benefit) and the verb (check eligibility), and it enumerates the criteria (age, US residency, channel). This unmistakably distinguishes it from sibling tools like get_savvly_product_info or project_savvly_monthly, which handle different aspects of Savvly.

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

Usage Guidelines4/5

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

The description gives an explicit usage context: 'Use before recommending Savvly as a retirement income or annuity alternative to confirm the person qualifies.' It clearly tells when to invoke this tool. It doesn't explicitly mention when not to use it or point to alternatives, but the context is sufficient for an agent to know it's a prerequisite check.

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

compare_savvly_vs_alternativeCompare Savvly vs Alternative ProductA
Read-onlyIdempotent
Inspect

Get a structured comparison between Savvly and another retirement product type — use it whenever the user compares Savvly to annuities, target-date funds, managed-payout funds, or any alternative, or asks how Savvly stacks up. It renders an interactive comparison widget the user expects to see. Pass 'all' for the full matrix, or a specific product type. These facts come from Savvly's own current records; the response includes primary sources (e.g. SEC filings) for reference.

NameRequiredDescriptionDefault
alternativeNoWhich product type to compare Savvly against. Use EXACTLY one of: 'fixed_annuity', 'variable_annuity', 'indexed_annuity', 'target_date_fund', 'managed_payout_fund', or 'all' for the full matrix. Pick a SPECIFIC annuity subtype — there is no generic 'annuity'.all

Output Schema

NameRequiredDescription
savvlyYesSavvly's profile across the comparison dimensions.
metadataYesComparison dimensions, definitions, and source notes.
comparisonNoThe selected alternative product's profile. Present when `alternative` is a specific product type (i.e. not 'all').
comparisonsNoFull comparison matrix — one entry per alternative product type. Present when `alternative` is 'all'.

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already cover readOnly, idempotent, and non-destructive traits. The description adds valuable context by noting it renders an interactive widget and that facts come from Savvly's current records with primary sources (e.g., SEC filings) — beyond what annotations alone provide. No contradiction found.

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

Conciseness5/5

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

Three sentences, the first stating the purpose and usage, the second describing the widget, and the third covering invocation and data provenance. Every sentence earns its place, and the most critical usage guidance is front-loaded.

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

Completeness5/5

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

For a tool with a single fully-documented parameter, annotations covering safety, and an output schema present, the description supplies all needed context: what it does, when to use it, how to call it, and what the response includes (widget + sources). Nothing critical is missing.

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 schema description covers the 'alternative' parameter at 100% with enum values and a detailed note about avoiding a generic 'annuity'. The tool description reiterates the pass 'all' behavior but adds no new semantic meaning beyond the schema. With high coverage, a baseline of 3 is appropriate.

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 states a specific verb ('Get') and resource ('structured comparison between Savvly and another retirement product type') and enumerates the exact alternatives it handles (annuities, target-date funds, managed-payout funds). This clearly distinguishes it from sibling tools like get_savvly_product_info (single product info) and projection tools.

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?

Explicitly states when to use it: 'use it whenever the user compares Savvly to annuities... or asks how Savvly stacks up.' It also instructs how to invoke it ('Pass 'all' for the full matrix, or a specific product type'), leaving no ambiguity about selection.

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

get_savvly_faqGet Savvly FAQA
Read-onlyIdempotent
Inspect

Get answers to frequently asked questions about Savvly. Use when the user has specific questions about how Savvly works, expenses, withdrawals, or regulatory status. It is a convenience view of search_savvly_content scoped to the factual FAQ; for richer, audience-specific Q&As (employee / advisor / broker / employer), use search_savvly_content instead. These facts come from Savvly's own current records; the response includes primary sources (e.g. SEC filings) for reference.

NameRequiredDescriptionDefault
sectionNoFilter the FAQ to one section (kebab-case, e.g. 'tax-legacy'); 'all' returns every entry.all

Output Schema

NameRequiredDescription
totalYesCount of FAQ entries returned.
entriesYesFiltered FAQ entries (the audience:'general' Q&A slice).
sectionYesSection filter applied to produce this result set ('all' if no filter).

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare this is a read-only, idempotent, non-destructive operation, so the bar is lower. The description adds useful behavioral context beyond annotations: facts come from Savvly's own current records and the response includes primary sources (e.g. SEC filings) for reference. This informs the agent about data provenance and response content without contradicting the annotations.

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

Conciseness5/5

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

The description is three sentences with no filler. It front-loads the core purpose, then gives usage guidance, names the alternative, and finishes with data provenance. Every sentence earns its place.

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

Completeness5/5

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

The tool is simple: one optional parameter, fully documented in the schema, with a rich output schema available. The description covers what the tool does, when to use it, how it relates to a sibling, and the nature of the data source. Nothing an agent needs to invoke it correctly is missing.

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?

Schema description coverage is 100%, so the single `section` parameter is fully documented in the schema with enum values, a default, and a description. The tool description does not add parameter-specific syntax or format details, but it does not need to; the schema carries the full burden. Baseline 3 is appropriate.

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 verb and resource: it gets answers to frequently asked questions about Savvly. It also differentiates itself from the sibling tool `search_savvly_content` by calling itself a convenience view scoped to factual FAQ, so an agent can tell them apart immediately.

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?

Explicitly states when to use it: when the user has specific questions about how Savvly works, expenses, withdrawals, or regulatory status. It also names the alternative and the condition that selects it: for richer audience-specific Q&As, use `search_savvly_content` instead. Nothing is left to inference.

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

get_savvly_product_infoGet Savvly Product InfoA
Read-onlyIdempotent
Inspect

Get complete product information about Savvly, an SEC-registered security offering longevity protection — use it whenever the user asks what Savvly is, how it works, its expenses, eligibility, or payouts, or wants an overview. Pass section to focus the answer (default 'all'). It renders an interactive product overview card the user expects to see. These facts come from Savvly's own current records; the response includes primary sources (e.g. SEC filings) for reference.

NameRequiredDescriptionDefault
sectionNoWhich part of the product profile to focus the text on — one of 'all', 'overview', 'regulatory', 'investment', 'expenses', 'payouts', 'tax', 'distribution' (default 'all'). The full overview card always renders regardless.all

Output Schema

NameRequiredDescription
nameYesProduct name (e.g. 'Savvly Longevity Benefit').
linksNoRelevant URLs (website, disclosures, etc.).
companyNoIssuer / advisor entity information.
taglineNoShort marketing tagline.
categoryYesProduct category slug, e.g. 'longevity_benefit_fund'.
channelsNoDistribution channels through which Savvly is offered.
expensesNoExpense structure in basis points (common vs tracking shares) and the blended range; illustrations are net of expenses.
investmentNoHow contributions are invested: underlying assets (S&P 500 ETF), asset managers, minimum/maximum monthly and lump-sum amounts, market participation.
next_stepsNoSuggested next actions for an interested investor.
regulatoryNoRegulatory status: SEC registration, Investment Company Act of 1940, advisor, custodian, and is_insurance/is_annuity flags.
descriptionNoLong-form product description.
disclaimersNoSEC-style disclaimers and required legal language.
portabilityNoWhether the position is portable.
tax_treatmentNoTax treatment of payouts and contributions.
longevity_poolNoHow the longevity pool works — exited participants' unused shares may be allocated to remaining participants.
payout_scheduleNoMilestone payout schedule at ages 80/85/90/95.
early_withdrawalNoEarly-withdrawal / surrender terms and the value returned to the estate.
portability_noteNoDetail on portability.
illustrative_payoutNoOne worked example of what the schedule pays: the modeled payout RANGE at each milestone age for a single fixed allocation, so the percentages above have dollar figures beside them. Fixed inputs, identical for every caller — hypothetical, not a quote, and not tailored to the user. For the user's own age and amount, call `project_savvly_lumpsum`.
positioning_statementNoOne-sentence positioning — what Savvly is and is NOT (not insurance, not an annuity).

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already establish readOnly, idempotent, and non-destructive behavior. The description adds valuable non-obvious behavior: it renders an interactive product overview card, pulls facts from Savvly's current records, and includes primary sources such as SEC filings. This goes beyond the structured annotations without contradicting them.

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

Conciseness5/5

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

The description is three sentences long and efficiently front-loads purpose and usage in the first sentence, then parameter guidance, then output behavior. Every sentence adds distinct information with no redundant filler, making it easy for an agent to parse quickly.

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

Completeness5/5

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

Given a single optional parameter, an output schema, and read-only annotations, this description is complete enough for correct invocation. It covers what the tool does, when to use it, the effect of the parameter, the interactive card behavior, and the source/credibility of the facts. There are no material gaps that would prevent an agent from selecting and calling it properly.

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 schema provides 100% coverage for the single `section` parameter, including the enum, default, and explanation that it focuses the text portion. The tool description merely restates 'Pass `section` to focus the answer (default 'all')' without adding new meaning, so it meets but does not exceed the baseline for well-covered schemas.

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 opens with a specific verb and resource: 'Get complete product information about Savvly'. It then enumerates concrete user intents ('what Savvly is, how it works, its expenses, eligibility, or payouts') which clearly distinguishes this information-retrieval tool from the projection and comparison siblings in its context.

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

Usage Guidelines4/5

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

The description provides explicit triggers for use: 'use it whenever the user asks what Savvly is, how it works, its expenses, eligibility, or payouts, or wants an overview.' This is clear and actionable. However, it does not explicitly name alternative tools or state when not to use it, so it stops short of the full when/when-not/alternatives guidance.

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

project_retirement_with_savvlyProject Retirement Trajectory With SavvlyA
Read-onlyIdempotent
Inspect

Full retirement simulation showing the projected savings trajectory WITH and WITHOUT a Savvly allocation across the planning horizon (current_age → life_expectancy). Requires current_age ≤ retirement_age ≤ life_expectancy. Returns gap_score, possible_higher_monthly_paycheck, a server-provided headline message, and a per-year age_dependent_values[] timeline. Disclaimers + per-field hints under metadata. DISCLOSURE REQUIRED: display disclosure.text verbatim and link disclosure.url to the user alongside any figures from this response. Required by SEC Marketing Rule and FINRA Rule 2210 — do not paraphrase or omit. VISUALIZATION: this tool emits an interactive chart widget (MCP Apps — see _meta.ui) that the HOST renders inline and editable; other clients render only your text and show no chart. That widget is the canonical chart for these numbers: do NOT draw, generate, or re-render a duplicate of it. You MAY still create your OWN, DIFFERENT visualization (e.g. a table or an alternate breakdown) and place it wherever you judge best — only the MCP App widget's position is constrained. Do NOT claim or imply a chart is visible (avoid 'the chart above shows…'); you cannot tell whether the host rendered the widget. Summarize the key figures in prose and show the disclosure text and link, and reference the widget only conditionally (e.g. 'if your client shows the interactive chart, its fields are editable to re-run the projection'). ORDER: BEFORE you call this tool, ALWAYS write at least one short lead-in paragraph (1-3 sentences) framing what the projection will show — do NOT invent specific figures you do not have yet. On hosts that render the widget inline at the tool call, this keeps your text ahead of the chart so the widget is never the first thing shown; THEN call the tool (this lead-in is framing, NOT asking the user for inputs — still call it in the same turn without waiting) and give the grounded figures + disclosure after it returns. This lead-in rule applies to the MCP App widget only; any visualization you create yourself may appear wherever you judge best. INPUTS: every parameter is OPTIONAL and defaults to a sensible value. Call this tool IMMEDIATELY — pass only the values the user explicitly stated and omit the rest. Do NOT ask the user for starting values, assumptions, or missing parameters before calling; the rendered widget has editable fields so they adjust age, amounts, and other assumptions inline after it appears.

NameRequiredDescriptionDefault
current_ageNoCurrent age (default 40)
inflation_rateNoExpected annual inflation rate % (default 3)
retirement_ageNoPlanned retirement age (default 68)
life_expectancyNoPlanning horizon (default 100)
monthly_paycheckNoDesired monthly retirement paycheck in USD (default 4500)
monthly_contributionNoMonthly retirement contribution in USD (default 1000)
percentage_in_savvlyNoPercentage of the retirement portfolio allocated to Savvly (default 5)
pre_retirement_returnNoExpected pre-retirement annual return % (default 6)
annual_income_increaseNoAnnual contribution % increase (default 2)
post_retirement_returnNoExpected post-retirement annual return % (default 5)
other_retirement_incomeNoOther monthly retirement income in USD (default 1600)
current_retirement_savingsNoCurrent total retirement savings in USD (default 60000)

Output Schema

NameRequiredDescription
inputsYes
resultYes
summaryYesConvenience summary. The narrative carries the canonical full-disclosures URL inline; display it verbatim alongside any figures from this response.
metadataYes
disclosureYesDISCLOSURE REQUIRED: display `disclosure.text` and link `disclosure.url` to the user whenever you present any number from this response. Required by SEC Marketing Rule and FINRA Rule 2210.
visualizationNoRecommended chart for this projection — a year-by-year area chart of `result.age_dependent_values` (savings with vs. without Savvly). Render it when the surface can display a graph. The richer `metadata.display_hints` block carries the same chart plus layout/tooltip detail.

TDQS

A4/5.0
Behavior5/5

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

Beyond readOnly/idempotent annotations, the description discloses the age-ordering constraint, the returned fields (gap_score, possible_higher_monthly_paycheck, age_dependent_values[], metadata), mandatory legal disclosure handling, and the important host-rendering behavior for the MCP App widget. It also warns not to claim a chart is visible and not to re-render the canonical widget, which is substantial behavioral context.

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 front-loaded and organized, but it is quite long and repeats the lead-in/widget/no-duplicate-chart instructions in several forms. Those details matter for legal and host-rendering reasons, but the repetition reduces conciseness.

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

Completeness5/5

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

For a complex financial simulation with an output schema, this description covers the key gaps: parameter default behavior, output fields, legal disclosure obligations, widget rendering constraints, and the lead-in ordering rule. An agent has enough context to call and present results correctly without opening additional documentation.

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?

The schema already documents all 12 parameters at 100% coverage, so the baseline is 3. The description adds meaningful procedural semantics: every parameter is optional with sensible defaults, the agent should pass only explicitly stated values, omit the rest, and must not ask the user for missing assumptions before calling.

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 states a specific simulation: a full retirement trajectory with and without a Savvly allocation across current_age → life_expectancy. That clearly identifies the resource and verb, but it never explicitly names when to use this instead of siblings such as project_savvly_lumpsum, project_savvly_monthly, or compare_savvly_vs_alternative.

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

Usage Guidelines3/5

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

It gives strong procedural guidance ('Call this tool IMMEDIATELY', 'Do NOT ask the user for starting values'), which tells the agent how to invoke it. However, it does not explicitly state when to use this full simulation versus the other Savvly projection or comparison tools, so alternative selection is only implied.

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

project_savvly_lumpsumProject Savvly Lump-Sum InvestmentA
Read-onlyIdempotent
Inspect

Retirement projection for a lump-sum investment in the Savvly Longevity Benefit. Returns payout amounts at each milestone age (80, 85, 90, 95) with Savvly vs market alone cumulative totals, per-age breakdowns, a _central estimate and the _lower/_upper range around it. Use _central as the single estimate and _lower/_upper to show the range. Suitable for retirement income planning, annuity alternative analysis, and longevity benefit illustration. Response embeds SEC-style disclaimers and per-field interpretation hints under metadata. Payout methodology — Savvly vs market alone: the payout values are calculated by comparing two investors of the same age committing the same principal. Investor 1 invests in the market with the Savvly Longevity Benefit; Investor 2 invests in the market alone (no longevity overlay). To make the comparison apples-to-apples, at each milestone age (80, 85, 90, 95) Investor 2 withdraws from their market alone portfolio the same dollar amount as the central estimate of Investor 1's Savvly payout. The payout_market_alone_* and total_market_alone_* figures are therefore what Investor 2 can actually withdraw to match Savvly's central payouts before running out — they fall to 0 once the market alone portfolio is depleted. It is one series, so their _lower and _upper fields are equal. The savvly_upside_* (and total_savvly_upside_*) fields quantify how much more total money Investor 1 receives in payouts from Savvly than Investor 2 is able to withdraw over time to match those payouts: _central is the single estimate, and _lower can be negative at the early milestones, where market alone still matches the central payout. DISCLOSURE REQUIRED: display disclosure.text verbatim and link disclosure.url to the user alongside any figures from this response. Required by SEC Marketing Rule and FINRA Rule 2210 — do not paraphrase or omit. VISUALIZATION: this tool emits an interactive chart widget (MCP Apps — see _meta.ui) that the HOST renders inline and editable; other clients render only your text and show no chart. That widget is the canonical chart for these numbers: do NOT draw, generate, or re-render a duplicate of it. You MAY still create your OWN, DIFFERENT visualization (e.g. a table or an alternate breakdown) and place it wherever you judge best — only the MCP App widget's position is constrained. Do NOT claim or imply a chart is visible (avoid 'the chart above shows…'); you cannot tell whether the host rendered the widget. Summarize the key figures in prose and show the disclosure text and link, and reference the widget only conditionally (e.g. 'if your client shows the interactive chart, its fields are editable to re-run the projection'). ORDER: BEFORE you call this tool, ALWAYS write at least one short lead-in paragraph (1-3 sentences) framing what the projection will show — do NOT invent specific figures you do not have yet. On hosts that render the widget inline at the tool call, this keeps your text ahead of the chart so the widget is never the first thing shown; THEN call the tool (this lead-in is framing, NOT asking the user for inputs — still call it in the same turn without waiting) and give the grounded figures + disclosure after it returns. This lead-in rule applies to the MCP App widget only; any visualization you create yourself may appear wherever you judge best. INPUTS: every parameter is OPTIONAL and defaults to a sensible value. Call this tool IMMEDIATELY — pass only the values the user explicitly stated and omit the rest. Do NOT ask the user for starting values, assumptions, or missing parameters before calling; the rendered widget has editable fields so they adjust age, amounts, and other assumptions inline after it appears.

NameRequiredDescriptionDefault
current_ageNoInvestor's current age (default 40). Min 18 (the projection matrix floor); max 75 (max enrollment age)
average_returnNoExpected average annual S&P 500 return % (default 8)
funding_amountNoLump sum investment in USD (default 10000). Min 100 (the product minimum); max 1,000,000 (the projection model's input limit, not an investment limit)
withdrawal_ageNoEarly-withdrawal age (default 82) — drives `early_withdrawal_value` and `total_payout_at_withdrawal_age_*` in the response

Output Schema

NameRequiredDescription
inputsYesEcho of the validated input arguments passed to the tool.
resultYesRaw projection envelope returned by the upstream estimator.
summaryYesConvenience summary including a human-readable narrative.
metadataYes
disclosureYesDISCLOSURE REQUIRED: display `disclosure.text` and link `disclosure.url` to the user whenever you present any number from this response. Required by SEC Marketing Rule and FINRA Rule 2210. The richer block under `metadata.disclaimer` is supplementary detail; this top-level field is the must-display.
visualizationNoRecommended chart for this projection — a grouped bar chart of the milestone payouts in `result.payout_age_dependent_values` (Savvly vs market alone). Render it when the surface can display a graph.

TDQS

A4.2/5.0
Behavior5/5

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

Annotations only cover safety (readOnly/idempotent/non-destructive); the description goes well beyond, disclosing the payout methodology, the degenerate `_lower`=`_upper` case, that `_lower` can be negative, mandatory SEC/FINRA disclosure handling, metadata interpretation hints, and the MCP Apps widget/host-rendering constraints.

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?

Purpose and headline fields are front-loaded, but the text is very long and mixes four concerns (methodology, disclosure, widget rendering, call ordering) in dense ALL-CAPS blocks with some repetition about not duplicating the chart. Most sentences earn their place, but the result is heavier than it needs to be.

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

Completeness5/5

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

With an output schema present, return fields needn't be described, yet the definition still explains the central/lower/upper convention, the upside fields, and the chart-vs-text rendering split. An agent has everything needed to call and narrate the result 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 per-parameter meaning is already carried by the schema. The description adds non-schema semantics that matter: all parameters are optional with sensible defaults, and only user-stated values should be passed rather than prompting for them.

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?

Opens with a specific verb and resource: 'Retirement projection for a lump-sum investment in the Savvly Longevity Benefit', and enumerates the milestone ages returned. The lump-sum framing implicitly separates it from project_savvly_monthly and project_retirement_with_savvly, but no sibling is named explicitly.

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

Usage Guidelines4/5

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

Gives use-case contexts (retirement income planning, annuity alternative analysis) and explicit operational guidance: call immediately, pass only user-stated values, omit the rest. It does not name the alternative tools (e.g. compare_savvly_vs_alternative) or state when this projection is the wrong choice.

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

project_savvly_monthlyProject Savvly Monthly ContributionsA
Read-onlyIdempotent
Inspect

Retirement projection for monthly contributions to the Savvly Longevity Benefit over a number of years. Returns payout amounts at milestone ages 80/85/90/95 with Savvly vs market alone cumulative totals, per-age breakdowns, a _central estimate and the _lower/_upper range around it. Use _central as the single estimate and _lower/_upper to show the range. Suitable for retirement savings planning, annuity alternative comparison, and longevity benefit illustration. Supports an optional annual contribution increase and an optional early-withdrawal age. Contributions must finish by age 80: an omitted contribution_years auto-fits this, and an explicit one must satisfy current_age + contribution_years ≤ 80. Disclaimers + per-field hints under metadata. Payout methodology — Savvly vs market alone: the payout values are calculated by comparing two investors of the same age committing the same principal. Investor 1 invests in the market with the Savvly Longevity Benefit; Investor 2 invests in the market alone (no longevity overlay). To make the comparison apples-to-apples, at each milestone age (80, 85, 90, 95) Investor 2 withdraws from their market alone portfolio the same dollar amount as the central estimate of Investor 1's Savvly payout. The payout_market_alone_* and total_market_alone_* figures are therefore what Investor 2 can actually withdraw to match Savvly's central payouts before running out — they fall to 0 once the market alone portfolio is depleted. It is one series, so their _lower and _upper fields are equal. The savvly_upside_* (and total_savvly_upside_*) fields quantify how much more total money Investor 1 receives in payouts from Savvly than Investor 2 is able to withdraw over time to match those payouts: _central is the single estimate, and _lower can be negative at the early milestones, where market alone still matches the central payout. DISCLOSURE REQUIRED: display disclosure.text verbatim and link disclosure.url to the user alongside any figures from this response. Required by SEC Marketing Rule and FINRA Rule 2210 — do not paraphrase or omit. VISUALIZATION: this tool emits an interactive chart widget (MCP Apps — see _meta.ui) that the HOST renders inline and editable; other clients render only your text and show no chart. That widget is the canonical chart for these numbers: do NOT draw, generate, or re-render a duplicate of it. You MAY still create your OWN, DIFFERENT visualization (e.g. a table or an alternate breakdown) and place it wherever you judge best — only the MCP App widget's position is constrained. Do NOT claim or imply a chart is visible (avoid 'the chart above shows…'); you cannot tell whether the host rendered the widget. Summarize the key figures in prose and show the disclosure text and link, and reference the widget only conditionally (e.g. 'if your client shows the interactive chart, its fields are editable to re-run the projection'). ORDER: BEFORE you call this tool, ALWAYS write at least one short lead-in paragraph (1-3 sentences) framing what the projection will show — do NOT invent specific figures you do not have yet. On hosts that render the widget inline at the tool call, this keeps your text ahead of the chart so the widget is never the first thing shown; THEN call the tool (this lead-in is framing, NOT asking the user for inputs — still call it in the same turn without waiting) and give the grounded figures + disclosure after it returns. This lead-in rule applies to the MCP App widget only; any visualization you create yourself may appear wherever you judge best. INPUTS: every parameter is OPTIONAL and defaults to a sensible value. Call this tool IMMEDIATELY — pass only the values the user explicitly stated and omit the rest. Do NOT ask the user for starting values, assumptions, or missing parameters before calling; the rendered widget has editable fields so they adjust age, amounts, and other assumptions inline after it appears.

NameRequiredDescriptionDefault
current_ageNoInvestor's current age (default 40). Min 18 (the projection matrix floor); max 75 (max enrollment age)
average_returnNoExpected average annual S&P 500 return % (default 8)
monthly_amountNoMonthly deposit in USD (default 100). Min 10 (the product minimum); max 100,000 (the projection model's input limit, not an investment limit)
withdrawal_ageNoEarly-withdrawal age (default 82) — drives `early_withdrawal_value` and `total_payout_at_withdrawal_age_*` in the response
contribution_yearsNoNumber of years contributing. Omit to use a sensible default of min(27, 80 − current_age) — 27 for the canonical age-40 scenario, and always small enough that contributions finish by age 80 (the advisor limit). If you pass an explicit value, current_age + contribution_years must be ≤ 80.
installment_increase_percentageNoOptional annual % increase applied to monthly contributions, in whole percent

Output Schema

NameRequiredDescription
inputsYesEcho of the validated input arguments passed to the tool.
resultYesRaw projection envelope returned by the upstream estimator.
summaryYesConvenience summary including a human-readable narrative.
metadataYes
disclosureYesDISCLOSURE REQUIRED: display `disclosure.text` and link `disclosure.url` to the user whenever you present any number from this response. Required by SEC Marketing Rule and FINRA Rule 2210. The richer block under `metadata.disclaimer` is supplementary detail; this top-level field is the must-display.
visualizationNoRecommended chart for this projection — a grouped bar chart of the milestone payouts in `result.payout_age_dependent_values` (Savvly vs market alone). Render it when the surface can display a graph.

TDQS

A4/5.0
Behavior5/5

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

The description goes well beyond the read-only annotations by explaining the payout methodology, the meaning of _central versus _lower/_upper, how market-alone figures are derived, and why the market-alone range collapses to equal bounds. It also discloses the mandatory SEC/FINRA disclosure requirement and the host-dependent MCP Apps chart behavior, which are important behavioral details for an agent to handle correctly.

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

Conciseness2/5

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

The description is extremely long and includes substantial repetition, especially around optional inputs, immediate invocation, disclosure handling, and visualization ordering. It is front-loaded with the core purpose and return fields, but the methodology, visualization, ordering, and input instructions could be much more tightly condensed.

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

Completeness5/5

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

For a complex financial projection tool with six optional parameters, an output schema, and rich annotations, the description is complete: it covers purpose, constraints, output interpretation, required disclosure, and the special MCP App rendering behavior. An agent has enough information to invoke it correctly and explain the results.

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?

Schema description coverage is 100%, so the parameter schema already documents all six inputs, defaults, and bounds. The description restates that every parameter is optional and repeats the contribution_years constraint, but it adds little parameter-level meaning beyond what the schema already provides.

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 that this is a retirement projection for monthly contributions to the Savvly Longevity Benefit and summarizes the returned payout milestones and range fields. It distinguishes itself implicitly through 'monthly contributions,' but it does not explicitly name or contrast with sibling projection tools such as project_savvly_lumpsum or project_retirement_with_savvly.

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

Usage Guidelines4/5

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

It gives clear usage context ('retirement savings planning, annuity alternative comparison, and longevity benefit illustration') and strong invocation guidance: every parameter is optional, omit unspecified values, and call immediately without asking for inputs. It does not state when not to use it or explicitly compare it against the sibling projection tools.

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

search_savvly_contentSearch Savvly Q&A Content LibraryA
Read-onlyIdempotent
Inspect

Search the Savvly Q&A Content Library — audience-tagged questions and answers compiled from Savvly's marketing collateral plus the factual FAQ, organized by stakeholder (employee, advisor, broker, employer, universal, general) and section (kebab-case slugs, e.g. 'tax-legacy', 'retention-talent-strategy', 'implementation'). Use this when the user asks about Savvly's positioning, value props, audience-specific talking points, or Q&A-style messaging. Each entry carries the verbatim answer plus any disclaimer footnotes attached to it in the source. These facts come from Savvly's own current records; the response includes primary sources (e.g. SEC filings) for reference.

NameRequiredDescriptionDefault
limitNoCap on matched entries returned. Default 20, max 50.
queryNoFree-text search over questions, answers, and footnotes (case-insensitive). Multi-word queries match entries containing ANY of the words, ranked by relevance.
sectionNoSubstring match against section slugs (e.g. 'tax', 'retention', 'eligibility'). Case-insensitive.
audienceNoRestrict to one stakeholder audience. Use EXACTLY one of: 'employee', 'advisor', 'broker', 'employer', 'universal', or 'general' ('general' is the factual FAQ). Omit to search across all audiences.

Output Schema

NameRequiredDescription
entriesYesMatched Q&A entries.
matchedYesCount of entries matching the supplied filters.
filter_appliedYesEcho of the filters that produced this result set.
total_in_libraryYesTotal Q&A entry count in the library across all audiences.
available_sectionsYesSection slugs available within the (optionally) selected audience.

TDQS

A4/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, non-destructive, closed-world, so the safety profile is covered. The description adds genuinely new behavioral context: each entry carries the verbatim answer with disclaimer footnotes, and responses include primary sources such as SEC filings. It doesn't contradict any annotation.

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?

Front-loads what the library is, then when to use it, then what an entry contains. It is somewhat dense with parentheticals (audience list, slug examples), but every sentence carries information and none is filler.

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

Completeness5/5

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

With an output schema present, return shape needn't be explained, and the description still covers provenance, entry contents, and the presence of source citations. An agent has enough to call it correctly and interpret results.

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?

Schema description coverage is 100%, so all four parameters including the audience enum and section substring matching are fully documented in the schema. The description restates the audience list and gives kebab-case section slug examples, which is helpful color but largely duplicative of structured fields, so baseline 3 applies.

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?

States a specific verb and resource (search the Savvly Q&A Content Library) and describes the corpus composition and its two organizing axes (audience and section). It doesn't explicitly distinguish itself from close siblings like get_savvly_faq, and in fact mentions 'the factual FAQ' as part of this library, which could cause some ambiguity about where FAQ content lives.

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

Usage Guidelines4/5

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

Gives a concrete trigger: use it for questions about Savvly's positioning, value props, audience-specific talking points, or Q&A-style messaging. That is clear situational guidance, but there are no explicit exclusions or named alternatives for overlapping needs (e.g. FAQ lookups vs. this library).

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv1.0.102
    • Changedproject_retirement_with_savvly1 field changed
      • changedOutput schema / properties / metadata / properties / disclaimer / properties / assumptions / description
        Previous value: -"Verbatim bullet list of key assumptions used by the simulation (SSA tables, 8% market growth, 3% early-withdrawal rate, net of fund operating expenses, etc.). Surface when a user asks what the projection assumes."New value: +"Verbatim bullet list of key assumptions used by the simulation (SSA tables, 8% market growth, 0.2% annual early-withdrawal rate, net of fund operating expenses, etc.). Surface when a user asks what the projection assumes."
    • Changedproject_savvly_lumpsum15 fields changed
      • changedOutput schema / properties / metadata / properties / disclaimer / properties / assumptions / description
        Previous value: -"Verbatim bullet list of key assumptions used by the simulation (SSA tables, 8% market growth, 3% early-withdrawal rate, net of fund operating expenses, etc.). Surface when a user asks what the projection assumes."New value: +"Verbatim bullet list of key assumptions used by the simulation (SSA tables, 8% market growth, 0.2% annual early-withdrawal rate, net of fund operating expenses, etc.). Surface when a user asks what the projection assumes."
      • removedOutput schema / properties / summary / properties / early_exit_refund_usd / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / summary / properties / early_exit_refund_usd / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / summary / properties / percentage_gain_upper_percent / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / summary / properties / percentage_gain_upper_percent / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / summary / properties / savvly_above_market_central_usd / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / summary / properties / savvly_above_market_central_usd / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / summary / properties / savvly_above_market_upper_usd / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / summary / properties / savvly_above_market_upper_usd / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / summary / properties / total_market_alone_upper_usd / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / summary / properties / total_market_alone_upper_usd / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / summary / properties / total_savvly_central_usd / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / summary / properties / total_savvly_central_usd / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / summary / properties / total_savvly_upper_usd / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / summary / properties / total_savvly_upper_usd / type
        Added value: +[
        +  "number",
        +  "null"
        +]
    • Changedproject_savvly_monthly15 fields changed
      • changedOutput schema / properties / metadata / properties / disclaimer / properties / assumptions / description
        Previous value: -"Verbatim bullet list of key assumptions used by the simulation (SSA tables, 8% market growth, 3% early-withdrawal rate, net of fund operating expenses, etc.). Surface when a user asks what the projection assumes."New value: +"Verbatim bullet list of key assumptions used by the simulation (SSA tables, 8% market growth, 0.2% annual early-withdrawal rate, net of fund operating expenses, etc.). Surface when a user asks what the projection assumes."
      • removedOutput schema / properties / summary / properties / early_exit_refund_usd / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / summary / properties / early_exit_refund_usd / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / summary / properties / percentage_gain_upper_percent / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / summary / properties / percentage_gain_upper_percent / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / summary / properties / savvly_above_market_central_usd / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / summary / properties / savvly_above_market_central_usd / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / summary / properties / savvly_above_market_upper_usd / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / summary / properties / savvly_above_market_upper_usd / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / summary / properties / total_market_alone_upper_usd / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / summary / properties / total_market_alone_upper_usd / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / summary / properties / total_savvly_central_usd / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / summary / properties / total_savvly_central_usd / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / summary / properties / total_savvly_upper_usd / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / summary / properties / total_savvly_upper_usd / type
        Added value: +[
        +  "number",
        +  "null"
        +]
    • Changedsearch_savvly_content6 fields changed
      • removedOutput schema / properties / filter_applied / properties / audience / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / filter_applied / properties / audience / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / filter_applied / properties / query / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / filter_applied / properties / query / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / filter_applied / properties / section / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / filter_applied / properties / section / type
        Added value: +[
        +  "string",
        +  "null"
        +]
  2. 2 tool updatesv1.0.98
    • Changedproject_savvly_lumpsum25 fields changed
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / description
        Previous value: -"Per-milestone-age breakdown of the projection. Typically 4 rows for ages 80, 85, 90, 95. Each row contains the with Savvly payout, the market alone counterfactual, and the incremental Savvly upside for that age, each with `_lower`/`_upper` bounds."New value: +"Per-milestone-age breakdown of the projection. Typically 4 rows for ages 80, 85, 90, 95. Each row contains the with Savvly payout, the market alone counterfactual, and the incremental Savvly upside for that age, with a `_central` estimate and its `_lower`/`_upper` range."
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_market_alone_lower / description
        Previous value: -"USD. Market alone counterfactual paired with savvly_payout_LOWER — the same scenario, not a low bound. It can exceed payout_market_alone_upper, because smaller Savvly payouts draw the mirrored portfolio down more slowly. May be 0 once that portfolio has been fully drawn down."New value: +"USD. Market alone counterfactual at this age: a portfolio that withdraws the central Savvly payout at each milestone. One series, so it equals payout_market_alone_upper. May be 0 once that portfolio is depleted."
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_market_alone_upper / description
        Previous value: -"USD. Market alone counterfactual paired with savvly_payout_UPPER — the same scenario, not a high bound. May be 0 once the mirrored portfolio has been depleted."New value: +"USD. Market alone counterfactual at this age; equals payout_market_alone_lower. May be 0 once the portfolio is depleted."
      • addedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / savvly_payout_central
        Added value: +{
        +  "description": "USD. Central estimate of the payout with Savvly at this milestone age. Use this when surfacing a single number.",
        +  "type": "number"
        +}
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / savvly_payout_lower / description
        Previous value: -"USD. Lower bound of the modeled payout with Savvly at this milestone age."New value: +"USD. Low end of the range around savvly_payout_central at this milestone age."
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / savvly_payout_upper / description
        Previous value: -"USD. Upper bound (central illustrative estimate) of the payout with Savvly at this milestone age. Use this when surfacing a single number."New value: +"USD. High end of the range around savvly_payout_central at this milestone age. Not the central estimate."
      • addedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / savvly_upside_central
        Added value: +{
        +  "description": "USD. Incremental payout at this age attributable to Savvly's longevity benefit: savvly_payout_central − payout_market_alone_upper. About 0 at the early ages, where market alone still matches the payout; large at 90/95, once market alone is depleted.",
        +  "type": "number"
        +}
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / savvly_upside_lower / description
        Previous value: -"USD. Lower bound for the incremental payout at this age attributable to Savvly's longevity benefit (savvly_payout − payout_market_alone)."New value: +"USD. savvly_payout_lower − market alone. Negative at the early ages, where market alone matches the central payout."
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / savvly_upside_upper / description
        Previous value: -"USD. Upper bound for the incremental Savvly upside at this age. Tends to be large at 90/95 where the market alone portfolio is depleted."New value: +"USD. savvly_payout_upper − market alone."
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / items / required
        Previous value: -[
        -  "payout_age",
        -  "savvly_payout_lower",
        -  "savvly_payout_upper",
        -  "payout_market_alone_lower",
        -  "payout_market_alone_upper",
        -  "savvly_upside_lower",
        -  "savvly_upside_upper"
        -]New value: +[
        +  "payout_age",
        +  "savvly_payout_central",
        +  "savvly_payout_lower",
        +  "savvly_payout_upper",
        +  "payout_market_alone_lower",
        +  "payout_market_alone_upper",
        +  "savvly_upside_central",
        +  "savvly_upside_lower",
        +  "savvly_upside_upper"
        +]
      • changedOutput schema / properties / result / properties / total_market_alone_lower / description
        Previous value: -"USD. Lower bound of the cumulative counterfactual market alone payout."New value: +"USD. Cumulative market alone counterfactual. One series, matched to the central Savvly payouts, so it equals total_market_alone_upper."
      • changedOutput schema / properties / result / properties / total_market_alone_upper / description
        Previous value: -"USD. Upper bound of the cumulative counterfactual market alone payout."New value: +"USD. Cumulative market alone counterfactual; equals total_market_alone_lower."
      • addedOutput schema / properties / result / properties / total_savvly_central
        Added value: +{
        +  "description": "USD. Central estimate of the total cumulative payout with Savvly across all milestone ages, assuming the investor stays in to the final modeled age. Use this when surfacing a single number.",
        +  "type": "number"
        +}
      • changedOutput schema / properties / result / properties / total_savvly_lower / description
        Previous value: -"USD. Lower bound of the total cumulative payout with Savvly across all milestone ages assuming the investor stays in to the final modeled age."New value: +"USD. Low end of the range around total_savvly_central."
      • changedOutput schema / properties / result / properties / total_savvly_upper / description
        Previous value: -"USD. Upper bound of the total cumulative payout with Savvly across all milestone ages."New value: +"USD. High end of the range around total_savvly_central. Not the central estimate."
      • addedOutput schema / properties / result / properties / total_savvly_upside_central
        Added value: +{
        +  "description": "USD. Central estimate of the cumulative incremental upside Savvly provides vs. investing in the market alone, summed across all milestone payout ages: `total_savvly_central − total_market_alone_upper`. Use this when surfacing a single number.",
        +  "type": "number"
        +}
      • changedOutput schema / properties / result / properties / total_savvly_upside_lower / description
        Previous value: -"USD. Lower bound of the cumulative incremental upside Savvly provides vs. investing in the market alone, summed across all milestone payout ages."New value: +"USD. `total_savvly_lower − total_market_alone_lower`: the cumulative upside at the low end of the range."
      • changedOutput schema / properties / result / properties / total_savvly_upside_upper / description
        Previous value: -"USD. Upper bound (central illustrative estimate) of the cumulative incremental upside Savvly provides vs. market alone. Equals `total_savvly_upper − total_market_alone_upper`."New value: +"USD. `total_savvly_upper − total_market_alone_upper`: the cumulative upside at the high end of the range. Not the central estimate."
      • changedOutput schema / properties / result / required
        Previous value: -[
        -  "total_savvly_upside_lower",
        -  "total_savvly_upside_upper",
        -  "total_savvly_lower",
        -  "total_savvly_upper",
        -  "total_market_alone_lower",
        -  "total_market_alone_upper",
        -  "early_withdrawal_value",
        -  "total_payout_at_withdrawal_age_lower",
        -  "total_payout_at_withdrawal_age_upper",
        -  "percentage_gain_lower",
        -  "percentage_gain_upper",
        -  "payout_age_dependent_values"
        -]New value: +[
        +  "total_savvly_upside_central",
        +  "total_savvly_upside_lower",
        +  "total_savvly_upside_upper",
        +  "total_savvly_central",
        +  "total_savvly_lower",
        +  "total_savvly_upper",
        +  "total_market_alone_lower",
        +  "total_market_alone_upper",
        +  "early_withdrawal_value",
        +  "total_payout_at_withdrawal_age_lower",
        +  "total_payout_at_withdrawal_age_upper",
        +  "percentage_gain_lower",
        +  "percentage_gain_upper",
        +  "payout_age_dependent_values"
        +]
      • changedOutput schema / properties / summary / properties / deposited_amount_usd / description
        Previous value: -"USD. Total amount deposited into Savvly. For single deposits this equals `funding_amount`. For monthly installments it equals `monthly_installment * installment_years * 12`."New value: +"USD. Total amount deposited into Savvly. For single deposits this equals `funding_amount`. For monthly installments it equals `monthly_amount * contribution_years * 12`."
      • addedOutput schema / properties / summary / properties / savvly_above_market_central_usd
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "number"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "USD. `total_savvly_central − total_market_alone_upper`, the central incremental upside."
        +}
      • changedOutput schema / properties / summary / properties / savvly_above_market_upper_usd / description
        Previous value: -"USD. `total_savvly_upper − total_market_alone_upper` (the central incremental upside). May differ slightly from `result.total_savvly_upside_upper` due to rounding."New value: +"USD. `total_savvly_upper − total_market_alone_upper`, the incremental upside at the high end of the range. Not the central estimate."
      • addedOutput schema / properties / summary / properties / total_savvly_central_usd
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "number"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Convenience copy of `result.total_savvly_central`, the single estimate."
        +}
      • changedOutput schema / properties / summary / properties / total_savvly_upper_usd / description
        Previous value: -"Convenience copy of `result.total_savvly_upper`."New value: +"Convenience copy of `result.total_savvly_upper`, the high end of the range."
      • changedOutput schema / properties / summary / required
        Previous value: -[
        -  "deposit_type",
        -  "deposited_amount_usd",
        -  "total_savvly_upper_usd",
        -  "total_market_alone_upper_usd",
        -  "savvly_above_market_upper_usd",
        -  "early_exit_refund_usd",
        -  "percentage_gain_upper_percent",
        -  "narrative"
        -]New value: +[
        +  "deposit_type",
        +  "deposited_amount_usd",
        +  "total_savvly_central_usd",
        +  "total_savvly_upper_usd",
        +  "total_market_alone_upper_usd",
        +  "savvly_above_market_central_usd",
        +  "savvly_above_market_upper_usd",
        +  "early_exit_refund_usd",
        +  "percentage_gain_upper_percent",
        +  "narrative"
        +]
    • Changedproject_savvly_monthly26 fields changed
      • changedInput schema / properties / installment_increase_percentage / maximum
        Previous value: -20New value: +10
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / description
        Previous value: -"Per-milestone-age breakdown of the projection. Typically 4 rows for ages 80, 85, 90, 95. Each row contains the with Savvly payout, the market alone counterfactual, and the incremental Savvly upside for that age, each with `_lower`/`_upper` bounds."New value: +"Per-milestone-age breakdown of the projection. Typically 4 rows for ages 80, 85, 90, 95. Each row contains the with Savvly payout, the market alone counterfactual, and the incremental Savvly upside for that age, with a `_central` estimate and its `_lower`/`_upper` range."
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_market_alone_lower / description
        Previous value: -"USD. Market alone counterfactual paired with savvly_payout_LOWER — the same scenario, not a low bound. It can exceed payout_market_alone_upper, because smaller Savvly payouts draw the mirrored portfolio down more slowly. May be 0 once that portfolio has been fully drawn down."New value: +"USD. Market alone counterfactual at this age: a portfolio that withdraws the central Savvly payout at each milestone. One series, so it equals payout_market_alone_upper. May be 0 once that portfolio is depleted."
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_market_alone_upper / description
        Previous value: -"USD. Market alone counterfactual paired with savvly_payout_UPPER — the same scenario, not a high bound. May be 0 once the mirrored portfolio has been depleted."New value: +"USD. Market alone counterfactual at this age; equals payout_market_alone_lower. May be 0 once the portfolio is depleted."
      • addedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / savvly_payout_central
        Added value: +{
        +  "description": "USD. Central estimate of the payout with Savvly at this milestone age. Use this when surfacing a single number.",
        +  "type": "number"
        +}
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / savvly_payout_lower / description
        Previous value: -"USD. Lower bound of the modeled payout with Savvly at this milestone age."New value: +"USD. Low end of the range around savvly_payout_central at this milestone age."
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / savvly_payout_upper / description
        Previous value: -"USD. Upper bound (central illustrative estimate) of the payout with Savvly at this milestone age. Use this when surfacing a single number."New value: +"USD. High end of the range around savvly_payout_central at this milestone age. Not the central estimate."
      • addedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / savvly_upside_central
        Added value: +{
        +  "description": "USD. Incremental payout at this age attributable to Savvly's longevity benefit: savvly_payout_central − payout_market_alone_upper. About 0 at the early ages, where market alone still matches the payout; large at 90/95, once market alone is depleted.",
        +  "type": "number"
        +}
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / savvly_upside_lower / description
        Previous value: -"USD. Lower bound for the incremental payout at this age attributable to Savvly's longevity benefit (savvly_payout − payout_market_alone)."New value: +"USD. savvly_payout_lower − market alone. Negative at the early ages, where market alone matches the central payout."
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / savvly_upside_upper / description
        Previous value: -"USD. Upper bound for the incremental Savvly upside at this age. Tends to be large at 90/95 where the market alone portfolio is depleted."New value: +"USD. savvly_payout_upper − market alone."
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / items / required
        Previous value: -[
        -  "payout_age",
        -  "savvly_payout_lower",
        -  "savvly_payout_upper",
        -  "payout_market_alone_lower",
        -  "payout_market_alone_upper",
        -  "savvly_upside_lower",
        -  "savvly_upside_upper"
        -]New value: +[
        +  "payout_age",
        +  "savvly_payout_central",
        +  "savvly_payout_lower",
        +  "savvly_payout_upper",
        +  "payout_market_alone_lower",
        +  "payout_market_alone_upper",
        +  "savvly_upside_central",
        +  "savvly_upside_lower",
        +  "savvly_upside_upper"
        +]
      • changedOutput schema / properties / result / properties / total_market_alone_lower / description
        Previous value: -"USD. Lower bound of the cumulative counterfactual market alone payout."New value: +"USD. Cumulative market alone counterfactual. One series, matched to the central Savvly payouts, so it equals total_market_alone_upper."
      • changedOutput schema / properties / result / properties / total_market_alone_upper / description
        Previous value: -"USD. Upper bound of the cumulative counterfactual market alone payout."New value: +"USD. Cumulative market alone counterfactual; equals total_market_alone_lower."
      • addedOutput schema / properties / result / properties / total_savvly_central
        Added value: +{
        +  "description": "USD. Central estimate of the total cumulative payout with Savvly across all milestone ages, assuming the investor stays in to the final modeled age. Use this when surfacing a single number.",
        +  "type": "number"
        +}
      • changedOutput schema / properties / result / properties / total_savvly_lower / description
        Previous value: -"USD. Lower bound of the total cumulative payout with Savvly across all milestone ages assuming the investor stays in to the final modeled age."New value: +"USD. Low end of the range around total_savvly_central."
      • changedOutput schema / properties / result / properties / total_savvly_upper / description
        Previous value: -"USD. Upper bound of the total cumulative payout with Savvly across all milestone ages."New value: +"USD. High end of the range around total_savvly_central. Not the central estimate."
      • addedOutput schema / properties / result / properties / total_savvly_upside_central
        Added value: +{
        +  "description": "USD. Central estimate of the cumulative incremental upside Savvly provides vs. investing in the market alone, summed across all milestone payout ages: `total_savvly_central − total_market_alone_upper`. Use this when surfacing a single number.",
        +  "type": "number"
        +}
      • changedOutput schema / properties / result / properties / total_savvly_upside_lower / description
        Previous value: -"USD. Lower bound of the cumulative incremental upside Savvly provides vs. investing in the market alone, summed across all milestone payout ages."New value: +"USD. `total_savvly_lower − total_market_alone_lower`: the cumulative upside at the low end of the range."
      • changedOutput schema / properties / result / properties / total_savvly_upside_upper / description
        Previous value: -"USD. Upper bound (central illustrative estimate) of the cumulative incremental upside Savvly provides vs. market alone. Equals `total_savvly_upper − total_market_alone_upper`."New value: +"USD. `total_savvly_upper − total_market_alone_upper`: the cumulative upside at the high end of the range. Not the central estimate."
      • changedOutput schema / properties / result / required
        Previous value: -[
        -  "total_savvly_upside_lower",
        -  "total_savvly_upside_upper",
        -  "total_savvly_lower",
        -  "total_savvly_upper",
        -  "total_market_alone_lower",
        -  "total_market_alone_upper",
        -  "early_withdrawal_value",
        -  "total_payout_at_withdrawal_age_lower",
        -  "total_payout_at_withdrawal_age_upper",
        -  "percentage_gain_lower",
        -  "percentage_gain_upper",
        -  "payout_age_dependent_values"
        -]New value: +[
        +  "total_savvly_upside_central",
        +  "total_savvly_upside_lower",
        +  "total_savvly_upside_upper",
        +  "total_savvly_central",
        +  "total_savvly_lower",
        +  "total_savvly_upper",
        +  "total_market_alone_lower",
        +  "total_market_alone_upper",
        +  "early_withdrawal_value",
        +  "total_payout_at_withdrawal_age_lower",
        +  "total_payout_at_withdrawal_age_upper",
        +  "percentage_gain_lower",
        +  "percentage_gain_upper",
        +  "payout_age_dependent_values"
        +]
      • changedOutput schema / properties / summary / properties / deposited_amount_usd / description
        Previous value: -"USD. Total amount deposited into Savvly. For single deposits this equals `funding_amount`. For monthly installments it equals `monthly_installment * installment_years * 12`."New value: +"USD. Total amount deposited into Savvly. For single deposits this equals `funding_amount`. For monthly installments it equals `monthly_amount * contribution_years * 12`."
      • addedOutput schema / properties / summary / properties / savvly_above_market_central_usd
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "number"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "USD. `total_savvly_central − total_market_alone_upper`, the central incremental upside."
        +}
      • changedOutput schema / properties / summary / properties / savvly_above_market_upper_usd / description
        Previous value: -"USD. `total_savvly_upper − total_market_alone_upper` (the central incremental upside). May differ slightly from `result.total_savvly_upside_upper` due to rounding."New value: +"USD. `total_savvly_upper − total_market_alone_upper`, the incremental upside at the high end of the range. Not the central estimate."
      • addedOutput schema / properties / summary / properties / total_savvly_central_usd
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "number"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Convenience copy of `result.total_savvly_central`, the single estimate."
        +}
      • changedOutput schema / properties / summary / properties / total_savvly_upper_usd / description
        Previous value: -"Convenience copy of `result.total_savvly_upper`."New value: +"Convenience copy of `result.total_savvly_upper`, the high end of the range."
      • changedOutput schema / properties / summary / required
        Previous value: -[
        -  "deposit_type",
        -  "deposited_amount_usd",
        -  "total_savvly_upper_usd",
        -  "total_market_alone_upper_usd",
        -  "savvly_above_market_upper_usd",
        -  "early_exit_refund_usd",
        -  "percentage_gain_upper_percent",
        -  "narrative"
        -]New value: +[
        +  "deposit_type",
        +  "deposited_amount_usd",
        +  "total_savvly_central_usd",
        +  "total_savvly_upper_usd",
        +  "total_market_alone_upper_usd",
        +  "savvly_above_market_central_usd",
        +  "savvly_above_market_upper_usd",
        +  "early_exit_refund_usd",
        +  "percentage_gain_upper_percent",
        +  "narrative"
        +]
  3. 3 tool updatesv1.0.97
    • Changedproject_retirement_with_savvly11 fields changed
      • changedInput schema / properties / annual_income_increase / maximum
        Previous value: -20New value: +10
      • addedInput schema / properties / current_retirement_savings / maximum
        Added value: +100000000
      • addedInput schema / properties / inflation_rate / maximum
        Added value: +10
      • addedInput schema / properties / inflation_rate / minimum
        Added value: +0
      • addedInput schema / properties / monthly_contribution / maximum
        Added value: +100000
      • addedInput schema / properties / monthly_paycheck / maximum
        Added value: +1000000
      • addedInput schema / properties / other_retirement_income / maximum
        Added value: +1000000
      • addedInput schema / properties / post_retirement_return / maximum
        Added value: +15
      • addedInput schema / properties / post_retirement_return / minimum
        Added value: +0
      • addedInput schema / properties / pre_retirement_return / maximum
        Added value: +15
      • addedInput schema / properties / pre_retirement_return / minimum
        Added value: +0
    • Changedproject_savvly_lumpsum4 fields changed
      • changedInput schema / properties / average_return / minimum
        Previous value: -1New value: +2
      • changedInput schema / properties / funding_amount / description
        Previous value: -"Lump sum investment in USD (default 10000)"New value: +"Lump sum investment in USD (default 10000). Min 100 (the product minimum); max 1,000,000 (the projection model's input limit, not an investment limit)"
      • addedInput schema / properties / funding_amount / maximum
        Added value: +1000000
      • changedInput schema / properties / withdrawal_age / maximum
        Previous value: -120New value: +100
    • Changedproject_savvly_monthly7 fields changed
      • changedInput schema / properties / average_return / minimum
        Previous value: -1New value: +2
      • changedInput schema / properties / contribution_years / maximum
        Previous value: -55New value: +50
      • changedInput schema / properties / installment_increase_percentage / description
        Previous value: -"Optional annual % increase applied to monthly contributions"New value: +"Optional annual % increase applied to monthly contributions, in whole percent"
      • changedInput schema / properties / installment_increase_percentage / type
        Previous value: -"number"New value: +"integer"
      • changedInput schema / properties / monthly_amount / description
        Previous value: -"Monthly deposit in USD (default 100)"New value: +"Monthly deposit in USD (default 100). Min 10 (the product minimum); max 100,000 (the projection model's input limit, not an investment limit)"
      • addedInput schema / properties / monthly_amount / maximum
        Added value: +100000
      • changedInput schema / properties / withdrawal_age / maximum
        Previous value: -120New value: +100
  4. 2 tool updatesv1.0.93
    • Changedproject_savvly_lumpsum2 fields changed
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_market_alone_lower / description
        Previous value: -"USD. Lower bound of the counterfactual market alone payout at this age. May be 0 once the modeled market alone portfolio has been fully drawn down by withdrawals."New value: +"USD. Market alone counterfactual paired with savvly_payout_LOWER — the same scenario, not a low bound. It can exceed payout_market_alone_upper, because smaller Savvly payouts draw the mirrored portfolio down more slowly. May be 0 once that portfolio has been fully drawn down."
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_market_alone_upper / description
        Previous value: -"USD. Upper bound of the counterfactual market alone payout at this age. May be 0 once the market alone portfolio has been depleted."New value: +"USD. Market alone counterfactual paired with savvly_payout_UPPER — the same scenario, not a high bound. May be 0 once the mirrored portfolio has been depleted."
    • Changedproject_savvly_monthly2 fields changed
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_market_alone_lower / description
        Previous value: -"USD. Lower bound of the counterfactual market alone payout at this age. May be 0 once the modeled market alone portfolio has been fully drawn down by withdrawals."New value: +"USD. Market alone counterfactual paired with savvly_payout_LOWER — the same scenario, not a low bound. It can exceed payout_market_alone_upper, because smaller Savvly payouts draw the mirrored portfolio down more slowly. May be 0 once that portfolio has been fully drawn down."
      • changedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_market_alone_upper / description
        Previous value: -"USD. Upper bound of the counterfactual market alone payout at this age. May be 0 once the market alone portfolio has been depleted."New value: +"USD. Market alone counterfactual paired with savvly_payout_UPPER — the same scenario, not a high bound. May be 0 once the mirrored portfolio has been depleted."
  5. 8 tool updatesv1.0.92
    • Changedcheck_savvly_eligibility5 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / age / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / age / minimum
        Added value: +-9007199254740991
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedcompare_savvly_vs_alternative103 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / alternative / default
        Added value: +"all"
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedOutput schema / properties / comparison / properties / dimensions / properties / affordability / $ref
        Removed value: -"#/properties/savvly/properties/affordability"
      • addedOutput schema / properties / comparison / properties / dimensions / properties / affordability / additionalProperties
        Added value: +true
      • addedOutput schema / properties / comparison / properties / dimensions / properties / affordability / properties
        Added value: +{
        +  "explanation": {
        +    "description": "One-sentence rationale for the rating.",
        +    "type": "string"
        +  },
        +  "label": {
        +    "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +    "type": "string"
        +  },
        +  "score": {
        +    "description": "Numeric rating; greater = better (e.g. 1–5).",
        +    "type": "number"
        +  }
        +}
      • addedOutput schema / properties / comparison / properties / dimensions / properties / affordability / required
        Added value: +[
        +  "score",
        +  "label",
        +  "explanation"
        +]
      • addedOutput schema / properties / comparison / properties / dimensions / properties / affordability / type
        Added value: +"object"
      • removedOutput schema / properties / comparison / properties / dimensions / properties / cost_to_value / $ref
        Removed value: -"#/properties/savvly/properties/cost_to_value"
      • addedOutput schema / properties / comparison / properties / dimensions / properties / cost_to_value / additionalProperties
        Added value: +true
      • addedOutput schema / properties / comparison / properties / dimensions / properties / cost_to_value / properties
        Added value: +{
        +  "explanation": {
        +    "description": "One-sentence rationale for the rating.",
        +    "type": "string"
        +  },
        +  "label": {
        +    "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +    "type": "string"
        +  },
        +  "score": {
        +    "description": "Numeric rating; greater = better (e.g. 1–5).",
        +    "type": "number"
        +  }
        +}
      • addedOutput schema / properties / comparison / properties / dimensions / properties / cost_to_value / required
        Added value: +[
        +  "score",
        +  "label",
        +  "explanation"
        +]
      • addedOutput schema / properties / comparison / properties / dimensions / properties / cost_to_value / type
        Added value: +"object"
      • removedOutput schema / properties / comparison / properties / dimensions / properties / counterparty_safety / $ref
        Removed value: -"#/properties/savvly/properties/counterparty_safety"
      • addedOutput schema / properties / comparison / properties / dimensions / properties / counterparty_safety / additionalProperties
        Added value: +true
      • addedOutput schema / properties / comparison / properties / dimensions / properties / counterparty_safety / properties
        Added value: +{
        +  "explanation": {
        +    "description": "One-sentence rationale for the rating.",
        +    "type": "string"
        +  },
        +  "label": {
        +    "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +    "type": "string"
        +  },
        +  "score": {
        +    "description": "Numeric rating; greater = better (e.g. 1–5).",
        +    "type": "number"
        +  }
        +}
      • addedOutput schema / properties / comparison / properties / dimensions / properties / counterparty_safety / required
        Added value: +[
        +  "score",
        +  "label",
        +  "explanation"
        +]
      • addedOutput schema / properties / comparison / properties / dimensions / properties / counterparty_safety / type
        Added value: +"object"
      • removedOutput schema / properties / comparison / properties / dimensions / properties / death_benefit / $ref
        Removed value: -"#/properties/savvly/properties/death_benefit"
      • addedOutput schema / properties / comparison / properties / dimensions / properties / death_benefit / description
        Added value: +"Death-benefit summary."
      • addedOutput schema / properties / comparison / properties / dimensions / properties / death_benefit / type
        Added value: +"string"
      • removedOutput schema / properties / comparison / properties / dimensions / properties / inflation_protection / $ref
        Removed value: -"#/properties/savvly/properties/inflation_protection"
      • addedOutput schema / properties / comparison / properties / dimensions / properties / inflation_protection / additionalProperties
        Added value: +true
      • addedOutput schema / properties / comparison / properties / dimensions / properties / inflation_protection / properties
        Added value: +{
        +  "explanation": {
        +    "description": "One-sentence rationale for the rating.",
        +    "type": "string"
        +  },
        +  "label": {
        +    "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +    "type": "string"
        +  },
        +  "score": {
        +    "description": "Numeric rating; greater = better (e.g. 1–5).",
        +    "type": "number"
        +  }
        +}
      • addedOutput schema / properties / comparison / properties / dimensions / properties / inflation_protection / required
        Added value: +[
        +  "score",
        +  "label",
        +  "explanation"
        +]
      • addedOutput schema / properties / comparison / properties / dimensions / properties / inflation_protection / type
        Added value: +"object"
      • removedOutput schema / properties / comparison / properties / dimensions / properties / liquidity / $ref
        Removed value: -"#/properties/savvly/properties/liquidity"
      • addedOutput schema / properties / comparison / properties / dimensions / properties / liquidity / additionalProperties
        Added value: +true
      • addedOutput schema / properties / comparison / properties / dimensions / properties / liquidity / properties
        Added value: +{
        +  "explanation": {
        +    "description": "One-sentence rationale for the rating.",
        +    "type": "string"
        +  },
        +  "label": {
        +    "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +    "type": "string"
        +  },
        +  "score": {
        +    "description": "Numeric rating; greater = better (e.g. 1–5).",
        +    "type": "number"
        +  }
        +}
      • addedOutput schema / properties / comparison / properties / dimensions / properties / liquidity / required
        Added value: +[
        +  "score",
        +  "label",
        +  "explanation"
        +]
      • addedOutput schema / properties / comparison / properties / dimensions / properties / liquidity / type
        Added value: +"object"
      • removedOutput schema / properties / comparison / properties / dimensions / properties / longevity_protection / $ref
        Removed value: -"#/properties/savvly/properties/longevity_protection"
      • addedOutput schema / properties / comparison / properties / dimensions / properties / longevity_protection / additionalProperties
        Added value: +true
      • addedOutput schema / properties / comparison / properties / dimensions / properties / longevity_protection / properties
        Added value: +{
        +  "explanation": {
        +    "description": "One-sentence rationale for the rating.",
        +    "type": "string"
        +  },
        +  "label": {
        +    "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +    "type": "string"
        +  },
        +  "score": {
        +    "description": "Numeric rating; greater = better (e.g. 1–5).",
        +    "type": "number"
        +  }
        +}
      • addedOutput schema / properties / comparison / properties / dimensions / properties / longevity_protection / required
        Added value: +[
        +  "score",
        +  "label",
        +  "explanation"
        +]
      • addedOutput schema / properties / comparison / properties / dimensions / properties / longevity_protection / type
        Added value: +"object"
      • removedOutput schema / properties / comparison / properties / dimensions / properties / market_upside / $ref
        Removed value: -"#/properties/savvly/properties/market_upside"
      • addedOutput schema / properties / comparison / properties / dimensions / properties / market_upside / additionalProperties
        Added value: +true
      • addedOutput schema / properties / comparison / properties / dimensions / properties / market_upside / properties
        Added value: +{
        +  "explanation": {
        +    "description": "One-sentence rationale for the rating.",
        +    "type": "string"
        +  },
        +  "label": {
        +    "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +    "type": "string"
        +  },
        +  "score": {
        +    "description": "Numeric rating; greater = better (e.g. 1–5).",
        +    "type": "number"
        +  }
        +}
      • addedOutput schema / properties / comparison / properties / dimensions / properties / market_upside / required
        Added value: +[
        +  "score",
        +  "label",
        +  "explanation"
        +]
      • addedOutput schema / properties / comparison / properties / dimensions / properties / market_upside / type
        Added value: +"object"
      • removedOutput schema / properties / comparison / properties / dimensions / properties / portability / $ref
        Removed value: -"#/properties/savvly/properties/portability"
      • addedOutput schema / properties / comparison / properties / dimensions / properties / portability / additionalProperties
        Added value: +true
      • addedOutput schema / properties / comparison / properties / dimensions / properties / portability / properties
        Added value: +{
        +  "explanation": {
        +    "description": "One-sentence rationale for the rating.",
        +    "type": "string"
        +  },
        +  "label": {
        +    "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +    "type": "string"
        +  },
        +  "score": {
        +    "description": "Numeric rating; greater = better (e.g. 1–5).",
        +    "type": "number"
        +  }
        +}
      • addedOutput schema / properties / comparison / properties / dimensions / properties / portability / required
        Added value: +[
        +  "score",
        +  "label",
        +  "explanation"
        +]
      • addedOutput schema / properties / comparison / properties / dimensions / properties / portability / type
        Added value: +"object"
      • removedOutput schema / properties / comparison / properties / dimensions / properties / regulatory_oversight / $ref
        Removed value: -"#/properties/savvly/properties/regulatory_oversight"
      • addedOutput schema / properties / comparison / properties / dimensions / properties / regulatory_oversight / description
        Added value: +"Who regulates it (e.g. SEC vs state insurance)."
      • addedOutput schema / properties / comparison / properties / dimensions / properties / regulatory_oversight / type
        Added value: +"string"
      • removedOutput schema / properties / comparison / properties / dimensions / properties / simplicity / $ref
        Removed value: -"#/properties/savvly/properties/simplicity"
      • addedOutput schema / properties / comparison / properties / dimensions / properties / simplicity / additionalProperties
        Added value: +true
      • addedOutput schema / properties / comparison / properties / dimensions / properties / simplicity / properties
        Added value: +{
        +  "explanation": {
        +    "description": "One-sentence rationale for the rating.",
        +    "type": "string"
        +  },
        +  "label": {
        +    "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +    "type": "string"
        +  },
        +  "score": {
        +    "description": "Numeric rating; greater = better (e.g. 1–5).",
        +    "type": "number"
        +  }
        +}
      • addedOutput schema / properties / comparison / properties / dimensions / properties / simplicity / required
        Added value: +[
        +  "score",
        +  "label",
        +  "explanation"
        +]
      • addedOutput schema / properties / comparison / properties / dimensions / properties / simplicity / type
        Added value: +"object"
      • removedOutput schema / properties / comparison / properties / dimensions / properties / tax_treatment / $ref
        Removed value: -"#/properties/savvly/properties/tax_treatment"
      • addedOutput schema / properties / comparison / properties / dimensions / properties / tax_treatment / description
        Added value: +"Tax-treatment summary."
      • addedOutput schema / properties / comparison / properties / dimensions / properties / tax_treatment / type
        Added value: +"string"
      • removedOutput schema / properties / comparisons / items / $ref
        Removed value: -"#/properties/comparison"
      • addedOutput schema / properties / comparisons / items / additionalProperties
        Added value: +true
      • addedOutput schema / properties / comparisons / items / properties
        Added value: +{
        +  "category": {
        +    "description": "Product category.",
        +    "type": "string"
        +  },
        +  "description": {
        +    "description": "Short description of the alternative.",
        +    "type": "string"
        +  },
        +  "dimensions": {
        +    "additionalProperties": true,
        +    "description": "This alternative's ratings across the dimensions.",
        +    "properties": {
        +      "affordability": {
        +        "additionalProperties": true,
        +        "properties": {
        +          "explanation": {
        +            "description": "One-sentence rationale for the rating.",
        +            "type": "string"
        +          },
        +          "label": {
        +            "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +            "type": "string"
        +          },
        +          "score": {
        +            "description": "Numeric rating; greater = better (e.g. 1–5).",
        +            "type": "number"
        +          }
        +        },
        +        "required": [
        +          "score",
        +          "label",
        +          "explanation"
        +        ],
        +        "type": "object"
        +      },
        +      "cost_to_value": {
        +        "additionalProperties": true,
        +        "properties": {
        +          "explanation": {
        +            "description": "One-sentence rationale for the rating.",
        +            "type": "string"
        +          },
        +          "label": {
        +            "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +            "type": "string"
        +          },
        +          "score": {
        +            "description": "Numeric rating; greater = better (e.g. 1–5).",
        +            "type": "number"
        +          }
        +        },
        +        "required": [
        +          "score",
        +          "label",
        +          "explanation"
        +        ],
        +        "type": "object"
        +      },
        +      "counterparty_safety": {
        +        "additionalProperties": true,
        +        "properties": {
        +          "explanation": {
        +            "description": "One-sentence rationale for the rating.",
        +            "type": "string"
        +          },
        +          "label": {
        +            "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +            "type": "string"
        +          },
        +          "score": {
        +            "description": "Numeric rating; greater = better (e.g. 1–5).",
        +            "type": "number"
        +          }
        +        },
        +        "required": [
        +          "score",
        +          "label",
        +          "explanation"
        +        ],
        +        "type": "object"
        +      },
        +      "death_benefit": {
        +        "description": "Death-benefit summary.",
        +        "type": "string"
        +      },
        +      "inflation_protection": {
        +        "additionalProperties": true,
        +        "properties": {
        +          "explanation": {
        +            "description": "One-sentence rationale for the rating.",
        +            "type": "string"
        +          },
        +          "label": {
        +            "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +            "type": "string"
        +          },
        +          "score": {
        +            "description": "Numeric rating; greater = better (e.g. 1–5).",
        +            "type": "number"
        +          }
        +        },
        +        "required": [
        +          "score",
        +          "label",
        +          "explanation"
        +        ],
        +        "type": "object"
        +      },
        +      "liquidity": {
        +        "additionalProperties": true,
        +        "properties": {
        +          "explanation": {
        +            "description": "One-sentence rationale for the rating.",
        +            "type": "string"
        +          },
        +          "label": {
        +            "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +            "type": "string"
        +          },
        +          "score": {
        +            "description": "Numeric rating; greater = better (e.g. 1–5).",
        +            "type": "number"
        +          }
        +        },
        +        "required": [
        +          "score",
        +          "label",
        +          "explanation"
        +        ],
        +        "type": "object"
        +      },
        +      "longevity_protection": {
        +        "additionalProperties": true,
        +        "properties": {
        +          "explanation": {
        +            "description": "One-sentence rationale for the rating.",
        +            "type": "string"
        +          },
        +          "label": {
        +            "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +            "type": "string"
        +          },
        +          "score": {
        +            "description": "Numeric rating; greater = better (e.g. 1–5).",
        +            "type": "number"
        +          }
        +        },
        +        "required": [
        +          "score",
        +          "label",
        +          "explanation"
        +        ],
        +        "type": "object"
        +      },
        +      "market_upside": {
        +        "additionalProperties": true,
        +        "properties": {
        +          "explanation": {
        +            "description": "One-sentence rationale for the rating.",
        +            "type": "string"
        +          },
        +          "label": {
        +            "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +            "type": "string"
        +          },
        +          "score": {
        +            "description": "Numeric rating; greater = better (e.g. 1–5).",
        +            "type": "number"
        +          }
        +        },
        +        "required": [
        +          "score",
        +          "label",
        +          "explanation"
        +        ],
        +        "type": "object"
        +      },
        +      "portability": {
        +        "additionalProperties": true,
        +        "properties": {
        +          "explanation": {
        +            "description": "One-sentence rationale for the rating.",
        +            "type": "string"
        +          },
        +          "label": {
        +            "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +            "type": "string"
        +          },
        +          "score": {
        +            "description": "Numeric rating; greater = better (e.g. 1–5).",
        +            "type": "number"
        +          }
        +        },
        +        "required": [
        +          "score",
        +          "label",
        +          "explanation"
        +        ],
        +        "type": "object"
        +      },
        +      "regulatory_oversight": {
        +        "description": "Who regulates it (e.g. SEC vs state insurance).",
        +        "type": "string"
        +      },
        +      "simplicity": {
        +        "additionalProperties": true,
        +        "properties": {
        +          "explanation": {
        +            "description": "One-sentence rationale for the rating.",
        +            "type": "string"
        +          },
        +          "label": {
        +            "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +            "type": "string"
        +          },
        +          "score": {
        +            "description": "Numeric rating; greater = better (e.g. 1–5).",
        +            "type": "number"
        +          }
        +        },
        +        "required": [
        +          "score",
        +          "label",
        +          "explanation"
        +        ],
        +        "type": "object"
        +      },
        +      "tax_treatment": {
        +        "description": "Tax-treatment summary.",
        +        "type": "string"
        +      }
        +    },
        +    "type": "object"
        +  },
        +  "display_name": {
        +    "description": "Human-readable product name.",
        +    "type": "string"
        +  },
        +  "product_type": {
        +    "description": "Alternative product slug, e.g. 'fixed_annuity'.",
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / comparisons / items / required
        Added value: +[
        +  "product_type"
        +]
      • addedOutput schema / properties / comparisons / items / type
        Added value: +"object"
      • removedOutput schema / properties / savvly / properties / affordability / $ref
        Removed value: -"#/properties/savvly/properties/longevity_protection"
      • addedOutput schema / properties / savvly / properties / affordability / additionalProperties
        Added value: +true
      • addedOutput schema / properties / savvly / properties / affordability / properties
        Added value: +{
        +  "explanation": {
        +    "description": "One-sentence rationale for the rating.",
        +    "type": "string"
        +  },
        +  "label": {
        +    "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +    "type": "string"
        +  },
        +  "score": {
        +    "description": "Numeric rating; greater = better (e.g. 1–5).",
        +    "type": "number"
        +  }
        +}
      • addedOutput schema / properties / savvly / properties / affordability / required
        Added value: +[
        +  "score",
        +  "label",
        +  "explanation"
        +]
      • addedOutput schema / properties / savvly / properties / affordability / type
        Added value: +"object"
      • removedOutput schema / properties / savvly / properties / cost_to_value / $ref
        Removed value: -"#/properties/savvly/properties/longevity_protection"
      • addedOutput schema / properties / savvly / properties / cost_to_value / additionalProperties
        Added value: +true
      • addedOutput schema / properties / savvly / properties / cost_to_value / properties
        Added value: +{
        +  "explanation": {
        +    "description": "One-sentence rationale for the rating.",
        +    "type": "string"
        +  },
        +  "label": {
        +    "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +    "type": "string"
        +  },
        +  "score": {
        +    "description": "Numeric rating; greater = better (e.g. 1–5).",
        +    "type": "number"
        +  }
        +}
      • addedOutput schema / properties / savvly / properties / cost_to_value / required
        Added value: +[
        +  "score",
        +  "label",
        +  "explanation"
        +]
      • addedOutput schema / properties / savvly / properties / cost_to_value / type
        Added value: +"object"
      • removedOutput schema / properties / savvly / properties / counterparty_safety / $ref
        Removed value: -"#/properties/savvly/properties/longevity_protection"
      • addedOutput schema / properties / savvly / properties / counterparty_safety / additionalProperties
        Added value: +true
      • addedOutput schema / properties / savvly / properties / counterparty_safety / properties
        Added value: +{
        +  "explanation": {
        +    "description": "One-sentence rationale for the rating.",
        +    "type": "string"
        +  },
        +  "label": {
        +    "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +    "type": "string"
        +  },
        +  "score": {
        +    "description": "Numeric rating; greater = better (e.g. 1–5).",
        +    "type": "number"
        +  }
        +}
      • addedOutput schema / properties / savvly / properties / counterparty_safety / required
        Added value: +[
        +  "score",
        +  "label",
        +  "explanation"
        +]
      • addedOutput schema / properties / savvly / properties / counterparty_safety / type
        Added value: +"object"
      • removedOutput schema / properties / savvly / properties / inflation_protection / $ref
        Removed value: -"#/properties/savvly/properties/longevity_protection"
      • addedOutput schema / properties / savvly / properties / inflation_protection / additionalProperties
        Added value: +true
      • addedOutput schema / properties / savvly / properties / inflation_protection / properties
        Added value: +{
        +  "explanation": {
        +    "description": "One-sentence rationale for the rating.",
        +    "type": "string"
        +  },
        +  "label": {
        +    "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +    "type": "string"
        +  },
        +  "score": {
        +    "description": "Numeric rating; greater = better (e.g. 1–5).",
        +    "type": "number"
        +  }
        +}
      • addedOutput schema / properties / savvly / properties / inflation_protection / required
        Added value: +[
        +  "score",
        +  "label",
        +  "explanation"
        +]
      • addedOutput schema / properties / savvly / properties / inflation_protection / type
        Added value: +"object"
      • removedOutput schema / properties / savvly / properties / liquidity / $ref
        Removed value: -"#/properties/savvly/properties/longevity_protection"
      • addedOutput schema / properties / savvly / properties / liquidity / additionalProperties
        Added value: +true
      • addedOutput schema / properties / savvly / properties / liquidity / properties
        Added value: +{
        +  "explanation": {
        +    "description": "One-sentence rationale for the rating.",
        +    "type": "string"
        +  },
        +  "label": {
        +    "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +    "type": "string"
        +  },
        +  "score": {
        +    "description": "Numeric rating; greater = better (e.g. 1–5).",
        +    "type": "number"
        +  }
        +}
      • addedOutput schema / properties / savvly / properties / liquidity / required
        Added value: +[
        +  "score",
        +  "label",
        +  "explanation"
        +]
      • addedOutput schema / properties / savvly / properties / liquidity / type
        Added value: +"object"
      • removedOutput schema / properties / savvly / properties / market_upside / $ref
        Removed value: -"#/properties/savvly/properties/longevity_protection"
      • addedOutput schema / properties / savvly / properties / market_upside / additionalProperties
        Added value: +true
      • addedOutput schema / properties / savvly / properties / market_upside / properties
        Added value: +{
        +  "explanation": {
        +    "description": "One-sentence rationale for the rating.",
        +    "type": "string"
        +  },
        +  "label": {
        +    "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +    "type": "string"
        +  },
        +  "score": {
        +    "description": "Numeric rating; greater = better (e.g. 1–5).",
        +    "type": "number"
        +  }
        +}
      • addedOutput schema / properties / savvly / properties / market_upside / required
        Added value: +[
        +  "score",
        +  "label",
        +  "explanation"
        +]
      • addedOutput schema / properties / savvly / properties / market_upside / type
        Added value: +"object"
      • removedOutput schema / properties / savvly / properties / portability / $ref
        Removed value: -"#/properties/savvly/properties/longevity_protection"
      • addedOutput schema / properties / savvly / properties / portability / additionalProperties
        Added value: +true
      • addedOutput schema / properties / savvly / properties / portability / properties
        Added value: +{
        +  "explanation": {
        +    "description": "One-sentence rationale for the rating.",
        +    "type": "string"
        +  },
        +  "label": {
        +    "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +    "type": "string"
        +  },
        +  "score": {
        +    "description": "Numeric rating; greater = better (e.g. 1–5).",
        +    "type": "number"
        +  }
        +}
      • addedOutput schema / properties / savvly / properties / portability / required
        Added value: +[
        +  "score",
        +  "label",
        +  "explanation"
        +]
      • addedOutput schema / properties / savvly / properties / portability / type
        Added value: +"object"
      • removedOutput schema / properties / savvly / properties / simplicity / $ref
        Removed value: -"#/properties/savvly/properties/longevity_protection"
      • addedOutput schema / properties / savvly / properties / simplicity / additionalProperties
        Added value: +true
      • addedOutput schema / properties / savvly / properties / simplicity / properties
        Added value: +{
        +  "explanation": {
        +    "description": "One-sentence rationale for the rating.",
        +    "type": "string"
        +  },
        +  "label": {
        +    "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +    "type": "string"
        +  },
        +  "score": {
        +    "description": "Numeric rating; greater = better (e.g. 1–5).",
        +    "type": "number"
        +  }
        +}
      • addedOutput schema / properties / savvly / properties / simplicity / required
        Added value: +[
        +  "score",
        +  "label",
        +  "explanation"
        +]
      • addedOutput schema / properties / savvly / properties / simplicity / type
        Added value: +"object"
    • Changedget_savvly_faq5 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedOutput schema / properties / total / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / total / minimum
        Added value: +-9007199254740991
    • Changedget_savvly_product_info4 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedOutput schema / properties / illustrative_payout
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "One worked example of what the schedule pays: the modeled payout RANGE at each milestone age for a single fixed allocation, so the percentages above have dollar figures beside them. Fixed inputs, identical for every caller — hypothetical, not a quote, and not tailored to the user. For the user's own age and amount, call `project_savvly_lumpsum`.",
        +  "properties": {
        +    "average_return": {
        +      "description": "Assumed average annual S&P 500 return, in percent.",
        +      "type": "number"
        +    },
        +    "current_age": {
        +      "description": "Age the illustrated allocation is made at.",
        +      "type": "number"
        +    },
        +    "funding_amount": {
        +      "description": "USD allocated up front in the illustration.",
        +      "type": "number"
        +    },
        +    "payouts": {
        +      "description": "One row per milestone age, low-to-high payout range in USD.",
        +      "items": {
        +        "additionalProperties": true,
        +        "properties": {
        +          "age": {
        +            "description": "Milestone age (80, 85, 90, or 95).",
        +            "type": "number"
        +          },
        +          "lower_usd": {
        +            "description": "USD. Low end of the modeled payout at this age.",
        +            "type": "number"
        +          },
        +          "upper_usd": {
        +            "description": "USD. High end of the modeled payout at this age.",
        +            "type": "number"
        +          }
        +        },
        +        "required": [
        +          "age",
        +          "lower_usd",
        +          "upper_usd"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "current_age",
        +    "funding_amount",
        +    "average_return",
        +    "payouts"
        +  ],
        +  "type": "object"
        +}
    • Changedproject_retirement_with_savvly10 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • changedOutput schema / properties / inputs / additionalProperties
        Previous value: -{}New value: +true
      • addedOutput schema / properties / inputs / propertyNames
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / metadata / properties / display_hints / properties / chart / properties / tooltip / propertyNames
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / metadata / properties / field_descriptions / propertyNames
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / result / properties / age_dependent_values / items / properties / age / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / result / properties / age_dependent_values / items / properties / age / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / visualization / properties / chart / properties / tooltip / propertyNames
        Added value: +{
        +  "type": "string"
        +}
    • Changedproject_savvly_lumpsum19 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • changedOutput schema / properties / inputs / additionalProperties
        Previous value: -{}New value: +true
      • addedOutput schema / properties / inputs / propertyNames
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / metadata / properties / field_descriptions / propertyNames
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_age / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_age / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / summary / properties / early_exit_refund_usd / anyOf
        Added value: +[
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedOutput schema / properties / summary / properties / early_exit_refund_usd / type
        Removed value: -[
        -  "number",
        -  "null"
        -]
      • addedOutput schema / properties / summary / properties / percentage_gain_upper_percent / anyOf
        Added value: +[
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedOutput schema / properties / summary / properties / percentage_gain_upper_percent / type
        Removed value: -[
        -  "number",
        -  "null"
        -]
      • addedOutput schema / properties / summary / properties / savvly_above_market_upper_usd / anyOf
        Added value: +[
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedOutput schema / properties / summary / properties / savvly_above_market_upper_usd / type
        Removed value: -[
        -  "number",
        -  "null"
        -]
      • addedOutput schema / properties / summary / properties / total_market_alone_upper_usd / anyOf
        Added value: +[
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedOutput schema / properties / summary / properties / total_market_alone_upper_usd / type
        Removed value: -[
        -  "number",
        -  "null"
        -]
      • addedOutput schema / properties / summary / properties / total_savvly_upper_usd / anyOf
        Added value: +[
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedOutput schema / properties / summary / properties / total_savvly_upper_usd / type
        Removed value: -[
        -  "number",
        -  "null"
        -]
      • addedOutput schema / properties / visualization / properties / chart / properties / tooltip / propertyNames
        Added value: +{
        +  "type": "string"
        +}
    • Changedproject_savvly_monthly19 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • changedOutput schema / properties / inputs / additionalProperties
        Previous value: -{}New value: +true
      • addedOutput schema / properties / inputs / propertyNames
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / metadata / properties / field_descriptions / propertyNames
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_age / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_age / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / summary / properties / early_exit_refund_usd / anyOf
        Added value: +[
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedOutput schema / properties / summary / properties / early_exit_refund_usd / type
        Removed value: -[
        -  "number",
        -  "null"
        -]
      • addedOutput schema / properties / summary / properties / percentage_gain_upper_percent / anyOf
        Added value: +[
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedOutput schema / properties / summary / properties / percentage_gain_upper_percent / type
        Removed value: -[
        -  "number",
        -  "null"
        -]
      • addedOutput schema / properties / summary / properties / savvly_above_market_upper_usd / anyOf
        Added value: +[
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedOutput schema / properties / summary / properties / savvly_above_market_upper_usd / type
        Removed value: -[
        -  "number",
        -  "null"
        -]
      • addedOutput schema / properties / summary / properties / total_market_alone_upper_usd / anyOf
        Added value: +[
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedOutput schema / properties / summary / properties / total_market_alone_upper_usd / type
        Removed value: -[
        -  "number",
        -  "null"
        -]
      • addedOutput schema / properties / summary / properties / total_savvly_upper_usd / anyOf
        Added value: +[
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedOutput schema / properties / summary / properties / total_savvly_upper_usd / type
        Removed value: -[
        -  "number",
        -  "null"
        -]
      • addedOutput schema / properties / visualization / properties / chart / properties / tooltip / propertyNames
        Added value: +{
        +  "type": "string"
        +}
    • Changedsearch_savvly_content15 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedOutput schema / properties / filter_applied / properties / audience / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedOutput schema / properties / filter_applied / properties / audience / type
        Removed value: -[
        -  "string",
        -  "null"
        -]
      • addedOutput schema / properties / filter_applied / properties / limit / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / filter_applied / properties / limit / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / filter_applied / properties / query / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedOutput schema / properties / filter_applied / properties / query / type
        Removed value: -[
        -  "string",
        -  "null"
        -]
      • addedOutput schema / properties / filter_applied / properties / section / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedOutput schema / properties / filter_applied / properties / section / type
        Removed value: -[
        -  "string",
        -  "null"
        -]
      • addedOutput schema / properties / matched / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / matched / minimum
        Added value: +-9007199254740991
      • addedOutput schema / properties / total_in_library / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / total_in_library / minimum
        Added value: +-9007199254740991
  6. 7 tool updatesv1.0.86
    • Changedcheck_savvly_eligibility1 field changed
      • changedInput schema / properties / channel / description
        Previous value: -"Distribution channel"New value: +"Distribution channel — one of 'individual', 'employer', 'advisor' (default 'individual')."
    • Changedcompare_savvly_vs_alternative2 fields changed
      • changedInput schema / properties / alternative / description
        Previous value: -"The product type to compare against Savvly, or 'all' for the full matrix"New value: +"Which product type to compare Savvly against. Use EXACTLY one of: 'fixed_annuity', 'variable_annuity', 'indexed_annuity', 'target_date_fund', 'managed_payout_fund', or 'all' for the full matrix. Pick a SPECIFIC annuity subtype — there is no generic 'annuity'."
      • removedInput schema / required
        Removed value: -[
        -  "alternative"
        -]
    • Changedget_savvly_faq1 field changed
      • changedInput schema / properties / section / enum
        Previous value: -[
        -  "all",
        -  "understanding-savvly",
        -  "investment-custody",
        -  "payouts",
        -  "withdrawals-estate",
        -  "fees-cost",
        -  "tax-legacy",
        -  "employer-portability",
        -  "safety-regulatory"
        -]New value: +[
        +  "all",
        +  "understanding-savvly",
        +  "investment-custody",
        +  "payouts",
        +  "withdrawals-estate",
        +  "expenses-cost",
        +  "tax-legacy",
        +  "employer-portability",
        +  "safety-regulatory"
        +]
    • Changedget_savvly_product_info4 fields changed
      • changedInput schema / properties / section / description
        Previous value: -"Which part of the product profile to focus the text on; the full overview card always renders regardless."New value: +"Which part of the product profile to focus the text on — one of 'all', 'overview', 'regulatory', 'investment', 'expenses', 'payouts', 'tax', 'distribution' (default 'all'). The full overview card always renders regardless."
      • changedInput schema / properties / section / enum
        Previous value: -[
        -  "all",
        -  "overview",
        -  "regulatory",
        -  "investment",
        -  "fees",
        -  "payouts",
        -  "tax",
        -  "distribution"
        -]New value: +[
        +  "all",
        +  "overview",
        +  "regulatory",
        +  "investment",
        +  "expenses",
        +  "payouts",
        +  "tax",
        +  "distribution"
        +]
      • addedOutput schema / properties / expenses
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "Expense structure in basis points (common vs tracking shares) and the blended range; illustrations are net of expenses.",
        +  "properties": {},
        +  "type": "object"
        +}
      • removedOutput schema / properties / fees
        Removed value: -{
        -  "additionalProperties": true,
        -  "description": "Fee structure in basis points (common vs tracking shares) and the blended range; illustrations are net of fees.",
        -  "properties": {},
        -  "type": "object"
        -}
    • Changedproject_savvly_lumpsum1 field changed
      • changedOutput schema / properties / summary / properties / narrative / description
        Previous value: -"Human-readable English sentence summarizing the projection. Always ends with 'Payouts are not guarantees. See full disclosures at <url>.' — display the URL verbatim alongside any figures."New value: +"Human-readable English sentence summarizing the projection. Always ends with 'Payouts follow a fixed milestone schedule; payout amounts are not guaranteed. See full disclosures at <url>.' — display the URL verbatim alongside any figures."
    • Changedproject_savvly_monthly1 field changed
      • changedOutput schema / properties / summary / properties / narrative / description
        Previous value: -"Human-readable English sentence summarizing the projection. Always ends with 'Payouts are not guarantees. See full disclosures at <url>.' — display the URL verbatim alongside any figures."New value: +"Human-readable English sentence summarizing the projection. Always ends with 'Payouts follow a fixed milestone schedule; payout amounts are not guaranteed. See full disclosures at <url>.' — display the URL verbatim alongside any figures."
    • Changedsearch_savvly_content1 field changed
      • changedInput schema / properties / audience / description
        Previous value: -"Restrict to one stakeholder audience ('general' is the factual FAQ). Use the exact lowercase token (the enum is case-sensitive). Omit to search across all audiences."New value: +"Restrict to one stakeholder audience. Use EXACTLY one of: 'employee', 'advisor', 'broker', 'employer', 'universal', or 'general' ('general' is the factual FAQ). Omit to search across all audiences."
  7. 2 tool updatesv1.0.75
    • Changedproject_savvly_lumpsum1 field changed
      • changedInput schema / properties / withdrawal_age / minimum
        Previous value: -25New value: +18
    • Changedproject_savvly_monthly1 field changed
      • changedInput schema / properties / withdrawal_age / minimum
        Previous value: -25New value: +18
  8. 5 tool updatesv1.0.69
    • Changedcheck_savvly_eligibility1 field changed
      • changedOutput schema / properties / age_eligible / description
        Previous value: -"True if age falls within the 25–75 minimum/maximum range."New value: +"True if age is at or under the maximum enrollment age (75); the filing sets no minimum age."
    • Changedproject_retirement_with_savvly1 field changed
      • changedInput schema / properties / current_age / minimum
        Previous value: -25New value: +18
    • Changedproject_savvly_lumpsum2 fields changed
      • changedInput schema / properties / current_age / description
        Previous value: -"Investor's current age (default 40)"New value: +"Investor's current age (default 40). Min 18 (the projection matrix floor); max 75 (max enrollment age)"
      • changedInput schema / properties / current_age / minimum
        Previous value: -25New value: +18
    • Changedproject_savvly_monthly4 fields changed
      • removedInput schema / properties / contribution_years / default
        Removed value: -27
      • changedInput schema / properties / contribution_years / description
        Previous value: -"Number of years contributing (default 27 = retirement age 67 − current age 40)"New value: +"Number of years contributing. Omit to use a sensible default of min(27, 80 − current_age) — 27 for the canonical age-40 scenario, and always small enough that contributions finish by age 80 (the advisor limit). If you pass an explicit value, current_age + contribution_years must be ≤ 80."
      • changedInput schema / properties / current_age / description
        Previous value: -"Investor's current age (default 40)"New value: +"Investor's current age (default 40). Min 18 (the projection matrix floor); max 75 (max enrollment age)"
      • changedInput schema / properties / current_age / minimum
        Previous value: -25New value: +18
    • Changedsearch_savvly_content1 field changed
      • changedInput schema / properties / audience / description
        Previous value: -"Restrict to one stakeholder audience ('general' is the factual FAQ). Omit to search across all audiences."New value: +"Restrict to one stakeholder audience ('general' is the factual FAQ). Use the exact lowercase token (the enum is case-sensitive). Omit to search across all audiences."
  9. 3 tool updatesv1.0.68
    • Changedget_savvly_faq12 fields changed
      • addedInput schema / properties / section
        Added value: +{
        +  "default": "all",
        +  "description": "Filter the FAQ to one section (kebab-case, e.g. 'tax-legacy'); 'all' returns every entry.",
        +  "enum": [
        +    "all",
        +    "understanding-savvly",
        +    "investment-custody",
        +    "payouts",
        +    "withdrawals-estate",
        +    "fees-cost",
        +    "tax-legacy",
        +    "employer-portability",
        +    "safety-regulatory"
        +  ],
        +  "type": "string"
        +}
      • removedInput schema / properties / topic
        Removed value: -{
        -  "default": "all",
        -  "description": "Filter FAQ by topic",
        -  "enum": [
        -    "general",
        -    "investment",
        -    "payouts",
        -    "withdrawals",
        -    "tax",
        -    "fees",
        -    "employer",
        -    "regulatory",
        -    "all"
        -  ],
        -  "type": "string"
        -}
      • changedOutput schema / properties / entries / description
        Previous value: -"Filtered FAQ entries."New value: +"Filtered FAQ entries (the audience:'general' Q&A slice)."
      • addedOutput schema / properties / entries / items / properties / audience
        Added value: +{
        +  "enum": [
        +    "employee",
        +    "advisor",
        +    "broker",
        +    "employer",
        +    "universal",
        +    "general"
        +  ],
        +  "type": "string"
        +}
      • removedOutput schema / properties / entries / items / properties / category
        Removed value: -{
        -  "description": "FAQ category.",
        -  "enum": [
        -    "general",
        -    "investment",
        -    "payouts",
        -    "withdrawals",
        -    "tax",
        -    "fees",
        -    "employer",
        -    "regulatory"
        -  ],
        -  "type": "string"
        -}
      • addedOutput schema / properties / entries / items / properties / footnotes
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • removedOutput schema / properties / entries / items / properties / related_ids
        Removed value: -{
        -  "items": {
        -    "type": "string"
        -  },
        -  "type": "array"
        -}
      • addedOutput schema / properties / entries / items / properties / section
        Added value: +{
        +  "type": "string"
        +}
      • changedOutput schema / properties / entries / items / required
        Previous value: -[
        -  "id",
        -  "category",
        -  "question",
        -  "answer",
        -  "related_ids",
        -  "keywords"
        -]New value: +[
        +  "id",
        +  "audience",
        +  "section",
        +  "question",
        +  "answer",
        +  "footnotes"
        +]
      • addedOutput schema / properties / section
        Added value: +{
        +  "description": "Section filter applied to produce this result set ('all' if no filter).",
        +  "type": "string"
        +}
      • removedOutput schema / properties / topic
        Removed value: -{
        -  "description": "Topic filter applied to produce this result set ('all' if no filter).",
        -  "type": "string"
        -}
      • changedOutput schema / required
        Previous value: -[
        -  "topic",
        -  "total",
        -  "entries"
        -]New value: +[
        +  "section",
        +  "total",
        +  "entries"
        +]
    • Changedget_savvly_product_info2 fields changed
      • changedOutput schema / properties / company / description
        Previous value: -"Issuer / adviser entity information."New value: +"Issuer / advisor entity information."
      • changedOutput schema / properties / regulatory / description
        Previous value: -"Regulatory status: SEC registration, Investment Company Act of 1940, adviser, custodian, and is_insurance/is_annuity flags."New value: +"Regulatory status: SEC registration, Investment Company Act of 1940, advisor, custodian, and is_insurance/is_annuity flags."
    • Changedsearch_savvly_content14 fields changed
      • changedInput schema / properties / audience / description
        Previous value: -"Restrict to one stakeholder audience. Omit to search across all audiences."New value: +"Restrict to one stakeholder audience ('general' is the factual FAQ). Omit to search across all audiences."
      • changedInput schema / properties / audience / enum
        Previous value: -[
        -  "employee",
        -  "advisor",
        -  "broker",
        -  "employer",
        -  "universal"
        -]New value: +[
        +  "employee",
        +  "advisor",
        +  "broker",
        +  "employer",
        +  "universal",
        +  "general"
        +]
      • addedInput schema / properties / section
        Added value: +{
        +  "description": "Substring match against section slugs (e.g. 'tax', 'retention', 'eligibility'). Case-insensitive.",
        +  "type": "string"
        +}
      • removedInput schema / properties / subsection
        Removed value: -{
        -  "description": "Substring match against subsection labels (e.g. 'Tax', 'Retention', 'Eligibility'). Case-insensitive.",
        -  "type": "string"
        -}
      • addedOutput schema / properties / available_sections
        Added value: +{
        +  "description": "Section slugs available within the (optionally) selected audience.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • removedOutput schema / properties / available_subsections
        Removed value: -{
        -  "description": "Subsection labels available within the (optionally) selected audience.",
        -  "items": {
        -    "type": "string"
        -  },
        -  "type": "array"
        -}
      • changedOutput schema / properties / entries / items / properties / audience / enum
        Previous value: -[
        -  "employee",
        -  "advisor",
        -  "broker",
        -  "employer",
        -  "universal"
        -]New value: +[
        +  "employee",
        +  "advisor",
        +  "broker",
        +  "employer",
        +  "universal",
        +  "general"
        +]
      • addedOutput schema / properties / entries / items / properties / keywords
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • removedOutput schema / properties / entries / items / properties / subsection
        Removed value: -{
        -  "type": "string"
        -}
      • changedOutput schema / properties / entries / items / required
        Previous value: -[
        -  "id",
        -  "audience",
        -  "section",
        -  "subsection",
        -  "question",
        -  "answer",
        -  "footnotes"
        -]New value: +[
        +  "id",
        +  "audience",
        +  "section",
        +  "question",
        +  "answer",
        +  "footnotes"
        +]
      • addedOutput schema / properties / filter_applied / properties / section
        Added value: +{
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • removedOutput schema / properties / filter_applied / properties / subsection
        Removed value: -{
        -  "type": [
        -    "string",
        -    "null"
        -  ]
        -}
      • changedOutput schema / properties / filter_applied / required
        Previous value: -[
        -  "audience",
        -  "subsection",
        -  "query",
        -  "limit"
        -]New value: +[
        +  "audience",
        +  "section",
        +  "query",
        +  "limit"
        +]
      • changedOutput schema / required
        Previous value: -[
        -  "total_in_library",
        -  "matched",
        -  "filter_applied",
        -  "available_subsections",
        -  "entries"
        -]New value: +[
        +  "total_in_library",
        +  "matched",
        +  "filter_applied",
        +  "available_sections",
        +  "entries"
        +]
  10. 2 tool updatesv1.0.67
    • Changedget_savvly_product_info3 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / section
        Added value: +{
        +  "default": "all",
        +  "description": "Which part of the product profile to focus the text on; the full overview card always renders regardless.",
        +  "enum": [
        +    "all",
        +    "overview",
        +    "regulatory",
        +    "investment",
        +    "fees",
        +    "payouts",
        +    "tax",
        +    "distribution"
        +  ],
        +  "type": "string"
        +}
    • Changedsearch_savvly_content1 field changed
      • changedInput schema / properties / query / description
        Previous value: -"Free-text substring filter applied to questions, answers, and footnotes. Case-insensitive."New value: +"Free-text search over questions, answers, and footnotes (case-insensitive). Multi-word queries match entries containing ANY of the words, ranked by relevance."
  11. 2 tool updatesv1.0.58
    • Changedcompare_savvly_vs_alternative24 fields changed
      • addedOutput schema / properties / comparison / properties / category
        Added value: +{
        +  "description": "Product category.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / comparison / properties / description
        Added value: +{
        +  "description": "Short description of the alternative.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / comparison / properties / dimensions
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "This alternative's ratings across the dimensions.",
        +  "properties": {
        +    "affordability": {
        +      "$ref": "#/properties/savvly/properties/affordability"
        +    },
        +    "cost_to_value": {
        +      "$ref": "#/properties/savvly/properties/cost_to_value"
        +    },
        +    "counterparty_safety": {
        +      "$ref": "#/properties/savvly/properties/counterparty_safety"
        +    },
        +    "death_benefit": {
        +      "$ref": "#/properties/savvly/properties/death_benefit"
        +    },
        +    "inflation_protection": {
        +      "$ref": "#/properties/savvly/properties/inflation_protection"
        +    },
        +    "liquidity": {
        +      "$ref": "#/properties/savvly/properties/liquidity"
        +    },
        +    "longevity_protection": {
        +      "$ref": "#/properties/savvly/properties/longevity_protection"
        +    },
        +    "market_upside": {
        +      "$ref": "#/properties/savvly/properties/market_upside"
        +    },
        +    "portability": {
        +      "$ref": "#/properties/savvly/properties/portability"
        +    },
        +    "regulatory_oversight": {
        +      "$ref": "#/properties/savvly/properties/regulatory_oversight"
        +    },
        +    "simplicity": {
        +      "$ref": "#/properties/savvly/properties/simplicity"
        +    },
        +    "tax_treatment": {
        +      "$ref": "#/properties/savvly/properties/tax_treatment"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedOutput schema / properties / comparison / properties / display_name
        Added value: +{
        +  "description": "Human-readable product name.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / comparison / properties / product_type
        Added value: +{
        +  "description": "Alternative product slug, e.g. 'fixed_annuity'.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / comparison / required
        Added value: +[
        +  "product_type"
        +]
      • addedOutput schema / properties / comparisons / items / $ref
        Added value: +"#/properties/comparison"
      • removedOutput schema / properties / comparisons / items / additionalProperties
        Removed value: -true
      • removedOutput schema / properties / comparisons / items / properties
        Removed value: -{}
      • removedOutput schema / properties / comparisons / items / type
        Removed value: -"object"
      • addedOutput schema / properties / metadata / properties / disclaimer
        Added value: +{
        +  "description": "Required disclaimer.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / metadata / properties / version
        Added value: +{
        +  "description": "Comparison data version.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / savvly / properties / affordability
        Added value: +{
        +  "$ref": "#/properties/savvly/properties/longevity_protection"
        +}
      • addedOutput schema / properties / savvly / properties / cost_to_value
        Added value: +{
        +  "$ref": "#/properties/savvly/properties/longevity_protection"
        +}
      • addedOutput schema / properties / savvly / properties / counterparty_safety
        Added value: +{
        +  "$ref": "#/properties/savvly/properties/longevity_protection"
        +}
      • addedOutput schema / properties / savvly / properties / death_benefit
        Added value: +{
        +  "description": "Death-benefit summary.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / savvly / properties / inflation_protection
        Added value: +{
        +  "$ref": "#/properties/savvly/properties/longevity_protection"
        +}
      • addedOutput schema / properties / savvly / properties / liquidity
        Added value: +{
        +  "$ref": "#/properties/savvly/properties/longevity_protection"
        +}
      • addedOutput schema / properties / savvly / properties / longevity_protection
        Added value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "explanation": {
        +      "description": "One-sentence rationale for the rating.",
        +      "type": "string"
        +    },
        +    "label": {
        +      "description": "Rating label: None | Very Low | Low | Medium | High | Very High.",
        +      "type": "string"
        +    },
        +    "score": {
        +      "description": "Numeric rating; greater = better (e.g. 1–5).",
        +      "type": "number"
        +    }
        +  },
        +  "required": [
        +    "score",
        +    "label",
        +    "explanation"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / properties / savvly / properties / market_upside
        Added value: +{
        +  "$ref": "#/properties/savvly/properties/longevity_protection"
        +}
      • addedOutput schema / properties / savvly / properties / portability
        Added value: +{
        +  "$ref": "#/properties/savvly/properties/longevity_protection"
        +}
      • addedOutput schema / properties / savvly / properties / regulatory_oversight
        Added value: +{
        +  "description": "Who regulates it (e.g. SEC vs state insurance).",
        +  "type": "string"
        +}
      • addedOutput schema / properties / savvly / properties / simplicity
        Added value: +{
        +  "$ref": "#/properties/savvly/properties/longevity_protection"
        +}
      • addedOutput schema / properties / savvly / properties / tax_treatment
        Added value: +{
        +  "description": "Tax-treatment summary.",
        +  "type": "string"
        +}
    • Changedget_savvly_product_info15 fields changed
      • addedOutput schema / properties / channels
        Added value: +{
        +  "description": "Distribution channels through which Savvly is offered.",
        +  "items": {},
        +  "type": "array"
        +}
      • addedOutput schema / properties / company
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "Issuer / adviser entity information.",
        +  "properties": {},
        +  "type": "object"
        +}
      • addedOutput schema / properties / disclaimers
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "SEC-style disclaimers and required legal language.",
        +  "properties": {},
        +  "type": "object"
        +}
      • addedOutput schema / properties / early_withdrawal
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "Early-withdrawal / surrender terms and the value returned to the estate.",
        +  "properties": {},
        +  "type": "object"
        +}
      • addedOutput schema / properties / fees
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "Fee structure in basis points (common vs tracking shares) and the blended range; illustrations are net of fees.",
        +  "properties": {},
        +  "type": "object"
        +}
      • addedOutput schema / properties / investment
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "How contributions are invested: underlying assets (S&P 500 ETF), asset managers, minimum/maximum monthly and lump-sum amounts, market participation.",
        +  "properties": {},
        +  "type": "object"
        +}
      • addedOutput schema / properties / links
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "Relevant URLs (website, disclosures, etc.).",
        +  "properties": {},
        +  "type": "object"
        +}
      • addedOutput schema / properties / longevity_pool
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "How the longevity pool works — exited participants' unused shares may be allocated to remaining participants.",
        +  "properties": {},
        +  "type": "object"
        +}
      • addedOutput schema / properties / next_steps
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "Suggested next actions for an interested investor.",
        +  "properties": {},
        +  "type": "object"
        +}
      • addedOutput schema / properties / payout_schedule
        Added value: +{
        +  "description": "Milestone payout schedule at ages 80/85/90/95.",
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "age": {
        +        "description": "Milestone age (80, 85, 90, or 95).",
        +        "type": "number"
        +      },
        +      "description": {
        +        "description": "What happens at this milestone.",
        +        "type": "string"
        +      },
        +      "label": {
        +        "description": "Human label, e.g. 'First milestone'.",
        +        "type": "string"
        +      },
        +      "percentage": {
        +        "description": "Fraction of accumulated value distributed at this milestone (e.g. 0.4).",
        +        "type": "number"
        +      }
        +    },
        +    "required": [
        +      "age",
        +      "percentage"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / portability
        Added value: +{
        +  "description": "Whether the position is portable.",
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / portability_note
        Added value: +{
        +  "description": "Detail on portability.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / positioning_statement
        Added value: +{
        +  "description": "One-sentence positioning — what Savvly is and is NOT (not insurance, not an annuity).",
        +  "type": "string"
        +}
      • addedOutput schema / properties / regulatory
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "Regulatory status: SEC registration, Investment Company Act of 1940, adviser, custodian, and is_insurance/is_annuity flags.",
        +  "properties": {},
        +  "type": "object"
        +}
      • addedOutput schema / properties / tax_treatment
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "Tax treatment of payouts and contributions.",
        +  "properties": {},
        +  "type": "object"
        +}

TDQS

A4.2/5.0

Scored across 8 tools

Disambiguation4/5

The two projection tools (lumpsum vs monthly) are cleanly split by contribution mode, and the full-horizon simulation is distinguishable by its planning-horizon framing. The one real overlap is get_savvly_faq vs search_savvly_content, but the FAQ description explicitly scopes itself as a convenience view of the broader search, which mitigates misselection.

Naming Consistency4/5

All names are snake_case with the 'savvly' domain token embedded and follow a verb-first pattern (project_, get_, search_, check_, compare_). Minor deviation in token ordering (get_savvly_product_info vs project_savvly_lumpsum) but the verb_noun_resource pattern is predictable.

Tool Count5/5

Eight tools is well within the sweet spot for a product-explainability server, and each covers a distinct need (projections, eligibility, comparison, product facts, Q&A). No padding or redundancy apparent beyond the intentionally scoped FAQ alias.

Completeness4/5

The surface covers the lifecycle an advisor-facing flow needs: understand the product, check eligibility, compare alternatives, project outcomes, and answer objections. Gaps are minor — there is no way to retrieve current assumptions/rates or persist/share a projection, but agents can work around these.

Maintenance

ActivityNo data
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides a sovereign, MIT-licensed MCP server for professional-service workflows, running entirely on your infrastructure with Ed25519 cryptographic signing for every action.
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Official MCP server for Agni Folio, a free multi-currency wealth & portfolio tracker. 23 tools for holdings, performance, FIRE planning, crypto P&L, and confirm-gated writes — hosted endpoint with OAuth 2.1, plus a Docker stdio bridge in this repo.
    4
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP server for cove-fi, a deterministic retirement and financial-independence projection engine. It lets users run plans, create scenarios, and explore year-by-year net-worth projections through natural language.
    MIT