# Changelog of AI DC BOM Stock Screener MCP (`neeenja/ai-dc-bom-scanner`) Actor

- **URL**: https://apify.com/neeenja/ai-dc-bom-scanner/changelog.md
- **Full Actor documentation**: https://apify.com/neeenja/ai-dc-bom-scanner.md

## Changelog

### 1.0.0 (2026-10-07)

Initial release.

**Keyless live data - the offline demo is gone.** The server no longer needs
an API key. Five of the seven composite signals are measured live from free,
public sources:

- **SEC EDGAR** `data.sec.gov/api/xbrl/companyfacts` - audited 10-K/10-Q XBRL
  for PE (with filed quarterly EPS) and both 36-month growth figures
- **Nasdaq** `api.nasdaq.com/api/analyst/...` - real buy/hold/sell counts and
  next-fiscal-year consensus EPS
- **Yahoo chart** `query1.finance.yahoo.com/v8/...` - last traded price

Forward revenue growth has no free equivalent and is deliberately left
undefined rather than estimated: the engine imputes it, penalises it and flags
`MISSING_FWDREVENUEGROWTH12M`, and caps the composite at 60 when two or more
quantitative signals are missing. Every row carries its own provenance
(price used, PE basis, estimate count, live signal count) so two rows are
never silently scored on different denominators. `FMP_API_KEY`, when present,
still takes precedence and measures all seven.

Four defects found and fixed while building this, each caught by checking a
result against a known figure rather than by the code running clean:

- `durationSeries` read only `units.USD`, but per-share facts live under
  `units["USD/shares"]`, so every PE came back undefined with no error raised.
- "Sum the last four quarters" spans 454 days, because Q4 is never filed as a
  10-Q. It mixes Q4 of one fiscal year with Q1-Q3 of the next and yields a
  plausible but wrong PE (NVDA 32.8 instead of 48.5). Quarter seams are now
  required to be contiguous.
- Older filings carry cumulative year-to-date figures whose duration lands in
  the 80-100 day band, so a contiguity test alone will find a clean
  four-quarter window from 2019 and call it current. Windows older than ~200
  days are rejected.
- `handle()` dispatched `tools/call` without `await`, so the reply was written
  after the function returned. The hosted handler reads the output stream the
  moment dispatch resolves and answered "No response produced" for every tool
  that touched the network. Tools answering from local memory had hidden it.

Foreign private issuers file 20-F under `ifrs-full`, leaving `us-gaap` empty for
TSM, so tag aliases now cover the IFRS spellings. Upstream failures are
counted and published as `sourceHealth` on the snapshot rather than swallowed,
because the first cloud run degraded to demo data with an empty failure list
and no log line - the one condition this module exists to prevent was the one
thing it could not report.

`SCAN_OFFLINE=1` pins the bundled baseline for tests and smokes.

**Hosted (Apify Standby) hardening — all verified by `scripts/http-smoke.mjs` (37 assertions):**

- Rewrote the hosted HTTP entry as a **zero-dependency** `node:http` server that reuses the existing hand-written JSON-RPC dispatcher, replacing the MCP SDK + Express + Apify SDK handler. Removes three runtime dependencies, the cloud `npm install` step and any lockfile / peer-dependency drift from the build.
- Added the **`x-apify-container-server-readiness-probe`** response. Without it a standby container never reports ready and every caller sees a timeout.
- Billing moved to Apify's public **REST charge API** with an explicit `Actor.charge` equivalent; it no longer depends on an SDK import succeeding, and a failed charge is logged loudly instead of swallowed.
- Platform detection now includes **`APIFY_META_ORIGIN`**, which is what standby actually injects — checking only `APIFY_TOKEN` silently disabled billing in the exact mode being sold.
- Correct **Streamable HTTP** semantics: `GET /mcp` → 405, `DELETE /mcp` → 204, missing `text/event-stream` in `Accept` → 406, malformed body → 400, notifications → 202.
- Pricing consolidated into **one** `pricingInfos` record with all four billable events. Apify activates only the most recently appended record, so events split across records are served free.
- **Removed the two `$0` events** (`mcp-initialize`, `mcp-list-tools`); a zero-price event is rejected by the API and discovery must never be billable. `get_methodology` is likewise free.
- `actor.json`: `version` corrected to `MAJOR.MINOR` (a three-segment version fails schema validation on push), conflicting `webServerMcpPath` removed so the process owns its own listener, and the input schema required before publishing added.
- **Honesty fix:** with no data provider configured, `scan` / `get_list` now print an explicit `*** OFFLINE DEMO DATA — NOT LIVE MARKET DATA ***` banner, and `get_methodology` returns a `dataSource.warning`. Every row already carried `OFFLINE_DEMO`, but a paying caller could still read a stale ranking as current.
- Added `handleMessageAsync` so the hosted path can await a tool result; the stdio path stays fire-and-forget.
- License changed to **proprietary** (source available on request) to match the private-repository distribution model.

**Core:**

- 7-signal composite ranking (analyst Buy %, PE inverted, 36m earnings/revenue growth, 12m forecast earnings/revenue growth, curated moat 1–5).
- Curated AI data-center BOM universe (~30 U.S.-listed tickers across 10 supply-chain categories) with moat scores.
- Zero-dependency stdio MCP server (hand-rolled JSON-RPC 2.0) + 5 tools + `sunday_scan` prompt.
- Offline demo mode (illustrative baseline when no `FMP_API_KEY`).
- Static weekly ranked-list site (dark "ink + amber" theme, responsive, accessible) + RSS 2.0 + iCalendar feeds.
- FMP (Financial Modeling Prep) live-data client with defensive parsing and imputation.
- Apify Standby + Pay-Per-Event configuration (`actor.json`, `pay_per_event.json`, `Dockerfile`).
- GitHub Actions: `preflight` (tests + smoke + P0 check) and `refresh` (Sunday scan → GitHub Pages).
- Tests: scoring edge cases, server JSON-RPC lifecycle, universe validation.
- Trilingual README (English / 简体中文 / 繁體中文), SPEC.md, docs/ (PRD, ARCHITECTURE, UIUX).
