mirror of
https://github.com/0xrsydn/idx-cli.git
synced 2026-11-07 09:45:36 +00:00
`stockbit::signin` is now the single sign-in flow. `idx stockbit login` waits on it in the foreground; the `stockbit_login` MCP tool runs it on a thread and `stockbit_status` reports `sign_in.state`, so an agent knows when to stop polling. Auto uses a browser unless the shell is over SSH or has no display, and falls back to the local page only when the browser cannot start. The browser way opens Stockbit's sign-in page in a profile only idx uses and reads the session cookie over DevTools. What a real sign-in showed: - The cookie is host-only on stockbit.com, so deleting by the assumed .stockbit.com removed nothing and left live tokens in the profile. It is now deleted by its own domain and path, with every other tab closed first, and read back to confirm. - A signed-out page writes the cookie without tokens; it no longer counts. - A profile belongs to one browser, so it records the executable that made it. - On macOS the config directory depends on XDG_CONFIG_HOME, so a shell and an app started from the Dock disagreed; both default locations are now checked. - A thread does not outlive main, so idx-mcp closes a waiting browser when stdin closes or on SIGTERM or Ctrl-C. Progress goes to stderr, which keeps `-o json` to one document on stdout. Google refused its own sign-in in this window on 2026-10-31, most likely over the debugging flag; password sign-in works, and the docs and roadmap say so. Claude-Session: https://claude.ai/code/session_01RqPPVaoFxLToGAXXBEoCtH
614 lines
21 KiB
JSON
614 lines
21 KiB
JSON
[
|
|
{
|
|
"description": "Bandarmology for one or more IDX tickers from the broker summary: for the top 1, 3, 5 and 10 brokers per side, buy value minus sell value as basis points of value traded (`imbalance_bps`), with a `signal` from big_accumulation (>= +1500) through neutral (within +-500) to big_distribution (<= -1500), headlined by `top` (default 5). Reports come strongest accumulation first; tickers that fail are listed under `failures`. A heuristic over end-of-day broker codes: brokers trade for many clients, and `both_sides` lists brokers whose gross figures overstate their direction. `method` names the rules applied. With `investor` foreign or domestic, shares are of that side's own buying (`buy_value`) and selling (`sell_value`); that needs `board` all.",
|
|
"inputSchema": {
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"properties": {
|
|
"board": {
|
|
"default": null,
|
|
"description": "Which board's trades to count (default \"all\"); \"regular\" leaves out\nnegotiated block trades.",
|
|
"enum": [
|
|
"all",
|
|
"regular",
|
|
"cash",
|
|
"negotiated"
|
|
],
|
|
"type": "string"
|
|
},
|
|
"date": {
|
|
"default": null,
|
|
"description": "One session, YYYY-MM-DD. Omit date, from and to for the latest session with trades.",
|
|
"type": [
|
|
"string",
|
|
"null"
|
|
]
|
|
},
|
|
"from": {
|
|
"default": null,
|
|
"description": "First session of a range, YYYY-MM-DD (at most 366 days).",
|
|
"type": [
|
|
"string",
|
|
"null"
|
|
]
|
|
},
|
|
"investor": {
|
|
"default": null,
|
|
"description": "Whose trades to count, by investor domicile (default \"all\").",
|
|
"enum": [
|
|
"all",
|
|
"foreign",
|
|
"domestic"
|
|
],
|
|
"type": "string"
|
|
},
|
|
"symbols": {
|
|
"description": "IDX tickers, e.g. [\"BBCA\", \"BBRI\"]; the `.JK` suffix is optional. At most 20.",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"type": "array"
|
|
},
|
|
"to": {
|
|
"default": null,
|
|
"description": "Last session of the range, YYYY-MM-DD (default today).",
|
|
"type": [
|
|
"string",
|
|
"null"
|
|
]
|
|
},
|
|
"top": {
|
|
"default": null,
|
|
"description": "Tier behind the headline signal: 1, 3, 5 or 10 brokers per side (default 5).",
|
|
"enum": [
|
|
1,
|
|
3,
|
|
5,
|
|
10
|
|
],
|
|
"type": "integer"
|
|
}
|
|
},
|
|
"required": [
|
|
"symbols"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"name": "analyze_bandar"
|
|
},
|
|
{
|
|
"description": "Analyze one IDX ticker: technical signals (trend, RSI, MACD, moving averages) and fundamental growth, valuation, and risk ratings. Analyses that fail are listed under `errors`; the call fails only if every analysis fails.",
|
|
"inputSchema": {
|
|
"$defs": {
|
|
"AnalysisKind": {
|
|
"enum": [
|
|
"technical",
|
|
"growth",
|
|
"valuation",
|
|
"risk"
|
|
],
|
|
"type": "string"
|
|
}
|
|
},
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"properties": {
|
|
"kinds": {
|
|
"description": "Analyses to run (default: all).",
|
|
"items": {
|
|
"$ref": "#/$defs/AnalysisKind"
|
|
},
|
|
"type": [
|
|
"array",
|
|
"null"
|
|
]
|
|
},
|
|
"symbol": {
|
|
"description": "IDX ticker, e.g. \"BBCA\".",
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": [
|
|
"symbol"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"name": "analyze_stock"
|
|
},
|
|
{
|
|
"description": "Compare fundamental reports (growth, valuation, risk) across IDX tickers. Tickers that fail are listed under `failures`.",
|
|
"inputSchema": {
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"properties": {
|
|
"symbols": {
|
|
"description": "IDX tickers, e.g. [\"BBCA\", \"BBRI\"]; the `.JK` suffix is optional. At most 20.",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"type": "array"
|
|
}
|
|
},
|
|
"required": [
|
|
"symbols"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"name": "compare_stocks"
|
|
},
|
|
{
|
|
"description": "Broker summary for one IDX ticker: the top 10 buyers and top 10 sellers by lots over a session or date range, each with lots (1 lot = 100 shares), value and average price in IDR, plus totals. Buyers and sellers are ranked separately and gross, so a broker can appear on both sides. End of day only (IDX hides broker codes during trading); `kind` is the broker's own status (local, foreign, state_owned), not its clients'. With `investor` foreign or domestic, each row is that broker's foreign or domestic clients' trades, `total_value` is null, and `buy_value`/`sell_value` give what that side bought and sold (`sell_value` needs `board` all). `rounded` = true means figures of a million and more carry one decimal of precision.",
|
|
"inputSchema": {
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"properties": {
|
|
"board": {
|
|
"default": null,
|
|
"description": "Which board's trades to count (default \"all\"); \"regular\" leaves out\nnegotiated block trades.",
|
|
"enum": [
|
|
"all",
|
|
"regular",
|
|
"cash",
|
|
"negotiated"
|
|
],
|
|
"type": "string"
|
|
},
|
|
"date": {
|
|
"default": null,
|
|
"description": "One session, YYYY-MM-DD. Omit date, from and to for the latest session with trades.",
|
|
"type": [
|
|
"string",
|
|
"null"
|
|
]
|
|
},
|
|
"from": {
|
|
"default": null,
|
|
"description": "First session of a range, YYYY-MM-DD (at most 366 days).",
|
|
"type": [
|
|
"string",
|
|
"null"
|
|
]
|
|
},
|
|
"investor": {
|
|
"default": null,
|
|
"description": "Whose trades to count, by investor domicile (default \"all\").",
|
|
"enum": [
|
|
"all",
|
|
"foreign",
|
|
"domestic"
|
|
],
|
|
"type": "string"
|
|
},
|
|
"symbol": {
|
|
"description": "IDX ticker, e.g. \"BBCA\".",
|
|
"type": "string"
|
|
},
|
|
"to": {
|
|
"default": null,
|
|
"description": "Last session of the range, YYYY-MM-DD (default today).",
|
|
"type": [
|
|
"string",
|
|
"null"
|
|
]
|
|
}
|
|
},
|
|
"required": [
|
|
"symbol"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"name": "get_broker_summary"
|
|
},
|
|
{
|
|
"description": "Company data for one IDX ticker: profile, financial statements, earnings, analyst sentiment, insights, and news. News items carry `relevance`: `company` (about this ticker) first, then `market` (general market news). Sections that fail are listed under `errors`; the call fails only if every section fails.",
|
|
"inputSchema": {
|
|
"$defs": {
|
|
"CompanySection": {
|
|
"enum": [
|
|
"profile",
|
|
"financials",
|
|
"earnings",
|
|
"sentiment",
|
|
"insights",
|
|
"news"
|
|
],
|
|
"type": "string"
|
|
}
|
|
},
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"properties": {
|
|
"sections": {
|
|
"description": "Sections to fetch (default: all).",
|
|
"items": {
|
|
"$ref": "#/$defs/CompanySection"
|
|
},
|
|
"type": [
|
|
"array",
|
|
"null"
|
|
]
|
|
},
|
|
"symbol": {
|
|
"description": "IDX ticker, e.g. \"BBCA\".",
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": [
|
|
"symbol"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"name": "get_company"
|
|
},
|
|
{
|
|
"description": "Foreign investors' buying and selling of one IDX ticker, session by session (oldest first), with range totals; end of day. With `source` \"ipot\" (default): `foreign_buy_value`, `foreign_sell_value` and `foreign_net_value` in IDR across all boards, `value` traded, and `foreign_share_bps` (foreign share of trading); share counts, close and `non_regular_bps` are null, and `rounded` = true means one decimal of precision. With \"idx\": exact foreign share counts on the regular board, values estimated at the session's average price, the close, `change_bps` and `non_regular_bps`.",
|
|
"inputSchema": {
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"properties": {
|
|
"days": {
|
|
"default": null,
|
|
"description": "Latest sessions (default 10, at most 60). Omit when giving from/to.",
|
|
"format": "uint",
|
|
"minimum": 0,
|
|
"type": [
|
|
"integer",
|
|
"null"
|
|
]
|
|
},
|
|
"from": {
|
|
"default": null,
|
|
"description": "First session of a range, YYYY-MM-DD (at most 92 days).",
|
|
"type": [
|
|
"string",
|
|
"null"
|
|
]
|
|
},
|
|
"source": {
|
|
"default": null,
|
|
"description": "Where the figures come from (default \"ipot\"): \"ipot\" gives foreign buy, sell and net\nvalue across all boards; \"idx\" gives exact share counts, the close and the non-regular\nshare, but needs curl-impersonate and may be blocked (HTTP 403).",
|
|
"enum": [
|
|
"ipot",
|
|
"idx"
|
|
],
|
|
"type": "string"
|
|
},
|
|
"symbol": {
|
|
"description": "IDX ticker, e.g. \"BBCA\".",
|
|
"type": "string"
|
|
},
|
|
"to": {
|
|
"default": null,
|
|
"description": "Last session of the range, YYYY-MM-DD (default today).",
|
|
"type": [
|
|
"string",
|
|
"null"
|
|
]
|
|
}
|
|
},
|
|
"required": [
|
|
"symbol"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"name": "get_foreign_flow"
|
|
},
|
|
{
|
|
"description": "Today's session of one IDX stock or index from Stockbit's public page (no login), whichever provider the server uses: `quote` (price, change, volume, `market_status`, `bid`/`offer` only while the market is open, `session_note`) and `points`, the price per minute in WIB, oldest first. Delayed at least 10 minutes; no per-minute volume. Empty `points` means the stock did not trade this session (see `session_note`), not an error. UPSTREAMBLOCKED means stockbit.com refused this machine (HTTP 403): do not retry at once.",
|
|
"inputSchema": {
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"properties": {
|
|
"symbol": {
|
|
"description": "IDX ticker, e.g. \"BBCA\"; indices as \"^JKSE\" or \"IHSG\".",
|
|
"type": "string"
|
|
},
|
|
"tail": {
|
|
"default": null,
|
|
"description": "Only the latest N minutes (default: the whole session, at most 400).",
|
|
"format": "uint",
|
|
"minimum": 0,
|
|
"type": [
|
|
"integer",
|
|
"null"
|
|
]
|
|
}
|
|
},
|
|
"required": [
|
|
"symbol"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"name": "get_intraday"
|
|
},
|
|
{
|
|
"description": "Every IDX holding (above 1%) of one investor, matched by name.",
|
|
"inputSchema": {
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"properties": {
|
|
"entity": {
|
|
"description": "Investor name or part of it, e.g. \"DWIMURIA\"; the closest match is used.",
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": [
|
|
"entity"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"name": "get_investor_holdings"
|
|
},
|
|
{
|
|
"description": "Order book of one IDX stock from the user's own Stockbit session: `bids` and `offers` (best price first) of {price, shares, orders}, the session's OHLC, volume (shares), value and frequency, and foreign buy/sell/net in IDR. `market_status` is Stockbit's state, verbatim; outside STATE_NAME_MARKET_OPEN the book is as the market left it. AUTHERROR means there is no session: call stockbit_status, then stockbit_login for a URL the user can open.",
|
|
"inputSchema": {
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"properties": {
|
|
"depth": {
|
|
"default": null,
|
|
"description": "Price levels per side (default 10, at most 50).",
|
|
"format": "uint",
|
|
"minimum": 0,
|
|
"type": [
|
|
"integer",
|
|
"null"
|
|
]
|
|
},
|
|
"symbol": {
|
|
"description": "IDX ticker, e.g. \"BBCA\".",
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": [
|
|
"symbol"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"name": "get_orderbook"
|
|
},
|
|
{
|
|
"description": "Holder changes (new, exited, increased, decreased) between two KSEI release dates, optionally for one ticker. Rows come largest change first, one page at a time: `summary` covers all of them (counts by type, tickers with the most changes), and `next_offset` is the `offset` for the next page, or null after the last.",
|
|
"inputSchema": {
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"properties": {
|
|
"from": {
|
|
"description": "Earlier release date, YYYY-MM-DD (see ownership_status).",
|
|
"type": "string"
|
|
},
|
|
"limit": {
|
|
"default": null,
|
|
"description": "Rows per page (default 200, at most 300); `total` reports the full count.",
|
|
"format": "uint",
|
|
"minimum": 0,
|
|
"type": [
|
|
"integer",
|
|
"null"
|
|
]
|
|
},
|
|
"offset": {
|
|
"default": null,
|
|
"description": "Rows to skip, for the next page: the previous response's `next_offset`.",
|
|
"format": "uint",
|
|
"minimum": 0,
|
|
"type": [
|
|
"integer",
|
|
"null"
|
|
]
|
|
},
|
|
"ticker": {
|
|
"default": null,
|
|
"description": "Only this ticker's changes.",
|
|
"type": [
|
|
"string",
|
|
"null"
|
|
]
|
|
},
|
|
"to": {
|
|
"description": "Later release date, YYYY-MM-DD.",
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": [
|
|
"from",
|
|
"to"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"name": "get_ownership_changes"
|
|
},
|
|
{
|
|
"description": "OHLCV price history for one IDX ticker.",
|
|
"inputSchema": {
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"properties": {
|
|
"interval": {
|
|
"default": null,
|
|
"description": "Candle size (default \"1d\").",
|
|
"enum": [
|
|
"1d",
|
|
"1wk",
|
|
"1mo"
|
|
],
|
|
"type": "string"
|
|
},
|
|
"period": {
|
|
"default": null,
|
|
"description": "Lookback window (default \"3mo\").",
|
|
"enum": [
|
|
"1d",
|
|
"5d",
|
|
"1mo",
|
|
"3mo",
|
|
"6mo",
|
|
"1y",
|
|
"2y",
|
|
"5y"
|
|
],
|
|
"type": "string"
|
|
},
|
|
"symbol": {
|
|
"description": "IDX ticker, e.g. \"BBCA\".",
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": [
|
|
"symbol"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"name": "get_price_history"
|
|
},
|
|
{
|
|
"description": "Latest quotes (price, change, volume, 52-week range, market cap) for one or more IDX tickers. `as_of` is the last trade in WIB; `behind_session` is true when that is before the latest IDX session, so the price is not that session's close: the provider lags, the stock did not trade, or the day was an exchange holiday. When the server runs with the stockbit provider, quotes also carry `market_status` (Stockbit's, e.g. \"open\", \"close\"), `bid`/`offer` (best price, only while the market is open) and `session_note` (suspended, delisted, no trades); Stockbit data is delayed at least 10 minutes.",
|
|
"inputSchema": {
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"properties": {
|
|
"symbols": {
|
|
"description": "IDX tickers, e.g. [\"BBCA\", \"BBRI\"]; the `.JK` suffix is optional. At most 20.",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"type": "array"
|
|
}
|
|
},
|
|
"required": [
|
|
"symbols"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"name": "get_quotes"
|
|
},
|
|
{
|
|
"description": "Shareholders above 1% of an IDX ticker from the latest KSEI release, with concentration metrics (top1, top3, HHI, free float).",
|
|
"inputSchema": {
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"properties": {
|
|
"ticker": {
|
|
"description": "IDX ticker, e.g. \"BBCA\".",
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": [
|
|
"ticker"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"name": "get_shareholders"
|
|
},
|
|
{
|
|
"description": "Ownership database status: whether it has data, and the imported KSEI release dates.",
|
|
"inputSchema": {
|
|
"properties": {},
|
|
"type": "object"
|
|
},
|
|
"name": "ownership_status"
|
|
},
|
|
{
|
|
"description": "Download or refresh the KSEI ownership snapshot (several MB) into the local database.",
|
|
"inputSchema": {
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"properties": {
|
|
"force": {
|
|
"default": false,
|
|
"description": "Re-download even when the local snapshot is current.",
|
|
"type": "boolean"
|
|
}
|
|
},
|
|
"type": "object"
|
|
},
|
|
"name": "ownership_sync"
|
|
},
|
|
{
|
|
"description": "Run a stock screen (top/worst performers, high dividend, low P/E, 52-week highs/lows, high volume, large cap). Rows carry `as_of` and, for the IDX region, `behind_session` as in get_quotes.",
|
|
"inputSchema": {
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"properties": {
|
|
"filter": {
|
|
"default": null,
|
|
"description": "Screen to run (default \"top-performers\").",
|
|
"enum": [
|
|
"top-performers",
|
|
"worst-performers",
|
|
"high-dividend",
|
|
"low-pe",
|
|
"52w-high",
|
|
"52w-low",
|
|
"high-volume",
|
|
"large-cap"
|
|
],
|
|
"type": "string"
|
|
},
|
|
"limit": {
|
|
"default": null,
|
|
"description": "Maximum results (default 50, at most 200).",
|
|
"format": "uint",
|
|
"minimum": 0,
|
|
"type": [
|
|
"integer",
|
|
"null"
|
|
]
|
|
},
|
|
"region": {
|
|
"default": null,
|
|
"description": "Market region (default \"id\").",
|
|
"enum": [
|
|
"id",
|
|
"us",
|
|
"sg",
|
|
"hk",
|
|
"jp"
|
|
],
|
|
"type": "string"
|
|
}
|
|
},
|
|
"type": "object"
|
|
},
|
|
"name": "screen_stocks"
|
|
},
|
|
{
|
|
"description": "Search investor names in the KSEI ownership database.",
|
|
"inputSchema": {
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"properties": {
|
|
"limit": {
|
|
"default": null,
|
|
"description": "Maximum results (default 20, at most 100).",
|
|
"format": "uint",
|
|
"minimum": 0,
|
|
"type": [
|
|
"integer",
|
|
"null"
|
|
]
|
|
},
|
|
"query": {
|
|
"description": "Full-text query over investor names.",
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": [
|
|
"query"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"name": "search_investors"
|
|
},
|
|
{
|
|
"description": "Start a Stockbit sign-in and return at once; this call does not wait for it. With method auto (the default), idx-mcp opens a browser window on Stockbit's own sign-in page when its machine has a display and is not reached over SSH (`method: \"browser\"` in the answer): the user signs in there and the window closes by itself. Otherwise it serves a page on 127.0.0.1 (`method: \"page\"`, with `url` and an `ssh -L` `forward` for a browser on another machine) that takes stockbit.com's session cookie from the user's own browser. Never ask the user for their password, and never type it. Then poll stockbit_status until `sign_in.state` is signed_in or failed. A session that already works answers state signed_in without opening anything; a second call while one is waiting returns it again (`already_open`).",
|
|
"inputSchema": {
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"properties": {
|
|
"method": {
|
|
"description": "\"auto\" (default): a browser window when idx-mcp's machine has a display and no SSH, else the local page; \"browser\" or \"page\" picks one.",
|
|
"enum": [
|
|
"auto",
|
|
"browser",
|
|
"page"
|
|
],
|
|
"type": "string"
|
|
}
|
|
},
|
|
"type": "object"
|
|
},
|
|
"name": "stockbit_login"
|
|
},
|
|
{
|
|
"description": "Whether a Stockbit session is stored (or seeded by IDX_STOCKBIT_REFRESH_TOKEN) and when its tokens expire; never the tokens. Without one, get_orderbook fails and stockbit-provider quotes use Stockbit's delayed public page; the user adds one with stockbit_login, or `idx stockbit login` in a terminal. After stockbit_login, `sign_in.state` says whether that sign-in is waiting, signed_in or failed (with `sign_in.error`).",
|
|
"inputSchema": {
|
|
"properties": {},
|
|
"type": "object"
|
|
},
|
|
"name": "stockbit_status"
|
|
}
|
|
]
|