Skip to main content
Glama
501,338 tools. Updated 2026-09-01 01:51

"EAC" matching MCP tools:

  • Consolidated breakdown tool. Pick `dimension`: 'channel' returns per-channel sessions/revenue/RPS plus engagement (visitors, avg dwell seconds, bounce rate) and bot_excluded_count (bot sessions removed from human metrics; a channel with sessions=0 but bot_excluded_count>0 is bot-only traffic, kept so it is not mistaken for 'no traffic') and — when ad spend is connected (Path B) — spend/ROAS/saturation; plus an 'Unattributed' row (is_unattributed=true) for purchase revenue not tied to any channel, with a revenue_breakdown summary (total_event_jpy/attributed_jpy/unattributed_jpy); pass attribution_model ('last_touch' default / 'first_touch' / 'linear' / 'time_decay') to switch how purchase revenue is attributed across channels — same models as the dashboard's attribution selector; only revenue_jpy/rps_jpy change (sessions/engagement/bot/spend/ROAS are model-independent), so compare models to see e.g. how much an awareness channel gains under first_touch vs last_touch. pass filter.channel to drill into that channel's campaigns (utm_campaign) with RPS/AOV/CVR — the value must be a channel name exactly as this tool returns it, case included (e.g. 'Google Ads', 'Meta', 'Criteo', 'Google検索'), since the match is exact and a lowercase slug returns nothing. 'page' returns per-page pageviews/unique visitors/avg time/bounce plus the page `title` (what the page IS, so a row reads as an article name rather than a slug; null for pages with no visit since 2026-08-21 — it does not backfill) ranked by pageviews (limit default 20, max 200; query strings stripped, bots excluded; each row also carries GSC Google-search impressions/clicks/ctr/avg_position merged by normalized path — null when the page has no GSC row, and a DIFFERENT denominator from pageviews, see notes). 'session_attribute' returns the device / time-of-day (4h JST) / day-of-week (ISO) / new-vs-returning (with AOV) / country (top-15 by sessions + 'Other', ISO2 code, share_pct; from first-party session geo, 'Unknown' when IP unresolved) breakdowns in one call. site_id is OPTIONAL when OAuth-authenticated. Default period is the last 30 days; pass period='today'/'7d'/'90d' or a raw day count (1-365). `filter` only applies to dimension='channel'; `limit` only applies to dimension='page'. Pass optional country (ISO2, e.g. 'JP') and/or device ('mobile'/'desktop'/'tablet') to scope session-derived metrics across any dimension (omit = all). Under such a filter, dimension='channel' keeps ad spend/ROAS site-wide (no country/device dimension) and omits the Unattributed row + revenue_breakdown (see notes); dimension='page' rows include pageviews_change (period-over-period % vs the previous equal-length window, null = new page).
    Connector
  • Return how ONE page's Google Search performance changed over time (FD-040) — the time-axis drill-down for a page surfaced by get_breakdown(dimension='page'). Given a `page` (a normalized path like '/news/rps-revenue-per-session-guide' or a full URL — both resolve), returns a `series` of day or week buckets, each with clicks, impressions, and impression-weighted avg_position, plus a `summary` (first/last/best/worst position, position_delta, click & impression totals). avg_position is a RANK: smaller is better, so a NEGATIVE position_delta means the page's ranking IMPROVED over the window (e.g. 12.0 → 9.0 = delta −3.0). Use this to verify whether SEO work on a page paid off (rank rose / clicks grew) or slipped. Buckets where the page never appeared in search are omitted (gaps), so the series can be shorter than the period. `granularity` defaults to 'day' for windows up to ~35 days and 'week' for longer (weekly smooths daily noise); pass it to override. site_id is OPTIONAL when OAuth-authenticated. Default period is the last 30 days; pass period='today'/'7d'/'90d' or a raw day count (1-365). Google-search only; data lags 1-2 days. This is per-page; for the cross-page snapshot use get_breakdown(dimension='page'), and for per-query (keyword) trends use get_keyword_performance.
    Connector
  • "Is it true that…" / "fact check" / "verify the claim that…" / "did X really…" / "was Y actually…" / "confirm or refute" / "true or false" — natural-language claim verification against authoritative sources. Use whenever the agent needs to check whether something a user said is factually correct. Company-financial claims (revenue, net income, cash for public US companies) verify via the structured SEC EDGAR + XBRL fast path with exact percent-delta math; ANY OTHER factual claim (macro statistics, rates, prices, drug data, records) automatically falls through to the grounded pipeline — routed to the right live source, answered with verbatim evidence, then judged. Returns a verdict (confirmed / approximately_correct / refuted / inconclusive / unsupported / could_not_verify), the grounded or structured actual value with pipeworx:// citation, and reasoning. IMPORTANT for callers: could_not_verify means the check did not happen (our LLM or source failed) and carries verification_error{stage,detail} — it is NOT evidence for or against the claim, and must not be shown as one. unsupported means we looked and cover no source for it. Replaces 4–6 sequential calls (NL parsing → entity resolution → data lookup → comparison).
    Connector
  • List the sites this caller can analyze, in two groups. my_sites = the sites connected to the signed-in account (each with its display name + domain, so you can match phrases like "the production site" or "revenuescope.jp" without the user pasting a UUID); empty when the caller is not signed in. demo_sites = ready-made sample sites for trying RevenueScope before connecting your own — each is a fictional site with sample data, not a real customer. When signed in (OAuth), prefer my_sites and, if site_id is omitted, default analytics tools to the is_primary=true site. When NOT signed in, my_sites is empty: use a demo_sites site_id and tell the user the numbers come from a sample site, not their own.
    Connector
  • Return a content 'playbook' for the site: every content page classified into ONE of five action buckets over a weekly-style window comparison (current window vs the immediately preceding window of equal length), ranked by search-opportunity × session gain so you can tell the user which page to GROW next and what to do: within the 'striking' bucket rows are ordered by expected_sessions_gain DESC (the band-CTR headroom that is the actionable lever there), while the other buckets keep real landing revenue DESC (largest revenue at stake first). This surfaces search intent to add sessions (grow the traffic denominator), NOT CVR — a page already winning on sessions/revenue but with zero clicks still shows up. Buckets: 'decaying' (search clicks actually fell, OR the page had real traffic (previous clicks ≥3) and its rank slid ≥2 positions from within the click zone while clicks did NOT grow → refresh/rewrite; a rank slide alone with growing/negligible clicks is NOT decay — search clicks are the primary signal, position only a leading indicator), 'striking' (has striking-distance queries at positions 4-20 with click upside but clicks still low → push those queries up; top 3 listed in striking_queries), 'rising' (clicks grew significantly → produce more of this, strengthen CTA), 'dormant' (has impressions but ~0 clicks and its main query is far below the click zone → big rewrite or consolidate; zero-pageview pure-rank pages surface here), 'stable' (none of the above → watch). Each page also carries current/previous clicks·impressions·avg_position, is_new, landing sessions/engaged/revenue_jpy, AI-referred sessions/revenue/sources, expected_sessions_gain (the window's expected incremental sessions from striking-band queries — a search click is ~1 session, so it is NOT re-converted via CTR; normalize to a monthly figure with the window length), and expected_revenue_gain (expected_sessions_gain × page RPS, returned ONLY when revenue>0 and sessions>=5 — display-only projection, never a sort key). The deterministic action mapping and all (provisional) thresholds come back in `criteria`; the model does the narrative interpretation (mcp-first). Rows with confidence='low' carry `caveats` — 'geo_winning_suspect' (AI Overview/citations likely substitute the click: a GEO win, don't break the page; cross-check get_ai_traffic), 'zero_click_suspect' (SERP-feature occupation or intent-mismatch/polysemous query: verify the live SERP first), 'ai_cited' (decaying but the AI citation is alive) — verify before acting on low-confidence rows; definitions in criteria.caveat_flags. The response is summary-first (token-aware): `bucket_summary` always holds the FULL pre-limit distribution (per-bucket count/revenue/clicks) plus `total_pages`, while `pages` returns only the top rows in priority order (default limit 15, max 200); pass bucket='striking' etc. to drill into one bucket, and check `truncated` — when present it tells how many rows were cut and how to fetch them. GSC-driven and Google-search only; data lags 1-2 days so the current window's right edge sits a few days back. When narrating a bucket to the user, scope it to Google search — say 'search traffic to this page is declining', NOT 'this page is declining'; the classification is a search-trend diagnosis, not overall page health, so a page labeled 'decaying' can be thriving on Direct/social/AI. Before calling a negative bucket (decaying/dormant) a problem, cross-check the row's landing sessions/revenue_jpy and ai_sessions. site_id is OPTIONAL when OAuth-authenticated. Default window is the last 7 days vs the prior 7; pass period='30d'/'90d' or a raw day count (2-365). Window date bounds are INCLUSIVE on both ends, so period=Nd actually spans N+1 calendar dates (the real range is in `window`); both windows share the same length, so the comparison stays symmetric. This is the cross-page action snapshot; for one page's time series use get_page_trend, and for AI-citation gaps use get_ai_traffic(mode='gaps').
    Connector
  • Return the latest competitor SEO snapshot for the site (FD-041): which keywords each tracked competitor DOMAIN ranks for on Google (Japan/ja), at what position, with monthly search_volume, cpc and etv (estimated monthly traffic — a visit estimate, not a monetary value), plus how each rank moved vs the previous snapshot. READ-ONLY — this tool never runs a research (that costs money and is triggered separately from the dashboard, the competitor-research Edge Function); it only reads what was already fetched. The response is summary-first (token-aware): each domain carries a constant-size `summary` (total_keywords, total_etv, volume_bands and rank_bands histograms, and vs_previous new/lost/improved/declined/same counts) that always reflects the FULL keyword set, while `keywords` returns only the top rows ranked by `sort` (etv default | volume | rank; default limit 10 per domain, max 100) with a `truncated` block (shown/matching_total/lost_total). rank is a POSITION: smaller is better, so a NEGATIVE rank_delta means the competitor's ranking IMPROVED (change ∈ new/improved/declined/same/unknown). Keywords the competitor ranked for before but lost are disclosed in `lost_keywords` (top 10 by previous etv), never dropped silently. Pass `domain` to focus one competitor, `min_volume` to drop low-volume keywords. When the site has NO completed research yet the response is { researched:false } with a `guidance` string explaining a research must be triggered from the dashboard first — this tool cannot start one. site_id is OPTIONAL when OAuth-authenticated. This is the external competitor lens (third-party SERP data); for YOUR OWN search performance use get_keyword_performance, and for your content playbook use get_content_actions.
    Connector

