tossinvest-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| HOST | No | Bind address for HTTP transport. | 0.0.0.0 |
| PORT | No | HTTP port when TRANSPORT=http. | 3000 |
| TRANSPORT | No | Transport mode: 'stdio' or 'http'. | stdio |
| MCP_AUTH_TOKEN | No | Bearer token clients must present for HTTP transport. Minimum 16 chars. Required when TRANSPORT=http and MCP_ALLOW_ANONYMOUS is not 'true'. | |
| MCP_ALLOW_ANONYMOUS | No | Set to 'true' to disable authentication for HTTP transport. | false |
| TOSSINVEST_CLIENT_ID | No | TOSS Securities Open API client id. | |
| TOSSINVEST_READ_ONLY | No | Set to 'true' to omit all order-mutating tools. | false |
| TOSSINVEST_ACCOUNT_SEQ | No | Default accountSeq for account-scoped tools. | |
| TOSSINVEST_ACCESS_TOKEN | No | Pre-issued access token; bypasses the client-credentials flow. | |
| TOSSINVEST_CLIENT_SECRET | No | TOSS Securities Open API client secret. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| tossinvest_get_pricesA | Get the latest traded price for one or more Korean (KRX) or US stocks. This is the cheapest way to answer "what is X trading at". Up to 200 symbols in one call, so batch rather than looping. Args:
Returns { count, prices: [{ symbol, lastPrice, currency, timestamp }] }. lastPrice is a decimal string in the symbol's own currency (KRW for KRX, USD for US). timestamp is null when the symbol has not traded yet today. Examples:
Errors: 404 stock-not-found when a symbol does not exist. |
| tossinvest_get_orderbookA | Get the current bid/ask ladder (호가) for one stock. Use this to judge liquidity and spread before choosing a limit price. For the single last-traded price use tossinvest_get_prices instead — it is cheaper and supports batching. Args:
Returns { symbol, currency, timestamp, asks: [{ price, volume }], bids: [{ price, volume }] }. asks are ascending by price (best ask first), bids descending (best bid first). Both arrays may be empty outside trading hours. Errors: 404 stock-not-found for unknown symbols. |
| tossinvest_get_tradesA | Get today's most recent executed trades (체결 내역) for one stock, newest first. Useful for gauging very recent momentum and actual traded sizes. Only covers the current session — it is not a historical trade archive. Args:
Returns { symbol, count, trades: [{ price, volume, timestamp, currency }] }. Returns an empty list before the session's first trade. Errors: 404 stock-not-found for unknown symbols. |
| tossinvest_get_price_limitsA | Get today's upper and lower price limits (상한가/하한가) for one stock. Check this before placing a limit order: a price outside the band is rejected with 422 price-out-of-range. Args:
Returns { symbol, currency, timestamp, upperLimitPrice, lowerLimitPrice }. Limits are decimal strings; either can be null for markets without a daily band (US stocks generally have none). Errors: 404 stock-not-found for unknown symbols. |
| tossinvest_get_candlesA | Get OHLCV candles for one stock, newest bar first. Max 200 bars per call. This is the tool for historical price analysis: trends, ranges, moving averages, "how did X do last month". Args:
Returns { symbol, interval, count, candles: [{ timestamp, openPrice, highPrice, lowPrice, closePrice, volume, currency }], nextBefore }. timestamp is the bar's OPEN time. nextBefore is null when no older data exists. Examples:
|
| tossinvest_get_stocksA | Get reference/master data for one or more symbols: names, listing market, security type, currency, listing status and shares outstanding. Use this to resolve what a symbol actually is, to check a symbol is still listed and tradable before ordering, or to get the shares-outstanding figure needed for a market-cap calculation (market cap = lastPrice x sharesOutstanding). Args:
Returns { count, stocks: [{ symbol, name, englishName, isinCode, market, securityType, isCommonShare, status, currency, listDate, delistDate, sharesOutstanding, leverageFactor, koreanMarketDetail }] }.
This does NOT search by company name — it takes symbols only. It also returns no prices; use tossinvest_get_prices for those. Errors: 404 stock-not-found when a symbol does not exist. |
| tossinvest_get_stock_warningsA | Get the currently active trading warnings and volatility-interruption (VI) flags for one symbol. Check this before buying anything unfamiliar — these flags mark designations that restrict or endanger trading. Args:
Returns { symbol, count, warnings: [{ warningType, exchange, startDate, endDate }] }, sorted by startDate descending. warningType values:
An existing symbol with no active warnings returns count 0 and an empty list — that is a clean result, not an error. VI flags update within seconds; exchange designations update on a daily batch. Errors: 404 stock-not-found when the symbol does not exist. |
| tossinvest_get_exchange_rateA | Get the KRW <-> USD exchange rate, refreshed once a minute. Use this to convert between the KRW and USD figures that holdings and orders report separately. Args:
Returns { baseCurrency, quoteCurrency, rate, midRate, basisPoint, rateChangeType, validFrom, validUntil }. rateChangeType is UP, EQUAL or DOWN. validFrom/validUntil bound the ~1-minute window this quote applies to. This is an indicative display rate — the rate actually applied when an order settles can differ. Errors: 404 exchange-rate-not-found when no rate exists for the requested instant. |
| tossinvest_get_market_calendarA | Get trading-session hours for the Korean or US market across three business days: previous, current and next. Use this to answer "is the market open?", "when does it open?", or to explain an order-hours-closed rejection. All times are ISO 8601 in KST (+09:00) for BOTH markets — US session times are already converted to Korean time. Args:
Returns { country, previousBusinessDay, today, nextBusinessDay }, each { date, ...sessions }.
Errors: none specific; an invalid date format returns 400 invalid-request. |
| tossinvest_get_rankingsA | Get a top-100 stock leaderboard by traded value, traded volume, or price change, for the Korean or US market over a chosen period. This is the discovery tool: "what is moving today", "most actively traded Korean stocks this week", "biggest losers this month". Args:
Returns { type, marketCountry, duration, count, rankedAt, rankings: [{ rank, symbol, currency, price: { lastPrice, basePrice, changeRate }, tradingVolume, tradingAmount }] }. Reading the numbers correctly:
Symbols come back without names; pass them to tossinvest_get_stocks to resolve company names. Errors: 400 unsupported-ranking-duration for TOP_GAINERS/TOP_LOSERS with duration='realtime'. |
| tossinvest_get_market_indicator_pricesA | Get the current level of Korean market indices and treasury yields. Supported symbols (this catalog and nothing else):
Args:
Returns { count, prices: [{ symbol, lastPrice, timestamp }] }. For individual stocks use tossinvest_get_prices — this endpoint rejects stock symbols. Errors: 400 unsupported-symbol for anything outside the catalog. |
| tossinvest_get_market_indicator_candlesA | Get OHLCV history for a Korean index or treasury yield, newest bar first. Max 200 bars per call. Args:
Returns { symbol, interval, count, candles: [{ timestamp, openPrice, highPrice, lowPrice, closePrice, volume }], nextBefore }. For KR_BOND_* the OHLC values are yields in percent, not prices. Errors: 400 unsupported-symbol outside the catalog; 400 invalid-request for '1m' on a bond symbol. |
| tossinvest_get_investor_tradingA | Get KRX buy/sell value broken down by investor type for KOSPI or KOSDAQ, newest period first. This answers "are foreigners buying or selling?" — the classic Korean-market flow question. Net flow = buyAmount - sellAmount. Args:
Returns { symbol, interval, count, records: [{ date, updatedAt, individual, foreigner, institution, otherCorporation }], nextUntil }. Each investor entry is { buyAmount, sellAmount }; institution additionally carries a 'breakdown' with seven sub-categories (financialInvestment, insurance, trust, privateEquityFund, bank, otherFinancialInstitution, pensionFund) that sum to the institution totals. All amounts are KRW integers as strings — there is no currency field. 'foreigner' is the total across registered and unregistered foreign investors. Buy totals across the four categories equal sell totals market-wide. The current day's record is provisional until the close; check updatedAt. Errors: 400 unsupported-symbol for anything other than KOSPI/KOSDAQ. |
| tossinvest_list_accountsA | List the Toss Securities accounts reachable with the configured credentials. Call this first when you do not know which account to act on. The 'accountSeq' in the response is what every account-scoped tool takes as 'account_seq'. Args:
Returns { count, accounts: [{ accountNo, accountSeq, accountType }] }. Only BROKERAGE (종합매매) accounts are exposed today; child accounts are not usable. An empty list means the credentials have no brokerage account. When exactly one account exists, other tools resolve it automatically, so you rarely need to pass account_seq by hand. Rate limit: the ACCOUNT group allows only 1 request per second. |
| tossinvest_get_holdingsA | Get the account's stock holdings with per-symbol detail and aggregate valuation. This is the portfolio tool: what is owned, at what average cost, worth how much, up or down how much. Args:
Returns { accountSeq, count, totalPurchaseAmount, marketValue, profitLoss, dailyProfitLoss, items }.
Covers KR and US stocks only — overseas derivatives and bonds are excluded. No holdings gives zeroed totals and an empty item list. |
| tossinvest_get_buying_powerA | Get how much cash is available to buy with, in KRW or USD. Check this before placing a buy order — an order beyond it fails with 422 insufficient-buying-power. Args:
Returns { accountSeq, currency, cashBuyingPower }. cashBuyingPower is cash-settled buying power only — margin (미수) is excluded, so this is the amount that can be spent without incurring a margin position. |
| tossinvest_get_sellable_quantityA | Get how many shares of one symbol can be sold right now. This can be lower than the holding quantity — shares tied up in an open sell order or not yet settled are excluded. Check it before selling; exceeding it fails with 422 insufficient-sellable-quantity. Args:
Returns { accountSeq, symbol, sellableQuantity }. KR quantities are whole shares; US quantities can be fractional. |
| tossinvest_get_commissionsA | Get the account's trading commission rates for the Korean and US markets. Use this to estimate trading costs before ordering, or to explain the gap between gross and after-cost profit in holdings. Args:
Returns { accountSeq, count, commissions: [{ marketCountry, commissionRate, startDate, endDate }] }. commissionRate is a PERCENT: '0.015' means 0.015% of notional, i.e. multiply notional by 0.00015. startDate/endDate bound a promotional rate; both are null for US, and endDate is null for an open-ended rate. |
| tossinvest_list_ordersA | List the account's orders, filtered by lifecycle group. Args:
Paging differs by status: OPEN returns every working order in one shot and ignores cursor/limit (nextCursor is always null, hasNext always false); CLOSED honours cursor and limit. Returns { accountSeq, status, count, orders: [...], nextCursor, hasNext }. Each order carries an 'execution' object: { filledQuantity, averageFilledPrice, filledAmount, commission, tax, filledAt, settlementDate }. filledQuantity is 0 when nothing has filled — check it on CANCELED and REJECTED orders too, since those can be partially filled. Note the two status vocabularies: the 'status' argument is a GROUP label, while 'orders[].status' is the individual order state. |
| tossinvest_get_orderA | Get the full detail of one order by id, in any state. Use this to confirm what happened after placing, modifying or cancelling — especially to read the fill result. Args:
Returns { accountSeq, order: { orderId, symbol, side, orderType, timeInForce, status, price, quantity, orderAmount, currency, orderedAt, canceledAt, execution } }. execution = { filledQuantity, averageFilledPrice, filledAmount, commission, tax, filledAt, settlementDate }. Errors: 404 order-not-found for an unknown id. |
| tossinvest_create_orderA | Place a REAL buy or sell order for a Korean or US stock. This spends or liquidates actual money — confirm the symbol, side, quantity and price with the user before calling. Args:
Supply exactly one of quantity or order_amount. Returns { accountSeq, orderId, operation: 'created' }. The response confirms acceptance, NOT execution — call tossinvest_get_order with the returned orderId to see the fill. Before ordering it is worth checking tossinvest_get_buying_power (buys), tossinvest_get_sellable_quantity (sells) and tossinvest_get_price_limits (limit prices). Errors: 422 insufficient-buying-power, 422 order-hours-closed, 422 price-out-of-range, 422 opposite-pending-order-exists, 400 confirm-high-value-required, 400 invalid-request with the correct tick size in 'data'. |
| tossinvest_modify_orderA | Change the price (and, for Korean stocks, the quantity) of a working order. This alters a REAL order — confirm the new terms with the user first. Args:
Returns { accountSeq, orderId, operation: 'modified' }. Errors: 409 already-filled / already-canceled / already-modified / already-processing, 422 modify-restricted, 404 order-not-found. |
| tossinvest_cancel_orderA | Cancel a working order. This cancels a REAL order — confirm with the user first. Args:
Returns { accountSeq, orderId, operation: 'canceled' }. A partially filled order can still be cancelled — the unfilled remainder is withdrawn and the filled part stands. Read execution.filledQuantity on the order afterwards to see what actually traded. Errors: 409 already-filled (nothing left to cancel), 409 already-canceled, 409 already-processing, 422 cancel-restricted, 404 order-not-found. |
| tossinvest_list_conditional_ordersA | List the account's conditional (price-triggered) orders. This returns conditional orders from every channel, including ones set up in the Toss Securities app — not just those created through this API. Args:
Returns { accountSeq, status, count, conditionalOrders: [{ conditionalOrderId, type, status, symbol, market, quantity, orderType, expireDate, createdAt, first, second }], nextCursor, hasNext }. type is SINGLE, OCO or OTO; there is no server-side type filter, so filter on this field yourself. Each condition leg carries { type, status, triggerPrice, targetProfitRate, orderPrice, triggeredOrderId }; triggeredOrderId links to the real order created on trigger, which you can then read with tossinvest_get_order. |
| tossinvest_get_conditional_orderA | Get the full detail of one conditional order by id, active or finished. Args:
Returns { accountSeq, conditionalOrder: { conditionalOrderId, type, status, symbol, market, quantity, orderType, expireDate, createdAt, first, second } }. Each leg has { type, status, triggerPrice, targetProfitRate, orderPrice, triggeredOrderId }. Leg status values: WATCHING, HOLDING, PAUSED, ORDERING, ORDERED, COMPLETED, EXPIRED, CANCELED. Errors: 404 conditional-order-not-found — note that modifying a conditional order issues a NEW id and voids the old one, so always use the most recently returned id. |
| tossinvest_create_conditional_orderA | Register a REAL price-triggered order: watch a symbol and automatically place a buy or sell when the price reaches a trigger. Confirm every parameter with the user first. Types:
Args:
Returns { accountSeq, conditionalOrderId, clientOrderId, operation: 'created' }. Errors: 422 condition-already-met when the trigger price has already been reached (pick another price), 422 duplicate-conditional-order, 400 invalid-request for a bad leg combination. |
| tossinvest_modify_conditional_orderA | Replace an existing conditional order's settings. This changes a REAL standing order — confirm with the user first. IMPORTANT: modification works by cancelling and recreating, so a NEW conditionalOrderId is issued and the old one stops working. Use the id from this response for every later read, modify or cancel. The whole conditional order is re-specified, so pass every leg you want to keep — anything omitted is dropped. The symbol cannot change (it is fixed by the id), and switching type (e.g. SINGLE to OCO) is allowed. Args:
Returns { accountSeq, conditionalOrderId, operation: 'modified' } — with the NEW id. Errors: 404 conditional-order-not-found, 422 condition-already-met. |
| tossinvest_cancel_conditional_orderA | Cancel a standing conditional order so it stops watching the price. This cancels a REAL standing order — confirm with the user first. Args:
Returns { accountSeq, conditionalOrderId, operation: 'canceled' }. This only removes the watcher. Any real order already placed by a fired condition is untouched — cancel that separately with tossinvest_cancel_order. Errors: 404 conditional-order-not-found. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 28 tools
Every tool has a clearly distinct purpose: get_prices vs get_orderbook vs get_trades vs get_candles all target different data facets, and order management tools are cleanly separated from conditional order tools. No two tools overlap in function, so an agent can confidently select the right one.
All tools follow a consistent verb_noun pattern with snake_case, prefixed by tossinvest_. Get_/list_ for retrieval, create_/modify_/cancel_ for mutations, and the noun clearly indicates the resource (orders, holdings, prices, etc.). This is a model of consistent naming.
At 28 tools, the count exceeds the typical well-scoped range (3-15) and pushes into the heavy category. However, the domain is a comprehensive trading platform covering two markets, market data, orders, conditional orders, and account management, so each tool serves a distinct need. It's on the upper edge but not unreasonable.
The tool surface is remarkably complete: full CRUD for orders and conditional orders, comprehensive market data (prices, candles, orderbook, trades, limits, indicators, rankings, investor flow), account management (holdings, buying power, sellable quantity, commissions), plus reference data, warnings, exchange rates, and calendar. No significant dead ends or missing lifecycle operations.