Skip to content

New Components - mboum #18129

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open

New Components - mboum #18129

wants to merge 7 commits into from

Conversation

michelle0927
Copy link
Collaborator

@michelle0927 michelle0927 commented Aug 20, 2025

Resolves #17889

@vunguyenhung These are all untested. To test, you'll need to wait until Sergio hears back from Mboum support about API access. #17889 (comment)

Summary by CodeRabbit

  • New Features
    • Full MBoum integration: market search, tickers, market info, movers, screener, news, realtime quotes, historical data, modules, and ticker summaries.
    • Data & analytics: analyst ratings, price targets, financials, revenue, short interest, institutional holdings, SEC filings.
    • Options: quotes, flow, unusual activity, most active, highest IV, IV change, IV rank/percentile.
    • Calendars & events: earnings, dividends, IPOs, public offerings, stock splits, economic events.
    • Technical indicators: SMA, RSI, MACD, CCI, ADX, AD, ADOSC, STOCH.
    • Crypto: currencies, quotes, profiles, holders, modules.
  • Chores
    • Bumped package version to 0.1.0 and added platform dependency.

Copy link
Contributor

coderabbitai bot commented Aug 20, 2025

Walkthrough

Adds a full Mboum REST client with authenticated request helpers, a shared constants module, many new action modules that call client endpoints (stocks, options, indicators, calendar, crypto), and a package.json version/dependency update.

Changes

Cohort / File(s) Summary
Core Mboum App Client
components/mboum/mboum.app.mjs
Replaces placeholder with an authenticated REST client using axios; adds propDefinitions; implements _baseUrl/_makeRequest and ~50 endpoint wrapper methods (search, markets, stocks, options, calendar, indicators, crypto).
Shared Constants
components/mboum/common/constants.mjs
Adds UI/config constants (INTERVALS, HISTORICAL_DATA_INTERVALS, SERIES_TYPES, MA_TYPES, INTERNATIONAL_HOLDINGS_TYPES, STOCK_MODULES, SCREENER_FILTERS, CRYPTO_MODULES) and default export.
Package Metadata
components/mboum/package.json
Bumps package version 0.0.1 → 0.1.0 and adds dependency "@pipedream/platform": "^3.1.0".
Technical Indicators Actions
components/mboum/actions/get-ad/get-ad.mjs, .../get-adosc/get-adosc.mjs, .../get-adx/get-adx.mjs, .../get-cci/get-cci.mjs, .../get-macd/get-macd.mjs, .../get-rsi/get-rsi.mjs, .../get-sma/get-sma.mjs, .../get-stoch/get-stoch.mjs
New actions for AD, ADOSC, ADX, CCI, MACD, RSI, SMA, STOCH. Each maps props → API params, calls mboum client, exports a summary, returns response.
Stocks & Market Data Actions
components/mboum/actions/get-analyst-ratings/get-analyst-ratings.mjs, .../get-financials/get-financials.mjs, .../get-price-targets/get-price-targets.mjs, .../get-revenue/get-revenue.mjs, .../get-sec-filings/get-sec-filings.mjs, .../get-short-interest/get-short-interest.mjs, .../get-institutional-holdings/get-institutional-holdings.mjs, .../get-modules/get-modules.mjs, .../get-news/get-news.mjs, .../get-historical-data/get-historical-data.mjs, .../get-history/get-history.mjs, .../get-tickers/get-tickers.mjs, .../get-market-info/get-market-info.mjs, .../get-realtime-quote/get-realtime-quote.mjs, .../get-ticker-summary/get-ticker-summary.mjs, .../search/search.mjs
New equity/market actions that call corresponding mboum client methods with mapped params, export summaries, and return responses.
Options Actions
components/mboum/actions/get-options/get-options.mjs, .../get-options-flow/get-options-flow.mjs, .../get-unusual-options-activity/get-unusual-options-activity.mjs, .../get-iv-rank-percentile/get-iv-rank-percentile.mjs, .../get-iv-change/get-iv-change.mjs, .../get-most-active-options/get-most-active-options.mjs, .../get-highest-iv-options/get-highest-iv-options.mjs, .../get-insider-trading/get-insider-trading.mjs, .../get-movers/get-movers.mjs, .../get-screener/get-screener.mjs
New options-related actions (options data, flow, unusual activity, IV metrics, most active/highest IV, insider trading, movers, screener). Map inputs to mboum client params and return responses.
Calendar & Events Actions
components/mboum/actions/get-earnings/get-earnings.mjs, .../get-dividends/get-dividends.mjs, .../get-economic-events/get-economic-events.mjs, .../get-ipo-data/get-ipo-data.mjs, .../get-public-offerings/get-public-offerings.mjs, .../get-stock-splits/get-stock-splits.mjs
New calendar/event actions (earnings, dividends, economic events, IPOs, public offerings, stock splits). Each forwards date/page params to the client and returns responses.
Crypto Actions
components/mboum/actions/get-crypto-currencies/get-crypto-currencies.mjs, .../get-crypto-holders/get-crypto-holders.mjs, .../get-crypto-modules/get-crypto-modules.mjs, .../get-crypto-profile/get-crypto-profile.mjs, .../get-crypto-quotes/get-crypto-quotes.mjs
New crypto actions (coins list, holders, modules, profile, quotes). Wire props → client calls; export summaries; return responses.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Action as Pipedream Action
  participant Mboum as Mboum App (_makeRequest)
  participant Axios as HTTP Client
  participant API as MBoum API

  User->>Action: Provide props (ticker, dates, params)
  Action->>Mboum: call method (e.g., getRSI) with { $, params }
  Mboum->>Mboum: build path, map params, set Authorization header
  Mboum->>Axios: _makeRequest(url, { params, headers })
  Axios->>API: HTTP request
  API-->>Axios: JSON response
  Axios-->>Mboum: response
  Mboum-->>Action: return response
  Action->>Action: $.export("$summary", ...)
  Action-->>User: return response
  note over Mboum,Axios: centralized auth + request construction
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Assessment against linked issues

