Repository navigation
Releases: 0xrsydn/idx-cli
Release list
v0.4.0
Broker summaries, bandarmology and foreign flow, from public data with no login or key.
New Features
idx stocks brokerand the MCP toolget_broker_summaryshow a stock's top 10 buying and selling brokers over a day or a date range, with totals. You can filter by investor side and board. The data comes from Indo Premier (IPOT). (#62, #63)idx stocks bandarandanalyze_bandarread broker concentration as buy minus sell value for the top 1, 3, 5 and 10 brokers, and give a signal from big accumulation to big distribution. Several symbols make a ranked screen thatstocks screencan pipe into. The thresholds are heuristics. (#64)idx stocks flowandget_foreign_flowshow foreign buying, selling and net value session by session. The data comes from IPOT by default;--source idxuses IDX's trading summary for exact share counts. (#65, #68)--investor foreign|domesticnow reads one investor side inbrokerandbandar, with that side's buy and sell totals. (#67)
Bug Fixes
- Quotes and IDX screen rows now carry
behind_session: true when the last trade is from before the latest IDX session. The quote table adds a note for these quotes, so a provider still showing the previous close after the session is no longer passed off as the latest price. (#71, #50)
Improvements
- IPOT broker pages are parsed with html5ever and accepted only in IPOT's exact markup. A page that differs is rejected with an error and never misread. (#70)
- IPOT pages for dates other than those requested are rejected before caching, and so are IDX trading summaries with no rows for the requested session. (#70)
- Bandar readings use checked arithmetic, and the table says "No trades." only when no broker traded. (#70)
- Flow and broker data share caches. Past sessions are cached for days and today for 5 minutes, and offline
latestlookups skip uncached days. (#62, #65, #68) - The
analyze_bandartopparameter lists its allowed values (1, 3, 5, 10) in the MCP schema. (#70)
Notes
stocks flow --source idxneeds curl-impersonate. The default IPOT source does not.- New dependency:
scraper0.27 (html5ever). Servo'sselectors,cssparseranddtoa-shortare MPL-2.0 and used unmodified. - JSON output for quotes and screens adds the
behind_sessionfield; no existing field changed.
Full Changelog: v0.3.3...v0.4.0
v0.3.3
Upgrade from 0.3.2: ownership changes could report the wrong direction for investors with several accounts, and invalid dates were answered instead of rejected.
Bug Fixes
ownership changesand theget_ownership_changestool compare an investor's total stake per ticker: KREN's KRESNA PRIMA INVEST, which added a second account, was reported as a decrease (944 → 401 bps) instead of an increase (944 → 1345). A corrected KSEI file for a month now replaces the original instead of mixing with it, and a file carrying several report dates compares each date on its own rows. (#53)get_ownership_changesrejects dates that are not imported releases, are reversed, or are malformed; an emptyfromused to report every holder as new. (#53)- Investor search finds aliases, the raw names KSEI prints:
PT ASTRA INTERNATIONAL TBKnow finds ASTRA INTERNATIONAL. An empty investor name is an error instead of an arbitrary match. (#53) ownership graphreaches every connected holder (holders whose id was a prefix of another's were dropped) and no longer slows down exponentially with depth. (#53)ownership syncreplaces the database in a single step, so an interrupted sync can no longer leave it missing; a snapshot whose holdings are missing is rejected before it replaces good data. A backup left by an interrupted older sync is restored, not overwritten. (#54)- Requests to MSN and Yahoo give up after 30 seconds instead of hanging, and ownership commands wait at most 30 seconds for another process's lock, so a stalled call cannot block every MCP tool. Downloads stop at 256 MiB as they arrive, including compressed ones. (#55)
- Escape sequences in provider text (news titles, insights, errors, names) are neutralized before reaching the terminal. Descriptions and URLs with non-ASCII characters no longer crash table output. (#56)
- In JSON mode, argument errors and warnings are JSON, so stderr stays parseable.
idx confighonors-o json; piped output stays plain text. (#56) - A "healthy" fundamental rating needs valuation and risk data; negative equity counts as high risk. (#57)
install.shinstalls the newest release even when the releases API answers on one line. (#58)cache clearremoves symlinks without following them out of the cache. (#56)
Improvements
zipmoves off a yanked release, to 9.0.4. (#52, #51)- Price data outside any plausible range is treated as missing instead of overflowing. (#55)
- The snapshot publisher handles report titles with line breaks, checks its manifest before upload, and copies its database safely. (#58)
- Release workflow actions are pinned to commit SHAs, and only the publishing job can write to releases. (#58)
- Help text covers config keys and output,
ownership changesdate rules, and alias search. (#56)
Testing
- Every fix has a regression test that fails on 0.3.2. The agent smoke test passes in Claude Code, Codex, pi, Hermes Agent, and opencode 1 and 2 through
npx -y idx-mcp, ten cases each. Found by a full-repo audit with Codex (gpt-6.1-sol, xhigh) and re-reviewed until clean; Pullfrog's PR review found four more, fixed here.
Full Changelog: v0.3.2...v0.3.3
v0.3.2
Upgrade from 0.3.1 if you run idx-mcp through npx, Hermes Agent, pnpm, or bun: 0.3.1 does not start there on npm 12.
New Features
- News items carry
relevance:companyitems about this ticker come first, newest first, thenmarketitems with general market news. Thestocks newstable gains anABOUTcolumn, and theget_companynews section returns the same labels. (#47) get_ownership_changespages through large diffs withoffset/next_offsetand returns asummaryover every row (counts by change type and the tickers with the most changes), so agents can answer overview questions without fetching every row. Rows are ordered by largest change first. (#48)
Bug Fixes
npx -y idx-mcpandnpx idx-cliwork on npm 12, pnpm 10+, and bun, which skip install scripts: the launcher now downloads the binary on first run instead of exiting withinstalled binary not found, which MCP clients reported as "Connection closed". This affected every Hermes Agent user. (#41, #42)- A first run with a read-only package directory, such as a root-owned
sudo npm install -gon npm 12, installs the binary to a per-user cache instead of failing withEACCES. (#46) - Stopping the launcher during the first-run download (
SIGTERM,SIGHUP, orSIGINTsent to its PID) stops the installer, removes the partial file, and exits by the same signal. (#46) - A local
IDX_BINARY_URLbinary is verified againstIDX_BINARY_SHA256after it is copied, so the installed bytes are the verified ones. (#46) - The user-cache fallback runs only from an absolute cache root, so an invalid
XDG_CACHE_HOMEor an emptyHOMEcan never make the launcher run a binary from the current directory. (#46) - News is ordered by publish time rather than by timestamp text, so fractional seconds and time-zone offsets no longer move older items ahead. (#47)
Improvements
get_ownership_changesreturns at most 300 rows per page (previously 2000, about 200 KB), which no longer overflows agents' tool output. The over-limit error points tooffsetandsummary. (#48)- News is fetched wider (at least 50 items), so this company's articles further down MSN's feed are found. MSN's stock tags are combined with the ticker and company name to find them. (#47)
Testing
- The agent smoke test runs Claude Code, Codex, pi, Hermes Agent, and opencode 1 and 2 against
npx -y idx-mcp, each from a cold npm cache in an empty directory. Each agent must install the binary itself, and ten cases call every MCP tool exceptownership_sync, which needs--allow-sync. All six harnesses pass on this release. (#44) - The npm smoke test covers installs without postinstall, read-only installs, and a planted binary that must never run. (#46)
Full Changelog: v0.3.1...v0.3.2
v0.3.1
Security and data-safety fixes for 0.3.0. Upgrade from 0.3.0; 0.3.0 is yanked on crates.io and deprecated on npm.
Security
- Path traversal via ticker symbols. A ticker such as
../../xwas used directly in cache file names, so idx could read or delete.jsonfiles outside its cache directory. Throughidx-mcp, a single tool call from a prompt-injected agent was enough. Tickers are now validated (invalid ticker symbol, exit 2) and cache file names are encoded.
Ownership database
- A cross-process lock (
<db>.lock) now guards the ownership database: sync installs, imports and entity edits take it exclusively, reads take it shared. Before, a sync could replace the database under an active import or reader and lose data. - Sync downloads without holding the lock, and downloads now time out (15 s connect, 10 min total) instead of hanging.
- A symlinked
ownership.db_pathkeeps its symlink: sync updates the real file and shares its lock. - A rebuilt snapshot never replaces a local database that holds more releases than it does.
MCP
- Input limits: at most 20 symbols per call (duplicates collapsed), caps on
limit, at most 4 concurrent tool calls. The tool schemas state the limits.
Robustness
- Atomic cache writes; per-client Yahoo cookie files.
- Size caps on ZIP entries and XLSX workbooks; two parser inputs that could crash or overflow now return errors.
Other
- Minimum supported Rust version is now 1.89 (for std file locks).
tests/agents/agent-smoke.sh: opt-in smoke test that drives real coding agents (Claude Code, Codex, pi, Hermes, opencode) against idx-mcp.
v0.3.0 - idx-mcp server, idx-core library, agent-native output
Highlights
- New:
idx-mcp, an MCP server. It serves the same market, financial and ownership data to MCP clients over stdio, through 11 tools:get_quotes,get_price_history,screen_stocks,get_company,analyze_stock,compare_stocks,get_shareholders,get_investor_holdings,search_investors,get_ownership_changes,ownership_status.- Install with
claude mcp add idx -- npx -y idx-mcp,cargo install idx-mcp, ornix profile install github:0xrsydn/idx-cli#idx-mcp. - Live results come as
{data, source, fetched_at, stale}. - Errors use the CLI's
{error, code, message}body. - The server shares idx's config, cache and ownership database.
--allow-syncadds anownership_synctool.
- Install with
- Agent-native CLI output. idx now prints JSON when stdout is not a terminal, and tables when it is. Agents and scripts get structured data without flags. JSON is compact when piped.
-o jsonlprints one record per line. No color codes appear when piped. idx-corelibrary. All data access, caching and analysis now live in a separate crate shared byidxandidx-mcp.
Breaking changes
-
Default output when piped is JSON. Use
-o table,IDX_OUTPUT=table, orgeneral.output = "table"to get tables back. A config created byidx config initbefore 0.3 pinsoutput = "table"; runidx config set general.output autoto switch to the new behavior. -
Exit codes by error class. Before 0.3, every error exited with 1.
Exit Meaning 2 invalid input or config 3 not found, no data, or no cached data offline 4 upstream unavailable; retry later 5 unsupported 1 other
CLI
stocks quote -andstocks compare -read symbols from stdin, separated by whitespace or commas. Example:idx stocks screen --filter high-dividend | jq -r '.[].symbol' | idx stocks compare -.- Financial statement line items come out in a stable order in JSON.
- Fixed: tables with colored cells (signals, change types) had a ragged right border in terminals.
Ownership
- Fixed: the IDX workbook stores the share code
TRUE(TRINITI DINAMIK) as a boolean cell, so its holders were imported under ticker1.- The published snapshot for 2026-09-30 has been rebuilt. The rebuild also corrects the bogus August→September changes for
TRUEand1. - With 0.3,
idx ownership syncpicks up the rebuild automatically. - On 0.2.x, run
idx ownership sync --forceonce.
- The published snapshot for 2026-09-30 has been rebuilt. The rebuild also corrects the bogus August→September changes for
- Sync now updates a database that is still byte-identical to an earlier build of the same snapshot. The manifest gains an optional
replaces_sqlite_sha256field, which older clients ignore. A database you imported or edited locally still needs--force.
Distribution
- Release assets add
idx-mcp-<platform>binaries next toidx-<platform>, all listed inSHA256SUMS. - New npm package
idx-mcp, alongsideidx-cli. New cratesidx-coreandidx-mcp. - Rust:
idxbuilds with 1.85+, andidx-mcpneeds 1.88+.
Verification
- 143 golden outputs (every command in table and JSON, plus error cases) are unchanged except for the documented output-default and exit-code changes.
- Live A/B checks against 0.2.4 match.
- Each MCP tool's data equals the CLI's JSON.
v0.2.4 - XLSX ownership data, curl/npm install
Highlights
- Ownership data is current again. Since June 2026 IDX publishes the monthly "Pemegang Saham di Atas 1%" list as XLSX on the Data Kepemilikan Saham page instead of a PDF announcement.
idx ownership discoverfinds it there andidx ownership importreads it. The published snapshot (idx ownership sync) now covers 2026-06-30, 2026-07-31 and 2026-08-31. - New install channels:
curl -fsSL https://raw.githubusercontent.com/0xrsydn/idx-cli/main/install.sh | shand npm (npx idx-cli,npm i -g idx-cli). Both use prebuilt binaries with SHA-256 verification. - Sync accepts larger snapshots. v0.2.3 and earlier cap snapshot downloads at 10 MiB. This version accepts up to the manifest's size (at most 1 GiB), which leaves room for more months of history later.
Ownership
- XLSX parser for the above-1% holder register (#25). Only the exact 12-column layout is accepted, so the daily above-5% and investor-type workbooks are rejected instead of mis-imported. Both the Feb/Mar 2026
INVESTOR_TYPEand the laterINVESTOR_CLASSIFICATIONheaders are handled. - Discovery merges the announcement API with the data page (#26). Downloads retry across curl-impersonate browser profiles, since IDX's Cloudflare rejects
curl_chrome142on the new page. ownership import --urlaccepts.xlsx.- Snapshot sync: the download is bounded by the manifest's
size_bytes, and a body larger than advertised is rejected (#31).
Snapshot publishing (maintainers)
build-latest-ownership-snapshot.sh --history <n>includes earlier months (#27).--max-snapshot-bytes(default 10 MiB) refuses snapshots that released clients can't download (#31).- Idempotent, packaged publisher:
nix build .#ownership-publishergivesidx-ownership-publishandidx-ownership-freshness. Every run ends in oneRESULT:line (#29). Upload verification and partial-publish recovery (#30).
Distribution
- Release workflow builds static musl Linux (x64, arm64) and macOS (arm64, x64) binaries, plus
SHA256SUMSandinstall.sh(#22, #24). - npm wrapper with checksum-verified postinstall (#22). pnpm 10+ and bun need
--allow-build/--trust.
Compatibility
- The snapshot manifest is still schema v1. v0.2.3 clients keep syncing as long as snapshots stay at or below 10 MiB, which the publisher enforces.
- Discover JSON gains
formatandas_of_datefields; existing fields are unchanged.
v0.2.3 - July 2026 KSEI Spaced-Header Parser Fix
Fixes
- handles the new spaced-header KSEI PDF layout (SHARE CODE, INVESTOR CLASSIFICATION) that broke schema classification
- normalizes spaced header text before schema classification so both underscore (SHARE_CODE) and spaced layouts parse
- adds INVESTOR_CLASSIFICATION to schema markers and header labels
- satisfies clippy 1.97 lints that failed the ubuntu CI step (filter, sort_by_key(Reverse), ?)
Scope
- published from commit
603c0e4(main, after PR #21 merge) - adds a test fixture from the live June 2026 KSEI PDF and a spaced-header test case
- all 222 tests pass (143 unit + 79 integration), clippy + fmt clean
- snapshot data asset unchanged: latest KSEI above-1% report is still as_of 2026-05-29; the parser fix enables future June/July imports once IDX publishes them
Ownership Snapshot Current
Stable release for idx ownership snapshot artifacts consumed by idx ownership sync.
v0.2.2 - April 2026 KSEI Parser Fix
Fixes
- handles April 2026 KSEI PDFs that omit zero-valued scrip columns on some holder rows
- defaults missing component share fields to zero while still requiring total shares
- restores successful import and sync against the live April 2026 KSEI ownership file format
Scope
- published from commit
04eaa75 - includes the
0.2.2version bump that was already shipped to crates.io - this release object backfills the missing GitHub tag/release for that published crate version
v0.2.1 - Ownership Sync Bootstrap
Highlights
- adds
idx ownership discoverto locate the latest supported IDX above-1 shareholder register PDF - adds
idx ownership import --url <pdf-url>for direct remote import - adds
idx ownership syncfor maintained snapshot-based bootstrap and refresh - adds local archive ZIP/TXT ingest as a fallback backstop path
- expands smoke coverage and fixture-backed ownership tests
Notes
stocksremains MSN-first, with Yahoo retained for history fallback- this release is being backfilled on GitHub so release objects match the existing tag history