Skip to main content
Glama

savvly

Project Retirement Trajectory With Savvly

project_retirement_with_savvly
Read-onlyIdempotent

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.

Input Schema

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

Output Schema

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

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • removedInput schema / properties / session_id
      Removed value: -{
      -  "description": "REQUIRED on every call after your first. This MCP server associates all of your tool calls for a given task using session_id; a call that arrives without it cannot be associated with your earlier work and is treated as the start of an unrelated task, disconnected from the original goal. Omit it on your first call only — the server will issue one in the _mcp_instructions field of the result (or a trailing [MCP INSTRUCTIONS] text block) — then echo that exact value on every later call. Never invent a value, and do not issue parallel tool calls until the server has issued your session_id. One session_id covers the whole goal from start to finish: when you spawn subagents you MUST give them this same session_id, or their work is severed from yours. Without session_id, this server does not function as intended.",
      -  "type": "string"
      -}
    • removedOutput schema / properties / _mcp_instructions
      Removed value: -{
      -  "description": "Your handles for this task, confirmed by this MCP server on every response, and the instructions for echoing them on later calls. Read and follow.",
      -  "properties": {
      -    "instructions": {
      -      "type": "string"
      -    },
      -    "session_id": {
      -      "description": "Echo this exact value as the session_id argument on every subsequent tool call.",
      -      "type": "string"
      -    }
      -  },
      -  "type": "object"
      -}
  2. Changed12 schema fields changed
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • removedInput schema / additionalProperties
      Removed value: -false
    • addedInput schema / properties / session_id
      Added value: +{
      +  "description": "REQUIRED on every call after your first. This MCP server associates all of your tool calls for a given task using session_id; a call that arrives without it cannot be associated with your earlier work and is treated as the start of an unrelated task, disconnected from the original goal. Omit it on your first call only — the server will issue one in the _mcp_instructions field of the result (or a trailing [MCP INSTRUCTIONS] text block) — then echo that exact value on every later call. Never invent a value, and do not issue parallel tool calls until the server has issued your session_id. One session_id covers the whole goal from start to finish: when you spawn subagents you MUST give them this same session_id, or their work is severed from yours. Without session_id, this server does not function as intended.",
      +  "type": "string"
      +}
    • changedOutput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedOutput schema / properties / _mcp_instructions
      Added value: +{
      +  "description": "Your handles for this task, confirmed by this MCP server on every response, and the instructions for echoing them on later calls. Read and follow.",
      +  "properties": {
      +    "instructions": {
      +      "type": "string"
      +    },
      +    "session_id": {
      +      "description": "Echo this exact value as the session_id argument on every subsequent tool call.",
      +      "type": "string"
      +    }
      +  },
      +  "type": "object"
      +}
    • changedOutput schema / properties / inputs / additionalProperties
      Previous value: -{}New value: +true
    • addedOutput schema / properties / inputs / propertyNames
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / metadata / properties / display_hints / properties / chart / properties / tooltip / propertyNames
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / metadata / properties / field_descriptions / propertyNames
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / result / properties / age_dependent_values / items / properties / age / maximum
      Added value: +9007199254740991
    • addedOutput schema / properties / result / properties / age_dependent_values / items / properties / age / minimum
      Added value: +-9007199254740991
    • addedOutput schema / properties / visualization / properties / chart / properties / tooltip / propertyNames
      Added value: +{
      +  "type": "string"
      +}
  3. Changed5 schema fields changed
    • changedInput schema / properties / current_age / description
      Previous value: -"Current age (default 40). Accepts 0–75; an age under 18 is modeled on the age-18 basis (growth understated), flagged via the response's `age_modeling` block"New value: +"Current age (default 40)"
    • changedInput schema / properties / current_age / minimum
      Previous value: -0New value: +18
    • removedOutput schema / properties / result / properties / current_age_clamp_note
      Removed value: -{
      -  "description": "Disclosure (single-sourced from advisor_functions) that the projection is modeled on the age-18 basis and the shown growth is understated for a younger investor. Present only when clamped; display alongside any figures.",
      -  "type": "string"
      -}
    • removedOutput schema / properties / result / properties / current_age_clamped
      Removed value: -{
      -  "description": "Present + true ONLY when the supplied current_age was below the age-18 matrix floor; the projection was then modeled on the age-18 basis.",
      -  "type": "boolean"
      -}
    • removedOutput schema / properties / result / properties / modeled_current_age
      Removed value: -{
      -  "description": "The age used for the matrix lookup (18) when current_age was younger. Present only when clamped.",
      -  "type": "integer"
      -}
  4. Changed4 schema fields changed
    • removedOutput schema / properties / age_modeling
      Removed value: -{
      -  "additionalProperties": true,
      -  "description": "Present ONLY when current_age was under 18 and the projection was modeled on the age-18 basis (growth understated). Surface `note` to the user.",
      -  "properties": {
      -    "current_age_clamped": {
      -      "const": true,
      -      "description": "Always true when present. The supplied `current_age` was below the age-18 modeling floor, so the projection was computed on the age-18 basis.",
      -      "type": "boolean"
      -    },
      -    "modeled_current_age": {
      -      "description": "The age actually used for the projection matrix lookup (18) when the supplied current_age was younger.",
      -      "type": "integer"
      -    },
      -    "note": {
      -      "description": "Plain-English disclosure that the projection is modeled on the age-18 basis and the shown growth is understated for a younger investor. Display alongside any figures from this response.",
      -      "type": "string"
      -    }
      -  },
      -  "required": [
      -    "current_age_clamped",
      -    "modeled_current_age",
      -    "note"
      -  ],
      -  "type": "object"
      -}
    • addedOutput schema / properties / result / properties / current_age_clamp_note
      Added value: +{
      +  "description": "Disclosure (single-sourced from advisor_functions) that the projection is modeled on the age-18 basis and the shown growth is understated for a younger investor. Present only when clamped; display alongside any figures.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / result / properties / current_age_clamped
      Added value: +{
      +  "description": "Present + true ONLY when the supplied current_age was below the age-18 matrix floor; the projection was then modeled on the age-18 basis.",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / result / properties / modeled_current_age
      Added value: +{
      +  "description": "The age used for the matrix lookup (18) when current_age was younger. Present only when clamped.",
      +  "type": "integer"
      +}
  5. Changed3 schema fields changed
    • changedInput schema / properties / current_age / description
      Previous value: -"Current age (default 40)"New value: +"Current age (default 40). Accepts 0–75; an age under 18 is modeled on the age-18 basis (growth understated), flagged via the response's `age_modeling` block"
    • changedInput schema / properties / current_age / minimum
      Previous value: -25New value: +0
    • addedOutput schema / properties / age_modeling
      Added value: +{
      +  "additionalProperties": true,
      +  "description": "Present ONLY when current_age was under 18 and the projection was modeled on the age-18 basis (growth understated). Surface `note` to the user.",
      +  "properties": {
      +    "current_age_clamped": {
      +      "const": true,
      +      "description": "Always true when present. The supplied `current_age` was below the age-18 modeling floor, so the projection was computed on the age-18 basis.",
      +      "type": "boolean"
      +    },
      +    "modeled_current_age": {
      +      "description": "The age actually used for the projection matrix lookup (18) when the supplied current_age was younger.",
      +      "type": "integer"
      +    },
      +    "note": {
      +      "description": "Plain-English disclosure that the projection is modeled on the age-18 basis and the shown growth is understated for a younger investor. Display alongside any figures from this response.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "current_age_clamped",
      +    "modeled_current_age",
      +    "note"
      +  ],
      +  "type": "object"
      +}
  6. Changed2 schema fields changed
    • changedInput schema / properties / current_age / maximum
      Previous value: -79New value: +75
    • changedOutput schema / properties / metadata / properties / disclaimer / properties / assumptions / description
      Previous value: -"Verbatim bullet list of key assumptions used by the simulation (SSA tables, 8% market growth, 3% early-withdrawal rate, net of 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."
  7. Changed25 schema fields changed
    • changedInput schema / properties / annual_income_increase / default
      Previous value: -0New value: +2
    • changedInput schema / properties / annual_income_increase / description
      Previous value: -"Annual contribution % increase"New value: +"Annual contribution % increase (default 2)"
    • addedInput schema / properties / current_age / default
      Added value: +40
    • changedInput schema / properties / current_age / description
      Previous value: -"Current age"New value: +"Current age (default 40)"
    • addedInput schema / properties / current_retirement_savings / default
      Added value: +60000
    • changedInput schema / properties / current_retirement_savings / description
      Previous value: -"Current total retirement savings in USD"New value: +"Current total retirement savings in USD (default 60000)"
    • changedInput schema / properties / inflation_rate / description
      Previous value: -"Expected annual inflation rate %"New value: +"Expected annual inflation rate % (default 3)"
    • addedInput schema / properties / monthly_contribution / default
      Added value: +1000
    • changedInput schema / properties / monthly_contribution / description
      Previous value: -"Monthly retirement contribution in USD"New value: +"Monthly retirement contribution in USD (default 1000)"
    • changedInput schema / properties / monthly_paycheck / default
      Previous value: -0New value: +4500
    • changedInput schema / properties / monthly_paycheck / description
      Previous value: -"Desired monthly retirement paycheck (USD)"New value: +"Desired monthly retirement paycheck in USD (default 4500)"
    • changedInput schema / properties / other_retirement_income / default
      Previous value: -0New value: +1600
    • changedInput schema / properties / other_retirement_income / description
      Previous value: -"Other monthly retirement income (USD)"New value: +"Other monthly retirement income in USD (default 1600)"
    • changedInput schema / properties / percentage_in_savvly / description
      Previous value: -"Percentage of retirement savings allocated to Savvly"New value: +"Percentage of the retirement portfolio allocated to Savvly (default 5)"
    • changedInput schema / properties / post_retirement_return / description
      Previous value: -"Expected post-retirement annual return %"New value: +"Expected post-retirement annual return % (default 5)"
    • changedInput schema / properties / pre_retirement_return / description
      Previous value: -"Expected pre-retirement annual return %"New value: +"Expected pre-retirement annual return % (default 6)"
    • addedInput schema / properties / retirement_age / default
      Added value: +68
    • changedInput schema / properties / retirement_age / description
      Previous value: -"Planned retirement age"New value: +"Planned retirement age (default 68)"
    • removedInput schema / required
      Removed value: -[
      -  "current_age",
      -  "retirement_age",
      -  "monthly_contribution",
      -  "current_retirement_savings"
      -]
    • changedOutput schema / properties / metadata / properties / display_hints / description
      Previous value: -"Rendering guidance for the retirement projection chart. Tells AI clients to render `age_dependent_values` as a stacked area chart matching estimator.savvly.com — linear interpolation (no spline), no markers, so Savvly milestone payouts at ages 80/85/90/95 appear as sharp spikes with visible year-by-year depletion between them. KPI cards above and a narrative paragraph below the chart are encouraged."New value: +"Rendering guidance for the retirement projection chart. Tells AI clients to render `age_dependent_values` as a stacked area chart matching estimator.savvly.com — MILD smoothing (Chart.js tension 0.4), no markers, so Savvly milestone payouts at ages 80/85/90/95 still read as distinct spikes with visible year-by-year depletion between them. KPI cards above and a narrative paragraph below the chart are encouraged."
    • changedOutput schema / properties / metadata / properties / display_hints / properties / chart / additionalProperties
      Previous value: -falseNew value: +true
    • removedOutput schema / properties / metadata / properties / display_hints / properties / chart / properties / interpolation / const
      Removed value: -"linear"
    • addedOutput schema / properties / metadata / properties / display_hints / properties / chart / properties / tension
      Added value: +{
      +  "type": "number"
      +}
    • changedOutput schema / properties / metadata / required
      Previous value: -[
      -  "disclaimer",
      -  "field_descriptions",
      -  "display_hints"
      -]New value: +[
      +  "disclaimer",
      +  "field_descriptions"
      +]
    • addedOutput schema / properties / visualization
      Added value: +{
      +  "additionalProperties": true,
      +  "description": "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.",
      +  "properties": {
      +    "chart": {
      +      "additionalProperties": true,
      +      "description": "Machine-readable chart spec: type, axes, series (with brand colors), and rendering notes.",
      +      "properties": {
      +        "reference": {
      +          "description": "Canonical Savvly visualization this chart mirrors.",
      +          "type": "string"
      +        },
      +        "rendering_notes": {
      +          "description": "Plain-English rendering guidance for the client.",
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        "series": {
      +          "description": "One entry per plotted series — typically Savvly vs. the baseline / market-alone counterfactual.",
      +          "items": {
      +            "additionalProperties": true,
      +            "properties": {
      +              "color": {
      +                "description": "Hex color for this series. The series representing Savvly is always #3478eb (the Savvly brand blue).",
      +                "type": "string"
      +              },
      +              "field": {
      +                "description": "Per-row field plotted by this series.",
      +                "type": "string"
      +              },
      +              "label": {
      +                "description": "Legend label for this series.",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "field",
      +              "label",
      +              "color"
      +            ],
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        "tooltip": {
      +          "additionalProperties": {
      +            "type": "string"
      +          },
      +          "description": "Optional `field -> human label` map for chart tooltips.",
      +          "type": "object"
      +        },
      +        "type": {
      +          "description": "Chart type the client should render.",
      +          "enum": [
      +            "area",
      +            "line",
      +            "bar"
      +          ],
      +          "type": "string"
      +        },
      +        "x_axis": {
      +          "additionalProperties": true,
      +          "description": "Per-row field mapped to the x-axis, plus its display label.",
      +          "properties": {
      +            "field": {
      +              "type": "string"
      +            },
      +            "label": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "field",
      +            "label"
      +          ],
      +          "type": "object"
      +        },
      +        "y_axis": {
      +          "additionalProperties": true,
      +          "description": "Y-axis label and value format (e.g. 'currency_usd').",
      +          "properties": {
      +            "format": {
      +              "type": "string"
      +            },
      +            "label": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "label",
      +            "format"
      +          ],
      +          "type": "object"
      +        }
      +      },
      +      "required": [
      +        "type",
      +        "x_axis",
      +        "y_axis",
      +        "series",
      +        "rendering_notes"
      +      ],
      +      "type": "object"
      +    },
      +    "instruction": {
      +      "description": "Plain-English instruction telling the client to render `chart` from the per-row data in `result`, color the Savvly series #3478eb, and show the `disclosure` alongside the chart.",
      +      "type": "string"
      +    },
      +    "recommended": {
      +      "const": true,
      +      "description": "Always true. Signals to the calling AI client that it SHOULD render `chart` whenever it can display a graph.",
      +      "type": "boolean"
      +    }
      +  },
      +  "required": [
      +    "recommended",
      +    "instruction",
      +    "chart"
      +  ],
      +  "type": "object"
      +}
  8. Changed3 schema fields changed
    • changedOutput schema / properties / metadata / additionalProperties
      Previous value: -falseNew value: +true
    • changedOutput schema / properties / result / additionalProperties
      Previous value: -falseNew value: +true
    • changedOutput schema / properties / result / properties / age_dependent_values / items / additionalProperties
      Previous value: -falseNew value: +true
  9. First observed

TDQS

A4.6/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.