@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.
Files changed (149) hide show
  1. package/README.md +350 -0
  2. package/dist/cli/doctor.d.ts +1 -0
  3. package/dist/cli/doctor.js +214 -0
  4. package/dist/cli/export-import.d.ts +6 -0
  5. package/dist/cli/export-import.js +132 -0
  6. package/dist/cli/index.d.ts +2 -0
  7. package/dist/cli/index.js +168 -0
  8. package/dist/cli/init.d.ts +1 -0
  9. package/dist/cli/init.js +171 -0
  10. package/dist/host-configs/cowork.json +11 -0
  11. package/dist/host-configs/goose.yaml +22 -0
  12. package/dist/host-configs/openclaw-manifest.json +16 -0
  13. package/dist/main.d.ts +2 -0
  14. package/dist/main.js +128 -0
  15. package/dist/mcp-app.html +155 -0
  16. package/dist/nestpilot-client.d.ts +44 -0
  17. package/dist/nestpilot-client.js +160 -0
  18. package/dist/planner.html +222 -0
  19. package/dist/server.d.ts +19 -0
  20. package/dist/server.js +245 -0
  21. package/dist/skills/SKILL.md +162 -0
  22. package/dist/skills/manifest.json +51 -0
  23. package/dist/skills/tools/activate_plan.md +36 -0
  24. package/dist/skills/tools/coach.md +59 -0
  25. package/dist/skills/tools/comprehensive_plan.md +65 -0
  26. package/dist/skills/tools/create_plan.md +59 -0
  27. package/dist/skills/tools/create_saved_plan.md +49 -0
  28. package/dist/skills/tools/delete_plan.md +42 -0
  29. package/dist/skills/tools/delete_scenario.md +38 -0
  30. package/dist/skills/tools/generate_proposal.md +63 -0
  31. package/dist/skills/tools/generate_retirement_report.md +50 -0
  32. package/dist/skills/tools/get_active_plan.md +44 -0
  33. package/dist/skills/tools/get_baseline_forecast.md +47 -0
  34. package/dist/skills/tools/get_plan.md +44 -0
  35. package/dist/skills/tools/get_plan_components.md +50 -0
  36. package/dist/skills/tools/get_scenario.md +46 -0
  37. package/dist/skills/tools/list_plans.md +44 -0
  38. package/dist/skills/tools/list_scenarios.md +42 -0
  39. package/dist/skills/tools/medicare-guardian.md +59 -0
  40. package/dist/skills/tools/nestpilot_run_plan.md +61 -0
  41. package/dist/skills/tools/optimize_roth_conversion.md +107 -0
  42. package/dist/skills/tools/optimize_ss_claiming.md +30 -0
  43. package/dist/skills/tools/rename_plan.md +34 -0
  44. package/dist/skills/tools/retirement-planner.md +55 -0
  45. package/dist/skills/tools/run_forecast.md +65 -0
  46. package/dist/skills/tools/run_saved_forecast.md +52 -0
  47. package/dist/skills/tools/run_scenario.md +66 -0
  48. package/dist/skills/tools/save_plan.md +48 -0
  49. package/dist/skills/tools/save_scenario.md +50 -0
  50. package/dist/skills/tools/verify_forecast.md +43 -0
  51. package/dist/src/config.d.ts +20 -0
  52. package/dist/src/config.js +44 -0
  53. package/dist/src/contracts/provenance.d.ts +37 -0
  54. package/dist/src/contracts/provenance.js +71 -0
  55. package/dist/src/contracts/tool-contract-registry.d.ts +43 -0
  56. package/dist/src/contracts/tool-contract-registry.js +282 -0
  57. package/dist/src/local/cloud-compute-client.d.ts +55 -0
  58. package/dist/src/local/cloud-compute-client.js +135 -0
  59. package/dist/src/local/encryption.d.ts +24 -0
  60. package/dist/src/local/encryption.js +105 -0
  61. package/dist/src/local/keychain.d.ts +41 -0
  62. package/dist/src/local/keychain.js +236 -0
  63. package/dist/src/local/local-config.d.ts +34 -0
  64. package/dist/src/local/local-config.js +61 -0
  65. package/dist/src/local/local-data-layer.d.ts +20 -0
  66. package/dist/src/local/local-data-layer.js +15 -0
  67. package/dist/src/local/local-plan-store.d.ts +66 -0
  68. package/dist/src/local/local-plan-store.js +195 -0
  69. package/dist/src/local/pii-scrubber.d.ts +26 -0
  70. package/dist/src/local/pii-scrubber.js +219 -0
  71. package/dist/src/policy/policy-engine.d.ts +44 -0
  72. package/dist/src/policy/policy-engine.js +119 -0
  73. package/dist/src/rate-limit.d.ts +17 -0
  74. package/dist/src/rate-limit.js +41 -0
  75. package/dist/src/security.d.ts +19 -0
  76. package/dist/src/security.js +118 -0
  77. package/dist/src/skills/index.d.ts +12 -0
  78. package/dist/src/skills/index.js +16 -0
  79. package/dist/src/skills/retirement-pack-v1.d.ts +28 -0
  80. package/dist/src/skills/retirement-pack-v1.js +295 -0
  81. package/dist/src/skills/skill-executor.d.ts +65 -0
  82. package/dist/src/skills/skill-executor.js +174 -0
  83. package/dist/src/skills/skill-manifest-schema.d.ts +337 -0
  84. package/dist/src/skills/skill-manifest-schema.js +94 -0
  85. package/dist/src/skills/skill-registry.d.ts +71 -0
  86. package/dist/src/skills/skill-registry.js +116 -0
  87. package/dist/src/telemetry.d.ts +12 -0
  88. package/dist/src/telemetry.js +59 -0
  89. package/dist/src/types.d.ts +46 -0
  90. package/dist/src/types.js +4 -0
  91. package/dist/tools/agent-tools.d.ts +12 -0
  92. package/dist/tools/agent-tools.js +141 -0
  93. package/dist/tools/forecast-management-tools.d.ts +9 -0
  94. package/dist/tools/forecast-management-tools.js +133 -0
  95. package/dist/tools/local-plan-tools.d.ts +8 -0
  96. package/dist/tools/local-plan-tools.js +357 -0
  97. package/dist/tools/mcp-helpers.d.ts +52 -0
  98. package/dist/tools/mcp-helpers.js +177 -0
  99. package/dist/tools/medicare-tools.d.ts +3 -0
  100. package/dist/tools/medicare-tools.js +162 -0
  101. package/dist/tools/optimize-roth-tools-test.d.ts +2 -0
  102. package/dist/tools/optimize-roth-tools-test.js +36 -0
  103. package/dist/tools/optimize-roth-tools.d.ts +3 -0
  104. package/dist/tools/optimize-roth-tools.js +818 -0
  105. package/dist/tools/plan-management-tools.d.ts +3 -0
  106. package/dist/tools/plan-management-tools.js +196 -0
  107. package/dist/tools/planning-tools.d.ts +3 -0
  108. package/dist/tools/planning-tools.js +290 -0
  109. package/dist/tools/proposal-tools.d.ts +3 -0
  110. package/dist/tools/proposal-tools.js +428 -0
  111. package/dist/tools/report-tools.d.ts +3 -0
  112. package/dist/tools/report-tools.js +245 -0
  113. package/dist/tools/scenario-management-tools.d.ts +3 -0
  114. package/dist/tools/scenario-management-tools.js +136 -0
  115. package/dist/views/verification-packet.html +211 -0
  116. package/host-configs/cowork.json +11 -0
  117. package/host-configs/goose.yaml +22 -0
  118. package/host-configs/openclaw-manifest.json +16 -0
  119. package/package.json +66 -0
  120. package/skills/SKILL.md +162 -0
  121. package/skills/manifest.json +51 -0
  122. package/skills/tools/activate_plan.md +36 -0
  123. package/skills/tools/coach.md +59 -0
  124. package/skills/tools/comprehensive_plan.md +65 -0
  125. package/skills/tools/create_plan.md +59 -0
  126. package/skills/tools/create_saved_plan.md +49 -0
  127. package/skills/tools/delete_plan.md +42 -0
  128. package/skills/tools/delete_scenario.md +38 -0
  129. package/skills/tools/generate_proposal.md +63 -0
  130. package/skills/tools/generate_retirement_report.md +50 -0
  131. package/skills/tools/get_active_plan.md +44 -0
  132. package/skills/tools/get_baseline_forecast.md +47 -0
  133. package/skills/tools/get_plan.md +44 -0
  134. package/skills/tools/get_plan_components.md +50 -0
  135. package/skills/tools/get_scenario.md +46 -0
  136. package/skills/tools/list_plans.md +44 -0
  137. package/skills/tools/list_scenarios.md +42 -0
  138. package/skills/tools/medicare-guardian.md +59 -0
  139. package/skills/tools/nestpilot_run_plan.md +61 -0
  140. package/skills/tools/optimize_roth_conversion.md +107 -0
  141. package/skills/tools/optimize_ss_claiming.md +30 -0
  142. package/skills/tools/rename_plan.md +34 -0
  143. package/skills/tools/retirement-planner.md +55 -0
  144. package/skills/tools/run_forecast.md +65 -0
  145. package/skills/tools/run_saved_forecast.md +52 -0
  146. package/skills/tools/run_scenario.md +66 -0
  147. package/skills/tools/save_plan.md +48 -0
  148. package/skills/tools/save_scenario.md +50 -0
  149. package/skills/tools/verify_forecast.md +43 -0
