K-invest

K-invest

English · GitHub

K-invest는 Claude나 ChatGPT 같은 AI 채팅 클라이언트가 내 증권·암호화폐 계좌에 대한 질문에 답할 수 있게 해 주는 읽기 전용 MCP 서버예요. 토스증권이나 한국투자증권(KIS) 계좌를 가진 국내 개인 투자자를 위한 것이에요. 보유 종목, 기간 수익률, 거래 내역, 실현 손익을 한곳에서 보여 줘요. 모든 숫자에는 출처와 기준 시각이 붙고, 데이터가 불완전하면 그 이유 코드도 함께 붙어요.

내 컴퓨터나 서버에서 내 API 키로 실행해요. 요청은 아래 표의 API로만 나가요.

데이터 출처

출처 접근 방식 용도
토스증권 Open API 공식, 본인 client ID·secret 계좌, 보유 종목, 예수금, 주문 내역, 시세, 캔들, 장 운영 일정, 환율
한국투자증권 Open API 공식, 본인 app key·secret 국내·해외 잔고, 예수금, 체결 내역, 시세
SEC EDGAR 공식, SEC_USER_AGENT에 연락처가 담긴 User-Agent 미국 재무제표, TTM 수치, Form 4 내부자 거래
yfinance를 통한 Yahoo Finance 비공식 재무제표와 주요 지표, 배당 일정, 미국 10년물 국채 금리, 보조 환율. 값에 yfinance 출처가 표시돼요.
바이낸스 USD-M 선물 API 공식, 읽기 전용 API 키 선물 포지션, 잔고, 체결, 펀딩비. 공개 시세는 키 없이 조회해요.
Hyperliquid info API 공식 공개 엔드포인트, 계정 주소만 필요 무기한 선물 포지션, 잔고, 체결, 펀딩비
업비트 공개 시세 공식 공개 엔드포인트 암호화폐 잔고 평가에 쓰는 USDT/USDC 원화 가격
내 파일 로컬 토스증권 PDF 거래내역서, 바이낸스 CSV 내보내기 파일 (요청할 때만 가져와요)

웹사이트를 스크래핑하거나 로그인하지 않아요. 설정하지 않은 계좌는 미설정으로 표시되고, 나머지 도구는 그대로 동작해요.

도구

채팅 클라이언트에는 도구 21개가 보여요. 서버에 등록된 도구는 68개예요. 나머지 47개는 21개 도구로 합쳐진 예전의 세분화된 도구이고, 스크립트와 로컬 서비스에서는 계속 호출할 수 있어요.

도구 반환 내용
get_status 연결 상태: 캐시된 서비스 상태, 실시간 출처 점검, 설정된 계좌, 사용 안내
get_holdings 종목별로 합친 현재 보유 종목(원 통화와 원화 기준)과 예수금
get_portfolio_summary 전체 증권 계좌 합계를 섹션별로: 합계, 노출, 집중도, 실현 손익
get_portfolio_returns 기간 수익률: 단순 수익률·TWR·XIRR 비교, 손익 분해, NAV 위험 통계
get_transactions 토스증권과 한국투자증권 전 계좌의 거래를 최신순으로, 페이지 단위로
get_trading_pnl 계좌별 이동평균 원가 기준 실현 손익, 왕복 거래, 승률
get_quote 최대 10개 종목 시세 (토스증권, 실패 시 한국투자증권)
get_candles 한 종목의 OHLCV 캔들
get_market_info 한국·미국 장 운영 시간과 휴장일, 환율, 미국 10년물 국채 금리
get_crypto_market 한 심볼의 바이낸스 USD-M 공개 시세
get_crypto_positions 암호화폐 선물 보유 포지션과 잔고 (바이낸스 USD-M, Hyperliquid)
get_crypto_account_history 내 암호화폐 선물 체결 또는 펀딩비 내역, 페이지 단위
get_stock_snapshot 한 종목의 시세, 지표, 애널리스트 컨센서스, 내부자 데이터
get_financials, get_key_metrics yfinance 재무제표와 주요 지표 (미국, 한국, 일본)
get_sec_financials, get_ttm_financials SEC 연간·분기 재무제표, TTM 수치 (미국)
get_insider_trades SEC Form 4 내부자 거래 (미국)
snapshot_portfolio_nav 로컬 쓰기. 오늘의 NAV 스냅숏을 저장해요. 평소에는 18:10 KST 타이머가 저장해요.
export_portfolio_dataset 로컬 쓰기. 검증 가능한 포트폴리오 데이터 사본을 고정하고 페이지 단위로 돌려줘요
import_statement 로컬 쓰기. 비공개 수신 폴더의 토스증권 PDF 거래내역서에서 매수·매도 행을 두 단계로 로컬 원장에 가져와요

