Retirement Lab MCP documentation
Run hypothetical retirement simulations across countries, taxes, spending, and market assumptions.
Endpoint: https://retirementlab.app/api/mcp
Retirement Lab is a financial calculator. Every result is a hypothetical projection based on the inputs and assumptions supplied, not financial, tax, investment, or legal advice and not a forecast or guarantee.
Connect a client
OAuth (primary)
Add https://retirementlab.app/api/mcp as a remote MCP server. A compatible client
discovers Retirement Lab’s OAuth metadata, opens a browser, and asks you to
approve the mcp scope. Access and refresh tokens are opaque and
hashed at rest. Disconnect a client from Connected apps in the
Retirement Lab account menu; its next MCP call will fail with 401.
- Protected-resource metadata: https://retirementlab.app/.well-known/oauth-protected-resource/api/mcp
- Authorization-server metadata: https://retirementlab.app/.well-known/oauth-authorization-server
API key (advanced fallback)
- Sign in at Retirement Lab.
- Open the account menu, choose MCP API keys, add a label, and issue the key.
- Copy the cleartext once. The server stores only its SHA-256 hash.
- Configure a Streamable HTTP client with URL
https://retirementlab.app/api/mcpand headerAuthorization: Bearer <key>. - Rotate or revoke the key from the same account screen. Rotation immediately invalidates the previous value.
Never send an API key to another host or place it in a prompt, source file, or shared transcript.
Supported clients and transport
Retirement Lab uses stateless Streamable HTTP and supports MCP protocol
revisions 2025-03-26 and 2025-06-18. It is designed for
remote-connector clients with OAuth, including Claude on the web and Claude
Desktop. Remote connectors already added on the web can be used from Claude
mobile. Claude Code and other MCP clients can connect when they support
Streamable HTTP plus OAuth, or a client-specific static bearer header for the
API-key fallback.
Generic setup values:
{
"name": "Retirement Lab",
"transport": "streamable_http",
"url": "https://retirementlab.app/api/mcp",
"authentication": "oauth"
}
Currency contract
- A simulation’s
countryis its country of tax residence. - Country never determines the units of monetary input values.
- Root-level
input_currencydeclares those units as an ISO 4217 code. - All monetary values in one payload must use the same currency.
- The server converts once into the tax-residence country’s calculator currency and returns the rate and provenance it used.
For explicit monetary sweep values, use sweep_currency. For a
JSON Merge Patch containing money, use patch_currency. Do not infer
currency from a symbol, country, citizenship, or income-source country.
Supported countries and tax regimes
This list is rendered from the calculator’s tax-policy registry:
Australia, Austria, Belgium, Brazil, Canada, Costa Rica, Cyprus, France, Germany, Greece, Italy, Japan, Malaysia, Malta, Mexico, Netherlands, Panama, Portugal, Singapore, Spain, Switzerland, Thailand, UAE, UK, US, Uruguay
The default regime is the ordinary resident tax model for the selected country. These additional time-bounded regimes are rendered from the implementation registry:
| Regime | Country | Input key | Modeled duration |
|---|---|---|---|
Cyprus_NonDom | Cyprus | non-dom | 17 years |
Greece_Pensioner | Greece | foreign-pensioner-flat-7pct | 15 years |
Italy_Pensioner | Italy | pensioner-flat-7pct | 10 years |
Malta_NonDom | Malta | non-dom | 17 years |
NHR | Portugal | nhr | 10 years |
Call get_supported_inputs at the start of a session for the
current machine-readable countries, regimes, currencies, portfolio presets,
assumptions version, and a minimal valid payload.
Asynchronous run lifecycle
- Enqueue: call
run_simulation,compare_countries,sensitivity_sweep, orrun_sweep. Save the returnedrun_idandpoll_after_ms. - Wait or poll: call
wait_for_runwith that id, or pollget_run_result, until status issucceededorfailed. - Inspect: call
get_run_resultwith selectors such ascomparison,yearly_percentiles, orsimulation_snapshot. The stored result reports what the hypothetical simulation shows; it does not rerun compute.
Current quotas and tier limitations
The values below are read from the same settings used by the runtime. They can change as the Public Beta is tuned.
| Limit | Free | Pro / 30-day Pass |
|---|---|---|
| Daily MCP compute units | 10 | 1000 |
| Simulation paths per payload | 10,000 | 100,000 |
| Explicit sweep values | 10 | 100 |
| Simulation horizon | 75 years | 120 years |
| Country comparison | Up to 2 countries | Subject to sweep caps |
Compute requests also use a distributed limit of
60 requests per 60 minutes, a
1,000,000-byte compact-result cap, and a
30-second maximum per wait_for_run call.
An account can keep up to 5 active API keys.
OAuth and API keys for one user draw from the same user-level compute allowance.
Product feature gates still apply; for example, a comparison with three or more
countries requires Pro or a 30-day Pass.
Complete example workflows
1. Run a retirement simulation
First call get_supported_inputs. Then call
run_simulation with these arguments:
{
"input_currency": "USD",
"simulation": {
"initial_year": 2026,
"age": 45,
"plan_to_age": 95,
"initial_net_worth": 1000000,
"baseline_annual_expenses": 60000,
"additional_expenses": [],
"additional_income": [],
"country": "US",
"avg_return": 0.07,
"volatility": 0.12,
"approximate_yield_rate": 0.02,
"taxable_balance": 500000,
"tax_deferred_balance": 350000,
"tax_free_balance": 150000,
"taxable_cost_basis": 350000
},
"idempotency_key": "example-retirement-run-1"
}
Use the returned id in wait_for_run:
{
"run_id": 123,
"max_wait_seconds": 10
}
If still queued or running, wait for poll_after_ms and repeat.
When it succeeds, inspect compact results:
{
"run_id": 123,
"selectors": [
"yearly_percentiles"
]
}
2. Compare countries or tax-residence assumptions
Call compare_countries with the same USD-denominated financial
inputs for each tax residence. A three-country comparison requires Pro or a
30-day Pass.
{
"input_currency": "USD",
"base_payload": {
"simulation": {
"initial_year": 2026,
"age": 45,
"plan_to_age": 95,
"initial_net_worth": 1000000,
"baseline_annual_expenses": 60000,
"additional_expenses": [],
"additional_income": [],
"country": "US",
"avg_return": 0.07,
"volatility": 0.12,
"approximate_yield_rate": 0.02,
"taxable_balance": 500000,
"tax_deferred_balance": 350000,
"tax_free_balance": 150000,
"taxable_cost_basis": 350000
}
},
"countries": [
"US",
"Spain",
"Portugal"
],
"idempotency_key": "example-country-comparison-1"
}
Wait for the returned run id, then call get_run_result with:
{
"run_id": 124,
"selectors": [
"comparison"
]
}
Each row is a hypothetical projection for the same supplied inputs under that tax-residence assumption. It is not a relocation instruction.
3. Run a sensitivity sweep and inspect the result
Call sensitivity_sweep to vary one supported assumption:
{
"input_currency": "USD",
"payload": {
"simulation": {
"initial_year": 2026,
"age": 45,
"plan_to_age": 95,
"initial_net_worth": 1000000,
"baseline_annual_expenses": 60000,
"additional_expenses": [],
"additional_income": [],
"country": "US",
"avg_return": 0.07,
"volatility": 0.12,
"approximate_yield_rate": 0.02,
"taxable_balance": 500000,
"tax_deferred_balance": 350000,
"tax_free_balance": 150000,
"taxable_cost_basis": 350000
}
},
"variable": "retirement_year",
"values": [
"2040",
"2045",
"2050"
],
"idempotency_key": "example-retirement-age-sweep-1"
}
Wait for the returned run id, then inspect the stored sweep:
{
"run_id": 125
}
Summarize only the failure probabilities and other values the simulation returns, given these assumptions.
Tool catalog and safety behavior
This catalog is generated from the registered MCP tools. Public-share creation is explicitly marked as a state-changing action that crosses a public boundary.
- Run Retirement Simulation
run_simulationChanges account state; may cross a public/external boundaryEnqueue a hypothetical projection; based on your inputs, the simulation shows status and polling details after REST authorization checks run.
- Run Parameter Sweep
run_sweepChanges account state; may cross a public/external boundaryEnqueue a sweep for a hypothetical projection; based on your inputs, the simulation shows queued status after REST tier and run-limit checks run.
- Compare Tax Residences
compare_countriesChanges account state; may cross a public/external boundaryCompare supported countries by enqueueing a country sweep for a hypothetical projection; based on your inputs, the simulation shows status and polling details.
- Run Sensitivity Sweep
sensitivity_sweepChanges account state; may cross a public/external boundaryEnqueue a single-variable non-country sensitivity sweep for a hypothetical projection; based on your inputs, the simulation shows status and polling details.
- Inspect Simulation Result
get_run_resultRead-onlyReturn compact stored results for a run; the simulation shows probabilities, terminal-wealth percentiles, and selected details based on your inputs. Use the yearly_percentiles selector for year-by-year percentile bands of the hypothetical projection, suitable for charting.
- Read Saved Scenario
get_scenarioRead-onlyRead a private mutable saved scenario and its normalized calculator inputs.
- Read Shared Result
get_shareRead-only; may cross a public/external boundaryRead an immutable public hypothetical-result share. To change its inputs, create a private variant from it.
- List Saved Scenarios
list_scenariosRead-onlyList private saved calculator scenarios, which may later be updated or cloned.
- List Simulation Runs
list_runsRead-onlyList private immutable hypothetical-run summaries without loading result or simulation payloads.
- List Shared Results
list_sharesRead-onlyList immutable public hypothetical-result share snapshots owned by this account.
- Create Saved Scenario
create_scenarioChanges account state; may cross a public/external boundaryCreate a new mutable saved calculator scenario from a validated simulation payload.
- Update Saved Scenario
update_scenarioChanges account stateApply JSON Merge Patch to saved calculator inputs using optimistic concurrency. Runs and public shares cannot be updated.
- Clone Scenario
clone_scenarioChanges account stateCreate a new mutable saved calculator scenario from a scenario, immutable run, or immutable public share snapshot.
- Create Scenario Variant
create_variantChanges account state; may cross a public/external boundaryApply JSON Merge Patch to a scenario, run, or public share; optionally save and enqueue the resulting hypothetical projection. Lineage is persisted.
- Preview Exit Tax
preview_exit_taxRead-only; may cross a public/external boundaryPreview a proposed relocation exit-tax calculation; based on your inputs, the hypothetical projection shows estimated tax impact without enqueueing compute.
- Preview Roth Conversion Tax
preview_conversion_taxRead-only; may cross a public/external boundaryPreview a Roth conversion tax calculation; based on your inputs, the hypothetical projection shows estimated tax impact without enqueueing compute.
- Wait for Simulation Run
wait_for_runRead-onlyPoll a stored run for a bounded period and return what the simulation shows once available, or a still-running envelope. Use the yearly_percentiles selector for year-by-year percentile bands of the hypothetical projection, suitable for charting.
- Save Run as Scenario
save_scenarioChanges account stateSave an unnamed run as a named scenario when the user asks to keep, name, or share it; otherwise runs stay unnamed and appear in the web app's run history. The history_url opens the stored hypothetical projection in the web app.
- Create Public Share Link
create_share_linkChanges account state; may cross a public/external boundaryCreate an externally visible, unlisted, immutable hypothetical-result share URL from exactly one completed run_id or the latest clean completed run for config_name. Anyone with the URL can view it; this never reruns a scenario.
- Cancel Simulation Run
cancel_runChanges account stateCancel a queued or running MCP-originated hypothetical projection owned by this account.
- List Supported Inputs
get_supported_inputsRead-onlyList supported calculator inputs, including countries, tax regimes, simulation modes, and the current assumptions version. The response also includes a ready-to-adapt minimal example payload and a short list of common input traps.
Data handling
- OAuth and API-key calls run as your Retirement Lab account and can read or change only resources the account can access.
- Scenario inputs and simulation results are stored so you can inspect and rerun them. Authenticated account data remains until account deletion.
- OAuth tokens and API keys are opaque and stored only as hashes. Cleartext API keys are displayed once.
- Tool-call analytics record an internal user id, tool name, result status, tier, and coarse authentication method. They do not store raw credentials, email addresses, prompts, or financial payloads for adoption measurement.
- A link created by
create_share_linkis unlisted but public: anyone with it can view the immutable shared result.
See the Retirement Lab Privacy Policy for collected data, processors, retention, export, deletion, and contact details.
Active-user metric: A distinct non-test Retirement Lab user with at least one MCP tool-call analytics event in the rolling window. OAuth and API-key breakdowns may overlap when one user uses both methods; no credential secrets or email addresses are stored in this metric.
Troubleshooting
- OAuth does not start or fails
- Confirm the endpoint is exactly
https://retirementlab.app/api/mcp, allow the browser sign-in window, and retry from the client. If a prior connection is stale, disconnect it under Connected apps and connect again. - Invalid inputs
- Call
get_supported_inputs, use an exact country label, includeinput_currency, and keep all money in that payload in the declared currency. Read structured validation details before retrying. - A run is still queued or running
- This is expected: simulations are asynchronous. Honor
poll_after_msand callwait_for_runorget_run_resultagain. Do not enqueue a duplicate; reuse anidempotency_keywhen retrying an enqueue. - Quota or tier error
- Read the returned cap, remaining daily compute units, and reset timing. Reduce paths, sweep values, or countries, or wait for the quota window. A tier error describes the product capability required.
- Expired or revoked credentials
- For OAuth, restart the connection flow. For an API key, issue or rotate a key in the account menu and replace the old bearer value. Revoked values cannot be restored.
Support
Contact [email protected] and include the client name, approximate time, tool name, and non-secret error text. Never send an API key, OAuth token, or complete financial payload. The availability of inbound routing does not establish how outbound replies are configured.