Matching MCP Servers

Matching MCP Connectors

  • Leadership-ratio benchmark, partnership ROI builder, community-launch readiness test. ELC data.

  • Build and price an ELC community partnership: match, customize, 12-month plan, 16% AI discount.

  • "What's new with X" / "latest on Y" / "what happened to Z this week / month / quarter" / "updates on Acme" / "news on Tesla recently" / "what's happening with Apple" — change feed for a company in the last N days/weeks/months in ONE parallel call. Fans out to SEC EDGAR (filings since `since`), GDELT→GNews fallback (news mentions in window — GDELT preferred, GNews when rate-limited or 5xx), USPTO (patents granted; PatentsView API sunset May 2025 so this soft-fails until reactivated). `since` accepts ISO date ("2026-04-01") or relative shorthand ("7d", "30d", "3m", "1y"). Returns structured changes[] grouped by source + total_changes count + pipeworx:// citation URIs. Use entity_profile instead when you want the static profile (filings + fundamentals + LEI + patents) regardless of window.
    Connector
  • Use when the visitor names a NUMBER rather than a band — 'we have 8,000 approved', 'can we do this for five thousand'. Returns a deterministic best-value composition under that ceiling: what fits, what was left out AND why, how much budget is unspent, and what the cheapest excluded item costs. Foundation items are kept first, then the remaining items cheapest-first so the budget buys as much as possible. Priced against the AI-channel figure by default, since that is what they would actually pay. Never hand-pick a basket yourself when a budget is stated — this tool is the authoritative composition, the same way customize_package is the authoritative total.
    Connector
  • 어떤 것의 **종류·구성요소·분류**를 완전 열거한다 — '건축물 하중의 종류', '구조용 강종 체계', '건축 도면의 종류' 같은 **'X의 종류/체계'** 요청에 호출하라(순서는 scenario, 비교는 compare). 권위표준 기반 큐레이션 분류학으로 완전한 멤버 목록을 반환하고, 각 멤버 정의는 그래프에서 당긴다. 결정론. match=None이면 미큐레이션 주제 — k_snippets로 폴백. gaps는 멤버 정의가 아직 그래프에 없다는 정직한 신호(지어내지 말고 그대로 전하라).
    Connector
  • ACCOUNT REQUIRED (free — sign in via GitHub at https://pipeworx.io/signup; depth:"thorough" needs a paid plan). If you are not signed in, use ask_pipeworx instead — it works on every tier. Grounded multi-source research across Pipeworx's 1494 STRUCTURED data sources (SEC filings, FRED/BLS economics, FDA, USPTO patents, markets, science, government records, etc.) in ONE call — this is NOT open-web search. Decomposes your question into focused facets, routes each to the right one of 5,708 tools IN PARALLEL, and returns a findings packet: verbatim evidence + confidence + source + fetched_at + a stable pipeworx:// citation per finding, with explicit gaps[] for facets the data couldn't answer (never invented). Best for broad/multi-part questions over structured data ("compare X and Y's regulatory + financial exposure", "research the filings + market picture for ACME"). For a single lookup use ask_pipeworx (one LLM call, not many). For BREAKING or colloquial CURRENT-NEWS / "what's the world saying about X" topics, prefer ask_pipeworx — it routes to live news APIs and the *-news-feeds packs; deep_research returns mostly empty gaps[] when the topic isn't in the structured catalog. Second-hop iteration: depth:"standard" re-angles unanswered gaps (gap recovery); depth:"thorough" additionally chases the best leads from the first pass — so multi-step questions resolve in one call. Every finding carries a `hop` field and a citation_uri — a resolvable pipeworx:// record URI, present only when the source emits one that resources/read can actually serve, so a citation you get back is always fetchable. "standard" and "thorough" also return contradictions[] flagging findings that disagree. Large records are semantically excerpted to the passages relevant to each facet (not head-truncated), so answers deep in a long filing/series aren't missed. Expect 15-60s (thorough with its follow-up + contradiction pass: up to ~90s).
    Connector
  • Find tools by describing the data or task. Use when you need to browse, search, look up, or discover what tools exist for: SEC filings, financials, revenue, profit, FDA drugs, adverse events, FRED economic data, Census demographics, BLS jobs/unemployment/inflation, ATTOM real estate, ClinicalTrials, USPTO patents, weather, news, crypto, stocks. Returns the top-N most relevant tools with names, descriptions, and full input schemas (with curated examples) — each result is ready to call directly, no second schema lookup needed. Call this FIRST when you have many tools available and want to see the option set (not just one answer).
    Connector
  • Realizable-vs-theoretical edge check against live CLOB order-book depth. REQUIRES one of `market` (single-market mode) or `event` (basket/partition mode). SINGLE-MARKET: pass a market slug/URL + side (buy_yes|sell_yes|buy_no|sell_no, default buy_yes) + size_usd (default 1000 — max spend on buys, target proceeds on sells); walks the ladder and returns top_of_book, vwap_fill_price, slippage_pp, shares_filled, max_fillable_usd, and a verdict (clean|degraded|cannot_fill). BASKET: pass an event slug/URL + side (sell_yes = capture overround by selling every leg, buy_yes = capture underround; default auto from partition sum) + size_usd interpreted as settlement notional S (shares per leg; each share pays $1); returns theoretical_sum vs realizable_sum (top-of-book vs VWAP across all legs), capture_ratio, profit_usd at executed size, per-leg fill detail, thin_legs[], max_clean_notional_usd, and forced_directional_risk naming the legs most likely to strand you unhedged. USE THIS before acting on any polymarket_arbitrage SELL/BUY-EVERY-LEG signal or any polymarket_edges trade above ~$500 — theoretical overround on thin books is not capturable, and partial basket fills convert an arb into an unhedged directional position (the dominant loss mode in real arb-bot P&L).
    Connector
  • Tell the Pipeworx team something is broken, missing, or needs to exist. Use when a tool returns wrong/stale data (bug), when a tool you wish existed isn't in the catalog (feature/data_gap), or when something worked surprisingly well (praise). ONLY for tools served by this Pipeworx connection — if the tool came from a different MCP server in your client (another vendor's Gmail, Splunk, Slack, etc. connector), we cannot fix it and reporting it here only delays you; file it with that server instead. Not sure? Pipeworx tool names are the ones this connection lists. Describe the issue in terms of Pipeworx tools/packs — don't paste the end-user's prompt. Filing without an account returns a `claim_token`; pass it back later as pipeworx_feedback({claim_token:"pwfb_…"}) to read whether it was fixed and what changed. The team reads digests daily and signal directly affects roadmap. Rate-limited to 5 per identifier per day. Free; doesn't count against your tool-call quota.
    Connector
  • The second legitimate ending besides request_offer: a direct booking link for a 1:1 intro meeting with Marian Kamenistak, ELC's founder. Offer it whenever the visitor hesitates, wants a human, or the package needs tailoring beyond the catalog. No contact details collected here — the booking page handles everything. Pass preset_id and item_ids if a package was composed: the response then carries a paste-ready booking note, so the call starts from their numbers instead of from scratch.
    Connector
  • The official mcp.ai marketplace — the in-platform catalog of every MCP/tool, AND the way to run them. Covers capability requests like "find an MCP that does X", "consulta um CPF", "is there a tool for Y". Core flow: action=search discovers MCPs by intent → describe returns one MCP's full profile (every tool with its id + params, pricing, auth) so you pick the right tool_id → invoke RUNS that tool. KEY: invoke works even when the MCP is NOT installed — it runs the tool pontualmente (one-off), without adding the MCP to the toolkit and without bloating the tool list. If the MCP needs a credential/login, invoke returns a connect link; if it is paid and the wallet is empty, invoke returns a checkout/top-up link (the user opens it, then you retry). Use install only to make an MCP PERMANENT in the active toolkit (its tools then show up natively in future sessions); prefer invoke for a single/occasional use. list_tools lists what is callable right now. subscribe/cancel handle per-MCP billing; report_bug sends feedback; request_mcp asks us to build a NEW MCP when nothing fits. Search/describe flag installed_in_toolkit vs installed_in_workspace. Writes (install/uninstall/subscribe/cancel and the one-off install behind invoke) require workspace owner/admin. It also carries the mcp.ai PROMPT LIBRARY, which is about ready-made prompt TEXT rather than MCPs: search_prompts finds one, get_prompt returns its full text with {{variables}} filled, and publish_prompt saves a prompt and returns a shareable mcp.ai/p/<slug> link that opens without login.
    Connector
  • The official mcp.ai marketplace — the in-platform catalog of every MCP/tool, AND the way to run them. Covers capability requests like "find an MCP that does X", "consulta um CPF", "is there a tool for Y". Core flow: action=search discovers MCPs by intent → describe returns one MCP's full profile (every tool with its id + params, pricing, auth) so you pick the right tool_id → invoke RUNS that tool. KEY: invoke works even when the MCP is NOT installed — it runs the tool pontualmente (one-off), without adding the MCP to the toolkit and without bloating the tool list. If the MCP needs a credential/login, invoke returns a connect link; if it is paid and the wallet is empty, invoke returns a checkout/top-up link (the user opens it, then you retry). Use install only to make an MCP PERMANENT in the active toolkit (its tools then show up natively in future sessions); prefer invoke for a single/occasional use. list_tools lists what is callable right now. subscribe/cancel handle per-MCP billing; report_bug sends feedback; request_mcp asks us to build a NEW MCP when nothing fits. Search/describe flag installed_in_toolkit vs installed_in_workspace. Writes (install/uninstall/subscribe/cancel and the one-off install behind invoke) require workspace owner/admin. It also carries the mcp.ai PROMPT LIBRARY, which is about ready-made prompt TEXT rather than MCPs: search_prompts finds one, get_prompt returns its full text with {{variables}} filled, and publish_prompt saves a prompt and returns a shareable mcp.ai/p/<slug> link that opens without login.
    Connector
  • 사용자가 직접 입력하는 폼이 아니라, 호출 에이전트가 직전 Den 응답을 활용한 뒤 사용자가 보인 반응(수정 지시/불만/채택/무시)을 대화 종료 전 요약 수준으로 기록하는 릴레이 툴. query_id가 있으면 그대로 전달하고, 없으면 직전 Den 툴에 전달한 question_text만 전달한다. satisfied를 기록하고, 불만족이면 issue_type을 지정하며 comment는 반응 요지만 200자 이내로 요약한다. 채택·긍정은 satisfied=true, 수정 지시·불만·명시적 무시는 satisfied=false와 가장 가까운 issue_type으로 매핑한다. 관찰 가능한 반응이 전혀 없으면 만족 여부를 추측하지 않는다. ★satisfied=true(채택·긍정)이면 comment 에 **den 이 없었으면 무엇을 하려 했는지** 한 마디를 함께 적는다 — "다른 값을 쓰려 했다" · "몰라서 정하지 못하고 있었다" · "다른 출처로 갔어야 했다" 중 사용자가 실제로 말한 것. 이 한 마디만이 'den 을 썼다'와 'den 때문에 달라졌다'를 가른다. ★★사용자가 말하지 않았으면 **비워 둔다.** 추측해 지어내지 않는다 — 없는 것을 적는 편이 안 적는 것보다 나쁘다. ★★★그렇다고 comment 를 통째로 생략하지는 않는다. satisfied=true 면 **무엇을 채택했는지** 한 줄은 항상 적는다(어느 값·조문·판단을 그대로 썼는가). 비워 두는 것은 반사실 한 마디뿐이다 — 요지까지 비면 그 만족은 기록에 남아도 쓸 수 없다. 사용자 대화 원문은 전송하지 않는다. 만족/불만족과 사유는 다음 날 그래프 보완에 반영된다.
    Connector
  • Request a change to an acceptance criterion. grounds=unreachable (default): the AC cannot be proven — requires ≥3 failed evidence attempts (weak/mismatch) with 0 matches. grounds=wrong_criterion: the AC measures the wrong thing (owner never approved this wording, or a revealed fact shows it tracks something else) — no failed attempts required, but you MUST pass quotedFragment: a verbatim slice of the criterion text you claim is wrong (checked against the stored text), and the reason must name the unapproved wording or the finding; difficulty alone is rejected. An LLM judge screens the reason either way. On pass, creates an escalation for the goal owner to resolve (edit AC text, split to sub-goal, drop AC without creating a child, or reject). Grove mode only, goal must be in_progress.
    Connector
  • Return the full headline summary for a site and period in ONE call: the 5 KPIs (revenue, sessions, RPS, AOV, CVR) PLUS two engagement KPIs (avg_duration = average dwell time in seconds, bounce_rate = % single-page-exit sessions) each with value AND the period-over-period change vs the previous equal-length window, PLUS a daily revenue/sessions/conversions trend, PLUS ad-spend availability (connected_channels, ad_spend_data_status, ad_spend_channels_in_period) and the Path A/B recommendation. avg_duration/bounce_rate are useful for sites with no revenue yet (engagement view). scroll_depth is the average scroll depth (%), taken per session as its deepest point then averaged; its change is a percentage-point delta. IMPORTANT: its denominator differs from avg_duration/bounce_rate — depth only covers sessions whose exit beacon landed, and sessions without one are excluded rather than counted as 0. scroll_depth is null when the window holds no depth signal at all (0% would read as 'read shallowly' when the truth is 'not measured'); depth has only been collected since 2026-06-15, so longer windows are partial. Pass optional country (ISO2, e.g. 'JP') and/or device ('mobile'/'desktop'/'tablet') to scope the session-derived KPIs and trend to that segment (omit = all); ROAS stays site-wide (ad spend has no country/device dimension). This is what the dashboard's KPI cards + revenue-trend chart show, merged with the site's ad-spend context. Call this first when a user asks 'how is my site doing?'. site_id is OPTIONAL when OAuth-authenticated (server falls back to the primary site). Default period is the last 30 days; pass period='today'/'7d'/'90d' or a raw day count (1-365). change is a percentage for revenue/sessions/RPS/AOV/avg_duration and an absolute percentage-point delta for CVR and bounce_rate. For period='today' the comparison is today-so-far vs the SAME elapsed window yesterday (e.g. midnight→now vs midnight→same-time-yesterday), so 'previous' can read below yesterday's full-day total — that is expected, not a discrepancy. ad_spend_data_status / ad_spend_channels_in_period reflect spend data ACTUALLY present in the period (consistent with get_channel_breakdown); path_recommendation reflects whether the requested period holds any channel with spend>0 (Path B = ad spend connected), the same definition the other tools use. kpis.roas is the SITE-WIDE ROAS (RS-measured revenue ÷ ad spend over channels that have spend — Σrevenue ÷ Σspend, the same definition as the dashboard's overall ROAS and FD-030 A-1; the spend-weighted aggregate of get_breakdown's per-channel ROAS) with value/previous/change (前期比 from a current + previous 2-window computation); it is null on Path A / when the period has no ad spend (ROAS is undefined with zero spend), so render it only when present. When the PREVIOUS window has no spend, roas.previous and roas.change are null (unknown baseline, not 0.00x) — treat that as 'no prior-period comparison', never as a drop from zero.
    Connector