@nestpilot/mcp-app 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +350 -0
- package/dist/cli/doctor.d.ts +1 -0
- package/dist/cli/doctor.js +214 -0
- package/dist/cli/export-import.d.ts +6 -0
- package/dist/cli/export-import.js +132 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +168 -0
- package/dist/cli/init.d.ts +1 -0
- package/dist/cli/init.js +171 -0
- package/dist/host-configs/cowork.json +11 -0
- package/dist/host-configs/goose.yaml +22 -0
- package/dist/host-configs/openclaw-manifest.json +16 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +128 -0
- package/dist/mcp-app.html +155 -0
- package/dist/nestpilot-client.d.ts +44 -0
- package/dist/nestpilot-client.js +160 -0
- package/dist/planner.html +222 -0
- package/dist/server.d.ts +19 -0
- package/dist/server.js +245 -0
- package/dist/skills/SKILL.md +162 -0
- package/dist/skills/manifest.json +51 -0
- package/dist/skills/tools/activate_plan.md +36 -0
- package/dist/skills/tools/coach.md +59 -0
- package/dist/skills/tools/comprehensive_plan.md +65 -0
- package/dist/skills/tools/create_plan.md +59 -0
- package/dist/skills/tools/create_saved_plan.md +49 -0
- package/dist/skills/tools/delete_plan.md +42 -0
- package/dist/skills/tools/delete_scenario.md +38 -0
- package/dist/skills/tools/generate_proposal.md +63 -0
- package/dist/skills/tools/generate_retirement_report.md +50 -0
- package/dist/skills/tools/get_active_plan.md +44 -0
- package/dist/skills/tools/get_baseline_forecast.md +47 -0
- package/dist/skills/tools/get_plan.md +44 -0
- package/dist/skills/tools/get_plan_components.md +50 -0
- package/dist/skills/tools/get_scenario.md +46 -0
- package/dist/skills/tools/list_plans.md +44 -0
- package/dist/skills/tools/list_scenarios.md +42 -0
- package/dist/skills/tools/medicare-guardian.md +59 -0
- package/dist/skills/tools/nestpilot_run_plan.md +61 -0
- package/dist/skills/tools/optimize_roth_conversion.md +107 -0
- package/dist/skills/tools/optimize_ss_claiming.md +30 -0
- package/dist/skills/tools/rename_plan.md +34 -0
- package/dist/skills/tools/retirement-planner.md +55 -0
- package/dist/skills/tools/run_forecast.md +65 -0
- package/dist/skills/tools/run_saved_forecast.md +52 -0
- package/dist/skills/tools/run_scenario.md +66 -0
- package/dist/skills/tools/save_plan.md +48 -0
- package/dist/skills/tools/save_scenario.md +50 -0
- package/dist/skills/tools/verify_forecast.md +43 -0
- package/dist/src/config.d.ts +20 -0
- package/dist/src/config.js +44 -0
- package/dist/src/contracts/provenance.d.ts +37 -0
- package/dist/src/contracts/provenance.js +71 -0
- package/dist/src/contracts/tool-contract-registry.d.ts +43 -0
- package/dist/src/contracts/tool-contract-registry.js +282 -0
- package/dist/src/local/cloud-compute-client.d.ts +55 -0
- package/dist/src/local/cloud-compute-client.js +135 -0
- package/dist/src/local/encryption.d.ts +24 -0
- package/dist/src/local/encryption.js +105 -0
- package/dist/src/local/keychain.d.ts +41 -0
- package/dist/src/local/keychain.js +236 -0
- package/dist/src/local/local-config.d.ts +34 -0
- package/dist/src/local/local-config.js +61 -0
- package/dist/src/local/local-data-layer.d.ts +20 -0
- package/dist/src/local/local-data-layer.js +15 -0
- package/dist/src/local/local-plan-store.d.ts +66 -0
- package/dist/src/local/local-plan-store.js +195 -0
- package/dist/src/local/pii-scrubber.d.ts +26 -0
- package/dist/src/local/pii-scrubber.js +219 -0
- package/dist/src/policy/policy-engine.d.ts +44 -0
- package/dist/src/policy/policy-engine.js +119 -0
- package/dist/src/rate-limit.d.ts +17 -0
- package/dist/src/rate-limit.js +41 -0
- package/dist/src/security.d.ts +19 -0
- package/dist/src/security.js +118 -0
- package/dist/src/skills/index.d.ts +12 -0
- package/dist/src/skills/index.js +16 -0
- package/dist/src/skills/retirement-pack-v1.d.ts +28 -0
- package/dist/src/skills/retirement-pack-v1.js +295 -0
- package/dist/src/skills/skill-executor.d.ts +65 -0
- package/dist/src/skills/skill-executor.js +174 -0
- package/dist/src/skills/skill-manifest-schema.d.ts +337 -0
- package/dist/src/skills/skill-manifest-schema.js +94 -0
- package/dist/src/skills/skill-registry.d.ts +71 -0
- package/dist/src/skills/skill-registry.js +116 -0
- package/dist/src/telemetry.d.ts +12 -0
- package/dist/src/telemetry.js +59 -0
- package/dist/src/types.d.ts +46 -0
- package/dist/src/types.js +4 -0
- package/dist/tools/agent-tools.d.ts +12 -0
- package/dist/tools/agent-tools.js +141 -0
- package/dist/tools/forecast-management-tools.d.ts +9 -0
- package/dist/tools/forecast-management-tools.js +133 -0
- package/dist/tools/local-plan-tools.d.ts +8 -0
- package/dist/tools/local-plan-tools.js +357 -0
- package/dist/tools/mcp-helpers.d.ts +52 -0
- package/dist/tools/mcp-helpers.js +177 -0
- package/dist/tools/medicare-tools.d.ts +3 -0
- package/dist/tools/medicare-tools.js +162 -0
- package/dist/tools/optimize-roth-tools-test.d.ts +2 -0
- package/dist/tools/optimize-roth-tools-test.js +36 -0
- package/dist/tools/optimize-roth-tools.d.ts +3 -0
- package/dist/tools/optimize-roth-tools.js +818 -0
- package/dist/tools/plan-management-tools.d.ts +3 -0
- package/dist/tools/plan-management-tools.js +196 -0
- package/dist/tools/planning-tools.d.ts +3 -0
- package/dist/tools/planning-tools.js +290 -0
- package/dist/tools/proposal-tools.d.ts +3 -0
- package/dist/tools/proposal-tools.js +428 -0
- package/dist/tools/report-tools.d.ts +3 -0
- package/dist/tools/report-tools.js +245 -0
- package/dist/tools/scenario-management-tools.d.ts +3 -0
- package/dist/tools/scenario-management-tools.js +136 -0
- package/dist/views/verification-packet.html +211 -0
- package/host-configs/cowork.json +11 -0
- package/host-configs/goose.yaml +22 -0
- package/host-configs/openclaw-manifest.json +16 -0
- package/package.json +66 -0
- package/skills/SKILL.md +162 -0
- package/skills/manifest.json +51 -0
- package/skills/tools/activate_plan.md +36 -0
- package/skills/tools/coach.md +59 -0
- package/skills/tools/comprehensive_plan.md +65 -0
- package/skills/tools/create_plan.md +59 -0
- package/skills/tools/create_saved_plan.md +49 -0
- package/skills/tools/delete_plan.md +42 -0
- package/skills/tools/delete_scenario.md +38 -0
- package/skills/tools/generate_proposal.md +63 -0
- package/skills/tools/generate_retirement_report.md +50 -0
- package/skills/tools/get_active_plan.md +44 -0
- package/skills/tools/get_baseline_forecast.md +47 -0
- package/skills/tools/get_plan.md +44 -0
- package/skills/tools/get_plan_components.md +50 -0
- package/skills/tools/get_scenario.md +46 -0
- package/skills/tools/list_plans.md +44 -0
- package/skills/tools/list_scenarios.md +42 -0
- package/skills/tools/medicare-guardian.md +59 -0
- package/skills/tools/nestpilot_run_plan.md +61 -0
- package/skills/tools/optimize_roth_conversion.md +107 -0
- package/skills/tools/optimize_ss_claiming.md +30 -0
- package/skills/tools/rename_plan.md +34 -0
- package/skills/tools/retirement-planner.md +55 -0
- package/skills/tools/run_forecast.md +65 -0
- package/skills/tools/run_saved_forecast.md +52 -0
- package/skills/tools/run_scenario.md +66 -0
- package/skills/tools/save_plan.md +48 -0
- package/skills/tools/save_scenario.md +50 -0
- package/skills/tools/verify_forecast.md +43 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Tool Skill: create_plan
|
|
2
|
+
|
|
3
|
+
Creates a quick retirement plan projection given basic inputs. Returns projected balance at
|
|
4
|
+
retirement, safe withdrawal amount, readiness score, and sustainability years.
|
|
5
|
+
|
|
6
|
+
## When to Use
|
|
7
|
+
|
|
8
|
+
Use `create_plan` when the user:
|
|
9
|
+
- Wants a quick retirement projection given basic inputs
|
|
10
|
+
- Asks "Am I on track to retire?" or "How much will I have at retirement?"
|
|
11
|
+
- Provides their age, retirement age, savings balance, and contribution amounts
|
|
12
|
+
- Wants to understand their withdrawal rate feasibility
|
|
13
|
+
- Is doing an initial assessment before a detailed forecast
|
|
14
|
+
|
|
15
|
+
Use `run_forecast` instead when the user has:
|
|
16
|
+
- Multiple accounts (401k, IRA, Roth, taxable)
|
|
17
|
+
- Multiple income streams (salary + Social Security + pension)
|
|
18
|
+
- Spouse data or household-level analysis needs
|
|
19
|
+
- Interest in year-by-year projections
|
|
20
|
+
|
|
21
|
+
## Required Inputs to Gather
|
|
22
|
+
|
|
23
|
+
- `currentAge` — current age (integer)
|
|
24
|
+
- `retireAge` — target retirement age (integer)
|
|
25
|
+
- `lifeExpectancy` — planning horizon / life expectancy (integer)
|
|
26
|
+
- `realReturnRate` — expected real annual return (decimal, e.g., 0.05 for 5%)
|
|
27
|
+
- `withdrawalRate` — planned annual withdrawal rate in retirement (decimal, e.g., 0.04)
|
|
28
|
+
|
|
29
|
+
Helpful optional inputs:
|
|
30
|
+
- `currentBalance` — current total savings in dollars
|
|
31
|
+
- `monthlyContribution` — monthly savings contribution in dollars
|
|
32
|
+
- `targetAnnualSpending` — desired annual spending in retirement
|
|
33
|
+
|
|
34
|
+
## Presenting the Results
|
|
35
|
+
|
|
36
|
+
Structure the response:
|
|
37
|
+
|
|
38
|
+
1. **Headline**: "Based on your inputs, you are [on track / at risk / needs attention] for
|
|
39
|
+
retirement at [age]."
|
|
40
|
+
|
|
41
|
+
2. **Key Numbers**:
|
|
42
|
+
- Projected balance at retirement: $X
|
|
43
|
+
- Safe withdrawal amount (monthly): $X (= projectedBalance × withdrawalRate / 12)
|
|
44
|
+
- Readiness score: X/100
|
|
45
|
+
- Sustainability years: X years (how long the portfolio covers spending)
|
|
46
|
+
|
|
47
|
+
3. **Key Assumptions** (always surface these):
|
|
48
|
+
- Return rate: X% real (after inflation)
|
|
49
|
+
- Withdrawal rate: X%
|
|
50
|
+
- Years until retirement: X
|
|
51
|
+
|
|
52
|
+
4. **Next Step**: Offer to run a scenario or open the interactive planner:
|
|
53
|
+
"Want to see what happens if you [retire earlier / save more / adjust return rate]?"
|
|
54
|
+
|
|
55
|
+
## Common Follow-Up Patterns
|
|
56
|
+
|
|
57
|
+
- User asks "what if I retire earlier?" → use `run_scenario` with retirement age delta
|
|
58
|
+
- User wants visual charts → use `retirement-planner` in `forecast` mode
|
|
59
|
+
- User has more detailed financial data → use `run_forecast`
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Tool Skill: create_saved_plan
|
|
2
|
+
|
|
3
|
+
Creates and persists a new retirement plan in the user's account. Unlike `create_plan` (which
|
|
4
|
+
is stateless and returns a quick projection), this tool saves the plan to the database so it
|
|
5
|
+
can be retrieved, forecasted, and iterated on over time.
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
|
|
9
|
+
Use `create_saved_plan` when the user:
|
|
10
|
+
- Wants to build a new plan and keep it for future sessions
|
|
11
|
+
- Says "Save this as a new plan" or "Create a plan called [name]"
|
|
12
|
+
- Is starting fresh and wants to set up their financial profile
|
|
13
|
+
- Has provided enough data to construct a PlanContract (household, accounts, goals)
|
|
14
|
+
|
|
15
|
+
Use `create_plan` instead for a quick one-off projection that doesn't need to persist.
|
|
16
|
+
|
|
17
|
+
## Required Inputs to Gather
|
|
18
|
+
|
|
19
|
+
- `name` (string) — a label for the plan (e.g., "Conservative 65", "Early Retirement")
|
|
20
|
+
- `household.primary.currentAge` — integer
|
|
21
|
+
- `household.primary.retireAge` — integer
|
|
22
|
+
- `accounts` — at least one: `{type, balance, annualContribution?, realReturn?}`
|
|
23
|
+
- `goals.retirement.targetSpending.amountMonthly` — target monthly spend
|
|
24
|
+
|
|
25
|
+
**Optional but recommended:**
|
|
26
|
+
- `household.primary.lifeExpectancy` — default 95
|
|
27
|
+
- `incomeStreams` — salary, Social Security, pension, etc.
|
|
28
|
+
- `household.spouse` — partner data for household-level planning
|
|
29
|
+
- `setActive` (boolean) — whether to make this the active plan immediately
|
|
30
|
+
|
|
31
|
+
## Presenting the Results
|
|
32
|
+
|
|
33
|
+
Structure the response:
|
|
34
|
+
|
|
35
|
+
1. **Confirmation**: "I've created your plan '[name]' (ID: [planId])."
|
|
36
|
+
|
|
37
|
+
2. **Summary**: Brief recap of household, total balances, and target spending.
|
|
38
|
+
|
|
39
|
+
3. **Active Status**: "This plan [is / is not] set as your active plan."
|
|
40
|
+
|
|
41
|
+
4. **Next Step**: "Want me to run a forecast on this plan, or add more accounts
|
|
42
|
+
and income streams?"
|
|
43
|
+
|
|
44
|
+
## Common Follow-Up Patterns
|
|
45
|
+
|
|
46
|
+
- User wants projections → `run_saved_forecast`
|
|
47
|
+
- User wants to add components → `save_plan` with updated accounts/streams
|
|
48
|
+
- User wants it as default → `activate_plan`
|
|
49
|
+
- User wants a quick comparison → `comprehensive_plan`
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Tool Skill: delete_plan
|
|
2
|
+
|
|
3
|
+
Soft-deletes a saved retirement plan. The plan is marked as deleted and hidden from
|
|
4
|
+
`list_plans` but can potentially be recovered by support. Associated forecasts and
|
|
5
|
+
scenarios are preserved but become inaccessible through normal API calls.
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
|
|
9
|
+
Use `delete_plan` when the user:
|
|
10
|
+
- Says "Delete my [plan name] plan" or "Remove this plan"
|
|
11
|
+
- Wants to clean up old or duplicate plans
|
|
12
|
+
- Confirms deletion after being prompted
|
|
13
|
+
|
|
14
|
+
**Always confirm before deleting.** Ask: "Are you sure you want to delete '[name]'?
|
|
15
|
+
This will hide the plan and its associated forecasts."
|
|
16
|
+
|
|
17
|
+
## Required Inputs to Gather
|
|
18
|
+
|
|
19
|
+
- `planId` (string, required) — UUID of the plan to delete
|
|
20
|
+
|
|
21
|
+
If the user refers to a plan by name, resolve the ID via `list_plans` first.
|
|
22
|
+
|
|
23
|
+
Never delete the active plan without warning. If the target is the active plan, say:
|
|
24
|
+
"This is currently your active plan. Deleting it means you won't have a default plan.
|
|
25
|
+
Want to proceed, or would you rather activate a different plan first?"
|
|
26
|
+
|
|
27
|
+
## Presenting the Results
|
|
28
|
+
|
|
29
|
+
Structure the response:
|
|
30
|
+
|
|
31
|
+
1. **Confirmation**: "Your plan '[name]' has been deleted."
|
|
32
|
+
|
|
33
|
+
2. **Active Plan Impact**: If the deleted plan was active, note that no plan is
|
|
34
|
+
currently active and offer to activate another.
|
|
35
|
+
|
|
36
|
+
3. **Remaining Plans**: "You have [N] remaining plan(s). Want to see them?"
|
|
37
|
+
|
|
38
|
+
## Common Follow-Up Patterns
|
|
39
|
+
|
|
40
|
+
- User needs a new active plan → `list_plans` then `activate_plan`
|
|
41
|
+
- User wants to create a replacement → `create_saved_plan`
|
|
42
|
+
- User deleted by mistake → advise contacting support for recovery
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Tool Skill: delete_scenario
|
|
2
|
+
|
|
3
|
+
Deletes a saved what-if scenario permanently. Unlike plan deletion (which is a soft delete),
|
|
4
|
+
scenario deletion is immediate. The scenario will no longer appear in `list_scenarios` and
|
|
5
|
+
cannot be used in future forecast runs.
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
|
|
9
|
+
Use `delete_scenario` when the user:
|
|
10
|
+
- Says "Delete my [scenario name] scenario" or "Remove that scenario"
|
|
11
|
+
- Wants to clean up old or irrelevant what-if explorations
|
|
12
|
+
- Confirms deletion after being prompted
|
|
13
|
+
|
|
14
|
+
**Always confirm before deleting.** Ask: "Are you sure you want to delete the '[label]'
|
|
15
|
+
scenario? This cannot be undone."
|
|
16
|
+
|
|
17
|
+
## Required Inputs to Gather
|
|
18
|
+
|
|
19
|
+
- `scenarioId` (string, required) — UUID of the scenario to delete
|
|
20
|
+
|
|
21
|
+
If the user refers to a scenario by label, resolve via `list_scenarios`.
|
|
22
|
+
|
|
23
|
+
## Presenting the Results
|
|
24
|
+
|
|
25
|
+
Structure the response:
|
|
26
|
+
|
|
27
|
+
1. **Confirmation**: "The scenario '[label]' has been deleted."
|
|
28
|
+
|
|
29
|
+
2. **Impact Note**: "Any forecast runs that used this scenario are still saved, but you
|
|
30
|
+
won't be able to re-run the scenario."
|
|
31
|
+
|
|
32
|
+
3. **Remaining Scenarios**: "You have [N] scenario(s) remaining. Want to see them?"
|
|
33
|
+
|
|
34
|
+
## Common Follow-Up Patterns
|
|
35
|
+
|
|
36
|
+
- User wants to see remaining scenarios → `list_scenarios`
|
|
37
|
+
- User wants to create a replacement → `save_scenario`
|
|
38
|
+
- User wants to clean up more → `list_scenarios` then `delete_scenario` again
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Tool Skill: generate_proposal
|
|
2
|
+
|
|
3
|
+
Assembles a client-ready advisor proposal by orchestrating the NestPilot plan summary
|
|
4
|
+
and proposal record APIs. Produces a structured deliverable an advisor can share with
|
|
5
|
+
(or release to) a client. **Advisor tier only** (FEAT-0063 entitlement gate).
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
|
|
9
|
+
Use `generate_proposal` when an **advisor** wants to:
|
|
10
|
+
- Package analysis results into a formal client deliverable
|
|
11
|
+
- Bundle forecast + optional Roth / SS analyses into one proposal document
|
|
12
|
+
- Create a proposal record that can be released to a client
|
|
13
|
+
- Generate a PDF summary alongside a structured proposal
|
|
14
|
+
|
|
15
|
+
Do **not** use for ad-hoc analysis — use `run_forecast`, `optimize_roth_conversion`, or
|
|
16
|
+
`run_scenario` first, then call this tool to assemble the proposal.
|
|
17
|
+
|
|
18
|
+
## Required Inputs
|
|
19
|
+
|
|
20
|
+
| Input | Description |
|
|
21
|
+
|---|---|
|
|
22
|
+
| `planId` | UUID of the plan to base the proposal on |
|
|
23
|
+
| `clientUserId` | UUID of the client the proposal is for |
|
|
24
|
+
| `title` | Proposal title shown to the client |
|
|
25
|
+
|
|
26
|
+
## Optional Inputs
|
|
27
|
+
|
|
28
|
+
| Input | Default | Description |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| `subtitle` | — | Optional tagline |
|
|
31
|
+
| `advisorNotes` | — | Custom notes appended to the proposal |
|
|
32
|
+
| `includeScenarios` | `[]` | Scenario IDs to include in comparison |
|
|
33
|
+
| `includeRothAnalysis` | `false` | Annotate that Roth analysis was performed |
|
|
34
|
+
| `includeSsAnalysis` | `false` | Annotate that SS analysis was performed |
|
|
35
|
+
| `unlockPriceCents` | `0` | Client unlock price (0 = free) |
|
|
36
|
+
| `autoRelease` | `false` | Release to client immediately |
|
|
37
|
+
|
|
38
|
+
## Workflow
|
|
39
|
+
|
|
40
|
+
1. **Gather context**: Advisor has reviewed the plan, run scenarios, and is ready to share.
|
|
41
|
+
2. **Confirm release preference**: Ask the advisor whether to release immediately or keep as draft.
|
|
42
|
+
3. **Call the tool** with gathered inputs.
|
|
43
|
+
4. **Present result**: Show `proposalId`, `status` (draft / released), `summaryUrl`, and `evidencePacket`.
|
|
44
|
+
|
|
45
|
+
## Safety Gates
|
|
46
|
+
|
|
47
|
+
- Proposal is **NOT released** unless `autoRelease: true` is explicitly provided.
|
|
48
|
+
- If `autoRelease` is true, prompt the advisor to confirm before proceeding.
|
|
49
|
+
- Compliance disclaimers are automatically included in the evidence packet.
|
|
50
|
+
|
|
51
|
+
## Presenting Results
|
|
52
|
+
|
|
53
|
+
Structure the response in three parts:
|
|
54
|
+
1. **Status**: `proposalId`, `status` (draft/released), whether summary PDF was generated.
|
|
55
|
+
2. **Evidence packet**: What analyses were included, assumptions, disclaimers, `generatedAt`.
|
|
56
|
+
3. **Next steps**: If draft, how to release. If released, client can view it in their portal.
|
|
57
|
+
|
|
58
|
+
## Error Handling
|
|
59
|
+
|
|
60
|
+
- If summary generation fails: report the error; no proposal record is created.
|
|
61
|
+
- If proposal creation fails: report the error; advise the advisor to retry.
|
|
62
|
+
- If release fails after creation: proposal is saved as draft; advise manual release from the
|
|
63
|
+
Proposal Manager UI (`/advisor/proposals`).
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Tool Skill: generate_retirement_report
|
|
2
|
+
|
|
3
|
+
Generates a comprehensive retirement planning PDF report. Loads a saved plan, runs a forecast,
|
|
4
|
+
optionally includes saved scenarios, and produces a professional PDF with plan details, charts,
|
|
5
|
+
year-by-year projections, and recommendations.
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
|
|
9
|
+
Use `generate_retirement_report` when the user wants to:
|
|
10
|
+
- Create a PDF document summarizing their retirement plan and forecast
|
|
11
|
+
- Generate a shareable/printable retirement analysis
|
|
12
|
+
- Export their plan details, projections, and charts to a document
|
|
13
|
+
- Produce a retirement readiness report in PDF format
|
|
14
|
+
|
|
15
|
+
## How It Works
|
|
16
|
+
|
|
17
|
+
The tool orchestrates several steps internally:
|
|
18
|
+
1. Resolves the plan ID (supports "active", "default", "current" aliases)
|
|
19
|
+
2. Loads the full plan via `GET /api/plans/{planId}`
|
|
20
|
+
3. Runs a forecast using the plan data
|
|
21
|
+
4. Optionally loads saved scenarios for comparison
|
|
22
|
+
5. Invokes the Python PDF generator (`generate_report.py`) with all data
|
|
23
|
+
6. Returns the PDF file path and metadata
|
|
24
|
+
|
|
25
|
+
## Presenting Results
|
|
26
|
+
|
|
27
|
+
After the tool returns successfully:
|
|
28
|
+
1. **Confirm generation**: "Your retirement report has been generated at [path]."
|
|
29
|
+
2. **Summarize contents**: Mention what sections are included (plan details, forecast KPIs,
|
|
30
|
+
charts, scenario comparison if applicable).
|
|
31
|
+
3. **Offer next steps**: Suggest opening the PDF, running additional scenarios, or using
|
|
32
|
+
the interactive planner for real-time exploration.
|
|
33
|
+
|
|
34
|
+
## Input Tips
|
|
35
|
+
|
|
36
|
+
- **planId**: Omit or pass "active" to use the user's active plan. Pass a UUID for a specific plan.
|
|
37
|
+
- **clientName**: Optional personalization for the report header (e.g., "John & Jane Doe").
|
|
38
|
+
- **includeScenarios**: Defaults to true. Set to false to skip the scenario comparison section.
|
|
39
|
+
- **outputPath**: Optional custom path. If omitted, generates in a temp directory.
|
|
40
|
+
|
|
41
|
+
## Error Handling
|
|
42
|
+
|
|
43
|
+
- If no plan is found, prompt the user to create or activate a plan first.
|
|
44
|
+
- If the forecast fails, report the backend error and suggest checking plan inputs.
|
|
45
|
+
- If Python/reportlab is not available, report the dependency requirement.
|
|
46
|
+
|
|
47
|
+
## Prerequisites
|
|
48
|
+
|
|
49
|
+
- Requires Python 3 with `reportlab` installed (`pip install reportlab`).
|
|
50
|
+
- Requires a saved plan in the system.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Tool Skill: get_active_plan
|
|
2
|
+
|
|
3
|
+
Retrieves the user's currently active (default) retirement plan. Returns the full PlanContract
|
|
4
|
+
just like `get_plan`, but without requiring a plan ID.
|
|
5
|
+
|
|
6
|
+
## When to Use
|
|
7
|
+
|
|
8
|
+
Use `get_active_plan` when the user:
|
|
9
|
+
- Says "my plan" or "my current plan" without naming a specific one
|
|
10
|
+
- Asks "What does my plan look like?" or "Show me my retirement plan"
|
|
11
|
+
- Starts a conversation wanting to run a forecast but hasn't specified which plan
|
|
12
|
+
- Asks about their current retirement readiness without further context
|
|
13
|
+
|
|
14
|
+
Use `get_plan` instead when the user references a specific plan by name or ID.
|
|
15
|
+
Use `list_plans` when the user wants to see all their plans.
|
|
16
|
+
|
|
17
|
+
## Required Inputs to Gather
|
|
18
|
+
|
|
19
|
+
No inputs required. The API resolves the active plan from the authenticated user's profile.
|
|
20
|
+
|
|
21
|
+
## Presenting the Results
|
|
22
|
+
|
|
23
|
+
Structure the response:
|
|
24
|
+
|
|
25
|
+
1. **Plan Identity**: "Your active plan is '[name]', last updated [date]."
|
|
26
|
+
|
|
27
|
+
2. **Quick Snapshot**:
|
|
28
|
+
- Retirement age: X
|
|
29
|
+
- Total account balances: $X across N accounts
|
|
30
|
+
- Target monthly spending: $X
|
|
31
|
+
- Readiness score (if cached from last forecast): X/100
|
|
32
|
+
|
|
33
|
+
3. **Offer Next Steps**: "Would you like me to run a fresh forecast, explore a what-if
|
|
34
|
+
scenario, or update any of these assumptions?"
|
|
35
|
+
|
|
36
|
+
If no active plan exists, say: "You don't have an active plan set. Would you like to
|
|
37
|
+
create one, or pick from your existing plans?"
|
|
38
|
+
|
|
39
|
+
## Common Follow-Up Patterns
|
|
40
|
+
|
|
41
|
+
- User wants a forecast → `run_saved_forecast` using the returned `planId`
|
|
42
|
+
- User wants to change assumptions → `save_plan` with updated fields
|
|
43
|
+
- User wants a different plan as default → `list_plans` then `activate_plan`
|
|
44
|
+
- User wants a combined analysis → `comprehensive_plan`
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Tool Skill: get_baseline_forecast
|
|
2
|
+
|
|
3
|
+
Retrieves the most recent baseline forecast results for a saved plan. Returns cached metrics
|
|
4
|
+
and yearly projections without re-running the forecast engine.
|
|
5
|
+
|
|
6
|
+
## When to Use
|
|
7
|
+
|
|
8
|
+
Use `get_baseline_forecast` when the user:
|
|
9
|
+
- Asks "What were my last forecast results?" or "Show me my numbers"
|
|
10
|
+
- Needs baseline metrics for comparison without waiting for a fresh run
|
|
11
|
+
- Wants to reference previous projections during a conversation
|
|
12
|
+
- Asks about readiness score, legacy value, or runway from their last forecast
|
|
13
|
+
|
|
14
|
+
Use `run_saved_forecast` instead when the user wants fresh projections, especially after
|
|
15
|
+
making plan changes. Stale results may not reflect recent edits.
|
|
16
|
+
|
|
17
|
+
## Required Inputs to Gather
|
|
18
|
+
|
|
19
|
+
- `planId` (string, required) — UUID of the saved plan
|
|
20
|
+
|
|
21
|
+
If the user doesn't specify, resolve via `get_active_plan`.
|
|
22
|
+
|
|
23
|
+
## Presenting the Results
|
|
24
|
+
|
|
25
|
+
Structure the response:
|
|
26
|
+
|
|
27
|
+
1. **Freshness Note**: "These results are from your last forecast run on [date].
|
|
28
|
+
Your plan [has / has not] changed since then."
|
|
29
|
+
|
|
30
|
+
2. **Key Metrics**:
|
|
31
|
+
- Readiness score: X/100
|
|
32
|
+
- Portfolio runway: X years
|
|
33
|
+
- Legacy value at [horizon age]: $X
|
|
34
|
+
- Peak portfolio value: $X at age X
|
|
35
|
+
|
|
36
|
+
3. **Year-by-Year Highlights**: Summarize key inflection points — when contributions
|
|
37
|
+
stop, when withdrawals begin, when portfolio peaks, and when it depletes (if ever).
|
|
38
|
+
|
|
39
|
+
4. **Staleness Warning** (if plan was modified after the forecast):
|
|
40
|
+
"Your plan has been updated since this forecast. Want me to run a fresh one?"
|
|
41
|
+
|
|
42
|
+
## Common Follow-Up Patterns
|
|
43
|
+
|
|
44
|
+
- Results look stale → `run_saved_forecast` with `runType: "baseline"`
|
|
45
|
+
- User wants to compare with a scenario → `run_saved_forecast` with `runType: "scenario"`
|
|
46
|
+
- User wants to drill into components → `get_plan_components`
|
|
47
|
+
- User wants charts → `retirement-planner` with the `planId`
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Tool Skill: get_plan
|
|
2
|
+
|
|
3
|
+
Retrieves a single saved retirement plan by its unique ID. Returns the full PlanContract
|
|
4
|
+
including household data, accounts, income streams, goals, and metadata.
|
|
5
|
+
|
|
6
|
+
## When to Use
|
|
7
|
+
|
|
8
|
+
Use `get_plan` when the user:
|
|
9
|
+
- Refers to a specific plan by name or ID and you need the full details
|
|
10
|
+
- Wants to review or edit a plan before running a forecast
|
|
11
|
+
- Needs to inspect plan components, assumptions, or configuration
|
|
12
|
+
- Asks "Show me my [plan name] plan" after you have resolved the ID via `list_plans`
|
|
13
|
+
|
|
14
|
+
Use `get_active_plan` instead when the user simply says "my plan" without specifying which one.
|
|
15
|
+
|
|
16
|
+
## Required Inputs to Gather
|
|
17
|
+
|
|
18
|
+
- `planId` (string, required) — the UUID of the saved plan
|
|
19
|
+
|
|
20
|
+
If the user refers to a plan by name, first call `list_plans` to resolve the name to a `planId`.
|
|
21
|
+
|
|
22
|
+
## Presenting the Results
|
|
23
|
+
|
|
24
|
+
Structure the response:
|
|
25
|
+
|
|
26
|
+
1. **Plan Summary**: "Here is your '[name]' plan, last updated [date]."
|
|
27
|
+
|
|
28
|
+
2. **Household**: Primary age, retirement age, life expectancy. Spouse if present.
|
|
29
|
+
|
|
30
|
+
3. **Accounts**: List each account with type, balance, and annual contribution.
|
|
31
|
+
|
|
32
|
+
4. **Income Streams**: List each stream with type, monthly amount, and start/end ages.
|
|
33
|
+
|
|
34
|
+
5. **Goals**: Target monthly spending, withdrawal strategy, safe withdrawal rate.
|
|
35
|
+
|
|
36
|
+
6. **Offer Next Steps**: "Want me to run a forecast on this plan, tweak any assumptions,
|
|
37
|
+
or compare it with a scenario?"
|
|
38
|
+
|
|
39
|
+
## Common Follow-Up Patterns
|
|
40
|
+
|
|
41
|
+
- User wants projections → `run_saved_forecast` with the `planId`
|
|
42
|
+
- User wants to change something → `save_plan` with updated fields
|
|
43
|
+
- User wants to make it the default → `activate_plan`
|
|
44
|
+
- User wants to see attached components → `get_plan_components`
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Tool Skill: get_plan_components
|
|
2
|
+
|
|
3
|
+
Returns the financial components attached to a saved plan — accounts, income streams,
|
|
4
|
+
expenses, and insurance policies. Each component includes its type, configuration, and
|
|
5
|
+
link back to the parent plan.
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
|
|
9
|
+
Use `get_plan_components` when the user:
|
|
10
|
+
- Asks "What accounts are in my plan?" or "Show me my income streams"
|
|
11
|
+
- Wants a detailed breakdown of plan building blocks without the full PlanContract
|
|
12
|
+
- Needs to verify which components exist before adding or removing one
|
|
13
|
+
- Asks about a specific component type (e.g., "Do I have a Roth in this plan?")
|
|
14
|
+
|
|
15
|
+
Use `get_plan` instead if you need the full plan including household, goals, and metadata.
|
|
16
|
+
|
|
17
|
+
## Required Inputs to Gather
|
|
18
|
+
|
|
19
|
+
- `planId` (string, required) — UUID of the plan
|
|
20
|
+
|
|
21
|
+
If the user doesn't specify, resolve from the active plan via `get_active_plan`.
|
|
22
|
+
|
|
23
|
+
## Presenting the Results
|
|
24
|
+
|
|
25
|
+
Structure the response by component type:
|
|
26
|
+
|
|
27
|
+
1. **Accounts**:
|
|
28
|
+
- Type | Balance | Annual Contribution | Return Rate
|
|
29
|
+
- e.g., "Traditional 401(k): $320,000, contributing $22,500/yr at 6% real return"
|
|
30
|
+
|
|
31
|
+
2. **Income Streams**:
|
|
32
|
+
- Type | Monthly Amount | Start Age | End Age
|
|
33
|
+
- e.g., "Social Security: $2,800/mo starting at age 67"
|
|
34
|
+
|
|
35
|
+
3. **Expenses** (if present):
|
|
36
|
+
- Label | Monthly Amount | Start Age | End Age
|
|
37
|
+
- e.g., "Healthcare: $800/mo from age 65 to 95"
|
|
38
|
+
|
|
39
|
+
4. **Insurance** (if present):
|
|
40
|
+
- Type | Coverage | Premium
|
|
41
|
+
|
|
42
|
+
5. **Offer Next Steps**: "Want to add a new account, adjust an income stream, or
|
|
43
|
+
run a forecast with these components?"
|
|
44
|
+
|
|
45
|
+
## Common Follow-Up Patterns
|
|
46
|
+
|
|
47
|
+
- User wants to add a component → `save_plan` with the new component appended
|
|
48
|
+
- User wants to remove one → `save_plan` with the component removed
|
|
49
|
+
- User wants to run numbers → `run_saved_forecast`
|
|
50
|
+
- User wants to see the full plan → `get_plan`
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Tool Skill: get_scenario
|
|
2
|
+
|
|
3
|
+
Retrieves a single saved what-if scenario by ID. Returns the full scenario definition
|
|
4
|
+
including label, deltas, overrides, bundle, linked plan, and metadata.
|
|
5
|
+
|
|
6
|
+
## When to Use
|
|
7
|
+
|
|
8
|
+
Use `get_scenario` when the user:
|
|
9
|
+
- Wants to review what a saved scenario contains before running it
|
|
10
|
+
- Asks "What's in my [scenario name] scenario?"
|
|
11
|
+
- Needs to verify scenario details before applying it to a different plan
|
|
12
|
+
- Refers to a scenario by name and you need the full definition
|
|
13
|
+
|
|
14
|
+
Use `list_scenarios` first if you need to resolve a name to an ID.
|
|
15
|
+
|
|
16
|
+
## Required Inputs to Gather
|
|
17
|
+
|
|
18
|
+
- `scenarioId` (string, required) — UUID of the scenario
|
|
19
|
+
|
|
20
|
+
If the user refers to a scenario by label, call `list_scenarios` to resolve the ID.
|
|
21
|
+
|
|
22
|
+
## Presenting the Results
|
|
23
|
+
|
|
24
|
+
Structure the response:
|
|
25
|
+
|
|
26
|
+
1. **Scenario Identity**: "Scenario '[label]', created [date]."
|
|
27
|
+
|
|
28
|
+
2. **Changes Defined**:
|
|
29
|
+
- **Deltas**: List each change in plain language:
|
|
30
|
+
"Retirement age changed to 60" / "Target spending increased to $7,000/mo"
|
|
31
|
+
- **Overrides**: List toggled components:
|
|
32
|
+
"Pension income: disabled" / "Rental income: enabled"
|
|
33
|
+
- **Stress Test**: Historical scenario if present:
|
|
34
|
+
"Applies 2008 financial crisis to equity returns"
|
|
35
|
+
- **Bundle**: Named preset if used
|
|
36
|
+
|
|
37
|
+
3. **Linked Plan**: "Associated with plan '[name]'" or "Standalone (can apply to any plan)."
|
|
38
|
+
|
|
39
|
+
4. **Next Step**: "Want me to run a forecast with this scenario, or modify it?"
|
|
40
|
+
|
|
41
|
+
## Common Follow-Up Patterns
|
|
42
|
+
|
|
43
|
+
- User wants to run it → `run_saved_forecast` with `runType: "scenario"` and the `scenarioId`
|
|
44
|
+
- User wants to change it → `save_scenario` with updated fields or delete and recreate
|
|
45
|
+
- User wants to delete it → `delete_scenario`
|
|
46
|
+
- User wants to apply it to a different plan → `run_saved_forecast` with a different `planId`
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Tool Skill: list_plans
|
|
2
|
+
|
|
3
|
+
Returns all saved retirement plans belonging to the authenticated user. Each entry includes the
|
|
4
|
+
plan ID, name, creation date, last-modified date, and whether it is the active plan.
|
|
5
|
+
|
|
6
|
+
## When to Use
|
|
7
|
+
|
|
8
|
+
Use `list_plans` when the user:
|
|
9
|
+
- Asks "What plans do I have?" or "Show me my saved plans"
|
|
10
|
+
- Wants to pick a plan before running a forecast or scenario
|
|
11
|
+
- Needs to compare or manage multiple plans (e.g., "conservative" vs. "aggressive")
|
|
12
|
+
- Refers to a plan by name and you need to resolve the plan ID
|
|
13
|
+
|
|
14
|
+
Do NOT call this if the user already provided a specific `planId` — go straight to `get_plan`.
|
|
15
|
+
|
|
16
|
+
## Required Inputs to Gather
|
|
17
|
+
|
|
18
|
+
No inputs required. The API identifies the user from the auth token.
|
|
19
|
+
|
|
20
|
+
Optional query hints the user might provide:
|
|
21
|
+
- A name fragment to filter on (client-side filtering after retrieval)
|
|
22
|
+
- Whether they only want the active plan — prefer `get_active_plan` in that case
|
|
23
|
+
|
|
24
|
+
## Presenting the Results
|
|
25
|
+
|
|
26
|
+
Structure the response:
|
|
27
|
+
|
|
28
|
+
1. **Count**: "You have [N] saved plan(s)."
|
|
29
|
+
|
|
30
|
+
2. **Plan List** (table or bullet list):
|
|
31
|
+
- Name | Created | Last Modified | Active?
|
|
32
|
+
- Highlight the currently active plan with a label like "(active)".
|
|
33
|
+
|
|
34
|
+
3. **Prompt for Action**: "Which plan would you like to work with? I can open it,
|
|
35
|
+
run a forecast, or compare scenarios."
|
|
36
|
+
|
|
37
|
+
If the list is empty, say: "You don't have any saved plans yet. Would you like to create one?"
|
|
38
|
+
|
|
39
|
+
## Common Follow-Up Patterns
|
|
40
|
+
|
|
41
|
+
- User picks a plan by name → resolve to `planId`, then `get_plan`
|
|
42
|
+
- User wants to create a new plan → `create_saved_plan`
|
|
43
|
+
- User asks which plan is active → `get_active_plan`
|
|
44
|
+
- User wants to delete or rename → `delete_plan` / `rename_plan`
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Tool Skill: list_scenarios
|
|
2
|
+
|
|
3
|
+
Returns all saved what-if scenarios for the authenticated user, optionally filtered to a
|
|
4
|
+
specific plan. Each entry includes the scenario ID, label, associated plan (if any),
|
|
5
|
+
and creation date.
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
|
|
9
|
+
Use `list_scenarios` when the user:
|
|
10
|
+
- Asks "What scenarios do I have?" or "Show me my saved what-ifs"
|
|
11
|
+
- Wants to pick a scenario before running a forecast
|
|
12
|
+
- Needs to compare or manage their scenario library
|
|
13
|
+
- Asks "What scenarios are attached to this plan?"
|
|
14
|
+
|
|
15
|
+
## Required Inputs to Gather
|
|
16
|
+
|
|
17
|
+
- `planId` (string, optional) — if provided, returns only scenarios linked to that plan;
|
|
18
|
+
if omitted, returns all scenarios across all plans plus standalone ones
|
|
19
|
+
|
|
20
|
+
If the user says "scenarios for my plan" without specifying which, resolve via `get_active_plan`.
|
|
21
|
+
|
|
22
|
+
## Presenting the Results
|
|
23
|
+
|
|
24
|
+
Structure the response:
|
|
25
|
+
|
|
26
|
+
1. **Count**: "You have [N] saved scenario(s) [for plan '[name]' / total]."
|
|
27
|
+
|
|
28
|
+
2. **Scenario List** (table or bullets):
|
|
29
|
+
- Label | Linked Plan | Created | Key Changes
|
|
30
|
+
- Summarize the deltas briefly, e.g., "Retire at 60, no pension"
|
|
31
|
+
|
|
32
|
+
3. **Prompt for Action**: "Which scenario would you like to run, view, or delete?"
|
|
33
|
+
|
|
34
|
+
If no scenarios exist: "You don't have any saved scenarios yet. Would you like to
|
|
35
|
+
create one? Tell me what change you'd like to explore."
|
|
36
|
+
|
|
37
|
+
## Common Follow-Up Patterns
|
|
38
|
+
|
|
39
|
+
- User picks a scenario → `get_scenario` for details, or `run_saved_forecast` to execute
|
|
40
|
+
- User wants to create a new one → `save_scenario`
|
|
41
|
+
- User wants to delete one → `delete_scenario`
|
|
42
|
+
- User wants to compare two → run `run_saved_forecast` for each and compare results
|