Objective Addressed Explanation
Implement Mboum MCP Server tools with actions across General/Stocks/Options/Calendar/Crypto (#17889)
Integrate authenticated Mboum API client and request handling (#17889)
Expose standardized propDefinitions for common inputs (ticker, page, date, interval, limit, seriesType) (#17889)
Provide endpoint coverage for technical indicators (RSI, MACD, SMA, etc.) (#17889)

Suggested labels

action

Suggested reviewers

  • lcaresia
  • jcortes

Poem

A hop, a skip, I wired the streams,
Of tickers, charts, and API dreams.
I tunnelled auth and routed calls,
Through burrowed code and tiny walls.
Now markets sing and data flows—🐇📈

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch issue-17889

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

vercel bot commented Aug 20, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
pipedream-docs Ignored Ignored Aug 20, 2025 7:13pm
pipedream-docs-redirect-do-not-edit Ignored Ignored Aug 20, 2025 7:13pm

@michelle0927 michelle0927 marked this pull request as ready for review August 20, 2025 18:51
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 14

♻️ Duplicate comments (2)
components/mboum/actions/get-crypto-quotes/get-crypto-quotes.mjs (1)

11-15: Prop name “key” comment mirrors prior suggestion.

Same naming concern as noted in get-crypto-holders; consider cryptoId or similar.

components/mboum/actions/get-crypto-profile/get-crypto-profile.mjs (1)

11-15: Prop name “key” comment mirrors prior suggestion.

Same naming concern as noted in get-crypto-holders; consider cryptoId or similar.

🧹 Nitpick comments (78)
components/mboum/actions/get-price-targets/get-price-targets.mjs (2)

26-27: Minor: Normalize ticker in summary

Uppercasing the ticker improves readability and keeps summaries consistent.

Apply this diff:

-    $.export("$summary", `Successfully retrieved price targets for ${this.ticker}`);
+    $.export("$summary", `Successfully retrieved price targets for ${this.ticker.toUpperCase()}`);

6-6: Docs link: avoid brittle, style-encoded anchors

The current link includes CSS-like fragments (small-stylecolor-…) that are likely unstable. Prefer a clean endpoint anchor if available, or link to the section root.

Example:

-  description: "Get analyst price targets and recommendations for a stock including target highs, lows, and consensus. [See the documentation](https://docs.mboum.com/#stocks-options-small-stylecolor-f8f2f2background-fa256fpadding-1px-4pxborder-radius-3pxhotsmall-GETapi-v2-markets-stock-price-targets)",
+  description: "Get analyst price targets and recommendations for a stock including target highs, lows, and consensus. [See the documentation](https://docs.mboum.com/)",

If a stable anchor exists for this endpoint on docs.mboum.com, link to that instead.

components/mboum/actions/get-most-active-options/get-most-active-options.mjs (2)

29-35: Confirmed: getMostActive maps to the Options “most-active” endpoint
The getMostActive method in components/mboum/mboum.app.mjs (around line 201) calls /v1/markets/options/most-active, so the current call in
components/mboum/actions/get-most-active-options/get-most-active-options.mjs is correct.

Optional: for clarity, you may rename getMostActivegetMostActiveOptions and update the import/call site accordingly.


11-20: Confirm and correct “type” parameter options

It appears the current options [“STOCKS”, “ETFS”, “INDICES”] describe asset classes, not option types—most options endpoints accept “call” and “put.” Please:

  • Verify the exact allowed values for type in the official Mboum API docs or sample requests.
  • Update components/mboum/actions/get-most-active-options/get-most-active-options.mjs, replacing the options array with the confirmed values.
  • (Optional) Extract these values into components/mboum/common/constants.mjs for reuse across related actions.
components/mboum/actions/get-cci/get-cci.mjs (2)

29-34: Constrain timePeriod input

Add a minimum bound to avoid invalid requests (e.g., 0 or negative periods). If the API documents a default, consider setting it; otherwise, min-only is safe.

Apply this diff:

     timePeriod: {
       type: "integer",
       label: "Time Period",
       description: "Number of periods for CCI calculation",
       optional: true,
+      min: 1,
     },

54-55: Avoid “CCI(undefined)” in the summary when timePeriod is omitted

Tweak the summary to include the period only when provided.

Apply this diff:

-    $.export("$summary", `Successfully calculated CCI(${this.timePeriod}) for ${this.ticker} on ${this.interval} intervals`);
+    $.export("$summary", `Successfully calculated CCI${this.timePeriod ? `(${this.timePeriod})` : ""} for ${this.ticker} on ${this.interval} intervals`);
components/mboum/actions/get-highest-iv-options/get-highest-iv-options.mjs (2)

11-19: Add a sensible default for sort (and consider making it optional).

Defaulting to "HIGHEST" reduces friction and mirrors likely API defaults.

     sort: {
       type: "string",
       label: "Sort",
       description: "Sort options by",
+      default: "HIGHEST",
       options: [
         "HIGHEST",
         "LOWEST",
       ],
     },

27-34: Ensure param naming is consistent across actions and the mboum client.

Other actions in this PR mix snake_case and camelCase (e.g., price_min vs priceMin). Please standardize to one style and ensure the mboum client maps to the API’s expected query keys to prevent subtle bugs.

If helpful, I can scan the repo and list all param key variants used across Mboum actions for cleanup.

components/mboum/actions/get-economic-events/get-economic-events.mjs (2)

9-17: Consider adding page support if this endpoint paginates.

Several calendar-like endpoints (dividends, stock splits) accept page. If economic events also paginate, expose page for consistency.

   props: {
     mboum,
     date: {
       propDefinition: [
         mboum,
         "date",
       ],
     },
+    page: {
+      propDefinition: [
+        mboum,
+        "page",
+      ],
+    },
   },

19-24: Pass page to the client if supported.

Only apply if the endpoint supports pagination to avoid sending unknown params.

   const response = await this.mboum.getEconomicEvents({
     $,
     params: {
       date: this.date,
+      page: this.page,
     },
   });
components/mboum/actions/get-options-flow/get-options-flow.mjs (1)

11-20: Centralize type options and set a default.

  • Reduce duplication and drift by importing options from a shared constants module if available (e.g., components/mboum/common/constants.mjs).
  • Defaulting to "STOCKS" provides a sensible UX.
     type: {
       type: "string",
       label: "Type",
       description: "Type of options flow to retrieve",
+      default: "STOCKS",
       options: [
         "STOCKS",
         "ETFS",
         "INDICES",
       ],
     },

I can locate the constants export and propose the exact import if you want to consolidate.

components/mboum/actions/get-public-offerings/get-public-offerings.mjs (3)

6-6: Fix likely-broken docs link (remove embedded style fragment).

The anchor includes style artifacts and almost certainly won’t resolve.

Apply this change and verify the link resolves:

-  description: "Get data on public offerings including secondary offerings, SPAC mergers, and other capital market events. [See the documentation](https://docs.mboum.com/#stocks-options-small-stylecolor-f8f2f2background-fa256fpadding-1px-4pxborder-radius-3pxhotsmall-GETapi-v1-markets-calendar-public_offerings)",
+  description: "Get data on public offerings including secondary offerings, SPAC mergers, and other capital market events. [See the documentation](https://docs.mboum.com/#stocks-options-GETapi-v1-markets-calendar-public_offerings)",

10-17: Confirm pagination support and add page prop if available.

Dividends and Stock Splits actions include page; this calendar endpoint may support it too. If supported, expose it for parity.

Proposed change:

   props: {
     mboum,
     date: {
       propDefinition: [
         mboum,
         "date",
       ],
     },
+    page: {
+      propDefinition: [
+        mboum,
+        "page",
+      ],
+      optional: true,
+    },
   },
   async run({ $ }) {
     const response = await this.mboum.getPublicOfferings({
       $,
       params: {
         date: this.date,
+        ...(this.page && { page: this.page }),
       },
     });

Also applies to: 21-23


26-27: Maintain consistent return shapes or bulk-refactor all actions

Most MBoum actions (including get-public-offerings) currently return the full response; only the three crypto endpoints (get-crypto-profile, get-crypto-holders, get-crypto-currencies) return response.data. Changing only this one action to return response.data would introduce a new inconsistency.

• If the intended standard is to return .data, please update all MBoum actions in a single refactor.
• Otherwise, keep return response; here to match the majority of actions and avoid surprises in downstream steps.

components/mboum/actions/get-crypto-holders/get-crypto-holders.mjs (1)

11-15: Nit: Consider renaming prop “key” to reduce ambiguity.

Using “key” (also used by the action’s top-level key) can be confusing in reviews and telemetry. Consider cryptoId or asset for clarity.

components/mboum/actions/get-crypto-quotes/get-crypto-quotes.mjs (1)

27-27: Return response.data for consistency with sibling actions.

Other crypto actions in this PR return response.data (e.g., holders, profile). Align this action to the same shape.

Apply:

-    return response;
+    return response.data;
components/mboum/actions/get-crypto-modules/get-crypto-modules.mjs (1)

27-30: Improve summary and return response.data for consistency.

Make the summary more informative and align return shape with other actions.

-    $.export("$summary", "Successfully fetched crypto modules");
-
-    return response;
+    $.export("$summary", `Successfully fetched crypto modules for ${this.module}`);
+
+    return response.data;
components/mboum/common/constants.mjs (2)

108-116: Naming mismatch: "INTERNATIONAL_HOLDINGS_TYPES" looks like it should be "INSTITUTIONAL_HOLDINGS_TYPES".

The values refer to institutional holdings categories. To avoid churn, you can introduce an alias now and flip references later.

Apply this diff to export an alias while keeping the current name:

 export default {
   INTERVALS,
   MA_TYPES,
   SERIES_TYPES,
   HISTORICAL_DATA_INTERVALS,
-  INTERNATIONAL_HOLDINGS_TYPES,
+  INTERNATIONAL_HOLDINGS_TYPES,
+  // Alias for clarity; prefer using INSTITUTIONAL_HOLDINGS_TYPES going forward
+  INSTITUTIONAL_HOLDINGS_TYPES: INTERNATIONAL_HOLDINGS_TYPES,
   STOCK_MODULES,
   SCREENER_FILTERS,
   CRYPTO_MODULES,
 };

Please also confirm references in actions (e.g., “Get Institutional Holdings”) align with the preferred alias before merge.

Also applies to: 189-198


11-48: Intervals set might be incomplete (missing "1d") and needs doc alignment.

The historical intervals jump from minutes to weekly/monthly/quarterly, skipping a daily interval. Also, ensure every value matches Mboum’s accepted tokens.

Proposed addition for daily candles (verify with docs before merging):

   {
     value: "30m",
     label: "30 mins candles",
   },
+  {
+    value: "1d",
+    label: "daily candles",
+  },
   {
     value: "1wk",
     label: "weekly candles",
   },

If Mboum expects different tokens (e.g., "day", "D"), adjust accordingly. I can script a quick scan across actions to ensure consistency once confirmed.

components/mboum/actions/get-crypto-currencies/get-crypto-currencies.mjs (2)

11-17: Prefer reusing the shared "page" propDefinition for consistency.

Other actions use the mboum app’s propDefinition for page. This keeps UI/options consistent and centralizes validation.

Apply this diff:

   props: {
     mboum,
-    page: {
-      type: "integer",
-      label: "Page",
-      description: "The page number to fetch",
-      optional: true,
-    },
+    page: {
+      propDefinition: [
+        mboum,
+        "page",
+      ],
+    },
   },

28-29: Standardize return shape across Mboum actions.

This action returns response.data while others often return response. Standardize one approach repo-wide to avoid surprises for users composing steps.

Want me to scan all Mboum actions in this PR and produce a report of return shapes to pick a convention?

components/mboum/actions/get-analyst-ratings/get-analyst-ratings.mjs (1)

33-34: Optional: Enrich $summary with pagination context.

If page is supplied, appending it to the summary helps in multi-page workflows.

-    $.export("$summary", `Successfully retrieved analyst ratings for ${this.ticker}`);
+    const pageSuffix = this.page ? ` (page ${this.page})` : "";
+    $.export("$summary", `Successfully retrieved analyst ratings for ${this.ticker}${pageSuffix}`);
components/mboum/actions/get-realtime-quote/get-realtime-quote.mjs (3)

3-28: Default a sensible Type to reduce friction.

The type prop frequently defaults to stocks on similar APIs. Setting a default avoids a required selection for common cases.

     type: {
       type: "string",
       label: "Type",
       description: "Type of quote to retrieve",
+      default: "STOCKS",
       options: [
         "STOCKS",
         "ETF",
         "MUTUALFUNDS",
         "FUTURES",
       ],
     },

17-27: Consider centralizing Type options to avoid drift.

Multiple actions duplicate instrument type options. Define once (e.g., in components/mboum/common/constants.mjs or as a propDefinition in mboum.app.mjs) and reuse to keep UI consistent across actions.


6-6: Update Mboum docs link to the canonical URL

Please replace the malformed anchor in components/mboum/actions/get-realtime-quote/get-realtime-quote.mjs (line 6) with the official Mboum docs URL:

  • Before:
    - description: "Get real-time stock quote data including current price, volume, and market data. [See the documentation](https://docs.mboum.com/#stocks-options-small-stylecolor-f8f2f2background-fa256fpadding-1px-4pxborder-radius-3pxhotsmall-GETapi-v1-markets-quote)",
  • After:
    + description: "Get real-time stock quote data including current price, volume, and market data. [See the documentation](https://docs.mboum.com)",

This points to the official Mboum documentation landing page for the GET /v1/markets/quote endpoint without embedding presentational styles.

components/mboum/actions/get-ticker-summary/get-ticker-summary.mjs (2)

3-28: Add a default for Type and centralize options.

  • Similar to the realtime quote action, a default of "STOCKS" improves UX.
  • Consider reusing a shared constant/propDefinition for the instrument types to avoid inconsistencies.
     type: {
       type: "string",
       label: "Type",
       description: "Type of ticker summary to retrieve",
+      default: "STOCKS",
       options: [
         "STOCKS",
         "ETF",
         "MUTUALFUNDS",
         "FUTURES",
       ],
     },

6-6: Update malformed Ticker Summary docs link

The current anchor in components/mboum/actions/get-ticker-summary/get-ticker-summary.mjs (line 6) embeds stray style parameters and points to an invalid fragment. Please replace it with the canonical v2 endpoint URL:

 description: "Get comprehensive ticker summary including key statistics, financial metrics, and company overview. 
- [See the documentation](https://docs.mboum.com/#stocks-options-small-stylecolor-f8f2f2background-fa256fpadding-1px-4pxborder-radius-3pxhotsmall-GETapi-v2-markets-stock-ticker-summary)",
+ [See the documentation](https://docs.mboum.com/#get-v2-ticker-summary)",

This ensures the link correctly points to https://docs.mboum.com/#get-v2-ticker-summary.

components/mboum/actions/get-ad/get-ad.mjs (1)

30-41: Optional: Include interval in the $summary only when provided.

If interval is optional downstream, guard it in the summary to avoid “undefined” in UI. If required, this is fine as-is.

-    $.export("$summary", `Successfully calculated A/D Line for ${this.ticker} on ${this.interval} intervals`);
+    const intervalSuffix = this.interval ? ` on ${this.interval} intervals` : "";
+    $.export("$summary", `Successfully calculated A/D Line for ${this.ticker}${intervalSuffix}`);
components/mboum/actions/get-iv-rank-percentile/get-iv-rank-percentile.mjs (3)

21-26: Constrain input: enforce non-negative price minimum.

Add a min constraint so the UI prevents invalid negative values.

     priceMin: {
       type: "number",
       label: "Price Min",
       description: "Filter results by min price of the stock per share value",
       optional: true,
+      min: 0,
     },

11-20: Default a sensible Type value.

Set a default of "STOCKS" to streamline usage when filtering by equities.

     type: {
       type: "string",
       label: "Type",
       description: "Type of IV rank percentile to retrieve",
+      default: "STOCKS",
       options: [
         "STOCKS",
         "ETFS",
         "INDICES",
       ],
     },

35-41: Normalize param casing across MBoum actions

We’ve got mixed usage of priceMin (camelCase) and price_min (snake_case) in the query params across several actions. To prevent accidental divergence:

• Align all actions to use snake_case for the MBoum API spec:
– components/mboum/actions/get-unusual-options-activity/get-unusual-options-activity.mjs
– components/mboum/actions/get-movers/get-movers.mjs

Change in each:

-   priceMin: this.priceMin,
+   price_min: this.priceMin,

• Optionally, add a small utility in the MBoum wrapper to convert camelCase keys to snake_case automatically:

// mboum.app.mjs
const toSnake = (s) => s.replace(/[A-Z]/g, m => `_${m.toLowerCase()}`);
const keysToSnake = (obj = {}) =>
  Object.fromEntries(Object.entries(obj).map(([k, v]) => [toSnake(k), v]));


// inside each wrapper method before calling the API:
const params = keysToSnake(userParams);
components/mboum/actions/get-news/get-news.mjs (1)

11-16: Make ticker and type optional to match the description (“optional filtering”).

Your description says filtering by ticker/category is optional, but both props are currently required. Mark them optional (and consider defaulting type to ALL) to align behavior with the UX copy.

Apply this diff:

 ticker: {
   propDefinition: [
     mboum,
     "ticker",
   ],
+  optional: true,
 },
 type: {
   type: "string",
   label: "Type",
   description: "Type of news to retrieve",
   options: [
     "ALL",
     "MARKET",
     "VIDEO",
     "PRESS-RELEASE",
   ],
+  default: "ALL",
+  optional: true,
 },

Also applies to: 17-27

components/mboum/actions/get-modules/get-modules.mjs (1)

18-23: Make “module” optional (summary logic already treats it as optional).

You only append module info to the summary if provided, but the prop is required. Make it optional to match behavior.

 module: {
   type: "string",
   label: "Module",
   description: "Specific module to retrieve data for",
   options: constants.STOCK_MODULES,
+  optional: true,
 },
components/mboum/actions/get-insider-trading/get-insider-trading.mjs (1)

28-33: Use an integer for minValue (and constrain to non-negative).

Using a string increases the risk of invalid inputs. Prefer integer type with a lower bound.

 minValue: {
-  type: "string",
+  type: "integer",
   label: "Minimum Value",
   description: "Filter results by min transaction value",
   optional: true,
+  min: 0,
 },
components/mboum/actions/get-institutional-holdings/get-institutional-holdings.mjs (1)

24-29: Constrain limit to a sensible lower bound.

Prevent accidental zeros/negatives.

 limit: {
   type: "integer",
   label: "Limit",
   description: "Maximum number of data points to return",
   optional: true,
+  min: 1,
 },
components/mboum/actions/get-tickers/get-tickers.mjs (1)

1-2: Centralize enum options in constants for reuse and maintainability.

These type options will likely be reused; move them to constants to avoid drift and simplify updates.

 import mboum from "../../mboum.app.mjs";
+import constants from "../../common/constants.mjs";

 ...

 type: {
   type: "string",
   label: "Type",
   description: "Type of tickers to retrieve",
-  options: [
-    "STOCKS",
-    "ETF",
-    "MUTUALFUNDS",
-    "FUTURES",
-    "INDEX",
-  ],
+  options: constants.TICKER_TYPES,
 },

Add to constants.mjs (outside this file) if not present:

export default {
  // ...
  TICKER_TYPES: ["STOCKS", "ETF", "MUTUALFUNDS", "FUTURES", "INDEX"],
};

Also applies to: 11-22

components/mboum/actions/get-short-interest/get-short-interest.mjs (1)

6-6: Docs link contains styling fragment; consider replacing with a stable URL

The link appears to include CSS-class fragments from the docs site. Suggest pointing to a stable anchor or the base docs to avoid future breakage.

-  description: "Get short interest data including short ratio, short percentage of float, and short interest trends. [See the documentation](https://docs.mboum.com/#stocks-options-small-stylecolor-f8f2f2background-fa256fpadding-1px-4pxborder-radius-3pxhotsmall-GETapi-v2-markets-stock-short-interest)",
+  description: "Get short interest data including short ratio, short percentage of float, and short interest trends. [See the documentation](https://docs.mboum.com/)",
components/mboum/actions/get-ipo-data/get-ipo-data.mjs (3)

6-6: Docs link contains styling fragment; consider replacing with a stable URL

-  description: "Get upcoming and recent Initial Public Offering (IPO) data including dates, prices, and company information. [See the documentation](https://docs.mboum.com/#stocks-options-small-stylecolor-f8f2f2background-fa256fpadding-1px-4pxborder-radius-3pxhotsmall-GETapi-v1-markets-calendar-ipo)",
+  description: "Get upcoming and recent Initial Public Offering (IPO) data including dates, prices, and company information. [See the documentation](https://docs.mboum.com/)",

26-27: Include the date in the summary for clarity

Showing the queried date makes the step output more actionable.

-    $.export("$summary", "Successfully retrieved IPO data");
+    $.export("$summary", `Successfully retrieved IPO data for ${this.date}`);

9-17: Optional: Consider adding pagination if the API supports it

If the underlying endpoint supports paging, exposing “page” (and possibly “limit”) would align with other calendar actions.

components/mboum/actions/get-iv-change/get-iv-change.mjs (3)

24-24: Fix grammar in description (“Direction to sort by”)

-      description: "Direction of to sort by",
+      description: "Direction to sort by",

45-53: Avoid sending undefined query params

Building the params object conditionally prevents sending direction=undefined or price_min=undefined if unset. This reduces noisy querystrings and accidental server-side parsing issues.

-    const response = await this.mboum.getIvChange({
-      $,
-      params: {
-        type: this.type,
-        direction: this.direction,
-        price_min: this.priceMin,
-        page: this.page,
-      },
-    });
+    const params = {
+      type: this.type,
+      ...(this.direction && { direction: this.direction }),
+      ...(this.priceMin !== undefined && { price_min: this.priceMin }),
+      ...(this.page && { page: this.page }),
+    };
+    const response = await this.mboum.getIvChange({ $, params });

6-6: Docs link contains styling fragment; consider replacing with a stable URL

-  description: "Get Implied Volatility (IV) change data showing volatility movements and trends over time. [See the documentation](https://docs.mboum.com/#stocks-options-small-stylecolor-f8f2f2background-fa256fpadding-1px-4pxborder-radius-3pxhotsmall-GETapi-v1-markets-options-iv-change)",
+  description: "Get Implied Volatility (IV) change data showing volatility movements and trends over time. [See the documentation](https://docs.mboum.com/)",
components/mboum/actions/get-sec-filings/get-sec-filings.mjs (4)

6-6: Docs link contains styling fragment; consider replacing with a stable URL

-  description: "Get SEC filings data including 10-K, 10-Q, 8-K, and other regulatory filings. [See the documentation](https://docs.mboum.com/#stocks-options-small-stylecolor-f8f2f2background-fa256fpadding-1px-4pxborder-radius-3pxhotsmall-GETapi-v2-markets-stock-sec-filings)",
+  description: "Get SEC filings data including 10-K, 10-Q, 8-K, and other regulatory filings. [See the documentation](https://docs.mboum.com/)",

18-25: Align filing type options with API or adjust description

The description mentions 10-K/10-Q/8-K, but options only include FORM-4 and ALL. Either expand the options to include supported forms or narrow the description.

If you choose to narrow the description:

-      description: "Type of SEC filing to retrieve",
+      description: "Type of SEC filing to retrieve (supports FORM-4 or ALL)",

26-31: Reuse shared “limit” propDefinition for consistency

Other actions use a common mboum “limit” propDefinition. Reuse it here to keep labels/help text consistent across actions.

-    limit: {
-      type: "integer",
-      label: "Limit",
-      description: "Maximum number of data points to return",
-      optional: true,
-    },
+    limit: {
+      propDefinition: [
+        mboum,
+        "limit",
+      ],
+      optional: true,
+    },

34-41: Avoid sending undefined limit

Optional: build params conditionally so limit isn’t sent if unset.

-    const response = await this.mboum.getSecFilings({
-      $,
-      params: {
-        ticker: this.ticker,
-        type: this.type,
-        limit: this.limit,
-      },
-    });
+    const params = {
+      ticker: this.ticker,
+      type: this.type,
+      ...(this.limit !== undefined && { limit: this.limit }),
+    };
+    const response = await this.mboum.getSecFilings({ $, params });
components/mboum/actions/get-sma/get-sma.mjs (4)

6-6: Docs link contains styling fragment; consider replacing with a stable URL

-  description: "Calculate Simple Moving Average technical indicator for stocks and crypto. [See the documentation](https://docs.mboum.com/#stocks-options-small-stylecolor-f8f2f2background-fa256fpadding-1px-4pxborder-radius-3pxhotsmall-GETapi-v1-markets-indicators-sma)",
+  description: "Calculate Simple Moving Average technical indicator for stocks and crypto. [See the documentation](https://docs.mboum.com/)",

43-51: Build params conditionally to avoid sending undefined time_period

Prevents passing time_period when it’s not set.

-    const response = await this.mboum.getSMA({
-      $,
-      params: {
-        ticker: this.ticker,
-        interval: this.interval,
-        series_type: this.seriesType,
-        time_period: this.timePeriod,
-        limit: this.limit,
-      },
-    });
+    const params = {
+      ticker: this.ticker,
+      interval: this.interval,
+      series_type: this.seriesType,
+      ...(this.timePeriod !== undefined && { time_period: this.timePeriod }),
+      limit: this.limit,
+    };
+    const response = await this.mboum.getSMA({ $, params });

54-55: Avoid “SMA(undefined)” in summary when timePeriod isn’t set

Conditionally include the period to keep summaries clean.

-    $.export("$summary", `Successfully calculated SMA(${this.timePeriod}) for ${this.ticker} on ${this.interval} intervals`);
+    const periodText = this.timePeriod !== undefined ? `SMA(${this.timePeriod})` : "SMA";
+    $.export("$summary", `Successfully calculated ${periodText} for ${this.ticker} on ${this.interval} intervals`);

29-34: Confirm whether timePeriod is required by the API

If the endpoint requires time_period, consider making it mandatory and providing a sensible default (e.g., 14 or 20).

components/mboum/actions/get-stoch/get-stoch.mjs (2)

7-7: Broken/odd docs link (likely typo: "stochh").

The link slug ends with "stochh" and includes UI-specific styling fragments. Likely broken. Prefer a clean anchor.

Apply this diff to use a cleaner, predictable anchor:

-  description: "Calculate Stochastic Oscillator technical indicator to identify momentum and potential reversal points. [See the documentation](https://docs.mboum.com/#stocks-options-small-stylecolor-f8f2f2background-fa256fpadding-1px-4pxborder-radius-3pxhotsmall-GETapi-v1-markets-indicators-stochh)",
+  description: "Calculate Stochastic Oscillator technical indicator to identify momentum and potential reversal points. [See the documentation](https://docs.mboum.com/#get-api-v1-markets-indicators-stoch)",

78-79: Avoid "undefined" in summary when optional periods aren’t set.

The current summary will print "undefined" if any period is omitted.

Apply:

-    $.export("$summary", `Successfully calculated STOCH(${this.fastKPeriod},${this.slowKPeriod},${this.slowDPeriod}) for ${this.ticker} on ${this.interval} intervals`);
+    const periods = [this.fastKPeriod, this.slowKPeriod, this.slowDPeriod]
+      .filter((v) => v !== undefined)
+      .join(",") || "defaults";
+    $.export("$summary", `Successfully calculated STOCH(${periods}) for ${this.ticker} on ${this.interval} intervals`);
components/mboum/actions/get-revenue/get-revenue.mjs (2)

6-6: Docs link cleanup (optional).

The anchor has embedded styling fragments. Consider a simpler anchor path to reduce future rot.

-  description: "Get detailed revenue breakdown and analysis for a company including revenue trends and segments. [See the documentation](https://docs.mboum.com/#stocks-options-small-stylecolor-f8f2f2background-fa256fpadding-1px-4pxborder-radius-3pxhotsmall-GETapi-v2-markets-stock-revenue)",
+  description: "Get detailed revenue breakdown and analysis for a company including revenue trends and segments. [See the documentation](https://docs.mboum.com/#get-api-v2-markets-stock-revenue)",

25-31: Prune undefined params before sending.

Page may be optional; prune undefineds to avoid sending page= or page=undefined.

-    const response = await this.mboum.getRevenue({
-      $,
-      params: {
-        ticker: this.ticker,
-        page: this.page,
-      },
-    });
+    const response = await this.mboum.getRevenue({
+      $,
+      params: ((params) => {
+        Object.keys(params).forEach((k) => params[k] === undefined && delete params[k]);
+        return params;
+      })({
+        ticker: this.ticker,
+        page: this.page,
+      }),
+    });
components/mboum/actions/get-adx/get-adx.mjs (3)

6-6: Docs link cleanup (optional).

Anchor includes style fragments; use a cleaner anchor to reduce link fragility.

-  description: "Calculate Average Directional Index technical indicator to measure trend strength and direction. [See the documentation](https://docs.mboum.com/#stocks-options-small-stylecolor-f8f2f2background-fa256fpadding-1px-4pxborder-radius-3pxhotsmall-GETapi-v1-markets-indicators-adx)",
+  description: "Calculate Average Directional Index technical indicator to measure trend strength and direction. [See the documentation](https://docs.mboum.com/#get-api-v1-markets-indicators-adx)",

43-52: Prune undefined params before sending.

timePeriod and limit can be optional. Avoid propagating undefined values.

-    const response = await this.mboum.getADX({
-      $,
-      params: {
-        ticker: this.ticker,
-        interval: this.interval,
-        series_type: this.seriesType,
-        time_period: this.timePeriod,
-        limit: this.limit,
-      },
-    });
+    const response = await this.mboum.getADX({
+      $,
+      params: ((params) => {
+        Object.keys(params).forEach((k) => params[k] === undefined && delete params[k]);
+        return params;
+      })({
+        ticker: this.ticker,
+        interval: this.interval,
+        series_type: this.seriesType,
+        time_period: this.timePeriod,
+        limit: this.limit,
+      }),
+    });

54-55: Avoid "undefined" in summary when timePeriod isn’t set.

If timePeriod is not provided, the current summary includes "ADX(undefined)".

-    $.export("$summary", `Successfully calculated ADX(${this.timePeriod}) for ${this.ticker} on ${this.interval} intervals`);
+    const suffix = this.timePeriod != null ? `(${this.timePeriod})` : "";
+    $.export("$summary", `Successfully calculated ADX${suffix} for ${this.ticker} on ${this.interval} intervals`);
components/mboum/actions/get-options/get-options.mjs (2)

24-31: Validate date format and prune undefined params.

Add a light validation for the optional expiration date and avoid sending undefined params.

-  async run({ $ }) {
-    const response = await this.mboum.getOptions({
-      $,
-      params: {
-        ticker: this.ticker,
-        expiration: this.expiration,
-      },
-    });
+  async run({ $ }) {
+    if (this.expiration && !/^\d{4}-\d{2}-\d{2}$/.test(this.expiration)) {
+      throw new Error("Invalid expiration date format. Expected YYYY-MM-DD.");
+    }
+    const response = await this.mboum.getOptions({
+      $,
+      params: ((params) => {
+        Object.keys(params).forEach((k) => params[k] === undefined && delete params[k]);
+        return params;
+      })({
+        ticker: this.ticker,
+        expiration: this.expiration,
+      }),
+    });

33-34: Enrich summary with expiration when provided.

Small UX improvement.

-    $.export("$summary", `Successfully retrieved options data for ${this.ticker}`);
+    $.export("$summary", `Successfully retrieved options data for ${this.ticker}${this.expiration ? ` expiring ${this.expiration}` : ""}`);
components/mboum/actions/get-adosc/get-adosc.mjs (2)

49-59: Prune undefined params before sending.

fastPeriod/slowPeriod/limit may be optional; avoid transmitting undefined values.

-    const response = await this.mboum.getADOSC({
-      $,
-      params: {
-        ticker: this.ticker,
-        interval: this.interval,
-        series_type: this.seriesType,
-        fast_period: this.fastPeriod,
-        slow_period: this.slowPeriod,
-        limit: this.limit,
-      },
-    });
+    const response = await this.mboum.getADOSC({
+      $,
+      params: ((params) => {
+        Object.keys(params).forEach((k) => params[k] === undefined && delete params[k]);
+        return params;
+      })({
+        ticker: this.ticker,
+        interval: this.interval,
+        series_type: this.seriesType,
+        fast_period: this.fastPeriod,
+        slow_period: this.slowPeriod,
+        limit: this.limit,
+      }),
+    });

61-62: Avoid "undefined" in summary when periods aren’t set.

Shows "ADOSC(undefined,undefined)" otherwise.

-    $.export("$summary", `Successfully calculated ADOSC(${this.fastPeriod},${this.slowPeriod}) for ${this.ticker} on ${this.interval} intervals`);
+    const parts = [this.fastPeriod, this.slowPeriod].filter((v) => v !== undefined).join(",") || "defaults";
+    $.export("$summary", `Successfully calculated ADOSC(${parts}) for ${this.ticker} on ${this.interval} intervals`);
components/mboum/actions/get-earnings/get-earnings.mjs (2)

41-51: Avoid sending undefined query params

Build the params object dynamically to omit optional fields when not provided. This reduces risk of the API receiving literal undefined values and keeps requests cleaner.

-    const response = await this.mboum.getEarnings({
-      $,
-      params: {
-        start_date: this.startDate,
-        end_date: this.endDate,
-        price_min: this.priceMin,
-        optionable: this.optionable,
-        page: this.page,
-      },
-    });
+    const params = {
+      start_date: this.startDate,
+      end_date: this.endDate,
+      page: this.page,
+    };
+    if (this.priceMin !== undefined) params.price_min = this.priceMin;
+    if (this.optionable !== undefined) params.optionable = this.optionable;
+    const response = await this.mboum.getEarnings({
+      $,
+      params,
+    });

40-40: Optional: Validate date range before calling the API

Prevent avoidable API calls by ensuring startDate <= endDate.

+    if (this.startDate && this.endDate && this.startDate > this.endDate) {
+      throw new Error("Start Date must be before or equal to End Date");
+    }
components/mboum/actions/get-history/get-history.mjs (1)

40-48: Build params dynamically to omit undefined limit/dividend

Keeps the query clean and avoids sending undefined values.

-    const response = await this.mboum.getHistory({
-      $,
-      params: {
-        ticker: this.ticker,
-        interval: this.interval,
-        limit: this.limit,
-        dividend: this.dividend,
-      },
-    });
+    const params = {
+      ticker: this.ticker,
+      interval: this.interval,
+    };
+    if (this.limit !== undefined) params.limit = this.limit;
+    if (this.dividend !== undefined) params.dividend = this.dividend;
+    const response = await this.mboum.getHistory({
+      $,
+      params,
+    });
components/mboum/actions/get-historical-data/get-historical-data.mjs (2)

45-55: Build params dynamically and validate date range

  • Validate from/to date order to prevent unnecessary API requests.
  • Avoid passing undefined limit.
-    const response = await this.mboum.getHistoricalData({
-      $,
-      params: {
-        ticker: this.ticker,
-        type: this.type,
-        from_date: this.fromDate,
-        to_date: this.toDate,
-        limit: this.limit,
-      },
-    });
+    if (this.fromDate && this.toDate && this.fromDate > this.toDate) {
+      throw new Error("From Date must be before or equal to To Date");
+    }
+    const params = {
+      ticker: this.ticker,
+      type: this.type,
+      from_date: this.fromDate,
+      to_date: this.toDate,
+    };
+    if (this.limit !== undefined) params.limit = this.limit;
+    const response = await this.mboum.getHistoricalData({
+      $,
+      params,
+    });

17-27: Consider centralizing instrument type options

These values appear in multiple actions across the PR. Moving them to a shared constant in components/mboum/common/constants.mjs reduces drift and improves reuse.

components/mboum/actions/get-screener/get-screener.mjs (1)

12-22: Optional: Move metricType options to constants for reuse

A shared enum in components/mboum/common/constants.mjs would keep these aligned across actions and future changes.

components/mboum/actions/get-rsi/get-rsi.mjs (4)

6-6: Docs link likely broken (copied CSS fragment in anchor). Replace with a stable URL.
The anchor has inline style artifacts and is unlikely to resolve. Suggest linking to the product docs root or the indicators section until a stable deep link is confirmed.

Apply this minimal, safe fix:

-  description: "Calculate Relative Strength Index technical indicator to measure momentum and identify overbought/oversold conditions. [See the documentation](https://docs.mboum.com/#stocks-options-small-stylecolor-f8f2f2background-fa256fpadding-1px-4pxborder-radius-3pxhotsmall-GETapi-v1-markets-indicators-rsi)",
+  description: "Calculate Relative Strength Index (RSI) to measure momentum and identify overbought/oversold conditions. See the documentation: https://docs.mboum.com/",

If you want me to update this with a verified deep link once access is available, I can follow up.


29-34: Set a sensible default for RSI time period (commonly 14).
Improves UX and avoids undefined in summaries/requests if the user doesn’t choose a value.

     timePeriod: {
       type: "integer",
       label: "Time Period",
       description: "Number of periods for RSI calculation",
-      optional: true,
+      optional: true,
+      default: 14,
     },

42-52: Avoid sending undefined query params.
Filter out undefined values to keep the request clean and reduce risk of API-side validation errors.

-  async run({ $ }) {
-    const response = await this.mboum.getRSI({
-      $,
-      params: {
-        ticker: this.ticker,
-        interval: this.interval,
-        series_type: this.seriesType,
-        time_period: this.timePeriod,
-        limit: this.limit,
-      },
-    });
+  async run({ $ }) {
+    const params = {
+      ticker: this.ticker,
+      interval: this.interval,
+      series_type: this.seriesType,
+      time_period: this.timePeriod,
+      limit: this.limit,
+    };
+    Object.keys(params).forEach((k) => params[k] === undefined && delete params[k]);
+
+    const response = await this.mboum.getRSI({
+      $,
+      params,
+    });

54-55: Make the summary robust when timePeriod isn’t provided.
Shows a clean message instead of “RSI(undefined)”.

-    $.export("$summary", `Successfully calculated RSI(${this.timePeriod}) for ${this.ticker} on ${this.interval} intervals`);
+    $.export("$summary", `Successfully calculated RSI${this.timePeriod ? `(${this.timePeriod})` : ""} for ${this.ticker} on ${this.interval} interval`);
components/mboum/actions/get-macd/get-macd.mjs (4)

6-6: Docs link likely broken (copied CSS fragment in anchor). Replace with a stable URL.
Same artifact as RSI. Use a stable link for now and update later if needed.

-  description: "Calculate Moving Average Convergence Divergence (MACD) technical indicator to identify trend changes and momentum. [See the documentation](https://docs.mboum.com/#stocks-options-small-stylecolor-f8f2f2background-fa256fpadding-1px-4pxborder-radius-3pxhotsmall-GETapi-v1-markets-indicators-macd)",
+  description: "Calculate Moving Average Convergence Divergence (MACD) to identify trend changes and momentum. See the documentation: https://docs.mboum.com/",

29-46: Provide standard MACD defaults (12, 26, 9).
Improves UX and avoids undefined values when users don’t configure periods.

     fastPeriod: {
       type: "integer",
       label: "Fast Period",
       description: "Fast period for MACD calculation",
-      optional: true,
+      optional: true,
+      default: 12,
     },
     slowPeriod: {
       type: "integer",
       label: "Slow Period",
       description: "Slow period for MACD calculation",
-      optional: true,
+      optional: true,
+      default: 26,
     },
     signalPeriod: {
       type: "integer",
       label: "Signal Period",
       description: "Signal line period for MACD calculation",
-      optional: true,
+      optional: true,
+      default: 9,
     },

54-66: Avoid sending undefined query params.
Same rationale as RSI.

-  async run({ $ }) {
-    const response = await this.mboum.getMACD({
-      $,
-      params: {
-        ticker: this.ticker,
-        interval: this.interval,
-        series_type: this.seriesType,
-        fast_period: this.fastPeriod,
-        slow_period: this.slowPeriod,
-        signal_period: this.signalPeriod,
-        limit: this.limit,
-      },
-    });
+  async run({ $ }) {
+    const params = {
+      ticker: this.ticker,
+      interval: this.interval,
+      series_type: this.seriesType,
+      fast_period: this.fastPeriod,
+      slow_period: this.slowPeriod,
+      signal_period: this.signalPeriod,
+      limit: this.limit,
+    };
+    Object.keys(params).forEach((k) => params[k] === undefined && delete params[k]);
+
+    const response = await this.mboum.getMACD({
+      $,
+      params,
+    });

68-69: Make the summary robust when any period is omitted.
Avoids “(undefined,undefined,undefined)” in the summary.

-    $.export("$summary", `Successfully calculated MACD(${this.fastPeriod},${this.slowPeriod},${this.signalPeriod}) for ${this.ticker} on ${this.interval} intervals`);
+    const parts = [this.fastPeriod, this.slowPeriod, this.signalPeriod].filter((v) => v !== undefined).join(",");
+    $.export("$summary", `Successfully calculated MACD${parts ? `(${parts})` : ""} for ${this.ticker} on ${this.interval} interval`);
components/mboum/mboum.app.mjs (2)

49-59: Harden URL joining and add a default timeout.
Prevents accidental double slashes in the URL and avoids indefinite waits on network hiccups.

-    _makeRequest({
-      $ = this, path, ...opts
-    }) {
-      return axios($, {
-        url: `${this._baseUrl()}${path}`,
-        headers: {
-          Authorization: `Bearer ${this.$auth.api_key}`,
-        },
-        ...opts,
-      });
-    },
+    _makeRequest({
+      $ = this, path, ...opts
+    }) {
+      const base = String(this._baseUrl()).replace(/\/+$/, "");
+      const p = String(path || "").replace(/^\/+/, "");
+      return axios($, {
+        url: `${base}/${p}`,
+        headers: {
+          Authorization: `Bearer ${this.$auth.api_key}`,
+        },
+        timeout: 15000,
+        ...opts,
+      });
+    },

32-37: Set limit default to align with the description (50).
The description says default: 50, but no default is set.

     limit: {
       type: "integer",
       label: "Limit",
       description: "Maximum number of results to return (default: 50)",
       optional: true,
+      default: 50,
     },

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
components/mboum/actions/get-unusual-options-activity/get-unusual-options-activity.mjs (1)

32-37: Use a numeric type for Price Min

Align with other actions and avoid sending a string to the API.

     priceMin: {
-      type: "string",
+      type: "number",
       label: "Price Min",
       description: "Filter results by min price of the stock per share value",
       optional: true,
     },
components/mboum/actions/get-options/get-options.mjs (1)

20-20: Typo fix acknowledged: “expiration”.

Thanks for correcting the user-facing copy from the earlier review.

🧹 Nitpick comments (5)
components/mboum/actions/get-unusual-options-activity/get-unusual-options-activity.mjs (2)

6-6: Tidy up the docs link to a stable anchor

The current URL includes style-specific fragments that may break. Prefer a stable anchor.

-  description: "Get unusual options activity including high volume and large trades that deviate from normal patterns. [See the documentation](https://docs.mboum.com/#stocks-options-small-stylecolor-f8f2f2background-fa256fpadding-1px-4pxborder-radius-3pxhotsmall-GETapi-v1-markets-options-unusual-options-activity)",
+  description: "Get unusual options activity including high volume and large trades that deviate from normal patterns. [See the documentation](https://docs.mboum.com/#stocks-options-GETapi-v1-markets-options-unusual-options-activity)",

If that anchor is not valid, consider linking to the root docs or the section page and updating later once confirmed.


27-31: Is Date required? If optional, don’t send it when absent

If the API allows omitting date, mark the prop optional and avoid sending undefined.

Only apply the following if the endpoint accepts requests without a date:

   date: {
     type: "string",
     label: "Date",
     description: "Enter a historical date: YYYY-MM-DD",
+    optional: true,
   },

And send it conditionally:

       params: {
         type: this.type,
         ticker: this.ticker,
-        date: this.date,
+        ...(this.date ? { date: this.date } : {}),
         price_min: this.priceMin,
         page: this.page,
       },

Also applies to: 49-55

components/mboum/actions/get-options/get-options.mjs (3)

6-6: Docs link anchor looks broken/unportable — switch to a stable URL.

The copied anchor includes inline style tokens that likely won’t resolve. Link to the stable section instead.

Apply this diff:

-  description: "Get comprehensive options data including prices, Greeks, and market metrics. [See the documentation](https://docs.mboum.com/#stocks-options-small-stylecolor-f8f2f2background-fa256fpadding-1px-4pxborder-radius-3pxhotsmall-GETapi-v3-markets-options)",
+  description: "Get comprehensive options data including prices, Greeks, and market metrics. [See the documentation](https://docs.mboum.com/#stocks-options)",

24-31: Guard against invalid expiration format before calling the API.

Pre-validate the optional expiration to fail fast with a clear error, instead of sending a bad query upstream.

Apply this diff:

   async run({ $ }) {
+    if (this.expiration && !/^\d{4}-\d{2}-\d{2}$/.test(this.expiration)) {
+      throw new Error('Invalid "Expiration Date". Expected format: YYYY-MM-DD');
+    }
-    const response = await this.mboum.getOptions({
-      $,
-      params: {
-        ticker: this.ticker,
-        expiration: this.expiration,
-      },
-    });
+    const response = await this.mboum.getOptions({
+      $,
+      params: {
+        ticker: this.ticker,
+        expiration: this.expiration,
+      },
+    });

33-34: Include expiration in the success summary when provided (minor UX).

Helps users quickly see which chain was fetched.

Apply this diff:

-    $.export("$summary", `Successfully retrieved options data for ${this.ticker}`);
+    const summary = `Successfully retrieved options data for ${this.ticker}` + (this.expiration ? ` (exp ${this.expiration})` : "");
+    $.export("$summary", summary);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 004e431 and 866572a.

📒 Files selected for processing (5)
  • components/mboum/actions/get-earnings/get-earnings.mjs (1 hunks)
  • components/mboum/actions/get-movers/get-movers.mjs (1 hunks)
  • components/mboum/actions/get-options/get-options.mjs (1 hunks)
  • components/mboum/actions/get-unusual-options-activity/get-unusual-options-activity.mjs (1 hunks)
  • components/mboum/actions/search/search.mjs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • components/mboum/actions/get-movers/get-movers.mjs
  • components/mboum/actions/get-earnings/get-earnings.mjs
  • components/mboum/actions/search/search.mjs
🧰 Additional context used
🧬 Code Graph Analysis (2)
components/mboum/actions/get-options/get-options.mjs (2)
components/mboum/actions/get-earnings/get-earnings.mjs (1)
  • response (41-50)
components/mboum/actions/search/search.mjs (1)
  • response (18-23)
components/mboum/actions/get-unusual-options-activity/get-unusual-options-activity.mjs (4)
components/mboum/actions/get-earnings/get-earnings.mjs (1)
  • response (41-50)
components/mboum/actions/get-movers/get-movers.mjs (1)
  • response (44-52)
components/mboum/actions/get-options/get-options.mjs (1)
  • response (25-31)
components/mboum/actions/get-iv-rank-percentile/get-iv-rank-percentile.mjs (1)
  • response (35-42)
🔇 Additional comments (4)
components/mboum/actions/get-unusual-options-activity/get-unusual-options-activity.mjs (2)

49-54: Good: snake_case param mapping (price_min) is correct and consistent

Thanks for mapping the camelCase prop to the API’s snake_case field. This will work with the current client which doesn’t normalize keys.


12-20: Allowed ‘type’ values are correct
According to the Mboum docs (https://docs.mboum.com), the “type” parameter accepts uppercase, plural values: “STOCKS”, “ETFS”, and “INDICES”, which matches the current implementation.

components/mboum/actions/get-options/get-options.mjs (2)

4-9: Action metadata looks consistent and clear (key/name/version/type).

Matches the pattern used by other actions in this package. No concerns.


25-31: Avoid sending expiration=undefined in requests
The getOptions method simply spreads your opts into the HTTP call via this._makeRequest, and there’s no pruning of undefined values in this repo. If this.expiration is undefined, you’ll end up sending expiration=undefined, which can trigger API errors.

Apply this conditional params construction:

-    const response = await this.mboum.getOptions({
-      $,
-      params: {
-        ticker: this.ticker,
-        expiration: this.expiration,
-      },
-    });
+    const params = {
+      ticker: this.ticker,
+      ...(this.expiration != null ? { expiration: this.expiration } : {}),
+    };
+    const response = await this.mboum.getOptions({
+      $,
+      params,
+    });

Please verify whether @pipedream/platform’s request client already strips out undefined params—if it doesn’t, this change is necessary to avoid sending expiration=undefined.

Copy link
Collaborator

@luancazarine luancazarine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @michelle0927, LGTM! Ready for QA!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[ACTION] Mboum MCP Server tools needed
2 participants