@mytheo-my/portfolio 1.0.39 → 1.0.41
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/cli.js +40 -11
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -75,7 +75,7 @@ return fn.apply(this, arguments)
|
|
|
75
75
|
|
|
76
76
|
## When to use this tool:
|
|
77
77
|
- After user completes profile questions
|
|
78
|
-
- When user wants to explore investment options`,inputSchema:{type:"object",properties:{metadata:{type:"object",description:"REQUIRED: Metadata for internal processing (provided by system, not user-facing). MUST be included if available from the system.",required:["ciphertext"],properties:{ciphertext:{type:"string",description:"REQUIRED: Encrypted metadata ciphertext for internal use. MUST be included if metadata is available."}}}},required:["metadata"]}}};async function dc(a){try{let e=await Z.getAvailableProducts(),i={type:ge.LIST,data:e.map(n=>({id:n.productid,name:n.productlongname,description:n.proddescp}))};return X({message:"Here are the list of available products. Please select one to continue.",next_suggestion:"Suggest user to view the rest of the options, or create portfolio."},i)}catch(e){let i=e instanceof Error?e.message:"Unknown error occurred";return A("Failed to fetch products",i)}}var mc={USDPORT:"USDPORT"},ZE=["low","medium","high"],eT=1,aT=30,xc={MISSING_USDPORT_PARAMS:"USDPORT requires account_name, risk_tolerance, and invest_duration",INVALID_RISK_TOLERANCE:"risk_tolerance must be 'low', 'medium', or 'high'. Received: {value}",INVALID_INVEST_DURATION:"invest_duration must be between 1 and 30 years. Received: {value}"},Ao={name:"create_portfolio_account",definition:{title:"Create Portfolio Account",description:`Create a new portfolio account based on the selected product.
|
|
78
|
+
- When user wants to explore investment options`,inputSchema:{type:"object",properties:{metadata:{type:"object",description:"REQUIRED: Metadata for internal processing (provided by system, not user-facing). MUST be included if available from the system instruction.",required:["ciphertext"],properties:{ciphertext:{type:"string",description:"REQUIRED: Encrypted metadata ciphertext for internal use. MUST be included if metadata is available."}}}},required:["metadata"]}}};async function dc(a){try{let e=await Z.getAvailableProducts(),i={type:ge.LIST,data:e.map(n=>({id:n.productid,name:n.productlongname,description:n.proddescp}))};return X({message:"Here are the list of available products. Please select one to continue.",next_suggestion:"Suggest user to view the rest of the options, or create portfolio."},i)}catch(e){let i=e instanceof Error?e.message:"Unknown error occurred";return A("Failed to fetch products",i)}}var mc={USDPORT:"USDPORT"},ZE=["low","medium","high"],eT=1,aT=30,xc={MISSING_USDPORT_PARAMS:"USDPORT requires account_name, risk_tolerance, and invest_duration",INVALID_RISK_TOLERANCE:"risk_tolerance must be 'low', 'medium', or 'high'. Received: {value}",INVALID_INVEST_DURATION:"invest_duration must be between 1 and 30 years. Received: {value}"},Ao={name:"create_portfolio_account",definition:{title:"Create Portfolio Account",description:`Create a new portfolio account based on the selected product.
|
|
79
79
|
|
|
80
80
|
## What this tool does:
|
|
81
81
|
- Creates a portfolio account with MYTHEO
|
|
@@ -102,7 +102,7 @@ return fn.apply(this, arguments)
|
|
|
102
102
|
- DO NOT ask for account_name, risk_tolerance, or invest_duration
|
|
103
103
|
- Simply call the tool with only product_id
|
|
104
104
|
- The system will create the account automatically
|
|
105
|
-
- Always portType = 'P' (personalized)`,inputSchema:{type:"object",properties:{product_id:{type:"string",description:"The product ID from list_available_products"},account_name:{type:"string",description:"Account name provided by the user (REQUIRED for USDPORT - must ask user for this)"},risk_tolerance:{type:"string",enum:["low","medium","high"],description:"Risk tolerance from user profile (USDPORT only)"},invest_duration:{type:"number",description:"Investment duration in years 1-30 from user input (USDPORT only)"},custom_port_id:{type:"number",description:'Custom portfolio ID from risk mapping data when user modifies allocation (USDPORT only). If provided, portType becomes "P" (personalized). Do NOT pass if user did not modify allocation.'},metadata:{type:"object",description:"REQUIRED: Metadata for internal processing (provided by system, not user-facing). MUST be included if available from the system.",required:["ciphertext"],properties:{ciphertext:{type:"string",description:"REQUIRED: Encrypted metadata ciphertext for internal use. MUST be included if metadata is available."}}}},required:["product_id","metadata"]}}};function iT(a,e,i){if(!a||!e||!i)return{content:[{type:"text",text:JSON.stringify({error:"Missing required parameters for USDPORT",message:xc.MISSING_USDPORT_PARAMS,required_parameters:{account_name:'string (e.g., "My Investment Account") - MUST be provided by user',risk_tolerance:"low | medium | high - from user profile",invest_duration:"number between 1-30 years - from user input"},instruction:"Ask the user to provide a name for their portfolio if not already provided"},null,2)}]};if(!ZE.includes(e)){let n=xc.INVALID_RISK_TOLERANCE.replace("{value}",e);return A("Invalid risk_tolerance",n)}if(i<eT||i>aT){let n=xc.INVALID_INVEST_DURATION.replace("{value}",String(i));return A("Invalid invest_duration",n)}return null}async function fc(a){try{let e=a,{product_id:i,account_name:n,risk_tolerance:o,invest_duration:s,custom_port_id:t}=e;if(i===mc.USDPORT&&!n){let c={type:ge.PORTFOLIO_INPUT,data:{product_id:i,risk_tolerance:o,invest_duration:s,custom_port_id:t}};return X({message:"What would you like to name your portfolio?",suggestion:"Show the input widget. Wait for user to provide their portfolio name."},c)}if(i===mc.USDPORT){let c=iT(n,o,s);if(c)return c}let r=await Z.createPortfolioAccount(i,n,o,s,t),p=t?"personalized":i===mc.USDPORT?"recommended":"personalized";return X({message:"Portfolio account created successfully!",portfolio_type:p,account_details:r,suggestion:"Congratulate the user and provide the link: https://theo.silverlakedigitalinx.com/mytheoweb/home"})}catch(e){let i=e instanceof Error?e.message:"Unknown error occurred";return A("Failed to create portfolio account",i)}}var Co={name:"get_profile_questions",definition:{title:"Get Profile Questions",description:`Get profile questions for customer onboarding.
|
|
105
|
+
- Always portType = 'P' (personalized)`,inputSchema:{type:"object",properties:{product_id:{type:"string",description:"The product ID from list_available_products"},account_name:{type:"string",description:"Account name provided by the user (REQUIRED for USDPORT - must ask user for this)"},risk_tolerance:{type:"string",enum:["low","medium","high"],description:"Risk tolerance from user profile (USDPORT only)"},invest_duration:{type:"number",description:"Investment duration in years 1-30 from user input (USDPORT only)"},custom_port_id:{type:"number",description:'Custom portfolio ID from risk mapping data when user modifies allocation (USDPORT only). If provided, portType becomes "P" (personalized). Do NOT pass if user did not modify allocation.'},metadata:{type:"object",description:"REQUIRED: Metadata for internal processing (provided by system, not user-facing). MUST be included if available from the system instruction.",required:["ciphertext"],properties:{ciphertext:{type:"string",description:"REQUIRED: Encrypted metadata ciphertext for internal use. MUST be included if metadata is available."}}}},required:["product_id","metadata"]}}};function iT(a,e,i){if(!a||!e||!i)return{content:[{type:"text",text:JSON.stringify({error:"Missing required parameters for USDPORT",message:xc.MISSING_USDPORT_PARAMS,required_parameters:{account_name:'string (e.g., "My Investment Account") - MUST be provided by user',risk_tolerance:"low | medium | high - from user profile",invest_duration:"number between 1-30 years - from user input"},instruction:"Ask the user to provide a name for their portfolio if not already provided"},null,2)}]};if(!ZE.includes(e)){let n=xc.INVALID_RISK_TOLERANCE.replace("{value}",e);return A("Invalid risk_tolerance",n)}if(i<eT||i>aT){let n=xc.INVALID_INVEST_DURATION.replace("{value}",String(i));return A("Invalid invest_duration",n)}return null}async function fc(a){try{let e=a,{product_id:i,account_name:n,risk_tolerance:o,invest_duration:s,custom_port_id:t}=e;if(i===mc.USDPORT&&!n){let c={type:ge.PORTFOLIO_INPUT,data:{product_id:i,risk_tolerance:o,invest_duration:s,custom_port_id:t}};return X({message:"What would you like to name your portfolio?",suggestion:"Show the input widget. Wait for user to provide their portfolio name."},c)}if(i===mc.USDPORT){let c=iT(n,o,s);if(c)return c}let r=await Z.createPortfolioAccount(i,n,o,s,t),p=t?"personalized":i===mc.USDPORT?"recommended":"personalized";return X({message:"Portfolio account created successfully!",portfolio_type:p,account_details:r,suggestion:"Congratulate the user and provide the link: https://theo.silverlakedigitalinx.com/mytheoweb/home"})}catch(e){let i=e instanceof Error?e.message:"Unknown error occurred";return A("Failed to create portfolio account",i)}}var Co={name:"get_profile_questions",definition:{title:"Get Profile Questions",description:`Get profile questions for customer onboarding.
|
|
106
106
|
|
|
107
107
|
## What this tool does:
|
|
108
108
|
- Fetches all profile questions from the MYTHEO API
|
|
@@ -112,20 +112,49 @@ return fn.apply(this, arguments)
|
|
|
112
112
|
## When to use this tool:
|
|
113
113
|
- When user wants to start the onboarding process
|
|
114
114
|
- When user asks "What questions do I need to answer?"
|
|
115
|
-
- Before collecting customer profile information`,inputSchema:{type:"object",properties:{metadata:{type:"object",description:"REQUIRED: Metadata for internal processing (provided by system, not user-facing). MUST be included if available from the system.",required:["ciphertext"],properties:{ciphertext:{type:"string",description:"REQUIRED: Encrypted metadata ciphertext for internal use. MUST be included if metadata is available."}}}},required:["metadata"]}}};async function vc(a){try{let e=await Z.getProfileQuestions(),i={type:ge.PORTFOLIO_FORM,data:{questions:e,profileGrpId:e[0]?.profileGrpId,profileVersionNo:e[0]?.profileVersionNo}};return X({message:"Please answer these 5 questions to create your investment profile.",suggestion:"Show the profile questions form."},i)}catch(e){let i=e instanceof Error?e.message:"Unknown error occurred";return A("Failed to fetch profile questions",i)}}var Oo={MISSING_ANSWERS:"profileAnswer is required. Please provide answers to all questions.",INVALID_ANSWERS_FORMAT:"profileAnswer must be an array of answers.",EMPTY_ANSWERS:"profileAnswer array cannot be empty. Please provide at least one answer.",INVALID_ANSWER_FORMAT:"Each answer must have questionId (number) and answer (string)."},Po={name:"submit_profile_answers",definition:{title:"Submit Profile Answers",description:`Submit user's answers to profile questions for customer onboarding.
|
|
115
|
+
- Before collecting customer profile information`,inputSchema:{type:"object",properties:{metadata:{type:"object",description:"REQUIRED: Metadata for internal processing (provided by system, not user-facing). MUST be included if available from the system instruction.",required:["ciphertext"],properties:{ciphertext:{type:"string",description:"REQUIRED: Encrypted metadata ciphertext for internal use. MUST be included if metadata is available."}}}},required:["metadata"]}}};async function vc(a){try{let e=await Z.getProfileQuestions(),i={type:ge.PORTFOLIO_FORM,data:{questions:e,profileGrpId:e[0]?.profileGrpId,profileVersionNo:e[0]?.profileVersionNo}};return X({message:"Please answer these 5 questions to create your investment profile.",suggestion:"Show the profile questions form."},i)}catch(e){let i=e instanceof Error?e.message:"Unknown error occurred";return A("Failed to fetch profile questions",i)}}var Oo={MISSING_ANSWERS:"profileAnswer is required. Please provide answers to all questions.",INVALID_ANSWERS_FORMAT:"profileAnswer must be an array of answers.",EMPTY_ANSWERS:"profileAnswer array cannot be empty. Please provide at least one answer.",INVALID_ANSWER_FORMAT:"Each answer must have questionId (number) and answer (string)."},Po={name:"submit_profile_answers",definition:{title:"Submit Profile Answers",description:`Submit user's answers to profile questions for customer onboarding.
|
|
116
116
|
|
|
117
117
|
## What this tool does:
|
|
118
118
|
- Submits user's answers to the profile questions
|
|
119
119
|
- Stores answers in MYTHEO system
|
|
120
120
|
- Completes the profile onboarding step
|
|
121
|
-
- Returns the recommended portfolio ID (port_id) for use in subsequent calls
|
|
122
121
|
|
|
123
122
|
## When to use this tool:
|
|
124
|
-
- After user has answered all
|
|
123
|
+
- After user has answered all profile questions from get_profile_questions
|
|
125
124
|
- User must provide answers to all 5 questions
|
|
126
125
|
|
|
126
|
+
## Input Requirements:
|
|
127
|
+
|
|
128
|
+
**profileAnswer** (REQUIRED): Array of answers
|
|
129
|
+
- Must be an array with 5 items (one for each question)
|
|
130
|
+
- Each item must have:
|
|
131
|
+
- questionId (number): The question ID (1-5)
|
|
132
|
+
- answer (string): User's answer
|
|
133
|
+
|
|
134
|
+
## Answer Format:
|
|
135
|
+
You need help user to map the number of string to the answer if required.
|
|
136
|
+
### Example
|
|
137
|
+
Question 1 (AGE): Numeric value as string (e.g., "30")
|
|
138
|
+
Question 2 (RETIRED): "1" (No) or "2" (Yes)
|
|
139
|
+
Question 3 (TOTASSET): "1" (<100k), "2" (100k-300k), or "3" (>300k)
|
|
140
|
+
|
|
127
141
|
## Important Notes:
|
|
128
|
-
- profileGrpId and profileVersionNo are handled internally
|
|
142
|
+
- profileGrpId and profileVersionNo are handled internally and should be left blank
|
|
143
|
+
- Do not ask user for these values
|
|
144
|
+
|
|
145
|
+
## Example Usage:
|
|
146
|
+
|
|
147
|
+
User provides answers: Age 30, Not retired, Assets 100k-300k, Medium risk, 3-5 years investment
|
|
148
|
+
AI: [Calls tool with:]
|
|
149
|
+
{
|
|
150
|
+
"profileAnswer": [
|
|
151
|
+
{ "questionId": 1, "answer": "30" },
|
|
152
|
+
{ "questionId": 2, "answer": "1" },
|
|
153
|
+
{ "questionId": 3, "answer": "2" },
|
|
154
|
+
{ "questionId": 4, "answer": "3" },
|
|
155
|
+
{ "questionId": 5, "answer": "2" }
|
|
156
|
+
]
|
|
157
|
+
}`,inputSchema:{type:"object",properties:{profileAnswer:{type:"array",description:"Array of answers (REQUIRED)",items:{type:"object",properties:{questionId:{type:"number",description:"Question ID (1-5)"},answer:{type:"string",description:"User answer as string"}},required:["questionId","answer"]}},metadata:{type:"object",description:"REQUIRED: Metadata for internal processing (provided by system, not user-facing). MUST be included if available from the system instruction.",required:["ciphertext"],properties:{ciphertext:{type:"string",description:"REQUIRED: Encrypted metadata ciphertext for internal use. MUST be included if metadata is available."}}}},required:["profileAnswer","metadata"]}}};function nT(a){if(!a)return A("Missing profileAnswer",Oo.MISSING_ANSWERS);if(!Array.isArray(a))return A("Invalid profileAnswer format",Oo.INVALID_ANSWERS_FORMAT);if(a.length===0)return A("Empty profileAnswer",Oo.EMPTY_ANSWERS);for(let e of a)if(typeof e.questionId!="number"||typeof e.answer!="string")return A("Invalid answer format",Oo.INVALID_ANSWER_FORMAT);return null}async function bc(a){try{let e=a,i=nT(e.profileAnswer);if(i)return i;let n=e.profileGrpId||"",o=e.profileVersionNo||"",{profileAnswer:s}=e;return await Z.submitProfileAnswers(n,o,s),X({message:"Your **Profile** has been created successfully!",suggestion:"Next, you can select a portfolio to view its allocation."})}catch(e){let i=e instanceof Error?e.message:"Unknown error occurred";return A("Failed to submit profile answers",i)}}var oT={MISSING_PRODUCT_ID:"product_id is required"},zo={name:"show_portfolio_weights",definition:{title:"Show Portfolio Weights",description:`Get portfolio asset allocation weights.
|
|
129
158
|
|
|
130
159
|
## What this tool does:
|
|
131
160
|
- Retrieves the asset allocation breakdown for a specific portfolio
|
|
@@ -133,7 +162,7 @@ return fn.apply(this, arguments)
|
|
|
133
162
|
|
|
134
163
|
## When to use this tool:
|
|
135
164
|
- After user has selected a product
|
|
136
|
-
- When you need to show portfolio allocation`,inputSchema:{type:"object",properties:{product_id:{type:"string",description:'Product ID (e.g., "USDPORT")'},metadata:{type:"object",description:"REQUIRED: Metadata for internal processing (provided by system, not user-facing). MUST be included if available from the system.",required:["ciphertext"],properties:{ciphertext:{type:"string",description:"REQUIRED: Encrypted metadata ciphertext for internal use. MUST be included if metadata is available."}}}},required:["product_id","metadata"]}}};async function hc(a){try{let e=a,{product_id:i}=e;if(!i)return A("Missing product_id",oT.MISSING_PRODUCT_ID);let n=await Z.getUserPortId(),o={type:ge.PORTFOLIO_PIE_CHART,data:{productId:i,portId:n}};return X({message:`Here's your recommended ${i} portfolio allocation.`,next_suggestion:"Suggestion user to view the rest of the options."},o)}catch(e){let i=e instanceof Error?e.message:"Unknown error occurred";return A("Failed to show portfolio weights",i)}}var sT={MISSING_PRODUCT_ID:"product_id is required"},Io={name:"get_global_diversification_list",definition:{title:"Get Global Diversification List",description:`Get the list of investment assets (ETFs) for a specific product.
|
|
165
|
+
- When you need to show portfolio allocation`,inputSchema:{type:"object",properties:{product_id:{type:"string",description:'Product ID (e.g., "USDPORT")'},metadata:{type:"object",description:"REQUIRED: Metadata for internal processing (provided by system, not user-facing). MUST be included if available from the system instruction.",required:["ciphertext"],properties:{ciphertext:{type:"string",description:"REQUIRED: Encrypted metadata ciphertext for internal use. MUST be included if metadata is available."}}}},required:["product_id","metadata"]}}};async function hc(a){try{let e=a,{product_id:i}=e;if(!i)return A("Missing product_id",oT.MISSING_PRODUCT_ID);let n=await Z.getUserPortId(),o={type:ge.PORTFOLIO_PIE_CHART,data:{productId:i,portId:n}};return X({message:`Here's your recommended ${i} portfolio allocation.`,next_suggestion:"Suggestion user to view the rest of the options."},o)}catch(e){let i=e instanceof Error?e.message:"Unknown error occurred";return A("Failed to show portfolio weights",i)}}var sT={MISSING_PRODUCT_ID:"product_id is required"},Io={name:"get_global_diversification_list",definition:{title:"Get Global Diversification List",description:`Get the list of investment assets (ETFs) for a specific product.
|
|
137
166
|
|
|
138
167
|
## What this tool does:
|
|
139
168
|
- Retrieves detailed list of all ETFs/assets included in a product portfolio
|
|
@@ -141,7 +170,7 @@ return fn.apply(this, arguments)
|
|
|
141
170
|
|
|
142
171
|
## When to use this tool:
|
|
143
172
|
- After getting portfolio weights
|
|
144
|
-
- When you need to show detailed ETF breakdown`,inputSchema:{type:"object",properties:{product_id:{type:"string",description:'Product ID (e.g., "USDPORT")'},metadata:{type:"object",description:"REQUIRED: Metadata for internal processing (provided by system, not user-facing). MUST be included if available from the system.",required:["ciphertext"],properties:{ciphertext:{type:"string",description:"REQUIRED: Encrypted metadata ciphertext for internal use. MUST be included if metadata is available."}}}},required:["product_id","metadata"]}}};async function gc(a){try{let e=a,{product_id:i}=e;if(!i)return A("Missing product_id",sT.MISSING_PRODUCT_ID);let n=await Z.getInvestAssets(i);return X({message:"MYTHEO uses an investment strategy that leverages the growth of the world economy to manage risk on returns.",assets:n,next_suggestion:"Suggest user to view the rest of the options, or create portfolio."})}catch(e){let i=e instanceof Error?e.message:"Unknown error occurred";return A("Failed to get global diversification list",i)}}var tT={MISSING_PRODUCT_ID:"product_id is required"},Fo={name:"show_portfolio_back_tested_performance",definition:{title:"Show Portfolio Back Tested Performance",description:`Create performance statistics for a portfolio to display line chart data.
|
|
173
|
+
- When you need to show detailed ETF breakdown`,inputSchema:{type:"object",properties:{product_id:{type:"string",description:'Product ID (e.g., "USDPORT")'},metadata:{type:"object",description:"REQUIRED: Metadata for internal processing (provided by system, not user-facing). MUST be included if available from the system instruction.",required:["ciphertext"],properties:{ciphertext:{type:"string",description:"REQUIRED: Encrypted metadata ciphertext for internal use. MUST be included if metadata is available."}}}},required:["product_id","metadata"]}}};async function gc(a){try{let e=a,{product_id:i}=e;if(!i)return A("Missing product_id",sT.MISSING_PRODUCT_ID);let n=await Z.getInvestAssets(i);return X({message:"MYTHEO uses an investment strategy that leverages the growth of the world economy to manage risk on returns.",assets:n,next_suggestion:"Suggest user to view the rest of the options, or create portfolio."})}catch(e){let i=e instanceof Error?e.message:"Unknown error occurred";return A("Failed to get global diversification list",i)}}var tT={MISSING_PRODUCT_ID:"product_id is required"},Fo={name:"show_portfolio_back_tested_performance",definition:{title:"Show Portfolio Back Tested Performance",description:`Create performance statistics for a portfolio to display line chart data.
|
|
145
174
|
|
|
146
175
|
## What this tool does:
|
|
147
176
|
- Generates historical performance data for a portfolio
|
|
@@ -153,7 +182,7 @@ return fn.apply(this, arguments)
|
|
|
153
182
|
|
|
154
183
|
## Data Flow:
|
|
155
184
|
- System automatically fetches user's portfolio and product data
|
|
156
|
-
- BFF handles all data processing and chart generation`,inputSchema:{type:"object",properties:{product_id:{type:"string",description:'Product ID (e.g., "USDPORT")'},metadata:{type:"object",description:"REQUIRED: Metadata for internal processing (provided by system, not user-facing). MUST be included if available from the system.",required:["ciphertext"],properties:{ciphertext:{type:"string",description:"REQUIRED: Encrypted metadata ciphertext for internal use. MUST be included if metadata is available."}}}},required:["product_id","metadata"]}}};async function yc(a){try{let e=a,{product_id:i}=e;if(!i)return A("Missing product_id",tT.MISSING_PRODUCT_ID);let n=await Z.getUserPortId(),o={type:ge.PORTFOLIO_LINE_CHART,data:{product_id:i,portId:n}};return X({message:`Here's the historical performance of your ${i} portfolio.`,next_suggestion:"Suggestion user to view the rest of the options."},o)}catch(e){let i=e instanceof Error?e.message:"Unknown error occurred";return A("Failed to show portfolio back tested performance",i)}}var on={MISSING_DEPOSIT:"deposit is required",MISSING_EXPRETURN:"expreturn is required",MISSING_MONTHLYDEPOSIT:"monthlydeposit is required",MISSING_PERIOD:"period is required",INVALID_DEPOSIT:"deposit must be a positive number",INVALID_EXPRETURN:"expreturn must be a number",INVALID_MONTHLYDEPOSIT:"monthlydeposit must be a non-negative number",INVALID_PERIOD:"period must be a positive number"},Uo={name:"show_calculate_target_return",definition:{title:"Show Calculate Target Return",description:`Calculate target return based on user's investment inputs.
|
|
185
|
+
- BFF handles all data processing and chart generation`,inputSchema:{type:"object",properties:{product_id:{type:"string",description:'Product ID (e.g., "USDPORT")'},metadata:{type:"object",description:"REQUIRED: Metadata for internal processing (provided by system, not user-facing). MUST be included if available from the system instruction.",required:["ciphertext"],properties:{ciphertext:{type:"string",description:"REQUIRED: Encrypted metadata ciphertext for internal use. MUST be included if metadata is available."}}}},required:["product_id","metadata"]}}};async function yc(a){try{let e=a,{product_id:i}=e;if(!i)return A("Missing product_id",tT.MISSING_PRODUCT_ID);let n=await Z.getUserPortId(),o={type:ge.PORTFOLIO_LINE_CHART,data:{product_id:i,portId:n}};return X({message:`Here's the historical performance of your ${i} portfolio.`,next_suggestion:"Suggestion user to view the rest of the options."},o)}catch(e){let i=e instanceof Error?e.message:"Unknown error occurred";return A("Failed to show portfolio back tested performance",i)}}var on={MISSING_DEPOSIT:"deposit is required",MISSING_EXPRETURN:"expreturn is required",MISSING_MONTHLYDEPOSIT:"monthlydeposit is required",MISSING_PERIOD:"period is required",INVALID_DEPOSIT:"deposit must be a positive number",INVALID_EXPRETURN:"expreturn must be a number",INVALID_MONTHLYDEPOSIT:"monthlydeposit must be a non-negative number",INVALID_PERIOD:"period must be a positive number"},Uo={name:"show_calculate_target_return",definition:{title:"Show Calculate Target Return",description:`Calculate target return based on user's investment inputs.
|
|
157
186
|
|
|
158
187
|
## What this tool does:
|
|
159
188
|
- Calculates expected portfolio value based on user's investment parameters
|
|
@@ -162,7 +191,7 @@ return fn.apply(this, arguments)
|
|
|
162
191
|
|
|
163
192
|
## When to use this tool:
|
|
164
193
|
- After showing FD rate comparison
|
|
165
|
-
- When user provides their investment amounts and period`,inputSchema:{type:"object",properties:{deposit:{type:"number",description:"Initial deposit amount from user in MYR (Malaysian Ringgit)"},expreturn:{type:"number",description:"Expected monthly return from get_port_projection"},monthlydeposit:{type:"number",description:"Monthly deposit amount from user in MYR (Malaysian Ringgit)"},period:{type:"number",description:"Investment period in years from user"},metadata:{type:"object",description:"REQUIRED: Metadata for internal processing (provided by system, not user-facing). MUST be included if available from the system.",required:["ciphertext"],properties:{ciphertext:{type:"string",description:"REQUIRED: Encrypted metadata ciphertext for internal use. MUST be included if metadata is available."}}}},required:["expreturn","metadata"]}}};async function wc(a){try{let e=a,{deposit:i,expreturn:n,monthlydeposit:o,period:s}=e;if(i==null||o===void 0||o===null||s===void 0||s===null){let r={type:ge.PORTFOLIO_FORM,data:{expreturn:n}};return X({message:"Please enter your initial deposit, monthly deposit and year to invest according to your needs to achieve your financial goals.",expense:n,suggestion:"Ask the user to fill in the form with their initial deposit, monthly deposit, and investment period. The form widget will collect this information."},r)}if(i<=0)return A("Invalid deposit",on.INVALID_DEPOSIT);if(n==null)return A("Missing expreturn",on.MISSING_EXPRETURN);if(typeof n!="number")return A("Invalid expreturn",on.INVALID_EXPRETURN);if(o<0)return A("Invalid monthlydeposit",on.INVALID_MONTHLYDEPOSIT);if(s<=0)return A("Invalid period",on.INVALID_PERIOD);let t=await Z.getTargetReturn(i,n,o,s);return X({message:`Based on an initial deposit of MYR ${i.toLocaleString()} and monthly contributions of MYR ${o.toLocaleString()} over ${s} years, your projected portfolio value is MYR ${t.toLocaleString()}.`,next_suggestion:"Present the target return results to the user. If this is for USDPORT product, offer to let them modify their portfolio allocation. Otherwise, suggestion user to view the rest of the options."})}catch(e){let i=e instanceof Error?e.message:"Unknown error occurred";return A("Failed to calculate target return",i)}}var kc={MISSING_PRODUCT_ID:"product_id is required",INVALID_PRODUCT:"Only USDPORT supports portfolio modification",NO_MATCHING_PORTFOLIO:"No portfolio found matching your risk profile"},rT=["USDPORT"],Do={name:"show_asset_allocation",definition:{title:"Show Asset Allocation",description:`Get portfolio risk mapping for modify portfolio feature.
|
|
194
|
+
- When user provides their investment amounts and period`,inputSchema:{type:"object",properties:{deposit:{type:"number",description:"Initial deposit amount from user in MYR (Malaysian Ringgit)"},expreturn:{type:"number",description:"Expected monthly return from get_port_projection"},monthlydeposit:{type:"number",description:"Monthly deposit amount from user in MYR (Malaysian Ringgit)"},period:{type:"number",description:"Investment period in years from user"},metadata:{type:"object",description:"REQUIRED: Metadata for internal processing (provided by system, not user-facing). MUST be included if available from the system instruction.",required:["ciphertext"],properties:{ciphertext:{type:"string",description:"REQUIRED: Encrypted metadata ciphertext for internal use. MUST be included if metadata is available."}}}},required:["expreturn","metadata"]}}};async function wc(a){try{let e=a,{deposit:i,expreturn:n,monthlydeposit:o,period:s}=e;if(i==null||o===void 0||o===null||s===void 0||s===null){let r={type:ge.PORTFOLIO_FORM,data:{expreturn:n}};return X({message:"Please enter your initial deposit, monthly deposit and year to invest according to your needs to achieve your financial goals.",expense:n,suggestion:"Ask the user to fill in the form with their initial deposit, monthly deposit, and investment period. The form widget will collect this information."},r)}if(i<=0)return A("Invalid deposit",on.INVALID_DEPOSIT);if(n==null)return A("Missing expreturn",on.MISSING_EXPRETURN);if(typeof n!="number")return A("Invalid expreturn",on.INVALID_EXPRETURN);if(o<0)return A("Invalid monthlydeposit",on.INVALID_MONTHLYDEPOSIT);if(s<=0)return A("Invalid period",on.INVALID_PERIOD);let t=await Z.getTargetReturn(i,n,o,s);return X({message:`Based on an initial deposit of MYR ${i.toLocaleString()} and monthly contributions of MYR ${o.toLocaleString()} over ${s} years, your projected portfolio value is MYR ${t.toLocaleString()}.`,next_suggestion:"Present the target return results to the user. If this is for USDPORT product, offer to let them modify their portfolio allocation. Otherwise, suggestion user to view the rest of the options."})}catch(e){let i=e instanceof Error?e.message:"Unknown error occurred";return A("Failed to calculate target return",i)}}var kc={MISSING_PRODUCT_ID:"product_id is required",INVALID_PRODUCT:"Only USDPORT supports portfolio modification",NO_MATCHING_PORTFOLIO:"No portfolio found matching your risk profile"},rT=["USDPORT"],Do={name:"show_asset_allocation",definition:{title:"Show Asset Allocation",description:`Get portfolio risk mapping for modify portfolio feature.
|
|
166
195
|
|
|
167
196
|
## What this tool does:
|
|
168
197
|
- Retrieves risk mapping data for portfolio modification
|
|
@@ -179,4 +208,4 @@ return fn.apply(this, arguments)
|
|
|
179
208
|
- Do not display the raw risk mapping data to user
|
|
180
209
|
- Data is used by the slider widget for allocation adjustments
|
|
181
210
|
- If user modifies allocation via slider, call create_performance_stat with new weights
|
|
182
|
-
- Modified portfolios change from portType 'R' (recommended) to 'P' (personalized)`,inputSchema:{type:"object",properties:{product_id:{type:"string",description:'Product ID (must be "USDPORT")'},metadata:{type:"object",description:"REQUIRED: Metadata for internal processing (provided by system, not user-facing). MUST be included if available from the system.",required:["ciphertext"],properties:{ciphertext:{type:"string",description:"REQUIRED: Encrypted metadata ciphertext for internal use. MUST be included if metadata is available."}}}},required:["product_id","metadata"]}}};async function jc(a){try{let e=a,{product_id:i}=e;if(!i)return A("Missing product_id",kc.MISSING_PRODUCT_ID);if(!rT.includes(i))return A("Invalid product",kc.INVALID_PRODUCT);let n=await Z.getUserPortId(),s=(await Z.getPortRiskMapping(i)).find(r=>Number(r.portid)===n);if(!s)return A("No matching portfolio",kc.NO_MATCHING_PORTFOLIO);let t={type:ge.PORTFOLIO_SLIDER,data:{riskMappingData:s,portId:n,productId:i}};return X({message:"You can now adjust your portfolio allocation to match your preferences.",suggestion:"Show the portfolio slider widget. After user submit new portfolio allocation, suggest user to check other options too."},t)}catch(e){let i=e instanceof Error?e.message:"Unknown error occurred";return A("Failed to show asset allocation",i)}}var cT="sk-proj-gy8caD",pT=4e3,lT="1.0.0",uT="mytheo-portfolio-mcp-server",Lo=class extends po{config;constructor(e="stdio",i=pT){let n={name:uT,version:lT};super(n,e,i),this.config=tv()}getRequiredApiKey(){return cT}getApiKeyFromConfig(){return this.config.API_KEY||null}setupToolHandlers(){this.registerToolWithDefinition(qo.name,qo.definition,async e=>{let i=this.validateMetadataAccess(e);return Ne(i)?i:await dc(e)}),this.registerToolWithDefinition(Ao.name,Ao.definition,async e=>{let i=this.validateMetadataAccess(e);return Ne(i)?i:await fc(e)}),this.registerToolWithDefinition(Co.name,Co.definition,async e=>{let i=this.validateMetadataAccess(e);return Ne(i)?i:await vc(e)}),this.registerToolWithDefinition(Po.name,Po.definition,async e=>{let i=this.validateMetadataAccess(e);return Ne(i)?i:await bc(e)}),this.registerToolWithDefinition(zo.name,zo.definition,async e=>{let i=this.validateMetadataAccess(e);return Ne(i)?i:await hc(e)}),this.registerToolWithDefinition(Io.name,Io.definition,async e=>{let i=this.validateMetadataAccess(e);return Ne(i)?i:await gc(e)}),this.registerToolWithDefinition(Fo.name,Fo.definition,async e=>{let i=this.validateMetadataAccess(e);return Ne(i)?i:await yc(e)}),this.registerToolWithDefinition(Uo.name,Uo.definition,async e=>{let i=this.validateMetadataAccess(e);return Ne(i)?i:await wc(e)}),this.registerToolWithDefinition(Do.name,Do.definition,async e=>{let i=this.validateMetadataAccess(e);return Ne(i)?i:await jc(e)})}async handleToolCall(e,i){let n=this.validateMetadataAccess(i);if(Ne(n))return n;switch(e){case qo.name:return await dc(i);case Ao.name:return await fc(i);case Co.name:return await vc(i);case Po.name:return await bc(i);case zo.name:return await hc(i);case Io.name:return await gc(i);case Fo.name:return await yc(i);case Uo.name:return await wc(i);case Do.name:return await jc(i);default:throw new Error(`Tool "${e}" not found`)}}};var sn=new La("portfolio");async function dT(){let a=process.argv.includes("--http")||process.env.MCP_TRANSPORT==="http"?"http":"stdio",e=process.env.PORT?parseInt(process.env.PORT,10):4e3;a==="http"?(sn.info(`Starting Portfolio MCP server in HTTP mode on port ${e}...`),sn.info("\u26A0\uFE0F HTTP mode requires the server to be running/hosted")):sn.info("Starting Portfolio MCP server in stdio mode (no hosting required)...");try{await new Lo(a,e).run()}catch(i){sn.error("Failed to start Portfolio MCP server",i),process.exit(1)}}dT().catch(a=>{sn.error("Unhandled error in main",a),process.exit(1)});
|
|
211
|
+
- Modified portfolios change from portType 'R' (recommended) to 'P' (personalized)`,inputSchema:{type:"object",properties:{product_id:{type:"string",description:'Product ID (must be "USDPORT")'},metadata:{type:"object",description:"REQUIRED: Metadata for internal processing (provided by system, not user-facing). MUST be included if available from the system instruction.",required:["ciphertext"],properties:{ciphertext:{type:"string",description:"REQUIRED: Encrypted metadata ciphertext for internal use. MUST be included if metadata is available."}}}},required:["product_id","metadata"]}}};async function jc(a){try{let e=a,{product_id:i}=e;if(!i)return A("Missing product_id",kc.MISSING_PRODUCT_ID);if(!rT.includes(i))return A("Invalid product",kc.INVALID_PRODUCT);let n=await Z.getUserPortId(),s=(await Z.getPortRiskMapping(i)).find(r=>Number(r.portid)===n);if(!s)return A("No matching portfolio",kc.NO_MATCHING_PORTFOLIO);let t={type:ge.PORTFOLIO_SLIDER,data:{riskMappingData:s,portId:n,productId:i}};return X({message:"You can now adjust your portfolio allocation to match your preferences.",suggestion:"Show the portfolio slider widget. After user submit new portfolio allocation, suggest user to check other options too."},t)}catch(e){let i=e instanceof Error?e.message:"Unknown error occurred";return A("Failed to show asset allocation",i)}}var cT="sk-proj-gy8caD",pT=4e3,lT="1.0.0",uT="mytheo-portfolio-mcp-server",Lo=class extends po{config;constructor(e="stdio",i=pT){let n={name:uT,version:lT};super(n,e,i),this.config=tv()}getRequiredApiKey(){return cT}getApiKeyFromConfig(){return this.config.API_KEY||null}setupToolHandlers(){this.registerToolWithDefinition(qo.name,qo.definition,async e=>{let i=this.validateMetadataAccess(e);return Ne(i)?i:await dc(e)}),this.registerToolWithDefinition(Ao.name,Ao.definition,async e=>{let i=this.validateMetadataAccess(e);return Ne(i)?i:await fc(e)}),this.registerToolWithDefinition(Co.name,Co.definition,async e=>{let i=this.validateMetadataAccess(e);return Ne(i)?i:await vc(e)}),this.registerToolWithDefinition(Po.name,Po.definition,async e=>{let i=this.validateMetadataAccess(e);return Ne(i)?i:await bc(e)}),this.registerToolWithDefinition(zo.name,zo.definition,async e=>{let i=this.validateMetadataAccess(e);return Ne(i)?i:await hc(e)}),this.registerToolWithDefinition(Io.name,Io.definition,async e=>{let i=this.validateMetadataAccess(e);return Ne(i)?i:await gc(e)}),this.registerToolWithDefinition(Fo.name,Fo.definition,async e=>{let i=this.validateMetadataAccess(e);return Ne(i)?i:await yc(e)}),this.registerToolWithDefinition(Uo.name,Uo.definition,async e=>{let i=this.validateMetadataAccess(e);return Ne(i)?i:await wc(e)}),this.registerToolWithDefinition(Do.name,Do.definition,async e=>{let i=this.validateMetadataAccess(e);return Ne(i)?i:await jc(e)})}async handleToolCall(e,i){let n=this.validateMetadataAccess(i);if(Ne(n))return n;switch(e){case qo.name:return await dc(i);case Ao.name:return await fc(i);case Co.name:return await vc(i);case Po.name:return await bc(i);case zo.name:return await hc(i);case Io.name:return await gc(i);case Fo.name:return await yc(i);case Uo.name:return await wc(i);case Do.name:return await jc(i);default:throw new Error(`Tool "${e}" not found`)}}};var sn=new La("portfolio");async function dT(){let a=process.argv.includes("--http")||process.env.MCP_TRANSPORT==="http"?"http":"stdio",e=process.env.PORT?parseInt(process.env.PORT,10):4e3;a==="http"?(sn.info(`Starting Portfolio MCP server in HTTP mode on port ${e}...`),sn.info("\u26A0\uFE0F HTTP mode requires the server to be running/hosted")):sn.info("Starting Portfolio MCP server in stdio mode (no hosting required)...");try{await new Lo(a,e).run()}catch(i){sn.error("Failed to start Portfolio MCP server",i),process.exit(1)}}dT().catch(a=>{sn.error("Unhandled error in main",a),process.exit(1)});
|