InvestMCP
Provides read-only access to Binance's official REST API for crypto futures market data and the user's own Binance futures account data using their read-only API key; no order or transfer capabilities.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@InvestMCP How are my holdings performing compared to the KOSPI?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
InvestMCP
English abstract. InvestMCP is a read-only MCP server that lets an individual investor ask an AI chat client such as Claude or ChatGPT about their own brokerage and crypto futures accounts together with public market data and ticker research. It merges my earlier K-invest and Ticker Research projects into one process with 28 tools: 10 account/portfolio, 11 public-data/status and 7 research. Account data comes only from official APIs (Toss Securities, Korea Investment & Securities, Binance, Hyperliquid), filings from SEC EDGAR, and unofficial Yahoo data via yfinance is labelled as such; there are no order or transfer tools. Each user runs it locally with their own keys for their own accounts; it is not a shared or hosted data service. Full English documentation: README.en.md.
무엇인가
개인 투자자가 Claude·ChatGPT 같은 AI 채팅에서 자기 증권·크립토 계좌와 공개 시장 데이터를 한곳에서 묻는 읽기 전용 MCP 서버다. 국내·미국 주식과 크립토 선물을 다룬다. "내 보유 종목이 코스피 대비 어떤가"라는 질문에는 get_holdings로 종목을 읽고 compare_price_performance로 비교한다. "이 종목의 TTM 실적과 최근 내부자 거래는"이라는 질문에는 SEC 공시 도구를 쓴다.
이전에 만든 두 프로젝트 K-invest와 Ticker Research를 하나로 합쳤다. 계좌·회계 엔진은 기존 InvestMCP 2.15.4에서, 리서치 계산은 Ticker Research의 최신 공개 포크에서 가져왔다. 프로세스 하나, 도구 카탈로그 하나, 인증 경계 하나다. SEC 구현은 합치지 않았다. 재무 도구와 리서치 도구는 회계 기간·연속성·출처 검증 장치가 서로 달라서 각자 자기 구현을 쓴다.
각 사용자가 자기 키로 자기 계좌만 조회하도록 직접 실행한다. 공유하거나 남에게 시세를 제공하는 호스팅 데이터 서비스가 아니다. 근거가 되는 약관은 내 계좌 설정에 있다.
이 프로젝트는 Codex와 Claude AI 코딩 에이전트를 오케스트레이션해 만들었다. 설계, 범위, 채택과 공개 결정은 내가 내렸고, 에이전트가 구현과 테스트 실행을 맡았다.
Related MCP server: milele-prime-mcp
설계 원칙
주문·이체 도구가 없다. 주문 제출, 체결, 취소, 이체, 출금 기능이 없다. 거래 이력은 읽지만 거래를 일으키지 못한다.
계좌는 공식 API로만 읽는다. 토스증권 Open API, 한국투자증권 Open API, Binance, Hyperliquid 공식 API를 쓴다. 공시는 SEC EDGAR, 환율은 ECB 기준환율이다. 비공식 출처인 yfinance(Yahoo 데이터)와 공개 시세 API인 Upbit은 데이터 출처 표에 구분해 적었다.
키는 사용자 기기의 환경 변수에만 둔다. 서버는 프로세스 환경 변수만 읽고
.env파일을 자동으로 불러오지 않는다. 브로커 키는 해당 브로커 인증에만 보낸다.숫자에는 출처와 기준 시각이 붙는다. 계좌·시장 도구는 응답 섹션마다
meta에 출처(provider), 데이터 기준 시각(as_of,as_of_basis), 조회 시각(observed_at)을 넣는다. 기준 시각을 알 수 없으면as_of를 null로 두고 이유 코드를 남긴다. 리서치 도구도 섹션마다as_of,as_of_basis,source를 붙인다.없는 데이터는 0이 아니다. 가격 누락, 불완전한 이력, 확인되지 않은 입출금은 unavailable로 남기고 0으로 채우지 않는다. 계좌를 설정하지 않았으면
NOT_CONFIGURED와 필요한 변수 이름을 돌려준다.
데이터 출처
출처 | 구분 | 키 | 용도 |
공식 | 본인 키 필요 | 계좌, 보유 종목, 체결 이력, 브로커 시세 조회 | |
공식 | 본인 키 필요 | 계좌, 국내·해외 잔고, 시세와 이력 | |
공식 | 시장 데이터는 불필요, 계좌는 본인 읽기 전용 키 | 선물 시장·계좌 데이터 | |
공식, 주소 기반 공개 조회 | 불필요 (본인 주소 입력) | 선택적 선물 계좌 조회 | |
공개 시세 API; terms: see provider | 불필요 | 크립토 NAV 관측용 KRW 스테이블코인 가격 | |
공식 공개 공시 | 불필요 | 재무 사실, TTM, 내부자 거래, EPS 이력 | |
공식 공개 일별 기준값 | 불필요 | 키 없는 환율. 참고용이며 체결 가격이 아니다 | |
Apache-2.0 라이브러리, 비공식 Yahoo 데이터; terms: see provider | 불필요 | 키 없는 시세·캔들, 재무 지표, 컨센서스, 기술적 리서치, 미 국채 수익률 대용 |
Yahoo 데이터 약관: see provider. Upbit 데이터 약관: see provider. 이 저장소에는 Yahoo 응답 녹화본이나 브로커 샘플 코드 픽스처가 없다.
공개 서비스는 요청을 제한하거나 지연하거나 지역에 따라 막을 수 있다. Yahoo는 공식 거래소 API가 아니다. 가격 수익률 차트는 따로 밝히지 않는 한 배당을 빼고 계산하며, 잠정 가격과 불완전한 구간은 표시한다. 분할 매수와 EPS 시나리오는 계산이지 예측이 아니다. 로컬 성과 추정은 거래 이력의 완전성, 환율의 신뢰성, 외부 입출금 근거에 달려 있다.
도구 28개
stdio와 HTTP가 같은 28개 도구를 노출한다. 모든 인자와 설명은 TOOLS.md에 있다.
영역 | 개수 | 도구 |
계좌·포트폴리오 | 10 |
|
시장 데이터·상태 | 11 |
|
종목 리서치 | 7 |
|
† local write로 표시한 도구다. 명세서 가져오기, NAV 스냅샷, 데이터셋 내보내기를 로컬 데이터 디렉터리에 기록한다. 계좌 조회도 나중의 회계 계산을 위해 관측값을 로컬에 남길 수 있다.
get_quote와get_portfolio_summary는 여러 종목·섹션을 한 번에 받는 스키마다. 브로커별 옛 도구 이름과 호환 별칭은 내부 함수로만 남겼고, 목록에도 나오지 않고 호출도 거부된다.가격 이력 비교는
compare_price_performance가 맡는다. 예전get_market_series를 대체했다.plan_entry와compare_tickers는 사용자가 넣은 금액으로 시나리오를 계산할 뿐 주문을 내지 않는다.토스증권을 설정하지 않으면 일반 시세와 캔들은 yfinance로 대체한다. 호가, 가격 제한, 장 운영 일정, 브로커 간 시세 비교 같은 선택 섹션은 본인 브로커 키가 있어야 하며 없으면 unavailable이다. 여러 출처를 합치는 도구는 부분 커버리지를 명시한다.
키 없이 환율을 보려면
get_market_info에include를["fx"]로 넘긴다.
빠른 시작
Python 3.11 이상이 필요하다. 소스 체크아웃이나 압축을 푼 소스 디렉터리에서 설치하고 데모 모드로 스모크 검사를 돌린다.
python -m pip install .
INVESTMCP_DEMO=1 python scripts/smoke.pyscripts/smoke.py는 설치된 패키지를 stdio로 띄워 MCP 클라이언트로 초기화하고, 도구 목록이 28개인지 확인하고, ECB의 실제 USD/KRW 기준환율을 받고, 합성 계좌의 보유 종목과 포트폴리오 수익률을 읽는다. 임시 데이터 디렉터리를 만들었다가 지우며 브로커 키는 필요 없다. 환율 단계에는 인터넷 연결이 필요하다. 성공하면 PASS 네 줄을 출력하고, 하나라도 실패하면 0이 아닌 코드로 끝난다.
PASS start: stdio initialization
PASS list: 28 tools
PASS public: ECB USD/KRW reference rate
PASS demo: synthetic holdings and portfolio returns가상 환경에 설치하려면 먼저 python -m venv .venv로 만들고 활성화한다. uv로는 다음과 같다.
uv venv
uv pip install --python .venv/bin/python .
INVESTMCP_DEMO=1 .venv/bin/python scripts/smoke.pyMCP 클라이언트용으로 서버를 띄운다.
INVESTMCP_DEMO=1 investmcp
# 같은 동작:
INVESTMCP_DEMO=1 python -m investmcp --transport stdiostdio는 JSON-RPC 메시지를 기다린다. 대화형 셸이 아니다. 로그는 stderr로 나간다.
데모 모드. INVESTMCP_DEMO=1이면 계좌·포트폴리오 응답이 가상 포트폴리오로 바뀐다. DEMO-TOSS-1, DEMO-KIS-1 계좌, 합성 국내·미국 종목과 거래, 환율, 빈 합성 Binance 선물 계좌다. 실제 계좌와 같은 포트폴리오 엔진이 보유 종목, 실현 손익, 성과, 집중도 위험을 계산한다. 생성된 거래와 31개 일별 NAV 관측이 30일 구간을 채우므로, 미리 수집하지 않아도 get_portfolio_returns가 비어 있지 않은 결과를 돌려준다. 데모 모드의 계좌 호출은 브로커나 네트워크에 접근하지 않는다. 공개 데이터·리서치 도구는 그대로 공개 데이터를 받아온다. 데모 NAV 스냅샷은 별도 demo 하위 디렉터리에 저장한다. 명세서 가져오기는 실제 계좌 설정이 있어야 하고, 데모 내보내기는 합성 데이터셋을 저장하지 않고 돌려준다.
연결
Claude Desktop · Claude Code (stdio)
데스크톱 클라이언트가 환경을 찾을 수 있도록 설치된 실행 파일의 절대 경로를 쓴다. Claude Desktop MCP 설정은 다음과 같다.
{
"mcpServers": {
"finance": {
"command": "/absolute/path/to/.venv/bin/investmcp",
"args": ["--transport", "stdio"],
"env": {"INVESTMCP_DEMO": "1"}
}
}
}Claude Code에서는 같은 mcpServers 객체를 프로젝트 .mcp.json에 넣거나, Claude Code의 MCP 설정으로 실행 파일을 등록한다. 실제 키는 공유되는 프로젝트 설정이 아니라 프로세스 환경이나 로컬 비밀 관리자에 둔다. 설정 파일 위치는 MCP 로컬 클라이언트 가이드를 따른다.
claude.ai · ChatGPT 원격 커넥터 (HTTP + OAuth)
HTTP는 선택 사항이며 MCP_AUTH_TOKEN이 없으면 시작하지 않는다. 기본 바인드 주소는 루프백, 기본 포트는 18800이다. 강한 무작위 토큰을 환경 변수로 넣고 실행한다.
investmcp --transport streamable-http --host 127.0.0.1 --port 18800엔드포인트는 /mcp다. 직접 베어러 인증을 지원하는 클라이언트는 설정한 토큰을 Authorization: Bearer로 보낸다. 이 토큰은 MCP 서버용이며 브로커 키와 별개다.
원격 커넥터는 리버스 프록시에서 HTTPS를 종료하고 서버 오리진 전체를 넘긴다. /mcp, OAuth 메타데이터, /register, /authorize, /token, /revoke가 모두 포함된다. MCP_PUBLIC_URL에 공개 HTTPS 오리진(예: https://finance.example.com)을 넣으면 같은 오리진이 OAuth 리소스 식별자로 광고된다. Host, Origin, Authorization 헤더를 보존하고 백엔드 포트를 직접 노출하지 않는다. 서버는 Host를 검증하고 프록시 헤더를 신뢰하지 않는다.
OAuth는 MCP_OAUTH_ENABLED=1과 MCP_OAUTH_APPROVAL_HASH로 켠다. 해시는 로컬에서 만든다.
python -m investmcp.consent_gate hash이 명령은 승인 암호를 화면에 표시하지 않고 읽어 scrypt 해시를 출력한다. 그 해시를 MCP_AUTH_TOKEN과 별도로 MCP_OAUTH_APPROVAL_HASH에 넣고, 설정을 바꾼 뒤에는 서버를 재시작한다. 동의 페이지는 인가 코드를 발급하기 전에 승인 암호를 요구한다. 이 페이지에 브로커 키를 넣지 않는다.
OAuth는 디스커버리, 동적 클라이언트 등록, PKCE S256 인가 코드 흐름, 동의 바인딩, 액세스 토큰 만료, 리프레시 토큰 회전과 폐기, 해시로 저장하는 토큰 상태를 지원한다. 기본 리다이렉트 오리진은 Claude와 ChatGPT의 HTTPS 오리진이다. 커넥터가 다른 콜백 오리진을 쓰면 CONSENT_GATE_REDIRECT_ORIGINS에 정확한 HTTPS 오리진의 JSON 목록을 넣는다. 수동 등록 클라이언트는 MCP_OAUTH_CLIENT_ID와 MCP_OAUTH_CLIENT_SECRET을 쓰고, 동적 등록에는 둘 다 필요 없다. OAuth를 켜도 직접 베어러 접근은 유지된다.
claude.ai:
https://finance.example.com/mcp를 가리키는 사용자 지정 원격 커넥터를 추가하고 OAuth 동의를 마친다. 사용 가능 여부는 계정과 워크스페이스 정책에 따른다. Claude custom connectors 참고.ChatGPT: 사용자 지정 MCP/플러그인 연결 화면에 HTTPS
/mcpURL을 넣고, 동적 클라이언트 등록 방식의 OAuth를 골라 연결한 뒤 동의를 마친다. 서버는 클라이언트 메타데이터 문서 등록을 광고하지 않는다. 현재 화면과 계정 요건은 Connect and test, OAuth authentication 참고.
브로커 키는 서버가 도는 기기에만 있고 해당 브로커 인증에만 쓰인다. 연결된 클라이언트는 요청한 도구 결과를 받으며, 여기에는 계좌 데이터가 들어갈 수 있다. 단일 사용자 서버다. 베어러 토큰이나 OAuth 동의 권한을 가진 사람은 그 사용자가 설정한 계좌를 읽을 수 있으므로, 원격으로 열더라도 접근 권한은 본인만 가져야 한다.
내 계좌 설정
각 사용자는 자기 키로 자기 계좌에만 이 서버를 쓴다. 공유·호스팅 데이터 서비스가 아니다. 토스증권과 한국투자증권 약관은 키 공유와 제3자 시세 제공을 금지한다. 다른 사람의 요청을 내 키로 대신 처리하지 않는다. 토스증권 Open API 약관, 한국투자증권 개인 고객 Open API 약관을 확인한다.
서버는 프로세스 환경 변수만 읽고 .env 파일을 자동으로 읽지 않는다. .env.example은 값이 빈 변수 이름 목록이다. 값은 실행기나 비밀 관리자로 넣는다.
토스증권: 토스증권 WTS → 설정 → Open API에서 본인 키를 발급받아
TOSS_CLIENT_ID,TOSS_CLIENT_SECRET을 설정한다. 여러 계좌는TOSS_ACCOUNTS_JSON에accounts배열을 가진 JSON 객체로 넣는다. 각 계좌 객체는label,client_id,client_secret을 갖고, 선택 필드account_id는 라벨이 바뀌어도 원장 식별자를 유지한다. 계좌 객체 하나만 넣어도 된다. 이것은 로컬 설정 형식이며 브로커 응답이 아니다.한국투자증권: 공식 API 포털에서 키를 받아
KIS_APP_KEY,KIS_APP_SECRET,KIS_CANO, 필요하면KIS_ACNT_PRDT_CD를 설정한다. 여러 계좌는KIS_ACCOUNTS_JSON에label,app_key,app_secret,cano,acnt_prdt_cd를 가진 계좌 객체들로 넣는다.Binance: 선물 계좌 조회에는 본인 읽기 전용 키를
BINANCE_API_KEY,BINANCE_API_SECRET에 넣는다. RSA 키는 PEM 텍스트로BINANCE_SIGNING_KEY에 넣을 수 있다. 키의 거래·출금 권한은 끈다. Binance 공개 시장 도구는 키가 필요 없다.Hyperliquid: 선택 사항이다. 본인이 넣은 계정 주소로 공식 info API를 읽는다. 서명 키는 받지 않는다.
SEC: 기본 User-Agent가
investmcp/0.1.0 (contact: you@example.com)이라 설치와 공개 도구에 비밀값이 필요 없다. SEC를 꾸준히 쓰기 전에SEC_USER_AGENT를 본인 애플리케이션 식별자와 실제 연락처로 바꾼다. 연락처가 적절하지 않거나 제한된 네트워크에서 온 요청은 SEC가 거부할 수 있다.
원장, NAV, OAuth, 토큰, 로컬 캐시는 모두 INVESTMCP_DATA_DIR(기본 ~/.investmcp) 아래에 둔다. 이 디렉터리는 비공개로 두고, 과거 수익률이 필요하면 백업한다. 명세서 PDF는 그 아래 statements/inbox에 둔다. 도구는 파일 이름만 받고 경로 이동과 심볼릭 링크를 거부한다. 이 저장소에는 명세서, 계좌 데이터베이스, 개인 픽스처가 없다.
환경 변수
이름과 설명만 적는다. 값은 적지 않는다. 전체 35개다.
이름 | 설명 |
| 켜면 계좌·포트폴리오 도구가 합성 데모 포트폴리오를 쓴다 |
| 원장, NAV, OAuth, 토큰, 캐시를 저장하는 디렉터리 |
| 기본 전송 방식 ( |
| HTTP 바인드 주소 |
| HTTP 포트 |
| 켜면 요청마다 모든 이력 구간을 브로커에서 다시 읽는다 |
| 토스증권 Open API 클라이언트 ID |
| 토스증권 Open API 클라이언트 시크릿 |
| 여러 토스증권 계좌 설정 (JSON) |
| 한국투자증권 앱 키 |
| 한국투자증권 앱 시크릿 |
| 한국투자증권 계좌번호 (CANO) |
| 한국투자증권 계좌 상품 코드 |
| 여러 한국투자증권 계좌 설정 (JSON) |
| 한국투자증권 요청 사이 최소 간격 (초) |
| 요청 제한 응답 뒤 재시도 횟수 (최대 2) |
| 이력 조회 한 번에 읽는 최대 페이지 수 |
| Binance 읽기 전용 API 키 |
| Binance API 시크릿 |
| 시크릿 대신 쓰는 Binance RSA 서명 키 (PEM 텍스트) |
| 조회할 본인 Hyperliquid 주소, 쉼표로 구분 |
| SEC 요청 User-Agent (애플리케이션 식별자와 연락처) |
|
|
| HTTP 베어러 토큰. HTTP 전송에 필수 |
| 공개 HTTPS 오리진. OAuth 리소스 식별자로도 쓴다 |
| OAuth 켜기 |
| 동의 페이지 승인 암호의 scrypt 해시 |
| 수동 등록 OAuth 클라이언트 ID |
| 수동 등록 OAuth 클라이언트 시크릿 |
| 수동 등록 클라이언트 허용 여부 |
| 동적 등록 클라이언트 최대 수 |
| 액세스 토큰 수명 (초) |
| 리프레시 토큰 수명 (초) |
| 회전된 리프레시 토큰의 재사용 유예 시간 (초). 이후 재사용하면 토큰 계열 전체를 폐기한다 |
| 허용할 OAuth 리다이렉트 HTTPS 오리진의 JSON 목록 |
구조
flowchart LR
A["MCP 클라이언트<br/>Claude · ChatGPT"] -->|"stdio / HTTP + OAuth"| B["investmcp 서버<br/>도구 28개"]
B --> C["계좌·포트폴리오 10"]
B --> D["시장 데이터·상태 11"]
B --> E["종목 리서치 7<br/>ticker_engine"]
C --> F["토스증권 · 한국투자증권 · Binance · Hyperliquid · Upbit"]
C --> G[("로컬 원장 · NAV<br/>INVESTMCP_DATA_DIR")]
D --> H["SEC EDGAR · ECB · Binance 공개 · yfinance<br/>설정 시 토스증권 · 한국투자증권"]
E --> I["SEC EDGAR · yfinance"]경로 | 내용 |
| 서버, 전송, OAuth, 계좌·포트폴리오 엔진, 재무용 SEC와 공개 데이터 모듈, 데모 포트폴리오 |
| 리서치 공급자와 계산. 같은 서버에 마운트된다 |
| stdio 온라인 스모크 검사 |
| 합성 데이터 단위 테스트 |
| 도구별 인자와 설명 |
| 값이 빈 환경 변수 이름 목록 |
설치하면 investmcp와 ticker_engine 두 패키지만 import 대상으로 들어간다. 리서치 도구는 통합 서버의 전송 인증을 그대로 쓰며 별도 서비스 토큰 파일이 필요 없다.
테스트
python -m pip install '.[dev]'
python -m pytest -q
ruff check .단위 테스트는 합성 입력과 임시 데이터 디렉터리만 쓰고, 외부 네트워크 연결을 막는다(tests/conftest.py). 첫 공개 릴리스 기준으로 Linux, Python 3.14에서 947개 테스트가 모두 통과했다. 온라인 동작은 별도의 scripts/smoke.py로 확인한다. 의존성 하한은 원래 프로젝트를 따르고, 실제 버전은 Python 리졸버가 호환되는 릴리스로 고른다.
라이선스
MIT — Copyright (c) 2026 ianlyoo. LICENSE를 본다. 런타임 의존성의 라이선스 점검 결과는 THIRD_PARTY_NOTICES.md에 있다.
이 소프트웨어와 그 출력은 정보 제공용이며 투자 조언이 아니다.
Available Tools
28 toolscompare_price_performanceARead-onlyIdempotent
Compare the daily price performance of 1-8 US or Korean stocks, ETFs or indices on one common trading calendar (상대강도, 기준일 100, 수익률 비교, 코스피와 비교). For 내 보유 종목을 코스피/S&P와 비교: get holdings from investmcp get_holdings, then call this once with their symbols (KR 6-digit codes and US tickers together) and benchmark KOSPI (or SPY/^GSPC). Prefer it for cross-market price history and index levels: it uses the KOSPI index itself (not an ETF proxy such as KODEX 200), aligns calendars, converts USD and KRW holdings into one currency and labels sources. metric: normalized_price (default; every series = 100 on the common base date), price_return_pct, relative_strength_ratio (symbol / benchmark, base 100) or excess_return_pp (return minus the benchmark's, %p); the last two need benchmark (e.g. SPY, QQQ, KOSPI, ^GSPC). If relative strength (상대강도) is asked without a benchmark, the result is normalized_price with a warning naming that choice; pass benchmark for a true relative-strength ratio. Window: period 1mo (default) | 3mo | 6mo | ytd | 1y | d calendar days, or start_date/end_date, or trading_days N (N common trading days ending at the latest one). Symbols: AVGO, BRK.B, 005930 (tries .KS then .KQ), 005930.KS, ^GSPC, aliases KOSPI, KOSDAQ, S&P500, SPX, NASDAQ, NDX; an ETF benchmark is labelled a proxy. currency native | USD | KRW converts with the Yahoo KRW=X close of the same date. Prices are Yahoo daily closes, split-adjusted, dividends excluded: price return, not total return. One symbol failing returns its entry in errors; the rest are still compared. Up to 260 points per series; long windows switch to weekly points (data_quality.sampling). trading_days N counts today's session when a provisional point ends the series. By default the last point is provisional: today's trades (regular session, or pre-market before the open) after the last confirmed close, with provisional=true, session and exchange-local time; the confirmed close replaces it after the close, so no date appears twice. After-hours trades appear in freshness and the summary, never as a point. confirmed_only=true: completed daily closes only. table: period_return_pct to the last point and confirmed_return_pct to the last confirmed close. Text: a one-line summary, then the full result as compact JSON (the same object as structuredContent). Show source_line and warnings under the chart. Read-only calculation; no account access or orders.
Inputs: symbols (required), metric, period, currency, +5 more. Returns: ok, as_of, error, table, +18 more
compare_tickersARead-only
Compare 1–8 tickers for entry-plan scoring and allocation: calculation, not an order; the amount is your input; no account access. Symbols: US tickers (USD) and KRX listings by code, e.g. 000660, 005930 (tries .KS then .KQ) or 005930.KS (KRW); not indices or other markets. currency defaults to the listing's; amounts and prices stay in it (no FX conversion): USD with a KRX listing or KRW with a US one returns CURRENCY_MISMATCH. KRX listings: Yahoo daily bars, the latest trade and indicators only (no options levels, SEC filings, consensus or earnings date, stated in warnings), limit prices on the KRX tick grid in force since 2023-01-25 (호가단위, rounded down) and whole shares per tranche. US and KRX tickers can be mixed: each keeps its own currency (data.currency_policy); total_amount then needs currency, the currency it is split in, and a ticker priced in the other one gets a percentage-only plan. An unsupported symbol is listed in data.unavailable with its reason_code and the rest are compared. For price-performance charts or relative strength (상대강도), use compare_price_performance. Returns {ok, data, error, meta} as structuredContent and the same compact JSON as text; ok=false is a tool error naming the problem. data.comparison: per ticker attractiveness and entry_plan (tranches), ranking and allocation_scenarios (with total_amount); data.freshness and technical_basis per ticker. Spots are latest trades with their times (freshness; a spread over 5 minutes is warned) and indicators match get_technical_indicators; confirmed_only=true uses confirmed closes. detail: standard (default) gives values with provenance once per section and rounded numbers, summary headline values only, full every field with per-value provenance; meta.detail_note says how to read same_as, _each and {columns, rows} tables. Per-ticker inputs_used and dropped_levels only in full.
Inputs: symbols (required), detail, currency, horizon_days, +2 more. Returns: object
export_portfolio_datasetA
Freeze an auditable portfolio dataset locally, then return small pages.
Only for an explicit request to export, save or freeze a dataset. A dated portfolio value series is get_portfolio_returns(include_series=true), which stores nothing.
Transaction exports default to YTD (365 days with end_date alone); pass start_date (e.g. 2024-01-01) or period="ALL" for older history.
Writes only local dataset copies and never places orders or uploads data. First call (no dataset_id) captures normalized inputs through existing engine paths. Later calls supply dataset_id and next_cursor as cursor; they read only the frozen copy, with no provider/FX refetch. Returned manifest identifies the original dates and filters; replay does not reapply collection parameters. IDs are content hashes. The latest 20 datasets are retained; expired/unknown IDs return DATASET_EXPIRED and never silently rebuild. Start a new first call explicitly to collect changed inputs. Missing money stays null with a status.
JSON rows have record_type, row_id, data. CSV has those first two columns and data_json (canonical JSON preserving nested fields, null and statuses). Supporting holdings, cash, source coverage, cost FX, quantity breaks and NAV components are paged audit records. Manifest descriptors name their row types; read every page to reconstruct/hash the entire dataset. Totals sum frozen input money by type/currency; reporting summaries retain their stated period. Account IDs are opaque keyed hashes. Human account labels are retained only when already exposed, and raw broker payloads/credentials are excluded.
Args: dataset: transactions, realized_pnl, holdings, or nav_history period: reporting period (default YTD); explicit ISO dates override it start_date: ISO YYYY-MM-DD; realized inputs include earlier basis history end_date: ISO YYYY-MM-DD. Holdings export is current, not historic backfill dataset_id: frozen ID for replay; omit only for a new collection cursor: opaque next_cursor from the preceding page; requires dataset_id format: json or csv; both carry the same typed audit rows page_size: 1–200, additionally limited to 64 KiB of row data per page account: existing account filter; nav_history requires all accounts symbol: optional existing symbol filter; not applicable to nav_history input_snapshot_ids: nav_history only, exact E-store versions; bounds use their dates when no explicit dates are supplied
Inputs: dataset (required), cursor, format, period, +7 more. Returns: object
get_candlesARead-onlyIdempotent
Get candlestick chart data (OHLCV) for a stock (Toss).
Args: symbol: Stock symbol (e.g., "AAPL", "005930") interval: Candle interval — "1d" for daily or "1m" for 1-minute count: Number of candles to retrieve (max 200, default 100) adjusted: Request provider adjustments (default True); actual basis unverified. before: Provider cursor; inclusive local timestamp filter, upstream boundary unverified. start_date/end_date: Inclusive YYYY-MM-DD candle-local labels. One page per call.
Returns: Raw provider payload for existing calls. Paging calls add returned_range, next_cursor, complete (page chain only, not historical coverage), limit, result_status/reason_codes and source_metadata. Merge pages ascending by timestamp and deduplicate; adjusted prices are not verified total returns.
Inputs: symbol (required), count, before, adjusted, +3 more. Returns: object
get_crypto_account_historyARead-onlyIdempotent
Your own crypto futures fills (with fees) or funding paid/received, newest first, paged.
start/end: inclusive UTC YYYY-MM-DD (default: the last 7 days). Values stay in their native asset. The page header carries per-venue coverage and next_cursor (limit 1-500, default 50). Fetched broker rows are recorded in the local append-only ledger (no broker writes).
Inputs: kind (required), end, limit, start, +3 more. Returns: object
get_crypto_marketARead-onlyIdempotent
Public Binance USD-M futures market data for one symbol (e.g. "BTCUSDT"); no API key.
Always returns the snapshot: last price, mark/index price, latest funding rate and open interest. include adds the public funding rate history, open interest history and OHLCV candles (interval; limit rows each, 1-500).
Inputs: symbol (required), limit, include, interval. Returns: object
get_crypto_positionsARead-onlyIdempotent
Your open crypto futures positions and native account balances (Binance USD-M, Hyperliquid).
Kept out of portfolio NAV and holdings. Unknown leverage, margin mode and mark prices stay null; inspect each venue's source_status and coverage.
Inputs: venue. Returns: object
get_eps_scenariosARead-onlyIdempotent
For any EPS question on a US SEC filer (EPS 시나리오, 약세/기본/강세, bear/base/bull, EPS 전망·컨센서스, P/E 적정가) call this first, before web search; web news can be added after. Returns chart-ready tables: GAAP diluted EPS per fiscal year from SEC EDGAR companyfacts (10-K) with the P/E at each fiscal year end, Yahoo Finance consensus EPS for the current and next fiscal year (low/avg/high, analysts; via yfinance, unofficial) and bear/base/bull implied prices = EPS x P/E multiple. The historical GAAP P/E band is applied only when the EPS bases match; otherwise rows keep EPS with implied_price and implied_return_pct null, a needs_input_pe_multiples note asks for pe_multiples (a dict, e.g. {"bear":25,"base":32,"bull":40}), and pe_multiples_used lists the band and forward P/E per year as reference only, not applied. A calculation, not a forecast or price target. Fiscal years filed before a later stock split are left out, not adjusted. Korean listings and indices return UNSUPPORTED_MARKET. No dividends. implied_return_pct is measured from reference_price: by default the latest trade (regular, pre-market or after-hours, with its basis, session and time), else the last confirmed close (latest_close, kept separately); eps_as_of (10-K filing) and estimates_as_of are separate from the price time. confirmed_only=true: from the close. Text: a one-line summary, then the full result as compact JSON (the same object as structuredContent). Show source_line and warnings with the table. Read-only calculation; no account access or orders.
Inputs: symbol (required), pe_multiples, confirmed_only. Returns: ok, cik, as_of, error, +27 more
get_financialsARead-onlyIdempotent
Get comprehensive financial data from yfinance (US, Korea, Japan).
Provides income statement, balance sheet, cash flow, valuation metrics, and profitability ratios from yfinance. Works with US stocks ("AAPL"), Korean stocks ("005930.KS"), and Japanese stocks ("7203.T").
Args: symbol: Stock ticker. US: "AAPL", Korean: "005930.KS", Japanese: "7203.T"
Returns: Structured JSON envelope with financial statements and key metrics.
Inputs: symbol (required). Returns: object
get_holdingsARead-onlyIdempotent
Current positions, merged per symbol in native currency and KRW, plus cash.
account: "all", "toss", "kis", or one account label ("toss:primary", "kis:pension"). detail_level "summary" lists the top 15 positions; "full" lists every position with its accounts and the look-through exposure per underlying; "raw" returns each broker's own balance payloads unmerged. Fetched broker rows are recorded in the local append-only ledger (no broker writes).
Inputs: account, detail_level, include_cash. Returns: object
get_insider_tradesARead-onlyIdempotent
Get insider trading data from SEC Form 4 filings (US stocks only).
Shows insider purchases (code P) and sales (code S), plus option exercises, grants, tax withholdings, etc. Each trade includes the insider name, title, shares, price, and whether it's a 10% operator.
Args: symbol: US stock ticker (e.g., "AAPL") days_back: How many days back to search (default 180, max 365)
Returns: Structured JSON envelope with insider trade records.
Inputs: symbol (required), days_back, detail_level. Returns: object
get_key_metricsARead-onlyIdempotent
Get key financial metrics summary from yfinance (US, Korea, Japan).
Returns P/E, PEG, P/B, EV/EBITDA, margins, ROE, ROA, growth rates, etc.
Args: symbol: Stock ticker. US: "AAPL", Korean: "005930.KS", Japanese: "7203.T"
Returns: Structured JSON envelope with key financial metrics.
Inputs: symbol (required). Returns: object
get_market_infoBRead-onlyIdempotent
Market sessions and holidays (KR or US; Toss), an ECB daily reference exchange rate, and the 10Y US Treasury yield (yfinance ^TNX). Each section's meta names its provider and as_of.
Inputs: base, quote, market, include. Returns: object
get_portfolio_returnsBRead-onlyIdempotent
Portfolio return for a period: simple return, TWR and XIRR side by side, P&L split and NAV risk statistics.
Read from stored daily NAV snapshots and the ledger. include_series adds the daily NAV history of the same period with drawdown statistics. That is the dated value series; it stores nothing, and no export or snapshot is needed for it. Fetched broker rows are recorded in the local append-only ledger (no broker writes).
Inputs: scope, period, detail_level, include_series. Returns: object
get_portfolio_summaryARead-onlyIdempotent
Whole-portfolio totals across every broker account, by section.
totals: total assets, stock value, cash, cost basis, unrealized P&L, per-account breakdown and the NAV bridge, in KRW at current spot. exposure: weights by currency and market, and look-through exposure per underlying (leveraged products at their daily multiple; open crypto futures at signed notional, never in totals). concentration: top positions, HHI and risk level. realized: year-to-date realized P&L, dividends, fees and taxes from the ledger (slower). Default: totals and realized. Never writes a snapshot. Fetched broker rows are recorded in the local append-only ledger (no broker writes).
Inputs: sections, detail_level. Returns: object
get_quoteARead-onlyIdempotent
Current stock quotes for up to 10 symbols (e.g. "AAPL", "005930").
provider "auto" uses yfinance without Toss keys, otherwise reads Toss with KIS fallback; "toss" or "kis" reads one; "both" compares the two with session timing. include adds per symbol: orderbook (bid/ask depth), trades (public market tape), limits (daily price limits), warnings (delisting/VI/overheated) and info (name, market, ISIN). KIS covers Japanese stocks (exchange TKSE).
Inputs: symbols (required), market, include, exchange, +2 more. Returns: object
get_sec_financialsARead-onlyIdempotent
Get SEC financials for US stocks: up to five annual fiscal years, quarterly facts, derived TTM, earnings quality, and segment revenue when available. Missing or incomplete data is marked unavailable or carries warnings; quarters/TTM/segments are not guaranteed for every issuer.
Uses CompanyFacts and filings (10-K/10-Q; applicable amended forms). No API key required. Uses SEC_USER_AGENT for fair access.
Args: symbol: US stock ticker (e.g., "AAPL", "MSFT")
Returns: Structured JSON envelope with annuals, quarters, TTM, quality and segment data.
Inputs: symbol (required). Returns: object
get_statusARead-onlyIdempotent
Connector status: cached service health, live source probes, configured accounts, or the usage guide.
mode="passive" reads cached status only (no upstream calls); "probe" calls each market-data source once; "accounts" lists the configured broker accounts and checks each one live; "help" returns the usage guide for this tool list (topic: overview, quotes, portfolio, financials, futures, futures_account, diagnostics, examples, all).
Inputs: mode, topic, detail_level. Returns: object
get_stock_snapshotBRead-onlyIdempotent
Return a compact stock snapshot with quotes, financial metrics, provider analyst consensus, and insider data.
Inputs: symbol (required), market. Returns: object
get_technical_indicatorsARead-onlyIdempotent
Daily technical indicators for one US or Korean stock, ETF or index (RSI/MACD/볼린저 밴드, 이동평균). For RSI/MACD/볼린저 of holdings, get symbols from investmcp get_holdings, then call this per symbol instead of computing indicators from raw candles. indicators: up to 6 of {name, params}: rsi {n:14}, macd {fast:12, slow:26, signal:9}, bb {n:20, k:2}, sma/ema/rma {n}, atr {n:14}, stdev, highest, lowest, roc {n}, volume; default rsi, macd and bb. Lengths 2-400; recursive ones (ema, rma, rsi, atr, macd) at most 252, as they need 10 x n warm-up bars. For SMA 20/50/200 pass three sma items. period 1mo | 3mo | 6mo (default) | ytd | 1y | d, at most 260 daily points; history before the window is fetched for warm-up, never reseeded. Returns the close series, one series per indicator output (unit, price or separate panel), a latest table and warnings, including possible split discontinuities. Yahoo daily closes, price return. By default a provisional last bar from today's trades (regular session, or pre-market before the open; never after-hours) ends every series: latest rows give the provisional value with session and time plus confirmed_value for the last confirmed bar (data_quality.bar_status partial). plan_entry and compare_tickers use the same bars and calculation, so their RSI/MACD/ATR match. confirmed_only=true: completed bars only; recursive indicators (RSI/MACD/EMA/ATR) can differ from earlier releases by about 0.001, as all three tools now share one warm-up window. Text: a one-line summary, then the full result as compact JSON (the same object as structuredContent). Show source_line and warnings under the chart. Read-only calculation; no account access or orders.
Inputs: symbol (required), period, indicators, confirmed_only. Returns: ok, feed, name, as_of, +19 more
get_ticker_researchARead-only
Issuer facts and explainable factors for one US ticker; explicit refresh; no account access or orders. Returns {ok, data, error, meta} as structuredContent and the same compact JSON as text; ok=false is a tool error naming the problem. data.snapshot.sections: sec_financials and sec_insider (SEC EDGAR), yfinance_metrics and yfinance_bars (Yahoo Finance via yfinance, unofficial), and factors calculated from the bars (RSI/MACD/ATR, moving averages, levels, risk), each section with as_of, as_of_basis and source; data.freshness gives the last confirmed close and the latest trade (session, time, status). For prices now/today/intraday use freshness, not the factors' bar dates. detail: standard (default) gives values with provenance once per section and rounded numbers, summary headline values only, full every field with per-value provenance; meta.detail_note says how to read same_as, _each and {columns, rows} tables. standard keeps the last 20 daily bars as columns {t,o,h,l,c,v} with the full bar_range, and the markdown report only in full.
Inputs: symbol (required), detail, refresh, confirmed_only. Returns: object
get_ticker_research_statusARead-only
Passive configuration status; performs no provider calls. Returns {ok, data, error, meta} as structuredContent and the same compact JSON as text; ok=false is a tool error naming the problem. data: status, provider readiness, auth mode, planning_configured and the latest-price source health.
Inputs: no named parameters. Returns: object
get_trading_pnlARead-onlyIdempotent
Realized trading P&L under per-account moving-average cost basis.
view "by_symbol": realized P&L, fees and taxes per symbol for the period. view "round_trips": closed buy-to-sell cycles, win rate and open-position P&L. start/end (ISO YYYY-MM-DD) override period. detail_level "summary" lists 20 by_symbol rows, incomplete data first, then the largest realized P&L (symbols_page has the total), or the top 10 round_trips symbols by |realized P&L| with reason groups (symbol_count, omitted_symbols); pass symbol or detail_level "full" for every symbol. Fetched broker rows are recorded in the local append-only ledger (no broker writes).
Inputs: end, view, start, period, +3 more. Returns: object
get_transactionsARead-onlyIdempotent
Your trades across every Toss and KIS account, newest first, one page at a time.
start/end: ISO YYYY-MM-DD (default: the last 90 days). account: "all", "toss", "kis" or one label. The page header carries the totals and counts for the whole window and next_cursor for the following page (limit 1-500, default 100). detail_level "summary" returns compact rows (columns + rows), "full" every normalized field per row, "raw" the brokers' own rows, one source at a time. Fetched broker rows are recorded in the local append-only ledger (no broker writes).
Inputs: end, limit, start, cursor, +3 more. Returns: object
get_ttm_financialsBRead-onlyIdempotent
Get SEC 10-Q/FY-derived TTM financials for a US stock.
Inputs: symbol (required). Returns: object
import_statementAIdempotent
Import Toss stock BUY/SELL rows from a private inbox PDF statement into the local ledger.
Two steps. 1) file=".pdf": parses it and returns the preview and the import plan (nothing is written); keep preview_id. 2) preview_id plus confirm=true stores the planned rows locally. A blocked plan (parse issues, conflicts, unmatched rows inside API coverage) cannot be confirmed. Never places orders; previews expire after 15 minutes.
Inputs: file, account, confirm, preview_id. Returns: object
plan_entryARead-only
Scaled entry calculation, not an order; the amount is your input; no account access. Symbols: US tickers (USD) and KRX listings by code, e.g. 000660, 005930 (tries .KS then .KQ) or 005930.KS (KRW); not indices or other markets. currency defaults to the listing's; amounts and prices stay in it (no FX conversion): USD with a KRX listing or KRW with a US one returns CURRENCY_MISMATCH. KRX listings: Yahoo daily bars, the latest trade and indicators only (no options levels, SEC filings, consensus or earnings date, stated in warnings), limit prices on the KRX tick grid in force since 2023-01-25 (호가단위, rounded down) and whole shares per tranche. Returns {ok, data, error, meta} as structuredContent and the same compact JSON as text; ok=false is a tool error naming the problem. data: attractiveness (score, band, components with their factor inputs), plan (tranches with price, percent, amount and touch probability, expected average cost and fill, comparison_vs_lump_sum, unfilled_remainder, reassess_below), freshness and technical_basis. Spot is the latest trade (any session) and RSI/MACD/ATR/MAs use the same bars as get_technical_indicators, including today's provisional bar (technical_basis, freshness); confirmed_only=true uses the last confirmed close and completed bars. detail: standard (default) gives values with provenance once per section and rounded numbers, summary headline values only, full every field with per-value provenance; meta.detail_note says how to read same_as, _each and {columns, rows} tables. Rejected candidate levels (dropped_levels): standard {reason: {level: price}}, full with their inputs; style constants (style_parameters) and method text only in full; summary drops inputs and levels.
Inputs: amount (required), symbol (required), style, detail, +3 more. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 28 tools
Several tool clusters have overlapping boundaries: get_financials, get_key_metrics, get_sec_financials, get_ttm_financials, get_stock_snapshot, and get_ticker_research all return related fundamental/quote/research data, so an agent may struggle to choose the right one. Portfolio tools also overlap (get_holdings, get_portfolio_summary, get_portfolio_returns, get_trading_pnl, export_portfolio_dataset), though the detailed descriptions mitigate some confusion.
All tool names use snake_case and follow a predictable verb_noun pattern (get_*, compare_*, export_*, import_*, snapshot_*, plan_entry). There are no mixed conventions or vague standalone names.
28 tools is heavy for a single server; the broad investment domain justifies some breadth, but the overlapping financial-data and portfolio-analysis tools suggest the surface could be consolidated. It sits at the borderline between appropriately comprehensive and overstuffed.
The surface covers portfolio holdings, transactions, NAV history, returns, P&L, market quotes, candles, fundamentals, SEC filings, insider data, crypto, technical indicators, planning, and comparisons. Order placement is intentionally excluded and some auxiliary areas (watchlists, alerts, news) are absent, but core read-only investment workflows are well covered.
Maintenance
Related MCP Connectors
Trading MCP server for AI agents, with live market data, account reads and controlled execution.
Free, read-only directory of 114 AI trading tools: broker MCP servers, market data APIs, bots and backtesters. Sourced facts on who can place orders and what safeguards exist; search, compare and check order gating for every broker MCP.
Read-only educational MCP for CryptoDecentral Sovereign. No auth, trading, custody, or advice.
Official Intrinio MCP server. US stock prices, options and fundamentals for AI agents.
Related MCP Servers
- AlicenseAqualityDmaintenanceA read-only MCP server that provides access to Charles Schwab account data and market information, including portfolio positions, real-time quotes, options chains, price history, and account balances through AI assistants.9MIT

milele-prime-mcpofficial
FlicenseNot gradedqualityDmaintenanceRead-only MCP server that lets a verified client connect their own AI to their trading account to read account data without order execution.-- AlicenseAqualityBmaintenanceA read-only MCP server for Trading 212 accounts, enabling AI assistants to query balances, positions, orders, dividends, pies, and instruments without trading capabilities.121MIT
- FlicenseNot gradedqualityDmaintenanceA read-only MCP server that exposes Interactive Brokers and Moomoo brokerage accounts as tools, enabling natural-language queries across positions, trade history, realized P&L, and sector exposure in one merged view.-