idx-cli/crates/idx-mcp/tests/golden/tools.json
hermes b5ae9b98de feat: Stockbit login for the order book, live quotes and daily history
Opt-in, with the user's own Stockbit session from a pasted
credentialStorage cookie (or IDX_STOCKBIT_REFRESH_TOKEN):

- idx stockbit login/status/logout; session file 0600, tokens never shown
- rotating refresh under a cross-process lock; one refresh+retry on 401
- stocks orderbook: depth with lots and orders, OHLC, value, foreign flow
- --provider stockbit quotes from the session API when logged in
- --history-provider stockbit, and auto under the stockbit provider for
  5d-1y daily windows
- MCP get_orderbook and stockbit_status (17 tools)

Endpoints, units and recorded responses from fzn0x/idx (MIT).
2026-10-23 08:35:57 +00:00

595 lines
20 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, and ask the user to run `idx stockbit login` in a terminal.",
"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": "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 `idx stockbit login` in a terminal.",
"inputSchema": {
"properties": {},
"type": "object"
},
"name": "stockbit_status"
}
]