Skip to main content
Glama
migusdn

KIS REST API MCP Server

inquery-balance

Retrieve current stock balance information from Korea Investment & Securities to monitor portfolio holdings and account status.

Instructions

Get current stock balance information from Korea Investment & Securities

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • server.py:298-301 (registration)
    The @mcp.tool decorator registers the 'inquery-balance' tool with the FastMCP server, specifying its name and description.
    @mcp.tool(
        name="inquery-balance",
        description="Get current stock balance information from Korea Investment & Securities",
    )
  • The main handler function for the 'inquery-balance' tool. It fetches an access token, prepares the request data for the KIS balance inquiry API, makes a GET request to the balance endpoint, and returns the JSON response.
    async def inquery_balance():
        """
        Get current stock balance information from Korea Investment & Securities
        
        Returns:
            Dictionary containing stock balance information including:
            - pdno: Stock code
            - prdt_name: Stock name
            - hldg_qty: Holding quantity
            - pchs_amt: Purchase amount
            - prpr: Current price
            - evlu_amt: Evaluation amount
            - evlu_pfls_amt: Evaluation profit/loss amount
            - evlu_pfls_rt: Evaluation profit/loss rate
        """
        async with httpx.AsyncClient() as client:
            token = await get_access_token(client)
            logger.info(f"TrIdManager.get_tr_id('balance'): {TrIdManager.get_tr_id('balance')}")
            # Prepare request data
            request_data = {
                "CANO": os.environ["KIS_CANO"],  # 계좌번호
                "ACNT_PRDT_CD": "01",  # 계좌상품코드 (기본값: 01)
                "AFHR_FLPR_YN": "N",  # 시간외단일가여부
                "INQR_DVSN": "01",  # 조회구분
                "UNPR_DVSN": "01",  # 단가구분
                "FUND_STTL_ICLD_YN": "N",  # 펀드결제분포함여부
                "FNCG_AMT_AUTO_RDPT_YN": "N",  # 융자금액자동상환여부
                "PRCS_DVSN": "00",  # 처리구분
                "CTX_AREA_FK100": "",  # 연속조회검색조건100
                "CTX_AREA_NK100": "",  # 연속조회키100
                "OFL_YN": ""  # 오프라인여부
            }
            response = await client.get(
                f"{TrIdManager.get_domain('balance')}{BALANCE_PATH}",
                headers={
                    "content-type": CONTENT_TYPE,
                    "authorization": f"{AUTH_TYPE} {token}",
                    "appkey": os.environ["KIS_APP_KEY"],
                    "appsecret": os.environ["KIS_APP_SECRET"],
                    "tr_id": TrIdManager.get_tr_id("balance")
                },
                params=request_data
            )
            
            if response.status_code != 200:
                raise Exception(f"Failed to get balance: {response.text}")
            
            return response.json()
  • Constant defining the API path for the domestic stock balance inquiry endpoint used by the inquery-balance tool.
    BALANCE_PATH = "/uapi/domestic-stock/v1/trading/inquire-balance"  # 잔고조회
  • TrIdManager class provides the transaction IDs ('TTTC8434R' for real, 'VTTC8434R' for virtual) and domain selection logic used by the inquery-balance handler for API requests.
    class TrIdManager:
        """Transaction ID manager for Korea Investment & Securities API"""
        
        # 실전계좌용 TR_ID
        REAL = {
            # 국내주식
            "balance": "TTTC8434R",  # 잔고조회
            "price": "FHKST01010100",  # 현재가조회
            "buy": "TTTC0802U",  # 주식매수
            "sell": "TTTC0801U",  # 주식매도
            "order_list": "TTTC8001R",  # 일별주문체결조회
            "order_detail": "TTTC8036R",  # 주문체결내역조회
            "stock_info": "FHKST01010400",  # 일별주가조회
            "stock_history": "FHKST03010200",  # 주식일별주가조회
            "stock_ask": "FHKST01010200",  # 주식호가조회
            
            # 해외주식
            "us_buy": "TTTT1002U",      # 미국 매수 주문
            "us_sell": "TTTT1006U",     # 미국 매도 주문
            "jp_buy": "TTTS0308U",      # 일본 매수 주문
            "jp_sell": "TTTS0307U",     # 일본 매도 주문
            "sh_buy": "TTTS0202U",      # 상해 매수 주문
            "sh_sell": "TTTS1005U",     # 상해 매도 주문
            "hk_buy": "TTTS1002U",      # 홍콩 매수 주문
            "hk_sell": "TTTS1001U",     # 홍콩 매도 주문
            "sz_buy": "TTTS0305U",      # 심천 매수 주문
            "sz_sell": "TTTS0304U",     # 심천 매도 주문
            "vn_buy": "TTTS0311U",      # 베트남 매수 주문
            "vn_sell": "TTTS0310U",     # 베트남 매도 주문
        }
        
        # 모의계좌용 TR_ID
        VIRTUAL = {
            # 국내주식
            "balance": "VTTC8434R",  # 잔고조회
            "price": "FHKST01010100",  # 현재가조회
            "buy": "VTTC0802U",  # 주식매수
            "sell": "VTTC0801U",  # 주식매도
            "order_list": "VTTC8001R",  # 일별주문체결조회
            "order_detail": "VTTC8036R",  # 주문체결내역조회
            "stock_info": "FHKST01010400",  # 일별주가조회
            "stock_history": "FHKST03010200",  # 주식일별주가조회
            "stock_ask": "FHKST01010200",  # 주식호가조회
            
            # 해외주식
            "us_buy": "VTTT1002U",      # 미국 매수 주문
            "us_sell": "VTTT1001U",     # 미국 매도 주문
            "jp_buy": "VTTS0308U",      # 일본 매수 주문
            "jp_sell": "VTTS0307U",     # 일본 매도 주문
            "sh_buy": "VTTS0202U",      # 상해 매수 주문
            "sh_sell": "VTTS1005U",     # 상해 매도 주문
            "hk_buy": "VTTS1002U",      # 홍콩 매수 주문
            "hk_sell": "VTTS1001U",     # 홍콩 매도 주문
            "sz_buy": "VTTS0305U",      # 심천 매수 주문
            "sz_sell": "VTTS0304U",     # 심천 매도 주문
            "vn_buy": "VTTS0311U",      # 베트남 매수 주문
            "vn_sell": "VTTS0310U",     # 베트남 매도 주문
        }
        
        @classmethod
        def get_tr_id(cls, operation: str) -> str:
            """
            Get transaction ID for the given operation
            
            Args:
                operation: Operation type ('balance', 'price', 'buy', 'sell', etc.)
                
            Returns:
                str: Transaction ID for the operation
            """
            is_real_account = os.environ.get("KIS_ACCOUNT_TYPE", "REAL").upper() == "REAL"
            tr_id_map = cls.REAL if is_real_account else cls.VIRTUAL
            return tr_id_map.get(operation)
        
        @classmethod
        def get_domain(cls, operation: str) -> str:
            """
            Get domain for the given operation
            
            Args:
                operation: Operation type ('balance', 'price', 'buy', 'sell', etc.)
                
            Returns:
                str: Domain URL for the operation
            """
            is_real_account = os.environ.get("KIS_ACCOUNT_TYPE", "REAL").upper() == "REAL"
            
            # 잔고조회는 실전/모의 계좌별로 다른 도메인 사용
            if operation == "balance":
                return DOMAIN if is_real_account else VIRTUAL_DOMAIN
                
            # 조회 API는 실전/모의 동일한 도메인 사용
            if operation in ["price", "stock_info", "stock_history", "stock_ask"]:
                return DOMAIN
                
            # 거래 API는 계좌 타입에 따라 다른 도메인 사용
            return DOMAIN if is_real_account else VIRTUAL_DOMAIN
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden but only states what the tool does, not how it behaves. It doesn't disclose whether this requires authentication, has rate limits, returns real-time vs. cached data, what format the balance information comes in, or any error conditions. The description adds no behavioral context beyond the basic purpose.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that communicates the essential purpose without any wasted words. It's appropriately sized for a simple read operation and front-loads the key information ('Get current stock balance information').

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a financial data tool with no annotations and no output schema, the description is insufficient. It doesn't explain what balance information is returned (cash balance, stock positions, margin status, etc.), the data format, whether authentication is required, or any limitations. Given the complexity of financial systems and lack of structured documentation, more context is needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters with 100% schema description coverage, so the schema already fully documents the parameter situation. The description appropriately doesn't mention parameters since none exist. A baseline of 4 is appropriate for zero-parameter tools where the schema handles documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Get') and resource ('current stock balance information') with specific context ('from Korea Investment & Securities'). It distinguishes from siblings by focusing on balance rather than orders, prices, or history. However, it doesn't explicitly differentiate from potential similar tools like account summaries.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided about when to use this tool versus alternatives. While the name suggests it's for balance inquiries (vs. order or price queries), the description doesn't mention when this specific balance tool should be used over other financial data tools or what prerequisites might exist.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/migusdn/KIS_MCP_Server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server