@@ -0,0 +1,19 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { AuthContext } from "./tools/mcp-helpers.js";
3
+ export type { AuthContext } from "./tools/mcp-helpers.js";
4
+ /**
5
+ * Auto-derive skill tool names from manifest.json (auto-registration convention).
6
+ * Adding a new tool only requires updating manifest.json — no server.ts edits needed.
7
+ * Exported for test access.
8
+ */
9
+ export declare function loadSkillToolNames(skillsDir?: string): string[];
10
+ /**
11
+ * Creates a new MCP server instance with all NestPilot tools and resources.
12
+ * When `authCtx` is provided (HTTP transport), it is threaded through to all
13
+ * tool registrations so backend calls carry the user's JWT.
14
+ *
15
+ * Mode detection (FEAT-0087):
16
+ * - NESTPILOT_MODE=cloud (default) → proxy all tools to Spring Boot API
17
+ * - NESTPILOT_MODE=local → local data layer + cloud compute for PII-free payloads
18
+ */
19
+ export declare function createServer(authCtx?: AuthContext): McpServer;
package/dist/server.js ADDED
@@ -0,0 +1,245 @@
1
+ /**
2
+ * NestPilot MCP Server — Orchestrator
3
+ *
4
+ * Creates the MCP server and registers tool groups by domain:
5
+ * - Medicare tools (medicare-guardian, medicare-analyze, email-subscribe)
6
+ * - Planning tools (create_plan, run_forecast, run_scenario, verify_forecast, coach)
7
+ * - Roth tools (optimize_roth_conversion) — FEAT-0066
8
+ * - Report tools (generate_retirement_report)
9
+ * - Agent Runtime tools (list_skills, run_skill, run_plan)
10
+ * - Views (retirement-planner, verification-packet, medicare-guardian)
11
+ *
12
+ * Unified MCP gateway — consolidates apps/mcp-edge into apps/mcp-app (FEAT-0053).
13
+ * Production features: security, rate-limit, telemetry.
14
+ */
15
+ import { registerAppResource, registerAppTool, RESOURCE_MIME_TYPE, } from "@modelcontextprotocol/ext-apps/server";
16
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
17
+ import fsSync from "node:fs";
18
+ import fs from "node:fs/promises";
19
+ import path from "node:path";
20
+ import { z } from "zod";
21
+ import { registerAgentTools } from "./tools/agent-tools.js";
22
+ import { registerForecastManagementTools } from "./tools/forecast-management-tools.js";
23
+ import { registerLocalPlanTools } from "./tools/local-plan-tools.js";
24
+ import { registerMedicareTools } from "./tools/medicare-tools.js";
25
+ import { registerRothTools } from "./tools/optimize-roth-tools.js";
26
+ import { registerPlanManagementTools } from "./tools/plan-management-tools.js";
27
+ import { registerPlanningTools } from "./tools/planning-tools.js";
28
+ import { registerProposalTools } from "./tools/proposal-tools.js";
29
+ import { registerReportTools } from "./tools/report-tools.js";
30
+ import { registerScenarioManagementTools } from "./tools/scenario-management-tools.js";
31
+ import { loadLocalConfig, EncryptionService, LocalPlanStore, CloudComputeClient, createKeychainProvider, } from "./src/local/local-data-layer.js";
32
+ // ── Skill resource constants (MCP Appliance — FEAT-0065 Phase 1) ────────
33
+ const SKILLS_DIR = path.join(import.meta.dirname, "skills");
34
+ const SKILL_MANIFEST_URI = "resource://skill/manifest.json";
35
+ const SKILL_MAIN_URI = "resource://skill/SKILL.md";
36
+ /**
37
+ * Auto-derive skill tool names from manifest.json (auto-registration convention).
38
+ * Adding a new tool only requires updating manifest.json — no server.ts edits needed.
39
+ * Exported for test access.
40
+ */
41
+ export function loadSkillToolNames(skillsDir = SKILLS_DIR) {
42
+ try {
43
+ const manifestPath = path.join(skillsDir, "manifest.json");
44
+ const raw = fsSync.readFileSync(manifestPath, "utf-8");
45
+ const manifest = JSON.parse(raw);
46
+ return Object.keys(manifest.skill.tool_skills);
47
+ }
48
+ catch (e) {
49
+ console.warn("[server] Failed to load skill tool names from manifest.json:", e.message);
50
+ return [];
51
+ }
52
+ }
53
+ const SKILL_TOOL_NAMES = loadSkillToolNames();
54
+ // Works both from source (*.ts) and compiled (dist/)
55
+ const DIST_DIR = import.meta.filename.endsWith(".ts")
56
+ ? path.join(import.meta.dirname, "dist")
57
+ : path.join(import.meta.dirname);
58
+ /**
59
+ * Creates a new MCP server instance with all NestPilot tools and resources.
60
+ * When `authCtx` is provided (HTTP transport), it is threaded through to all
61
+ * tool registrations so backend calls carry the user's JWT.
62
+ *
63
+ * Mode detection (FEAT-0087):
64
+ * - NESTPILOT_MODE=cloud (default) → proxy all tools to Spring Boot API
65
+ * - NESTPILOT_MODE=local → local data layer + cloud compute for PII-free payloads
66
+ */
67
+ export function createServer(authCtx) {
68
+ const localConfig = loadLocalConfig();
69
+ const server = new McpServer({
70
+ name: "NestPilot",
71
+ version: "1.0.0",
72
+ });
73
+ if (localConfig.mode === "local") {
74
+ // ── Local mode (FEAT-0087) ────────────────────────────────────────
75
+ console.log("[server] Starting in LOCAL mode — data stays on this machine");
76
+ const keychain = createKeychainProvider(localConfig.dataDir);
77
+ const encryption = new EncryptionService(keychain);
78
+ const store = new LocalPlanStore(localConfig.dataDir, encryption);
79
+ const computeClient = new CloudComputeClient(localConfig.cloudApiUrl, localConfig.apiKey ?? "");
80
+ console.log("Registering Local Plan tools...");
81
+ registerLocalPlanTools(server, store, computeClient);
82
+ // Cloud-backed tools that use PII-free payloads
83
+ console.log("Registering Medicare tools (cloud)...");
84
+ registerMedicareTools(server, authCtx);
85
+ console.log("Registering Roth tools (cloud)...");
86
+ registerRothTools(server, authCtx);
87
+ console.log("Registering Report tools (cloud)...");
88
+ registerReportTools(server, authCtx);
89
+ }
90
+ else {
91
+ // ── Cloud mode (default — existing behavior) ──────────────────────
92
+ console.log("[server] Starting in CLOUD mode — proxy to Spring Boot API");
93
+ console.log("Registering Medicare tools...");
94
+ registerMedicareTools(server, authCtx);
95
+ console.log("Registering Planning tools...");
96
+ registerPlanningTools(server, authCtx);
97
+ console.log("Registering Roth tools...");
98
+ registerRothTools(server, authCtx);
99
+ console.log("Registering Agent tools...");
100
+ registerAgentTools(server, authCtx);
101
+ console.log("Registering Plan Management tools...");
102
+ registerPlanManagementTools(server, authCtx);
103
+ console.log("Registering Forecast Management tools...");
104
+ registerForecastManagementTools(server, authCtx);
105
+ console.log("Registering Scenario Management tools...");
106
+ registerScenarioManagementTools(server, authCtx);
107
+ console.log("Registering Proposal tools...");
108
+ registerProposalTools(server, authCtx);
109
+ console.log("Registering Report tools...");
110
+ registerReportTools(server, authCtx);
111
+ }
112
+ // ── Shared registrations (both modes) ─────────────────────────────────
113
+ console.log("Registering views...");
114
+ registerPlannerView(server);
115
+ registerVerificationPacketView(server);
116
+ registerSkillResources(server);
117
+ console.log("Server registration complete");
118
+ return server;
119
+ }
120
+ // ── Retirement Planner view ─────────────────────────────────────────────
121
+ function registerPlannerView(server) {
122
+ // Keep stable URI for host compatibility and support the old cache-busting alias.
123
+ const resourceUri = "ui://retirement-planner/planner.html";
124
+ const resourceUriAlias = "ui://retirement-planner/planner-v2.html";
125
+ // Tool that launches the interactive planner view
126
+ registerAppTool(server, "retirement-planner", {
127
+ title: "Retirement Planner",
128
+ description: `Opens an interactive retirement planner with plan creation form, forecast charts, and scenario comparison.
129
+
130
+ USE THIS TOOL WHEN THE USER:
131
+ - Wants to create or edit a retirement plan interactively
132
+ - Asks to see their retirement forecast as charts
133
+ - Wants a visual retirement planning experience
134
+ - Says "show me my retirement plan" or "open the planner"
135
+
136
+ The view supports three modes:
137
+ - editor (default): Input form for quick plan creation
138
+ - forecast: Displays forecast charts for an existing plan
139
+ - scenario: Shows baseline vs candidate scenario comparison`,
140
+ inputSchema: {
141
+ mode: z
142
+ .enum(["editor", "forecast", "scenario"])
143
+ .default("editor")
144
+ .describe("View mode: 'editor' (plan form), 'forecast' (charts), or 'scenario' (comparison)"),
145
+ },
146
+ _meta: {
147
+ ui: {
148
+ resourceUri,
149
+ visibility: ["model", "app"],
150
+ },
151
+ // Host compatibility fallback for clients that still read OpenAI-style keys.
152
+ "openai/outputTemplate": resourceUri,
153
+ "openai/widgetAccessible": true,
154
+ },
155
+ }, async (args) => {
156
+ const { mode = "editor" } = args;
157
+ return {
158
+ content: [
159
+ {
160
+ type: "text",
161
+ text: JSON.stringify({
162
+ mode,
163
+ message: `Retirement planner opened in ${mode} mode`,
164
+ }),
165
+ },
166
+ {
167
+ type: "resource_link",
168
+ uri: resourceUri,
169
+ name: "NestPilot Retirement Planner",
170
+ title: "Open Retirement Planner",
171
+ description: `Interactive planner view (${mode} mode)`,
172
+ mimeType: RESOURCE_MIME_TYPE,
173
+ },
174
+ ],
175
+ _meta: {
176
+ "openai/outputTemplate": resourceUri,
177
+ "openai/widgetDescription": "Interactive retirement planner with editor, forecast chart, and scenario comparison.",
178
+ },
179
+ };
180
+ });
181
+ // UI resource: serves the bundled single-file HTML for the planner view
182
+ registerAppResource(server, resourceUri, resourceUri, { mimeType: RESOURCE_MIME_TYPE }, async () => {
183
+ const html = await fs.readFile(path.join(DIST_DIR, "planner.html"), "utf-8");
184
+ return {
185
+ contents: [
186
+ { uri: resourceUri, mimeType: RESOURCE_MIME_TYPE, text: html },
187
+ ],
188
+ };
189
+ });
190
+ // Alias registration for hosts that still reference the previous URI.
191
+ registerAppResource(server, resourceUriAlias, resourceUriAlias, { mimeType: RESOURCE_MIME_TYPE }, async () => {
192
+ const html = await fs.readFile(path.join(DIST_DIR, "planner.html"), "utf-8");
193
+ return {
194
+ contents: [
195
+ { uri: resourceUriAlias, mimeType: RESOURCE_MIME_TYPE, text: html },
196
+ ],
197
+ };
198
+ });
199
+ }
200
+ // ── Verification Packet view ─────────────────────────────────────────────
201
+ function registerVerificationPacketView(server) {
202
+ const resourceUri = "ui://verification-packet/verification-packet.html";
203
+ registerAppResource(server, resourceUri, resourceUri, { mimeType: RESOURCE_MIME_TYPE }, async () => {
204
+ const html = await fs.readFile(path.join(DIST_DIR, "views", "verification-packet.html"), "utf-8");
205
+ return {
206
+ contents: [
207
+ { uri: resourceUri, mimeType: RESOURCE_MIME_TYPE, text: html },
208
+ ],
209
+ };
210
+ });
211
+ }
212
+ // ── Skill resources (MCP Appliance — FEAT-0065 Phase 1) ─────────────────
213
+ //
214
+ // Registers well-known skill URIs so any MCP host can discover and load
215
+ // NestPilot's operational skills via the resource://skill/ convention.
216
+ // All files are read lazily (on resource/read request) so createServer()
217
+ // stays synchronous and fast.
218
+ function registerSkillResources(server) {
219
+ // Tier 0: manifest — AI host discovers skill capabilities
220
+ server.resource("skill-manifest", SKILL_MANIFEST_URI, { mimeType: "application/json" }, async () => {
221
+ const text = await fs.readFile(path.join(SKILLS_DIR, "manifest.json"), "utf-8");
222
+ return {
223
+ contents: [
224
+ { uri: SKILL_MANIFEST_URI, mimeType: "application/json", text },
225
+ ],
226
+ };
227
+ });
228
+ // Tier 2: main skill document — workflow overview and boundaries
229
+ server.resource("skill-main", SKILL_MAIN_URI, { mimeType: "text/markdown" }, async () => {
230
+ const text = await fs.readFile(path.join(SKILLS_DIR, "SKILL.md"), "utf-8");
231
+ return {
232
+ contents: [{ uri: SKILL_MAIN_URI, mimeType: "text/markdown", text }],
233
+ };
234
+ });
235
+ // Tier 2: per-tool skill documents — tool-specific guidance loaded on demand
236
+ for (const toolName of SKILL_TOOL_NAMES) {
237
+ const uri = `resource://skill/tools/${toolName}.md`;
238
+ server.resource(`skill-tool-${toolName}`, uri, { mimeType: "text/markdown" }, async () => {
239
+ const text = await fs.readFile(path.join(SKILLS_DIR, "tools", `${toolName}.md`), "utf-8");
240
+ return {
241
+ contents: [{ uri, mimeType: "text/markdown", text }],
242
+ };
243
+ });
244
+ }
245
+ }
@@ -0,0 +1,162 @@
1
+ ---
2
+ name: nestpilot-retirement
3
+ version: "1.0.0"
4
+ description: "Retirement planning, forecasting, scenario analysis, Medicare enrollment, and AI coaching"
5
+ tools:
6
+ - medicare-guardian
7
+ - create_plan
8
+ - run_forecast
9
+ - verify_forecast
10
+ - run_scenario
11
+ - retirement-planner
12
+ - nestpilot_run_plan
13
+ - coach
14
+ - optimize_roth_conversion
15
+ - optimize_ss_claiming
16
+ - generate_proposal
17
+ references:
18
+ - tools/medicare-guardian.md
19
+ - tools/create_plan.md
20
+ - tools/run_forecast.md
21
+ - tools/verify_forecast.md
22
+ - tools/run_scenario.md
23
+ - tools/retirement-planner.md
24
+ - tools/nestpilot_run_plan.md
25
+ - tools/coach.md
26
+ - tools/optimize_roth_conversion.md
27
+ - tools/optimize_ss_claiming.md
28
+ - tools/generate_proposal.md
29
+ ---
30
+
31
+ # NestPilot Retirement Planning Skill
32
+
33
+ NestPilot is an independent retirement planning and verification platform for mass affluent
34
+ Americans navigating the saving-to-spending transition. It is NOT a product seller — it is a
35
+ client-side verification and planning engine with no conflicts of interest.
36
+
37
+ ## Core Principles
38
+
39
+ 1. **Show the math.** Always explain calculations, not just results. Users trust verifiable numbers.
40
+ 2. **Assumptions are first-class.** Make every assumption explicit. Users should be able to see what
41
+ drives the forecast (return rate, withdrawal rate, life expectancy, inflation).
42
+ 3. **Independent verification.** NestPilot verifies plans mathematically — do not recommend specific
43
+ products. Say "the math shows X" not "you should buy Y."
44
+ 4. **Decumulation focus.** The critical problem is the saving-to-spending transition: tax-efficient
45
+ withdrawal sequencing, Medicare timing, longevity risk management.
46
+
47
+ ## Workflow Overview
48
+
49
+ ### Quick Retirement Projection
50
+
51
+ 1. Gather user inputs: current age, target retirement age, life expectancy, current balance,
52
+ monthly contribution, expected return rate, withdrawal rate, target annual spending.
53
+ 2. Call `create_plan` with the gathered inputs.
54
+ 3. Present the result focusing on: projected balance at retirement, estimated monthly income,
55
+ readiness score, sustainability years.
56
+ 4. Offer to open the interactive planner (`retirement-planner`) for visual exploration.
57
+
58
+ ### Comprehensive Forecast
59
+
60
+ - Use `run_forecast` when the user has detailed financial data: multiple accounts (401k, IRA,
61
+ Roth, taxable), multiple income streams (salary, Social Security, pension), spouse data.
62
+ - The forecast returns year-by-year projections, portfolio runway, legacy value, and success
63
+ probability.
64
+ - Present as a narrative: "Based on your plan, here is how your portfolio is projected to evolve..."
65
+
66
+ ### What-If Scenario Analysis
67
+
68
+ - Use `run_scenario` for what-if analysis: "What if I retire 3 years earlier?" "What if markets
69
+ return 5% instead of 7%?" "What if I add an annuity?"
70
+ - Always present the difference vs. the base case: delta metrics for readiness score, legacy value.
71
+ - Frame scenarios as exploration: "If X, then Y" not "you should do X."
72
+ - Supports historical stress tests (2008 crisis, dot-com bust, 1929 crash).
73
+
74
+ ### Verifying a Forecast
75
+
76
+ - Use `verify_forecast` when the user wants to double-check their advisor's numbers
77
+ or validate a scenario.
78
+ - The verification packet includes the assumptions, the calculation trace, and the verdict.
79
+ - Present the verdict clearly: "The math checks out" or "The projection is optimistic because..."
80
+ - NEVER suggest the advisor was wrong — present verification as confirmation or a starting
81
+ point for a conversation with the advisor.
82
+
83
+ ### Interactive Retirement Planner
84
+
85
+ - Use `retirement-planner` when the user wants a visual, interactive planning experience.
86
+ - Supports three modes: editor (plan input form), forecast (charts), scenario (comparison view).
87
+ - The planner renders as a full interactive UI in the host application.
88
+ - Offer this after running `create_plan` or `run_forecast` for visual exploration.
89
+
90
+ ### Medicare Guardian
91
+
92
+ - Use `medicare-guardian` when the user is approaching 65 or asking about Medicare.
93
+ - The tool opens an interactive Medicare enrollment readiness view.
94
+ - Key outputs: enrollment window (IEP/SEP/GEP), penalty risk, IRMAA income surcharge exposure.
95
+ - CRITICAL: Never recommend specific Medicare plans (Part C/D plans). Only clarify enrollment
96
+ timing rules, penalty risks, and income thresholds. This is an educational tool.
97
+
98
+ ### AI Coach
99
+
100
+ - Use `coach` for open-ended retirement guidance and personalized advice.
101
+ - Coach is powered by AI and provides explanations, not calculations.
102
+ - Use coach for: "Explain Roth conversions", "Should I delay Social Security?",
103
+ "What is the tax torpedo?"
104
+ - Coach output is advisory — always suggest verifying with `run_forecast` or `verify_forecast`
105
+ for quantitative decisions.
106
+
107
+ ### Agent-Powered Retirement Readiness
108
+
109
+ - Use `nestpilot_run_plan` for a complete retirement readiness assessment powered by the agent
110
+ runtime. This combines skill execution, context gathering, and structured analysis.
111
+ - Use when the user provides their retirement situation in natural language and wants a full
112
+ assessment without manually providing structured inputs.
113
+
114
+ ### Roth Conversion Optimization
115
+
116
+ - Use `optimize_roth_conversion` when asking about Roth conversions, tax bracket optimization,
117
+ or Traditional-to-Roth IRA strategies.
118
+ - The tool analyzes multi-year conversion windows: bracket headroom, IRMAA thresholds, RMD
119
+ impact, and break-even timing.
120
+ - Present results as: "Based on your tax situation, converting $X over Y years could save
121
+ $Z in lifetime taxes."
122
+ - CRITICAL: This is tax-related analysis. Always include: "Consult a tax professional before
123
+ making conversion decisions." The tool provides math, not tax advice.
124
+ - Flag IRMAA cliff warnings when income approaches Medicare surcharge thresholds.
125
+
126
+ ### Social Security Claiming Optimization
127
+
128
+ - Use `optimize_ss_claiming` when the user asks "When should I claim Social Security?" or
129
+ wants to compare claiming ages.
130
+ - The tool simulates claiming at ages 62-70, shows break-even ages, and calculates NPV of
131
+ lifetime benefits.
132
+ - For couples, it analyzes spousal and survivor benefit strategies.
133
+ - Present break-even analysis in plain language: "If you delay from 62 to 67, you break even
134
+ at age 78. If you live past 78, delaying pays off."
135
+ - Coordinate with Roth conversion windows: "The years you delay SS may create low-income
136
+ years ideal for Roth conversions."
137
+ - NEVER predict government policy changes. Note that benefit formulas may change.
138
+
139
+ ### Proposal Generation (Advisor)
140
+
141
+ - Use `generate_proposal` when an advisor wants to create a client-ready proposal package.
142
+ - The tool assembles: plan summary PDF, scenario comparisons, optional Roth and SS analyses,
143
+ AI recommendations, and an evidence packet.
144
+ - Always confirm with the advisor before releasing to the client (`autoRelease` defaults to false).
145
+ - Present the draft for review first: "Here's your proposal draft. Shall I release it to the client?"
146
+
147
+ ## Response Formatting
148
+
149
+ - Lead with the user's outcome in plain language ("You are on track for retirement at 65").
150
+ - Follow with the key numbers (balance, income, years of coverage).
151
+ - Explain the 1-2 most important assumptions that drive the result.
152
+ - Offer a next step: scenario to explore, planner to open, or forecast to run.
153
+ - Keep responses concise. Users are busy adults making important decisions — respect their time.
154
+
155
+ ## Boundaries
156
+
157
+ - Do NOT recommend specific investment products, funds, or advisors.
158
+ - Do NOT provide tax advice (explain tax concepts, but say "consult a tax professional for your
159
+ specific situation").
160
+ - Do NOT make predictions about market returns — use the user's provided return rate assumption.
161
+ - Do NOT recommend specific Medicare Advantage or Medigap plans.
162
+ - Do NOT discuss NestPilot pricing, subscriptions, or business model unless asked directly.
@@ -0,0 +1,51 @@
1
+ {
2
+ "skill": {
3
+ "name": "nestpilot-retirement",
4
+ "version": "1.0.0",
5
+ "description": "Retirement planning, forecasting, verification, scenario analysis, Medicare enrollment, AI coaching, interactive planner UI, and agent-powered retirement readiness.",
6
+ "entry_point": "resource://skill/SKILL.md",
7
+ "loading_strategy": "on_demand",
8
+ "priority": "primary",
9
+ "tool_skills": {
10
+ "medicare-guardian": "resource://skill/tools/medicare-guardian.md",
11
+ "create_plan": "resource://skill/tools/create_plan.md",
12
+ "run_forecast": "resource://skill/tools/run_forecast.md",
13
+ "verify_forecast": "resource://skill/tools/verify_forecast.md",
14
+ "run_scenario": "resource://skill/tools/run_scenario.md",
15
+ "retirement-planner": "resource://skill/tools/retirement-planner.md",
16
+ "nestpilot_run_plan": "resource://skill/tools/nestpilot_run_plan.md",
17
+ "coach": "resource://skill/tools/coach.md",
18
+ "optimize_roth_conversion": "resource://skill/tools/optimize_roth_conversion.md",
19
+ "optimize_ss_claiming": "resource://skill/tools/optimize_ss_claiming.md",
20
+ "generate_proposal": "resource://skill/tools/generate_proposal.md",
21
+ "list_plans": "resource://skill/tools/list_plans.md",
22
+ "get_plan": "resource://skill/tools/get_plan.md",
23
+ "get_active_plan": "resource://skill/tools/get_active_plan.md",
24
+ "create_saved_plan": "resource://skill/tools/create_saved_plan.md",
25
+ "save_plan": "resource://skill/tools/save_plan.md",
26
+ "activate_plan": "resource://skill/tools/activate_plan.md",
27
+ "delete_plan": "resource://skill/tools/delete_plan.md",
28
+ "rename_plan": "resource://skill/tools/rename_plan.md",
29
+ "get_plan_components": "resource://skill/tools/get_plan_components.md",
30
+ "run_saved_forecast": "resource://skill/tools/run_saved_forecast.md",
31
+ "get_baseline_forecast": "resource://skill/tools/get_baseline_forecast.md",
32
+ "save_scenario": "resource://skill/tools/save_scenario.md",
33
+ "list_scenarios": "resource://skill/tools/list_scenarios.md",
34
+ "get_scenario": "resource://skill/tools/get_scenario.md",
35
+ "delete_scenario": "resource://skill/tools/delete_scenario.md",
36
+ "comprehensive_plan": "resource://skill/tools/comprehensive_plan.md",
37
+ "generate_retirement_report": "resource://skill/tools/generate_retirement_report.md"
38
+ },
39
+ "composes_with": [
40
+ "data-analysis",
41
+ "document-creator"
42
+ ],
43
+ "model_hints": {
44
+ "min_context_window": 8000,
45
+ "supports": [
46
+ "claude-3+",
47
+ "gpt-4+"
48
+ ]
49
+ }
50
+ }
51
+ }
@@ -0,0 +1,36 @@
1
+ # Tool Skill: activate_plan
2
+
3
+ Sets a specific saved plan as the user's active (default) plan. The active plan is the one
4
+ returned by `get_active_plan` and used as the implicit context when the user says "my plan."
5
+
6
+ ## When to Use
7
+
8
+ Use `activate_plan` when the user:
9
+ - Says "Make this my main plan" or "Set [plan name] as active"
10
+ - Wants to switch their default plan after comparing options
11
+ - Just created a new plan and wants it to be the primary one
12
+ - Asks "Use this plan going forward"
13
+
14
+ ## Required Inputs to Gather
15
+
16
+ - `planId` (string, required) — UUID of the plan to activate
17
+
18
+ If the user refers to a plan by name, resolve the ID via `list_plans` first.
19
+
20
+ ## Presenting the Results
21
+
22
+ Structure the response:
23
+
24
+ 1. **Confirmation**: "Done — '[name]' is now your active plan."
25
+
26
+ 2. **Context**: "Future requests like 'run a forecast' or 'show my plan' will use this
27
+ plan by default unless you specify another."
28
+
29
+ 3. **Previous Active** (if known): "Your previous active plan was '[old name]'. It's
30
+ still saved and accessible."
31
+
32
+ ## Common Follow-Up Patterns
33
+
34
+ - User wants to see the plan → `get_active_plan`
35
+ - User wants a forecast on it → `run_saved_forecast`
36
+ - User realizes they picked the wrong one → `list_plans` then `activate_plan` again
@@ -0,0 +1,59 @@
1
+ # Tool Skill: coach
2
+
3
+ Provides AI-powered retirement coaching — conversational guidance, explanations of retirement
4
+ concepts, and personalized next-step suggestions. Coach is advisory; it explains and frames
5
+ decisions but does not replace quantitative tools.
6
+
7
+ ## When to Use
8
+
9
+ Use `coach` for:
10
+ - Explaining retirement concepts ("What is a Roth conversion?", "How does the 4% rule work?")
11
+ - Personalized guidance when the user has described their situation and wants advice
12
+ - Synthesizing insights after running forecasts or scenarios ("What does this mean for me?")
13
+ - Behavioral nudges ("I'm worried I'm saving too little — what should I think about?")
14
+ - Open-ended questions that need narrative answers, not calculations
15
+
16
+ ## When NOT to Use
17
+
18
+ - Do NOT use coach for calculation requests — use `run_forecast` or `create_plan` instead
19
+ - Do NOT use coach for Medicare enrollment timing — use `medicare_guardian` instead
20
+ - Do NOT use coach for "verify my advisor's numbers" — use `verify_forecast` instead
21
+
22
+ ## Sending a Good Coaching Request
23
+
24
+ Provide as much context as possible in the `content` field:
25
+ - User's age, retirement timeline, and current savings (if known from prior conversation)
26
+ - Specific question or concern
27
+ - Any plan or scenario results from prior tool calls (to give coach the math context)
28
+
29
+ Example: "User is 58, wants to retire at 63, has $850K saved, asking about Roth conversion
30
+ ladder strategy to reduce RMDs."
31
+
32
+ Pass `planId` if there is a saved plan — coach will use it as context.
33
+
34
+ ## Presenting Coach Output
35
+
36
+ Coach output is narrative guidance. Present it as:
37
+ - A direct, empathetic response to the user's question
38
+ - Explanation of the relevant concept in plain language
39
+ - Actionable next step (run a scenario, consult an advisor, make a specific change)
40
+
41
+ Always end coaching responses with a bridge to quantitative verification:
42
+ "To see the numbers, we can run a [forecast / scenario / verification] — want me to set that
43
+ up for you?"
44
+
45
+ ## Tone and Boundaries
46
+
47
+ - Be empathetic but not patronizing. Users are intelligent adults making complex decisions.
48
+ - Be honest about uncertainty: "The math depends on your return assumption — here's the range."
49
+ - Do NOT tell users what to do — frame as "here are the options and trade-offs."
50
+ - Do NOT recommend specific financial products, advisors, or tax strategies.
51
+ - For questions beyond NestPilot's scope (estate planning, insurance selection, tax filing),
52
+ recommend consulting a CFP, CPA, or estate attorney.
53
+
54
+ ## Error Handling
55
+
56
+ If the backend returns an error, acknowledge the issue and offer to answer the conceptual
57
+ question from general knowledge while the service recovers:
58
+ "I'm having trouble reaching the coaching service right now. Based on what you've described,
59
+ here's what I can share from general retirement planning principles: [response]"
@@ -0,0 +1,65 @@
1
+ # Tool Skill: comprehensive_plan
2
+
3
+ Executes a combined coaching analysis and retirement forecast in a single call. Takes a full
4
+ PlanContract payload, runs the coaching engine for qualitative guidance and the forecast engine
5
+ for quantitative projections, and returns both results together.
6
+
7
+ ## When to Use
8
+
9
+ Use `comprehensive_plan` when the user:
10
+ - Wants a complete picture: both actionable advice and hard numbers in one pass
11
+ - Says "Give me the full analysis" or "What should I do and where do I stand?"
12
+ - Is a new user providing all their data at once and wants immediate value
13
+ - Wants coaching recommendations alongside projected outcomes
14
+ - Asks "How can I improve my plan?" (needs both diagnosis and projection)
15
+
16
+ Use `run_forecast` or `run_saved_forecast` instead when the user only needs numbers.
17
+ Use `coach` instead when the user only needs qualitative advice without projections.
18
+
19
+ ## Required Inputs to Gather
20
+
21
+ This tool accepts a full PlanContract payload — the same structure used by `run_forecast`:
22
+
23
+ **Required:**
24
+ - `household.primary.currentAge` — integer
25
+ - `household.primary.retireAge` — integer
26
+ - `goals.retirement.targetSpending.amountMonthly` — target monthly spending
27
+ - `accounts` — at least one: `{type, balance, annualContribution?, realReturn?}`
28
+ - `incomeStreams` — at least one: `{type, amountMonthly, startAge?, endAge?}`
29
+
30
+ **Optional but improves coaching quality:**
31
+ - `household.primary.socialSecurity` — claiming age and estimated benefit
32
+ - `household.spouse` — enables household-level coaching
33
+ - `goals.retirement.safeWithdrawalRate` — default 0.04
34
+ - `goals.retirement.withdrawalStrategy` — `"taxable_first"` or `"traditional_first"`
35
+ - `riskProfile` — conservative, moderate, aggressive (influences coaching tone)
36
+
37
+ ## Presenting the Results
38
+
39
+ Structure the response in two sections:
40
+
41
+ 1. **Coaching Summary**:
42
+ - Top 3 recommendations ranked by impact
43
+ - Each with a plain-language explanation and estimated benefit
44
+ - e.g., "Delay Social Security from 62 to 67 — adds ~$450/mo to your benefit"
45
+
46
+ 2. **Forecast Summary**:
47
+ - Readiness score: X/100
48
+ - Portfolio runway: X years
49
+ - Legacy value: $X
50
+ - Success probability: X%
51
+
52
+ 3. **Integrated Insight**: Connect the coaching to the numbers:
53
+ "Your readiness score of 72 reflects the gap between your $6,000/mo target and your
54
+ projected $4,800/mo sustainable withdrawal. The top recommendation (delaying SS) would
55
+ close roughly half that gap."
56
+
57
+ 4. **Next Steps**: Offer to save as a plan, run a specific scenario from the coaching
58
+ recommendations, or explore the planner visually.
59
+
60
+ ## Common Follow-Up Patterns
61
+
62
+ - User wants to save the plan → `create_saved_plan`
63
+ - User wants to explore a recommendation → `run_scenario` with the suggested delta
64
+ - User wants just the coaching detail → `coach`
65
+ - User wants year-by-year breakdown → `run_forecast` or `retirement-planner`