savvly-mcp
The Savvly MCP server lets financial advisors, planning tools, and AI agents query fund data, model retirement projections, compare products, check eligibility, and get compliance-grade disclosures — conversationally and in real time.
Product Info (
get_savvly_product_info): Retrieve a full overview of Savvly's longevity-linked investment fund, including description, category, and tagline.Compare vs. Alternatives (
compare_savvly_vs_alternative): Get structured comparisons of Savvly against fixed/variable/indexed annuities, target-date funds, managed payout funds, or all at once.Check Eligibility (
check_savvly_eligibility): Verify whether a person qualifies based on age (25–75), US residency, and distribution channel (individual, employer-sponsored, or advisor-placed).FAQ Answers (
get_savvly_faq): Access answers to common questions, filterable by topic (general, investment, payouts, withdrawals, tax, fees, employer, regulatory).Search Content Library (
search_savvly_content): Search 50+ audience-tagged Q&A entries, filterable by audience (employee, advisor, broker, employer, universal) and subsection.Project Lump-Sum Investment (
project_savvly_lumpsum): Model milestone payouts at ages 80, 85, 90, and 95 for a one-time investment, with Savvly vs. market-alone comparisons, early-withdrawal estimates, and lower/upper range bounds.Project Monthly Contributions (
project_savvly_monthly): Simulate milestone payouts for recurring monthly contributions, with optional annual increases and early-withdrawal scenarios.Full Retirement Trajectory (
project_retirement_with_savvly): Run a year-by-year retirement simulation comparing portfolio outcomes with and without Savvly, including a gap score and achievable monthly paycheck estimates.Interactive Widgets & Compliance: Emit editable chart widgets on supported MCP hosts; every projection includes verbatim SEC-required disclosure text — no personal data collected.
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) |
|
npm |
|
PyPI |
|
NuGet |
|
Docker / OCI |
|
MCPB | download the |
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 overviewcompare_savvly_vs_alternative— Savvly vs annuities, target-date funds, etc.check_savvly_eligibility— age / residency / channel eligibilityget_savvly_faq— FAQ by topicsearch_savvly_content— audience-tagged Q&A libraryproject_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.
Links
Website: https://savvly.com
Disclosures: https://www.savvly.com/disclosures
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 toolscheck_savvly_eligibilityCheck Savvly EligibilityARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| age | Yes | Person's current age | |
| channel | No | Distribution channel — one of 'individual', 'employer', 'advisor' (default 'individual'). | individual |
| us_resident | No | Whether the person is a US resident |
Output Schema
| Name | Required | Description |
|---|---|---|
| channel | Yes | Distribution channel under consideration for this check. |
| message | Yes | Human-readable explanation of the eligibility outcome. |
| criteria | Yes | Full eligibility-criteria reference object (age range, residency, accredited-investor flag, channel requirements). |
| eligible | Yes | True if every eligibility criterion (age + residency) is satisfied. |
| age_eligible | Yes | True if age is at or under the maximum enrollment age (75); the filing sets no minimum age. |
| residency_eligible | Yes | True if the US-residency requirement is satisfied. |
TDQS
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.
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.
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.
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.
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.
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 ProductARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| alternative | No | 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'. | all |
Output Schema
| Name | Required | Description |
|---|---|---|
| savvly | Yes | Savvly's profile across the comparison dimensions. |
| metadata | Yes | Comparison dimensions, definitions, and source notes. |
| comparison | No | The selected alternative product's profile. Present when `alternative` is a specific product type (i.e. not 'all'). |
| comparisons | No | Full comparison matrix — one entry per alternative product type. Present when `alternative` is 'all'. |
TDQS
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.
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.
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.
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.
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.
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 FAQARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| section | No | Filter the FAQ to one section (kebab-case, e.g. 'tax-legacy'); 'all' returns every entry. | all |
Output Schema
| Name | Required | Description |
|---|---|---|
| total | Yes | Count of FAQ entries returned. |
| entries | Yes | Filtered FAQ entries (the audience:'general' Q&A slice). |
| section | Yes | Section filter applied to produce this result set ('all' if no filter). |
TDQS
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.
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.
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.
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.
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.
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 InfoARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| section | No | 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. | all |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | Product name (e.g. 'Savvly Longevity Benefit'). |
| links | No | Relevant URLs (website, disclosures, etc.). |
| company | No | Issuer / advisor entity information. |
| tagline | No | Short marketing tagline. |
| category | Yes | Product category slug, e.g. 'longevity_benefit_fund'. |
| channels | No | Distribution channels through which Savvly is offered. |
| expenses | No | Expense structure in basis points (common vs tracking shares) and the blended range; illustrations are net of expenses. |
| investment | No | How contributions are invested: underlying assets (S&P 500 ETF), asset managers, minimum/maximum monthly and lump-sum amounts, market participation. |
| next_steps | No | Suggested next actions for an interested investor. |
| regulatory | No | Regulatory status: SEC registration, Investment Company Act of 1940, advisor, custodian, and is_insurance/is_annuity flags. |
| description | No | Long-form product description. |
| disclaimers | No | SEC-style disclaimers and required legal language. |
| portability | No | Whether the position is portable. |
| tax_treatment | No | Tax treatment of payouts and contributions. |
| longevity_pool | No | How the longevity pool works — exited participants' unused shares may be allocated to remaining participants. |
| payout_schedule | No | Milestone payout schedule at ages 80/85/90/95. |
| early_withdrawal | No | Early-withdrawal / surrender terms and the value returned to the estate. |
| portability_note | No | Detail on portability. |
| illustrative_payout | No | 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`. |
| positioning_statement | No | One-sentence positioning — what Savvly is and is NOT (not insurance, not an annuity). |
TDQS
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.
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.
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.
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.
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.
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 SavvlyARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| current_age | No | Current age (default 40) | |
| inflation_rate | No | Expected annual inflation rate % (default 3) | |
| retirement_age | No | Planned retirement age (default 68) | |
| life_expectancy | No | Planning horizon (default 100) | |
| monthly_paycheck | No | Desired monthly retirement paycheck in USD (default 4500) | |
| monthly_contribution | No | Monthly retirement contribution in USD (default 1000) | |
| percentage_in_savvly | No | Percentage of the retirement portfolio allocated to Savvly (default 5) | |
| pre_retirement_return | No | Expected pre-retirement annual return % (default 6) | |
| annual_income_increase | No | Annual contribution % increase (default 2) | |
| post_retirement_return | No | Expected post-retirement annual return % (default 5) | |
| other_retirement_income | No | Other monthly retirement income in USD (default 1600) | |
| current_retirement_savings | No | Current total retirement savings in USD (default 60000) |
Output Schema
| Name | Required | Description |
|---|---|---|
| inputs | Yes | |
| result | Yes | |
| summary | Yes | Convenience summary. The narrative carries the canonical full-disclosures URL inline; display it verbatim alongside any figures from this response. |
| metadata | Yes | |
| disclosure | Yes | DISCLOSURE 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. |
| visualization | No | Recommended 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
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
This description adds extensive behavioral context beyond the readOnly/idempotent annotations: the age-ordering requirement, disclosure obligations under SEC/FINRA, the interactive chart widget emission and rendering constraints, the prohibition on duplicate visualizations, and the lead-in ordering rule. It does not contradict any annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but it is well-structured into clear sections (purpose, returns, disclosure, visualization, order, inputs) and every sentence carries necessary operational or compliance guidance. Slightly verbose, but the complexity of the tool justifies the length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for a tool with this complexity: it covers required disclosure text, URL linking, chart rendering behavior, ordering constraints, and parameter handling. The presence of an output schema means the return fields do not need detailed enumeration, but the description still highlights key outputs like gap_score and age_dependent_values[].
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds meaningful parameter-policy context: 'every parameter is OPTIONAL and defaults to a sensible value' and 'pass only the values the user explicitly stated and omit the rest.' This clarifies invocation semantics beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Full retirement simulation showing the projected savings trajectory WITH and WITHOUT a Savvly allocation across the planning horizon.' This clearly distinguishes it from sibling projection tools like project_savvly_lumpsum or project_savvly_monthly by emphasizing the comparative full-trajectory scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit operational guidance: 'Call this tool IMMEDIATELY — pass only the values the user explicitly stated and omit the rest' and 'Do NOT ask the user for starting values... before calling.' It also explains the lead-in paragraph ordering. It does not explicitly name sibling alternatives, but the context is clear enough for an agent to know when to invoke.
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 InvestmentARead-onlyIdempotentInspect
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, and server-provided _lower/_upper range bounds. Use _upper as the central illustrative estimate and _lower to communicate downside. 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 Investor 1 receives as a payout from Savvly. The payout_market_alone_* and total_market_alone_* figures are therefore what Investor 2 can actually withdraw to match Savvly's payouts before running out — they fall to 0 once the market alone portfolio is depleted. 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. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| current_age | No | Investor's current age (default 40). Min 18 (the projection matrix floor); max 75 (max enrollment age) | |
| average_return | No | Expected average annual S&P 500 return % (default 8) | |
| funding_amount | No | Lump sum investment in USD (default 10000) | |
| withdrawal_age | No | Early-withdrawal age (default 82) — drives `early_withdrawal_value` and `total_payout_at_withdrawal_age_*` in the response |
Output Schema
| Name | Required | Description |
|---|---|---|
| inputs | Yes | Echo of the validated input arguments passed to the tool. |
| result | Yes | Raw projection envelope returned by the upstream estimator. |
| summary | Yes | Convenience summary including a human-readable narrative. |
| metadata | Yes | |
| disclosure | Yes | DISCLOSURE 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. |
| visualization | No | Recommended 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
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description adds substantial behavioral detail: the exact apples-to-apples payout methodology, why market-alone values fall to zero, the meaning of `_lower`/`_upper`, mandatory SEC/FINRA disclosure requirements, the widget rendering behavior, and the instruction not to claim a chart is visible. There is no contradiction with 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured into labeled sections (methodology, disclosure, visualization, order, inputs). Every section carries operational guidance needed for correct use, especially around compliance and widget handling. It is not maximally concise, but the length is justified by the complexity of the tool's behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Combined with a full output schema and annotations, the description covers invocation timing, default handling, payout methodology, disclosure compliance, widget rendering, host variations, and caveats about claiming chart visibility. Nothing an agent needs to call the tool correctly and communicate results responsibly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3 because the schema already explains all four parameters with ranges and defaults. The description adds meaningful invocation-level semantics—every parameter is optional, defaults to a sensible value, and only explicitly user-stated values should be passed—which clarifies agent behavior beyond the schema itself.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb and resource: it produces a retirement projection for a lump-sum investment in the Savvly Longevity Benefit. It also enumerates concrete outputs—milestone-age payout amounts, Savvly vs market-alone totals, per-age breakdowns, and range bounds—making it immediately distinguishable from a generic projection or the monthly-investment sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives strong invocation guidance: call immediately, pass only user-stated parameters, omit the rest, never ask for missing inputs, and write a lead-in paragraph before calling. It states suitable use cases (retirement income planning, annuity alternative analysis, longevity benefit illustration) but does not explicitly name sibling alternatives or conditions for choosing project_savvly_monthly over this tool, so exclusion guidance is slightly less explicit.
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 ContributionsARead-onlyIdempotentInspect
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, and server-provided _lower/_upper range bounds. Use _upper as the central illustrative estimate and _lower to communicate downside. 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 Investor 1 receives as a payout from Savvly. The payout_market_alone_* and total_market_alone_* figures are therefore what Investor 2 can actually withdraw to match Savvly's payouts before running out — they fall to 0 once the market alone portfolio is depleted. 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. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| current_age | No | Investor's current age (default 40). Min 18 (the projection matrix floor); max 75 (max enrollment age) | |
| average_return | No | Expected average annual S&P 500 return % (default 8) | |
| monthly_amount | No | Monthly deposit in USD (default 100) | |
| withdrawal_age | No | Early-withdrawal age (default 82) — drives `early_withdrawal_value` and `total_payout_at_withdrawal_age_*` in the response | |
| contribution_years | No | 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. | |
| installment_increase_percentage | No | Optional annual % increase applied to monthly contributions |
Output Schema
| Name | Required | Description |
|---|---|---|
| inputs | Yes | Echo of the validated input arguments passed to the tool. |
| result | Yes | Raw projection envelope returned by the upstream estimator. |
| summary | Yes | Convenience summary including a human-readable narrative. |
| metadata | Yes | |
| disclosure | Yes | DISCLOSURE 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. |
| visualization | No | Recommended 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
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes far beyond the read-only/idempotent annotations, explaining the two-investor comparison methodology, how `payout_market_alone_*` and `savvly_upside_*` are derived, the meaning of `_lower`/`_upper` bounds, mandatory SEC/FINRA disclosure handling, the MCP App widget behavior, and the required lead-in ordering. No annotation contradiction exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but every section earns its place: methodology, disclosure, widget behavior, invocation order, and input policy are all required for correct use. It is logically organized and front-loaded with the core projection purpose before the more detailed instructions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with compliance obligations, an interactive widget, subtle methodology, and optional parameters, the description is exceptionally complete. It covers what is returned, how figures should be interpreted, mandatory disclosure text, chart rendering expectations, and exactly how and when to call the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all six parameters, defaults, ranges, and constraints. The description adds some reinforcement (e.g., contributions must finish by age 80, withdrawal_age drives early-withdrawal fields) but does not substantially extend the schema's parameter documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Retirement projection for monthly contributions to the Savvly Longevity Benefit.' It also lists concrete outputs (payout amounts at ages 80/85/90/95, cumulative totals, per-age breakdowns), which differentiates it from sibling tools like project_savvly_lumpsum. The monthly-contribution focus is explicit and distinguishable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear use cases ('retirement savings planning, annuity alternative comparison, and longevity benefit illustration') and very explicit invocation guidance: call immediately, pass only user-stated values, do not ask for missing parameters. It does not explicitly name sibling alternatives or state when not to use this tool, but the context is clear enough for an agent to select it.
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 LibraryARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Cap on matched entries returned. Default 20, max 50. | |
| query | No | Free-text search over questions, answers, and footnotes (case-insensitive). Multi-word queries match entries containing ANY of the words, ranked by relevance. | |
| section | No | Substring match against section slugs (e.g. 'tax', 'retention', 'eligibility'). Case-insensitive. | |
| audience | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| entries | Yes | Matched Q&A entries. |
| matched | Yes | Count of entries matching the supplied filters. |
| filter_applied | Yes | Echo of the filters that produced this result set. |
| total_in_library | Yes | Total Q&A entry count in the library across all audiences. |
| available_sections | Yes | Section slugs available within the (optionally) selected audience. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds meaningful behavioral context: entries carry 'verbatim answer plus any disclaimer footnotes,' and responses include 'primary sources (e.g. SEC filings)' for reference. This goes beyond annotations by describing data provenance and content structure. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured, front-loading the core purpose and use case, then adding content details and source attribution. Each sentence contributes value: purpose, when-to-use, data characteristics, and provenance. It is somewhat lengthy but not redundant. A slightly tighter version could condense the examples, but overall it's efficient and organized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the existence of an output schema (noted in context signals), the description does not need to explain return values. Annotations cover safety, and the description provides comprehensive context: what the library contains, how it's organized, when to use it, and what each entry includes (verbatim answers, footnotes, primary sources). For a read-only search tool with four optional parameters, nothing essential is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% (all four parameters have descriptions), baseline 3. The description adds value by specifying multi-word query behavior ('match entries containing ANY of the words, ranked by relevance') and provides concrete examples for section slugs ('tax-legacy', 'retention-talent-strategy') and clarifies audience semantics ('general' is the factual FAQ). It also notes substring matching for section. These details enhance the schema's minimal descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb (search), the resource (Savvly Q&A Content Library), and the content type (audience-tagged questions and answers). It differentiates from siblings by specifying the use case: 'positioning, value props, audience-specific talking points, or Q&A-style messaging,' which distinguishes it from get_savvly_faq (likely a static FAQ) and other tools. The organization by stakeholder and section is also included, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use this when the user asks about Savvly's positioning...' providing clear when-to-use guidance. However, it does not explicitly mention when NOT to use it or name specific alternatives, though the sibling list and context imply get_savvly_faq might serve the full FAQ. It also clarifies the 'general' audience as the factual FAQ, giving additional contextual direction. Lacks explicit exclusions but is still strong.
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.
2 tool updates
v1.0.93- Changed
project_savvly_lumpsum2 fields changed- changed
Output schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_market_alone_lower / descriptionPrevious 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." - changed
Output schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_market_alone_upper / descriptionPrevious 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."
- Changed
project_savvly_monthly2 fields changed- changed
Output schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_market_alone_lower / descriptionPrevious 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." - changed
Output schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_market_alone_upper / descriptionPrevious 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."
8 tool updates
v1.0.92- Changed
check_savvly_eligibility5 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / age / maximumAdded value: +9007199254740991 - added
Input schema / properties / age / minimumAdded value: +-9007199254740991 - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
compare_savvly_vs_alternative103 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / alternative / defaultAdded value: +"all" - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - removed
Output schema / properties / comparison / properties / dimensions / properties / affordability / $refRemoved value: -"#/properties/savvly/properties/affordability" - added
Output schema / properties / comparison / properties / dimensions / properties / affordability / additionalPropertiesAdded value: +true - added
Output schema / properties / comparison / properties / dimensions / properties / affordability / propertiesAdded 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" + } +} - added
Output schema / properties / comparison / properties / dimensions / properties / affordability / requiredAdded value: +[ + "score", + "label", + "explanation" +] - added
Output schema / properties / comparison / properties / dimensions / properties / affordability / typeAdded value: +"object" - removed
Output schema / properties / comparison / properties / dimensions / properties / cost_to_value / $refRemoved value: -"#/properties/savvly/properties/cost_to_value" - added
Output schema / properties / comparison / properties / dimensions / properties / cost_to_value / additionalPropertiesAdded value: +true - added
Output schema / properties / comparison / properties / dimensions / properties / cost_to_value / propertiesAdded 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" + } +} - added
Output schema / properties / comparison / properties / dimensions / properties / cost_to_value / requiredAdded value: +[ + "score", + "label", + "explanation" +] - added
Output schema / properties / comparison / properties / dimensions / properties / cost_to_value / typeAdded value: +"object" - removed
Output schema / properties / comparison / properties / dimensions / properties / counterparty_safety / $refRemoved value: -"#/properties/savvly/properties/counterparty_safety" - added
Output schema / properties / comparison / properties / dimensions / properties / counterparty_safety / additionalPropertiesAdded value: +true - added
Output schema / properties / comparison / properties / dimensions / properties / counterparty_safety / propertiesAdded 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" + } +} - added
Output schema / properties / comparison / properties / dimensions / properties / counterparty_safety / requiredAdded value: +[ + "score", + "label", + "explanation" +] - added
Output schema / properties / comparison / properties / dimensions / properties / counterparty_safety / typeAdded value: +"object" - removed
Output schema / properties / comparison / properties / dimensions / properties / death_benefit / $refRemoved value: -"#/properties/savvly/properties/death_benefit" - added
Output schema / properties / comparison / properties / dimensions / properties / death_benefit / descriptionAdded value: +"Death-benefit summary." - added
Output schema / properties / comparison / properties / dimensions / properties / death_benefit / typeAdded value: +"string" - removed
Output schema / properties / comparison / properties / dimensions / properties / inflation_protection / $refRemoved value: -"#/properties/savvly/properties/inflation_protection" - added
Output schema / properties / comparison / properties / dimensions / properties / inflation_protection / additionalPropertiesAdded value: +true - added
Output schema / properties / comparison / properties / dimensions / properties / inflation_protection / propertiesAdded 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" + } +} - added
Output schema / properties / comparison / properties / dimensions / properties / inflation_protection / requiredAdded value: +[ + "score", + "label", + "explanation" +] - added
Output schema / properties / comparison / properties / dimensions / properties / inflation_protection / typeAdded value: +"object" - removed
Output schema / properties / comparison / properties / dimensions / properties / liquidity / $refRemoved value: -"#/properties/savvly/properties/liquidity" - added
Output schema / properties / comparison / properties / dimensions / properties / liquidity / additionalPropertiesAdded value: +true - added
Output schema / properties / comparison / properties / dimensions / properties / liquidity / propertiesAdded 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" + } +} - added
Output schema / properties / comparison / properties / dimensions / properties / liquidity / requiredAdded value: +[ + "score", + "label", + "explanation" +] - added
Output schema / properties / comparison / properties / dimensions / properties / liquidity / typeAdded value: +"object" - removed
Output schema / properties / comparison / properties / dimensions / properties / longevity_protection / $refRemoved value: -"#/properties/savvly/properties/longevity_protection" - added
Output schema / properties / comparison / properties / dimensions / properties / longevity_protection / additionalPropertiesAdded value: +true - added
Output schema / properties / comparison / properties / dimensions / properties / longevity_protection / propertiesAdded 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" + } +} - added
Output schema / properties / comparison / properties / dimensions / properties / longevity_protection / requiredAdded value: +[ + "score", + "label", + "explanation" +] - added
Output schema / properties / comparison / properties / dimensions / properties / longevity_protection / typeAdded value: +"object" - removed
Output schema / properties / comparison / properties / dimensions / properties / market_upside / $refRemoved value: -"#/properties/savvly/properties/market_upside" - added
Output schema / properties / comparison / properties / dimensions / properties / market_upside / additionalPropertiesAdded value: +true - added
Output schema / properties / comparison / properties / dimensions / properties / market_upside / propertiesAdded 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" + } +} - added
Output schema / properties / comparison / properties / dimensions / properties / market_upside / requiredAdded value: +[ + "score", + "label", + "explanation" +] - added
Output schema / properties / comparison / properties / dimensions / properties / market_upside / typeAdded value: +"object" - removed
Output schema / properties / comparison / properties / dimensions / properties / portability / $refRemoved value: -"#/properties/savvly/properties/portability" - added
Output schema / properties / comparison / properties / dimensions / properties / portability / additionalPropertiesAdded value: +true - added
Output schema / properties / comparison / properties / dimensions / properties / portability / propertiesAdded 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" + } +} - added
Output schema / properties / comparison / properties / dimensions / properties / portability / requiredAdded value: +[ + "score", + "label", + "explanation" +] - added
Output schema / properties / comparison / properties / dimensions / properties / portability / typeAdded value: +"object" - removed
Output schema / properties / comparison / properties / dimensions / properties / regulatory_oversight / $refRemoved value: -"#/properties/savvly/properties/regulatory_oversight" - added
Output schema / properties / comparison / properties / dimensions / properties / regulatory_oversight / descriptionAdded value: +"Who regulates it (e.g. SEC vs state insurance)." - added
Output schema / properties / comparison / properties / dimensions / properties / regulatory_oversight / typeAdded value: +"string" - removed
Output schema / properties / comparison / properties / dimensions / properties / simplicity / $refRemoved value: -"#/properties/savvly/properties/simplicity" - added
Output schema / properties / comparison / properties / dimensions / properties / simplicity / additionalPropertiesAdded value: +true - added
Output schema / properties / comparison / properties / dimensions / properties / simplicity / propertiesAdded 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" + } +} - added
Output schema / properties / comparison / properties / dimensions / properties / simplicity / requiredAdded value: +[ + "score", + "label", + "explanation" +] - added
Output schema / properties / comparison / properties / dimensions / properties / simplicity / typeAdded value: +"object" - removed
Output schema / properties / comparison / properties / dimensions / properties / tax_treatment / $refRemoved value: -"#/properties/savvly/properties/tax_treatment" - added
Output schema / properties / comparison / properties / dimensions / properties / tax_treatment / descriptionAdded value: +"Tax-treatment summary." - added
Output schema / properties / comparison / properties / dimensions / properties / tax_treatment / typeAdded value: +"string" - removed
Output schema / properties / comparisons / items / $refRemoved value: -"#/properties/comparison" - added
Output schema / properties / comparisons / items / additionalPropertiesAdded value: +true - added
Output schema / properties / comparisons / items / propertiesAdded 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" + } +} - added
Output schema / properties / comparisons / items / requiredAdded value: +[ + "product_type" +] - added
Output schema / properties / comparisons / items / typeAdded value: +"object" - removed
Output schema / properties / savvly / properties / affordability / $refRemoved value: -"#/properties/savvly/properties/longevity_protection" - added
Output schema / properties / savvly / properties / affordability / additionalPropertiesAdded value: +true - added
Output schema / properties / savvly / properties / affordability / propertiesAdded 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" + } +} - added
Output schema / properties / savvly / properties / affordability / requiredAdded value: +[ + "score", + "label", + "explanation" +] - added
Output schema / properties / savvly / properties / affordability / typeAdded value: +"object" - removed
Output schema / properties / savvly / properties / cost_to_value / $refRemoved value: -"#/properties/savvly/properties/longevity_protection" - added
Output schema / properties / savvly / properties / cost_to_value / additionalPropertiesAdded value: +true - added
Output schema / properties / savvly / properties / cost_to_value / propertiesAdded 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" + } +} - added
Output schema / properties / savvly / properties / cost_to_value / requiredAdded value: +[ + "score", + "label", + "explanation" +] - added
Output schema / properties / savvly / properties / cost_to_value / typeAdded value: +"object" - removed
Output schema / properties / savvly / properties / counterparty_safety / $refRemoved value: -"#/properties/savvly/properties/longevity_protection" - added
Output schema / properties / savvly / properties / counterparty_safety / additionalPropertiesAdded value: +true - added
Output schema / properties / savvly / properties / counterparty_safety / propertiesAdded 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" + } +} - added
Output schema / properties / savvly / properties / counterparty_safety / requiredAdded value: +[ + "score", + "label", + "explanation" +] - added
Output schema / properties / savvly / properties / counterparty_safety / typeAdded value: +"object" - removed
Output schema / properties / savvly / properties / inflation_protection / $refRemoved value: -"#/properties/savvly/properties/longevity_protection" - added
Output schema / properties / savvly / properties / inflation_protection / additionalPropertiesAdded value: +true - added
Output schema / properties / savvly / properties / inflation_protection / propertiesAdded 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" + } +} - added
Output schema / properties / savvly / properties / inflation_protection / requiredAdded value: +[ + "score", + "label", + "explanation" +] - added
Output schema / properties / savvly / properties / inflation_protection / typeAdded value: +"object" - removed
Output schema / properties / savvly / properties / liquidity / $refRemoved value: -"#/properties/savvly/properties/longevity_protection" - added
Output schema / properties / savvly / properties / liquidity / additionalPropertiesAdded value: +true - added
Output schema / properties / savvly / properties / liquidity / propertiesAdded 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" + } +} - added
Output schema / properties / savvly / properties / liquidity / requiredAdded value: +[ + "score", + "label", + "explanation" +] - added
Output schema / properties / savvly / properties / liquidity / typeAdded value: +"object" - removed
Output schema / properties / savvly / properties / market_upside / $refRemoved value: -"#/properties/savvly/properties/longevity_protection" - added
Output schema / properties / savvly / properties / market_upside / additionalPropertiesAdded value: +true - added
Output schema / properties / savvly / properties / market_upside / propertiesAdded 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" + } +} - added
Output schema / properties / savvly / properties / market_upside / requiredAdded value: +[ + "score", + "label", + "explanation" +] - added
Output schema / properties / savvly / properties / market_upside / typeAdded value: +"object" - removed
Output schema / properties / savvly / properties / portability / $refRemoved value: -"#/properties/savvly/properties/longevity_protection" - added
Output schema / properties / savvly / properties / portability / additionalPropertiesAdded value: +true - added
Output schema / properties / savvly / properties / portability / propertiesAdded 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" + } +} - added
Output schema / properties / savvly / properties / portability / requiredAdded value: +[ + "score", + "label", + "explanation" +] - added
Output schema / properties / savvly / properties / portability / typeAdded value: +"object" - removed
Output schema / properties / savvly / properties / simplicity / $refRemoved value: -"#/properties/savvly/properties/longevity_protection" - added
Output schema / properties / savvly / properties / simplicity / additionalPropertiesAdded value: +true - added
Output schema / properties / savvly / properties / simplicity / propertiesAdded 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" + } +} - added
Output schema / properties / savvly / properties / simplicity / requiredAdded value: +[ + "score", + "label", + "explanation" +] - added
Output schema / properties / savvly / properties / simplicity / typeAdded value: +"object"
- Changed
get_savvly_faq5 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - removed
Input schema / additionalPropertiesRemoved value: -false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / properties / total / maximumAdded value: +9007199254740991 - added
Output schema / properties / total / minimumAdded value: +-9007199254740991
- Changed
get_savvly_product_info4 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - removed
Input schema / additionalPropertiesRemoved value: -false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / properties / illustrative_payoutAdded 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" +}
- Changed
project_retirement_with_savvly10 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - removed
Input schema / additionalPropertiesRemoved value: -false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - changed
Output schema / properties / inputs / additionalPropertiesPrevious value: -{}New value: +true - added
Output schema / properties / inputs / propertyNamesAdded value: +{ + "type": "string" +} - added
Output schema / properties / metadata / properties / display_hints / properties / chart / properties / tooltip / propertyNamesAdded value: +{ + "type": "string" +} - added
Output schema / properties / metadata / properties / field_descriptions / propertyNamesAdded value: +{ + "type": "string" +} - added
Output schema / properties / result / properties / age_dependent_values / items / properties / age / maximumAdded value: +9007199254740991 - added
Output schema / properties / result / properties / age_dependent_values / items / properties / age / minimumAdded value: +-9007199254740991 - added
Output schema / properties / visualization / properties / chart / properties / tooltip / propertyNamesAdded value: +{ + "type": "string" +}
- Changed
project_savvly_lumpsum19 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - removed
Input schema / additionalPropertiesRemoved value: -false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - changed
Output schema / properties / inputs / additionalPropertiesPrevious value: -{}New value: +true - added
Output schema / properties / inputs / propertyNamesAdded value: +{ + "type": "string" +} - added
Output schema / properties / metadata / properties / field_descriptions / propertyNamesAdded value: +{ + "type": "string" +} - added
Output schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_age / maximumAdded value: +9007199254740991 - added
Output schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_age / minimumAdded value: +-9007199254740991 - added
Output schema / properties / summary / properties / early_exit_refund_usd / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - removed
Output schema / properties / summary / properties / early_exit_refund_usd / typeRemoved value: -[ - "number", - "null" -] - added
Output schema / properties / summary / properties / percentage_gain_upper_percent / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - removed
Output schema / properties / summary / properties / percentage_gain_upper_percent / typeRemoved value: -[ - "number", - "null" -] - added
Output schema / properties / summary / properties / savvly_above_market_upper_usd / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - removed
Output schema / properties / summary / properties / savvly_above_market_upper_usd / typeRemoved value: -[ - "number", - "null" -] - added
Output schema / properties / summary / properties / total_market_alone_upper_usd / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - removed
Output schema / properties / summary / properties / total_market_alone_upper_usd / typeRemoved value: -[ - "number", - "null" -] - added
Output schema / properties / summary / properties / total_savvly_upper_usd / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - removed
Output schema / properties / summary / properties / total_savvly_upper_usd / typeRemoved value: -[ - "number", - "null" -] - added
Output schema / properties / visualization / properties / chart / properties / tooltip / propertyNamesAdded value: +{ + "type": "string" +}
- Changed
project_savvly_monthly19 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - removed
Input schema / additionalPropertiesRemoved value: -false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - changed
Output schema / properties / inputs / additionalPropertiesPrevious value: -{}New value: +true - added
Output schema / properties / inputs / propertyNamesAdded value: +{ + "type": "string" +} - added
Output schema / properties / metadata / properties / field_descriptions / propertyNamesAdded value: +{ + "type": "string" +} - added
Output schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_age / maximumAdded value: +9007199254740991 - added
Output schema / properties / result / properties / payout_age_dependent_values / items / properties / payout_age / minimumAdded value: +-9007199254740991 - added
Output schema / properties / summary / properties / early_exit_refund_usd / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - removed
Output schema / properties / summary / properties / early_exit_refund_usd / typeRemoved value: -[ - "number", - "null" -] - added
Output schema / properties / summary / properties / percentage_gain_upper_percent / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - removed
Output schema / properties / summary / properties / percentage_gain_upper_percent / typeRemoved value: -[ - "number", - "null" -] - added
Output schema / properties / summary / properties / savvly_above_market_upper_usd / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - removed
Output schema / properties / summary / properties / savvly_above_market_upper_usd / typeRemoved value: -[ - "number", - "null" -] - added
Output schema / properties / summary / properties / total_market_alone_upper_usd / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - removed
Output schema / properties / summary / properties / total_market_alone_upper_usd / typeRemoved value: -[ - "number", - "null" -] - added
Output schema / properties / summary / properties / total_savvly_upper_usd / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - removed
Output schema / properties / summary / properties / total_savvly_upper_usd / typeRemoved value: -[ - "number", - "null" -] - added
Output schema / properties / visualization / properties / chart / properties / tooltip / propertyNamesAdded value: +{ + "type": "string" +}
- Changed
search_savvly_content15 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - removed
Input schema / additionalPropertiesRemoved value: -false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / properties / filter_applied / properties / audience / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Output schema / properties / filter_applied / properties / audience / typeRemoved value: -[ - "string", - "null" -] - added
Output schema / properties / filter_applied / properties / limit / maximumAdded value: +9007199254740991 - added
Output schema / properties / filter_applied / properties / limit / minimumAdded value: +-9007199254740991 - added
Output schema / properties / filter_applied / properties / query / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Output schema / properties / filter_applied / properties / query / typeRemoved value: -[ - "string", - "null" -] - added
Output schema / properties / filter_applied / properties / section / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Output schema / properties / filter_applied / properties / section / typeRemoved value: -[ - "string", - "null" -] - added
Output schema / properties / matched / maximumAdded value: +9007199254740991 - added
Output schema / properties / matched / minimumAdded value: +-9007199254740991 - added
Output schema / properties / total_in_library / maximumAdded value: +9007199254740991 - added
Output schema / properties / total_in_library / minimumAdded value: +-9007199254740991
7 tool updates
v1.0.86- Changed
check_savvly_eligibility1 field changed- changed
Input schema / properties / channel / descriptionPrevious value: -"Distribution channel"New value: +"Distribution channel — one of 'individual', 'employer', 'advisor' (default 'individual')."
- Changed
compare_savvly_vs_alternative2 fields changed- changed
Input schema / properties / alternative / descriptionPrevious 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'." - removed
Input schema / requiredRemoved value: -[ - "alternative" -]
- Changed
get_savvly_faq1 field changed- changed
Input schema / properties / section / enumPrevious 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" +]
- Changed
get_savvly_product_info4 fields changed- changed
Input schema / properties / section / descriptionPrevious 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." - changed
Input schema / properties / section / enumPrevious value: -[ - "all", - "overview", - "regulatory", - "investment", - "fees", - "payouts", - "tax", - "distribution" -]New value: +[ + "all", + "overview", + "regulatory", + "investment", + "expenses", + "payouts", + "tax", + "distribution" +] - added
Output schema / properties / expensesAdded 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" +} - removed
Output schema / properties / feesRemoved 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" -}
- Changed
project_savvly_lumpsum1 field changed- changed
Output schema / properties / summary / properties / narrative / descriptionPrevious 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."
- Changed
project_savvly_monthly1 field changed- changed
Output schema / properties / summary / properties / narrative / descriptionPrevious 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."
- Changed
search_savvly_content1 field changed- changed
Input schema / properties / audience / descriptionPrevious 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."
2 tool updates
v1.0.75- Changed
project_savvly_lumpsum1 field changed- changed
Input schema / properties / withdrawal_age / minimumPrevious value: -25New value: +18
- Changed
project_savvly_monthly1 field changed- changed
Input schema / properties / withdrawal_age / minimumPrevious value: -25New value: +18
5 tool updates
v1.0.69- Changed
check_savvly_eligibility1 field changed- changed
Output schema / properties / age_eligible / descriptionPrevious 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."
- Changed
project_retirement_with_savvly1 field changed- changed
Input schema / properties / current_age / minimumPrevious value: -25New value: +18
- Changed
project_savvly_lumpsum2 fields changed- changed
Input schema / properties / current_age / descriptionPrevious 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)" - changed
Input schema / properties / current_age / minimumPrevious value: -25New value: +18
- Changed
project_savvly_monthly4 fields changed- removed
Input schema / properties / contribution_years / defaultRemoved value: -27 - changed
Input schema / properties / contribution_years / descriptionPrevious 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." - changed
Input schema / properties / current_age / descriptionPrevious 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)" - changed
Input schema / properties / current_age / minimumPrevious value: -25New value: +18
- Changed
search_savvly_content1 field changed- changed
Input schema / properties / audience / descriptionPrevious 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."
3 tool updates
v1.0.68- Changed
get_savvly_faq12 fields changed- added
Input schema / properties / sectionAdded 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" +} - removed
Input schema / properties / topicRemoved value: -{ - "default": "all", - "description": "Filter FAQ by topic", - "enum": [ - "general", - "investment", - "payouts", - "withdrawals", - "tax", - "fees", - "employer", - "regulatory", - "all" - ], - "type": "string" -} - changed
Output schema / properties / entries / descriptionPrevious value: -"Filtered FAQ entries."New value: +"Filtered FAQ entries (the audience:'general' Q&A slice)." - added
Output schema / properties / entries / items / properties / audienceAdded value: +{ + "enum": [ + "employee", + "advisor", + "broker", + "employer", + "universal", + "general" + ], + "type": "string" +} - removed
Output schema / properties / entries / items / properties / categoryRemoved value: -{ - "description": "FAQ category.", - "enum": [ - "general", - "investment", - "payouts", - "withdrawals", - "tax", - "fees", - "employer", - "regulatory" - ], - "type": "string" -} - added
Output schema / properties / entries / items / properties / footnotesAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +} - removed
Output schema / properties / entries / items / properties / related_idsRemoved value: -{ - "items": { - "type": "string" - }, - "type": "array" -} - added
Output schema / properties / entries / items / properties / sectionAdded value: +{ + "type": "string" +} - changed
Output schema / properties / entries / items / requiredPrevious value: -[ - "id", - "category", - "question", - "answer", - "related_ids", - "keywords" -]New value: +[ + "id", + "audience", + "section", + "question", + "answer", + "footnotes" +] - added
Output schema / properties / sectionAdded value: +{ + "description": "Section filter applied to produce this result set ('all' if no filter).", + "type": "string" +} - removed
Output schema / properties / topicRemoved value: -{ - "description": "Topic filter applied to produce this result set ('all' if no filter).", - "type": "string" -} - changed
Output schema / requiredPrevious value: -[ - "topic", - "total", - "entries" -]New value: +[ + "section", + "total", + "entries" +]
- Changed
get_savvly_product_info2 fields changed- changed
Output schema / properties / company / descriptionPrevious value: -"Issuer / adviser entity information."New value: +"Issuer / advisor entity information." - changed
Output schema / properties / regulatory / descriptionPrevious 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."
- Changed
search_savvly_content14 fields changed- changed
Input schema / properties / audience / descriptionPrevious 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." - changed
Input schema / properties / audience / enumPrevious value: -[ - "employee", - "advisor", - "broker", - "employer", - "universal" -]New value: +[ + "employee", + "advisor", + "broker", + "employer", + "universal", + "general" +] - added
Input schema / properties / sectionAdded value: +{ + "description": "Substring match against section slugs (e.g. 'tax', 'retention', 'eligibility'). Case-insensitive.", + "type": "string" +} - removed
Input schema / properties / subsectionRemoved value: -{ - "description": "Substring match against subsection labels (e.g. 'Tax', 'Retention', 'Eligibility'). Case-insensitive.", - "type": "string" -} - added
Output schema / properties / available_sectionsAdded value: +{ + "description": "Section slugs available within the (optionally) selected audience.", + "items": { + "type": "string" + }, + "type": "array" +} - removed
Output schema / properties / available_subsectionsRemoved value: -{ - "description": "Subsection labels available within the (optionally) selected audience.", - "items": { - "type": "string" - }, - "type": "array" -} - changed
Output schema / properties / entries / items / properties / audience / enumPrevious value: -[ - "employee", - "advisor", - "broker", - "employer", - "universal" -]New value: +[ + "employee", + "advisor", + "broker", + "employer", + "universal", + "general" +] - added
Output schema / properties / entries / items / properties / keywordsAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +} - removed
Output schema / properties / entries / items / properties / subsectionRemoved value: -{ - "type": "string" -} - changed
Output schema / properties / entries / items / requiredPrevious value: -[ - "id", - "audience", - "section", - "subsection", - "question", - "answer", - "footnotes" -]New value: +[ + "id", + "audience", + "section", + "question", + "answer", + "footnotes" +] - added
Output schema / properties / filter_applied / properties / sectionAdded value: +{ + "type": [ + "string", + "null" + ] +} - removed
Output schema / properties / filter_applied / properties / subsectionRemoved value: -{ - "type": [ - "string", - "null" - ] -} - changed
Output schema / properties / filter_applied / requiredPrevious value: -[ - "audience", - "subsection", - "query", - "limit" -]New value: +[ + "audience", + "section", + "query", + "limit" +] - changed
Output schema / requiredPrevious value: -[ - "total_in_library", - "matched", - "filter_applied", - "available_subsections", - "entries" -]New value: +[ + "total_in_library", + "matched", + "filter_applied", + "available_sections", + "entries" +]
2 tool updates
v1.0.67- Changed
get_savvly_product_info3 fields changed- added
Input schema / $schemaAdded value: +"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / sectionAdded 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" +}
- Changed
search_savvly_content1 field changed- changed
Input schema / properties / query / descriptionPrevious 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."
2 tool updates
v1.0.58- Changed
compare_savvly_vs_alternative24 fields changed- added
Output schema / properties / comparison / properties / categoryAdded value: +{ + "description": "Product category.", + "type": "string" +} - added
Output schema / properties / comparison / properties / descriptionAdded value: +{ + "description": "Short description of the alternative.", + "type": "string" +} - added
Output schema / properties / comparison / properties / dimensionsAdded 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" +} - added
Output schema / properties / comparison / properties / display_nameAdded value: +{ + "description": "Human-readable product name.", + "type": "string" +} - added
Output schema / properties / comparison / properties / product_typeAdded value: +{ + "description": "Alternative product slug, e.g. 'fixed_annuity'.", + "type": "string" +} - added
Output schema / properties / comparison / requiredAdded value: +[ + "product_type" +] - added
Output schema / properties / comparisons / items / $refAdded value: +"#/properties/comparison" - removed
Output schema / properties / comparisons / items / additionalPropertiesRemoved value: -true - removed
Output schema / properties / comparisons / items / propertiesRemoved value: -{} - removed
Output schema / properties / comparisons / items / typeRemoved value: -"object" - added
Output schema / properties / metadata / properties / disclaimerAdded value: +{ + "description": "Required disclaimer.", + "type": "string" +} - added
Output schema / properties / metadata / properties / versionAdded value: +{ + "description": "Comparison data version.", + "type": "string" +} - added
Output schema / properties / savvly / properties / affordabilityAdded value: +{ + "$ref": "#/properties/savvly/properties/longevity_protection" +} - added
Output schema / properties / savvly / properties / cost_to_valueAdded value: +{ + "$ref": "#/properties/savvly/properties/longevity_protection" +} - added
Output schema / properties / savvly / properties / counterparty_safetyAdded value: +{ + "$ref": "#/properties/savvly/properties/longevity_protection" +} - added
Output schema / properties / savvly / properties / death_benefitAdded value: +{ + "description": "Death-benefit summary.", + "type": "string" +} - added
Output schema / properties / savvly / properties / inflation_protectionAdded value: +{ + "$ref": "#/properties/savvly/properties/longevity_protection" +} - added
Output schema / properties / savvly / properties / liquidityAdded value: +{ + "$ref": "#/properties/savvly/properties/longevity_protection" +} - added
Output schema / properties / savvly / properties / longevity_protectionAdded 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" +} - added
Output schema / properties / savvly / properties / market_upsideAdded value: +{ + "$ref": "#/properties/savvly/properties/longevity_protection" +} - added
Output schema / properties / savvly / properties / portabilityAdded value: +{ + "$ref": "#/properties/savvly/properties/longevity_protection" +} - added
Output schema / properties / savvly / properties / regulatory_oversightAdded value: +{ + "description": "Who regulates it (e.g. SEC vs state insurance).", + "type": "string" +} - added
Output schema / properties / savvly / properties / simplicityAdded value: +{ + "$ref": "#/properties/savvly/properties/longevity_protection" +} - added
Output schema / properties / savvly / properties / tax_treatmentAdded value: +{ + "description": "Tax-treatment summary.", + "type": "string" +}
- Changed
get_savvly_product_info15 fields changed- added
Output schema / properties / channelsAdded value: +{ + "description": "Distribution channels through which Savvly is offered.", + "items": {}, + "type": "array" +} - added
Output schema / properties / companyAdded value: +{ + "additionalProperties": true, + "description": "Issuer / adviser entity information.", + "properties": {}, + "type": "object" +} - added
Output schema / properties / disclaimersAdded value: +{ + "additionalProperties": true, + "description": "SEC-style disclaimers and required legal language.", + "properties": {}, + "type": "object" +} - added
Output schema / properties / early_withdrawalAdded value: +{ + "additionalProperties": true, + "description": "Early-withdrawal / surrender terms and the value returned to the estate.", + "properties": {}, + "type": "object" +} - added
Output schema / properties / feesAdded 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" +} - added
Output schema / properties / investmentAdded 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" +} - added
Output schema / properties / linksAdded value: +{ + "additionalProperties": true, + "description": "Relevant URLs (website, disclosures, etc.).", + "properties": {}, + "type": "object" +} - added
Output schema / properties / longevity_poolAdded value: +{ + "additionalProperties": true, + "description": "How the longevity pool works — exited participants' unused shares may be allocated to remaining participants.", + "properties": {}, + "type": "object" +} - added
Output schema / properties / next_stepsAdded value: +{ + "additionalProperties": true, + "description": "Suggested next actions for an interested investor.", + "properties": {}, + "type": "object" +} - added
Output schema / properties / payout_scheduleAdded 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" +} - added
Output schema / properties / portabilityAdded value: +{ + "description": "Whether the position is portable.", + "type": "boolean" +} - added
Output schema / properties / portability_noteAdded value: +{ + "description": "Detail on portability.", + "type": "string" +} - added
Output schema / properties / positioning_statementAdded value: +{ + "description": "One-sentence positioning — what Savvly is and is NOT (not insurance, not an annuity).", + "type": "string" +} - added
Output schema / properties / regulatoryAdded value: +{ + "additionalProperties": true, + "description": "Regulatory status: SEC registration, Investment Company Act of 1940, adviser, custodian, and is_insurance/is_annuity flags.", + "properties": {}, + "type": "object" +} - added
Output schema / properties / tax_treatmentAdded value: +{ + "additionalProperties": true, + "description": "Tax treatment of payouts and contributions.", + "properties": {}, + "type": "object" +}
6 tool updates
v1.0.39- Changed
check_savvly_eligibility1 field changed- changed
Output schema / properties / age_eligible / descriptionPrevious value: -"True if age falls within the 25–79 minimum/maximum range."New value: +"True if age falls within the 25–75 minimum/maximum range."
- Changed
compare_savvly_vs_alternative1 field changed- changed
Input schema / properties / alternative / enumPrevious value: -[ - "fixed_annuity", - "variable_annuity", - "indexed_annuity", - "target_date_fund", - "managed_payout_fund", - "social_security_delay", - "self_managed_drawdown", - "all" -]New value: +[ + "fixed_annuity", + "variable_annuity", + "indexed_annuity", + "target_date_fund", + "managed_payout_fund", + "all" +]
- Changed
get_savvly_product_info1 field changed- changed
Output schema / properties / name / descriptionPrevious value: -"Product name (e.g. 'Savvly Longevity Benefit Fund')."New value: +"Product name (e.g. 'Savvly Longevity Benefit')."
- Changed
project_retirement_with_savvly2 fields changed- changed
Input schema / properties / current_age / maximumPrevious value: -79New value: +75 - changed
Output schema / properties / metadata / properties / disclaimer / properties / assumptions / descriptionPrevious value: -"Verbatim bullet list of key assumptions used by the simulation (SSA tables, 8% market growth, 3% early-withdrawal rate, net of fees, 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, 3% early-withdrawal rate, net of fund operating expenses, etc.). Surface when a user asks what the projection assumes."
- Changed
project_savvly_lumpsum3 fields changed- changed
Input schema / properties / current_age / maximumPrevious value: -79New value: +75 - changed
Output schema / properties / metadata / properties / disclaimer / properties / assumptions / descriptionPrevious value: -"Verbatim bullet list of key assumptions used by the simulation (SSA tables, 8% market growth, 3% early-withdrawal rate, net of fees, 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, 3% early-withdrawal rate, net of fund operating expenses, etc.). Surface when a user asks what the projection assumes." - changed
Output schema / properties / result / properties / payout_age_dependent_values / items / properties / savvly_upside_lower / descriptionPrevious 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. Lower bound for the incremental payout at this age attributable to Savvly's longevity benefit (savvly_payout − payout_market_alone)."
- Changed
project_savvly_monthly3 fields changed- changed
Input schema / properties / current_age / maximumPrevious value: -79New value: +75 - changed
Output schema / properties / metadata / properties / disclaimer / properties / assumptions / descriptionPrevious value: -"Verbatim bullet list of key assumptions used by the simulation (SSA tables, 8% market growth, 3% early-withdrawal rate, net of fees, 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, 3% early-withdrawal rate, net of fund operating expenses, etc.). Surface when a user asks what the projection assumes." - changed
Output schema / properties / result / properties / payout_age_dependent_values / items / properties / savvly_upside_lower / descriptionPrevious 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. Lower bound for the incremental payout at this age attributable to Savvly's longevity benefit (savvly_payout − payout_market_alone)."
8 tool updates
v0.1.0- First observed
check_savvly_eligibility - First observed
compare_savvly_vs_alternative - First observed
get_savvly_faq - First observed
get_savvly_product_info - First observed
project_retirement_with_savvly - First observed
project_savvly_lumpsum - First observed
project_savvly_monthly - First observed
search_savvly_content
TDQS
Scored across 8 tools
The three projection tools (lumpsum, monthly, retirement_with_savvly) are separable by their input scenarios, but the informational cluster—get_savvly_product_info, get_savvly_faq, and search_savvly_content—overlaps heavily, with the FAQ tool even admitting it is a convenience view of search_savvly_content. Descriptions clarify boundaries reasonably well, but an agent could still pick the wrong info-retrieval tool.
All names use snake_case with a leading verb and the 'savvly' domain token (compare_savvly_vs_alternative, get_savvly_product_info, project_savvly_lumpsum, search_savvly_content). The pattern is highly predictable and readable throughout.
Eight tools is well-scoped for a product-information and retirement-projection server, with no redundant or filler tools. Each tool covers a distinct capability (info, comparison, eligibility, FAQ, search, and three projection variants).
The surface covers the core lifecycle of a retirement-product info server: educate (info/FAQ/search), compare, check eligibility, and project (lump sum, monthly, full trajectory). Minor gaps remain—no explicit expense/cost breakdown tool or enrollment/contact operation—but these are largely absorbed by the product info tool.
Maintenance
Related MCP Connectors
Public, read-only MCP server for FarmNeural company facts, packages, and capabilities.
MCP server for querying Forkast documentation
- UnifAPIOAuthcom.unifapi
Hosted MCP server for live public-data APIs and Skills for AI agents.
Read-only MCP server for Sandwich aging-parent care resources and cost data.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceProvides a sovereign, MIT-licensed MCP server for professional-service workflows, running entirely on your infrastructure with Ed25519 cryptographic signing for every action.MIT
- AlicenseNot gradedqualityAmaintenanceA stateless MCP server for composing, validating, auditing, and rendering consequential documents from a small semantic model.MIT
- AlicenseAqualityAmaintenanceOfficial 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.4MIT
- AlicenseNot gradedqualityAmaintenanceMCP 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