수익률은 내가 저장한 데이터로 계산해요. 어떤 API도 알려 주지 않는 입금처럼 기록이 빠진 부분이 있으면, 이유 코드와 함께 그 사실을 밝히고 수치를 추정치로 표시해요.

구조

flowchart LR
    client["MCP 클라이언트<br/>(Claude, ChatGPT)"] -->|"Streamable HTTP /mcp<br/>Bearer 토큰 또는 OAuth 2.1"| auth
    subgraph server["server.py (127.0.0.1:8100)"]
        auth["auth<br/>정적 토큰, 선택형 OAuth 2.1 + 소유자 확인,<br/>루프백 서비스 토큰"]
        catalog["tools_v2<br/>등록 68개 중 채팅 도구 21개"]
        shape["response_shape<br/>압축 JSON 텍스트 + structuredContent,<br/>detail_level summary / full"]
        engine["portfolio_engine, interval_returns<br/>평가, 원가, TWR / XIRR, 입출금 흐름"]
        sources["portfolio_sources<br/>계좌별 수집, 환율, 상태"]
        store[("SQLite<br/>NAV 스냅숏, 원장, 데이터셋")]
        auth --> catalog --> shape
        catalog --> engine --> sources
        engine --> store
    end
    sources --> toss["토스증권 Open API"]
    sources --> kis["한국투자증권 Open API"]
    catalog --> crypto["바이낸스 USD-M,<br/>Hyperliquid, 업비트"]
    catalog --> research["SEC EDGAR,<br/>yfinance (비공식)"]
    timers["systemd 타이머<br/>NAV 18:10 KST, 원장 04:10 KST,<br/>선물 위험 매시"] --> store
    files["내 토스증권 PDF,<br/>바이낸스 CSV"] -->|"요청 시 가져오기"| store

deploy/의 타이머는 서버 없이 scripts/snapshot_nav.py, scripts/collect_ledger.py, scripts/snapshot_futures_risk.py를 실행해요. 두 날짜 사이의 수익률에는 각 날짜의 저장된 NAV가 필요해서, 매일 찍는 스냅숏이 있어야 기간 수익률을 계산할 수 있어요. 암호화폐 선물은 따로 보고하고 포트폴리오 NAV에는 넣지 않아요.

응답 크기 예산

모든 도구 결과에는 structuredContent 객체 하나와, 같은 객체를 압축 JSON으로 담은 텍스트 블록 하나가 들어 있어요 (MCP 2025-06-18). 그래서 모델에게 텍스트만 보여 주는 클라이언트(claude.ai)와 structuredContent를 읽는 클라이언트(ChatGPT)가 같은 필드를 봐요.

이 한도는 tests/test_merge_budget.py, tests/test_merge_paging.py, tests/test_route_returns_size.py가 검사해요.

교차 클라이언트 회귀 검사

릴리스 전에 정해진 질문 19개를 같은 서버에 연결한 Claude와 ChatGPT에 각각 물어봐요. 각 답변은 근거가 되어야 할 도구 출력과 비교해 pass, partial, fail로 채점해요. 소유자의 채점 규칙에 따라 ChatGPT는 포트폴리오 데이터를 K-invest에서 가져오는 한 자체 내장 도구도 쓸 수 있어요.

최근 결과, 이번 릴리스 기준 (2026-10-22 21:14 KST, 클라이언트별 질문 19개):

클라이언트 Pass Partial Fail
Claude 18 1 0
ChatGPT 16 3 0

오프라인 테스트는 두 클라이언트가 의존하는 응답 형식을 검사해요. 텍스트 블록은 structuredContent와 같아야 하고, 호출 전체가 실패하면 isError가 설정되어야 해요. 채팅 도구 목록, 설명, 스키마는 해시로 고정돼 있어요 (tests/test_tx_wire.py, tests/test_merge_catalog.py, tests/test_tool_offloop.py).

읽기 전용 안전성

빠른 시작

Python 3.10 이상과, 설정된 출처가 하나 이상 필요해요.

git clone <this repository> k-invest && cd k-invest
python -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt
pip install pytest pytest-asyncio exceptiongroup ruff
python -m pytest tests/ -q          # 오프라인; 네트워크, 키, 계좌 불필요

cp .env.example .env                # 사용할 출처를 채워요
echo "MCP_AUTH_TOKEN=$(python -c 'import secrets; print(secrets.token_urlsafe(32))')" >> .env
python server.py                    # http://127.0.0.1:8100/mcp

MCP 클라이언트를 http://127.0.0.1:8100/mcp에 Authorization: Bearer <MCP_AUTH_TOKEN> 헤더로 연결한 뒤 get_status를 호출해 설정을 확인하세요. MCP_AUTH_TOKEN이 없으면 서버가 시작되지 않아요.

서버에 설치할 때는 deploy/의 systemd 유닛(서버와 타이머 세 개)을 쓰세요 (youruser와 경로를 바꿔야 해요). 선택 설정은 모두 .env.example에 설명돼 있어요.

변수 효과
TOSS_CREDS_FILE, KIS_ACCOUNTS_JSON 토스증권이나 한국투자증권 계좌 여러 개
BINANCE_FUTURES_API_KEY_FILE, BINANCE_FUTURES_SIGNING_KEY_FILE, HYPERLIQUID_ACCOUNT_ADDRESSES 암호화폐 선물 계정
MCP_OAUTH_ENABLED, MCP_PUBLIC_URL, OWNER_GATE_REDIRECT_ORIGINS 호스팅된 클라이언트를 위한 OAuth 2.1과 동적 클라이언트 등록. 암호 해시는 python -m owner_gate hash로 만들어요.
KINVEST_PRODUCT_MAP_FILE 레버리지·단일 종목 ETF를 기초자산으로 환산하는 매핑 (형식은 product_map.example.json). 없으면 각 상품을 그 자체의 노출로 봐요.
KINVEST_STATEMENT_INBOX import_statement가 읽는 토스증권 PDF 거래내역서 폴더
KINVEST_PORTFOLIO_DB, KINVEST_CACHE_DIR SQLite 저장소와 캐시 위치

테스트

python -m pytest tests/ -q는 합성 데이터와 모의 HTTP로 전체 테스트를 오프라인에서 실행해요. 일부 테스트는 git 기록에 있는 예전 릴리스 파일과 비교해요. 그 기록이 없는 저장소에서는 건너뛰고 이유를 출력해요.

라이선스와 지원

MIT 라이선스예요. LICENSE를 보세요.

개인 프로젝트를 있는 그대로(as-is) 공개한 것이에요. 지원, 유지보수, 이슈 응답을 약속하지 않아요. 토스증권, 한국투자증권, 바이낸스, Hyperliquid, 업비트와 관계가 없어요. 수치는 API가 돌려주는 데이터만큼만 정확하고, yfinance는 비공식이에요. 이 소프트웨어의 출력은 투자 조언이 아니에요.