토스증권 API로 AI에 연결하기 1편

전에 증권사 API 글을 쓰면서 이런 약속을 했습니다. “제가 쓰는 증권사에서 API가 나오면 직접 테스트해보고 방법을 공유하겠다”고요.

채팅창에 “내 잔고 알려줘”라고 치면 실제 계좌를 조회해서 답이 옵니다. 토스증권 API를 발급받아서 AI와 연결하는 데까지 성공했거든요. 다만 과정이 순탄하진 않았습니다. 몇 군데서 꽤 헤맸고, 그래서 이 글은 성공담보다는 삽질 기록에 가깝습니다.

토스증권 API를 AI에 연결하는 4단계 흐름과 각 단계에서 막히는 지점

미리 알아두면 좋은 것

필요한 것

  • 토스증권 계좌
  • 윈도우 PC (맥도 되지만 이 글은 윈도우 기준입니다)
  • 파이썬
  • 클로드 데스크톱 앱 (무료 계정도 가능합니다)

난이도

코딩을 몰라도 따라 할 수 있게 썼습니다. 다만 복사·붙여넣기와 파일 경로 다루기 정도는 하셔야 합니다. 저도 개발자가 아니라 제조업 엔지니어입니다.

소요 시간

막히지 않으면 30분, 저처럼 헤매면 2시간쯤 걸립니다.

중요한 전제 하나

이 글에서 만드는 건 조회 전용입니다. AI가 제 계좌를 들여다볼 수는 있지만 주문은 낼 수 없게 만듭니다. 이유는 마지막에 따로 설명드리겠습니다.


1단계 — API 키 발급받기

앱에서 아무리 찾아도 안 나옵니다

저는 여기서 처음 막혔습니다. 토스증권 앱을 아무리 뒤져도 Open API 메뉴가 없더라구요. “HTS만 되는 건가?” 싶었는데 아니었습니다.

Open API는 PC 웹에서만 설정할 수 있습니다. 정확히는 토스증권 WTS(웹 트레이딩 화면)에서요. 모바일 앱 메뉴에는 없습니다.

PC 브라우저로 토스증권에 로그인하면 이런 화면이 뜹니다. 여기서 화면 맨 오른쪽 아래 구석의 톱니바퀴 아이콘을 찾으세요. 아래 사진에 빨간 네모로 표시해뒀습니다.

화면 오른쪽 아래 구석에 있어서 그냥 보면 잘 안 보입니다

저는 이 아이콘을 못 찾아서 한참 헤맸습니다. 화면 구석에 작게 있고 메뉴 이름도 없어서, 위쪽 메뉴바만 계속 뒤졌거든요.

아이콘을 누르면 설정 창이 뜨는데, 왼쪽 목록 맨 아래에 Open API 항목이 있습니다.

키 발급

Open API 메뉴에 들어가면 이런 화면이 나옵니다.

키 발급과 허용 IP 등록을 이 한 화면에서 다 합니다

여기서 Client IdClient Secret 두 개를 발급받게 됩니다. 아이디와 비밀번호 같은 거라고 생각하시면 됩니다. 유효기간은 1년이라 만료일도 같이 표시됩니다.

⚠️ 여기서 제가 크게 당황했습니다

Client Secret은 처음 발급될 때 딱 한 번만 보입니다.

Client Id는 옆에 ‘복사’ 버튼이 있어서 언제든 다시 가져올 수 있는데, Secret은 별표로만 표시되고 다시 볼 수가 없습니다. 저는 “나중에 보면 되겠지” 하고 창을 닫았다가 낭패를 봤어요.

발급되는 순간 바로 복사해서 메모장에 저장하세요. 그 화면을 닫으면 끝입니다.

이미 놓치셨다면 방법은 하나, 재발급입니다. 재발급 버튼을 누르면 새 Secret이 화면에 뜨는데, 그때 바로 저장하시면 됩니다. 아직 아무 데도 안 쓰셨다면 재발급해도 잃을 게 없으니 부담 갖지 마세요. 다만 기존 키는 무효가 되니, 이미 어딘가에 등록해두셨다면 그것도 전부 새 값으로 바꿔야 합니다.

⚠️ 허용 IP 등록 — 안 하면 무조건 막힙니다

같은 화면 아래쪽에 허용 IP 관리가 있습니다. 이게 없으면 API 호출이 전부 차단됩니다. 등록되지 않은 IP에서 요청하면 403 에러가 떨어져요.

구글에 “내 아이피”를 검색하면 지금 쓰는 인터넷 주소가 나옵니다. 그 값을 등록하세요.

참고로 가정용 인터넷은 IP가 바뀔 수 있습니다. 잘 되던 게 어느 날 갑자기 403이 뜬다면 이걸 제일 먼저 의심하세요.


2단계 — 파이썬 설치

설치 자체는 간단합니다

파이썬 공식 홈페이지에서 최신 버전을 받아 설치하시면 됩니다. 설치 화면 맨 아래의 “Add python.exe to PATH” 체크박스를 꼭 켜세요. 이걸 놓치면 명령어를 인식 못 합니다.

⚠️ 파이썬이 여러 개로 보이는 문제

설치 후 명령 프롬프트(시작 메뉴에서 cmd 검색)에서 이걸 쳐보세요.

where python

저는 이렇게 세 줄이 나왔습니다.

...\AppData\Local\Programs\Python\Python314\python.exe
...\AppData\Local\Microsoft\WindowsApps\python.exe
...\AppData\Local\Python\bin\python.exe

파이썬을 하나만 깔았는데 왜 세 개일까요. 아래 둘은 실제 파이썬이 아니라 연결용 껍데기입니다. 특히 WindowsApps 쪽은 마이크로소프트 스토어로 연결되는 바로가기라, 이걸 지정하면 엉뚱하게 스토어 창이 뜨기도 합니다.

진짜는 Programs\Python\Python3xx\python.exe 경로입니다. 나중에 이 경로를 쓸 일이 있으니 메모해두세요.


3단계 — 첫 연동 테스트

AI 연결은 나중 이야기고, 먼저 파이썬으로 직접 호출해봅니다. 여기서 성공해야 다음 단계가 의미가 있습니다.

먼저, 명령 프롬프트 여는 법

앞으로 나오는 명령어들은 전부 명령 프롬프트라는 검은 창에 입력합니다. 파이썬 프로그램은 아이콘을 더블클릭해서 실행하는 게 아니라 여기서 실행하거든요.

여는 방법은 간단합니다. 키보드의 윈도우 키를 누르고 cmd를 입력한 뒤 엔터를 치면 검은 창이 하나 뜹니다. 이게 명령 프롬프트입니다.

창이 열리면 C:\Users\사용자명> 같은 글자 뒤에 커서가 깜빡이고 있을 겁니다. 그 자리에 명령어를 한 줄 입력하고 엔터를 치면 실행됩니다. 아래에 나오는 코드 블록들은 한 줄씩 복사해서 붙여넣고 엔터를 치시면 됩니다.

참고로 검은 창에 붙여넣기는 마우스 우클릭으로 됩니다. Ctrl+V도 요즘은 대부분 동작합니다.

라이브러리 설치

명령 프롬프트에 이걸 입력하고 엔터를 치세요.

pip install requests

테스트 코드

메모장에 아래를 붙여넣고 toss_test.py로 저장하세요. 저장 위치는 C 드라이브에 toss 폴더를 하나 만들어서 거기 두시길 권합니다. 나중에 경로 지정할 때 훨씬 편합니다.

저장할 때 함정이 하나 있습니다. 메모장에서 그냥 저장하면 파일명이 toss_test.py.txt가 되어버려서 실행이 안 됩니다. 저장 대화상자에서 파일 형식을 “모든 파일”로 바꾸고 파일 이름에 toss_test.py를 입력하세요.

import requests

CLIENT_ID = "발급받은_client_id"
CLIENT_SECRET = "발급받은_client_secret"
BASE = "https://openapi.tossinvest.com"

# 1) 토큰 발급
res = requests.post(f"{BASE}/oauth2/token", data={
    "grant_type": "client_credentials",
    "client_id": CLIENT_ID,
    "client_secret": CLIENT_SECRET,
})
print("토큰 응답:", res.status_code)
token = res.json()["access_token"]

# 2) 삼성전자 현재가 조회
r = requests.get(f"{BASE}/api/v1/prices",
                 params={"symbols": "005930"},
                 headers={"Authorization": f"Bearer {token}"})
print(r.json())

실행

명령 프롬프트에서 먼저 파일이 있는 폴더로 이동한 다음 실행합니다. cd는 폴더를 이동하는 명령어예요.

cd C:\toss

엔터를 치면 커서 앞의 경로가 C:\toss>로 바뀝니다. 이제 그 폴더 안에 있다는 뜻입니다. 이어서 실행합니다.

python toss_test.py

현재가 정보가 주르륵 나오면 성공입니다.

파일을 다른 곳에 저장하셨다면 cd 뒤의 경로만 바꾸시면 됩니다. 경로를 모르겠으면, 탐색기에서 그 폴더를 연 뒤 주소창을 클릭하면 전체 경로가 글자로 바뀌는데 그걸 복사해서 cd 뒤에 붙여넣으시면 됩니다.

파일을 찾을 수 없습니다라는 에러가 나오면 폴더를 잘못 찾아간 것이거나 파일명이 .py.txt로 저장된 경우입니다.

여기서 나올 수 있는 에러

403이 뜬다면 — 허용 IP 등록을 확인하세요. 열에 아홉은 이겁니다.

401이 뜬다면 — 키가 잘못됐습니다. 복사할 때 앞뒤 공백이 섞이지 않았는지 보세요.

토큰이라는 개념이 헷갈렸습니다

Client ID Secret과 액세스 토큰의 차이, 시크릿은 한 번만 표시됨

저는 처음에 “토큰은 어느 사이트에서 받는 거지?” 하고 한참 찾았습니다. 그런 페이지는 없습니다.

토큰은 사람이 받는 게 아니라 프로그램이 받는 겁니다. Client Id와 Secret을 서버에 보내면 서버가 임시 출입증을 하나 내주는데, 그게 토큰이에요. 유효기간도 있어서 만료되면 프로그램이 다시 받아옵니다. 그래서 발급 페이지가 아니라 코드 몇 줄인 겁니다.


4단계 — AI(클로드)와 연결하기

여기부터가 진짜입니다.

MCP가 뭔가요

AI에게 외부 도구를 붙여주는 표준 규격입니다. 쉽게 말하면 AI가 쓸 수 있는 리모컨을 만들어 쥐여주는 것이라고 보시면 됩니다.

우리는 “토스 계좌를 조회하는 리모컨”을 만들어서 클로드에게 줄 겁니다. 그러면 클로드가 필요할 때 그 버튼을 눌러서 데이터를 가져옵니다.

⚠️ 웹 브라우저 클로드로는 안 됩니다

브라우저 클로드와 데스크톱 앱의 차이, MCP 서버는 내 PC에서 실행됨

이 리모컨(MCP 서버)은 내 PC에서 돌아가는 프로그램입니다. 브라우저에서 접속한 클로드는 내 PC 안을 들여다볼 수 없어요. 그래서 클로드 데스크톱 앱이 필요합니다.

⚠️⚠️ 여기서 제일 크게 막혔습니다 — 스토어 버전

저는 무심코 마이크로소프트 스토어에서 클로드를 설치했습니다. 그리고 설정 파일을 아무리 고쳐도 인식이 안 돼서 한참을 헤맸어요.

원인은 이랬습니다. 스토어 앱은 격리된 공간에서 돌아갑니다. 그래서 일반적인 설정 폴더가 아니라 이런 깊은 경로를 씁니다.

C:\Users\사용자명\AppData\Local\Packages\Claude_xxxxx\LocalCache\Roaming\Claude

즉 제가 편집한 파일과 앱이 읽는 파일이 서로 다른 곳에 있었던 겁니다.

해결책은 두 가지입니다.

  1. 위 경로를 직접 찾아가서 그곳의 설정 파일을 고친다
  2. 스토어 버전을 지우고 공식 홈페이지에서 설치 파일을 받아 다시 설치한다

저는 1번으로 해결했지만, 처음 하시는 분께는 2번을 권합니다. 경로가 단순해져서 나중에 로그 확인할 때도 편합니다.

조회 전용 서버 코드

아래를 toss_mcp_server.py로 저장하세요. 위치는 C:\toss 폴더입니다.

이 코드에는 API 키를 적지 않습니다. 설정 파일에서 따로 넘겨받도록 만들었어요. 그래야 코드를 블로그에 올리거나 남에게 보여줄 때 안전합니다.

import os, json, time, requests

try:
    from mcp.server import MCPServer as ServerClass       # mcp 2.x
except ImportError:
    from mcp.server.fastmcp import FastMCP as ServerClass  # mcp 1.x

BASE = "https://openapi.tossinvest.com"
CLIENT_ID = os.environ.get("TOSS_CLIENT_ID", "")
CLIENT_SECRET = os.environ.get("TOSS_CLIENT_SECRET", "")

mcp = ServerClass("toss-securities")
_token = {"value": None, "expires_at": 0}
_account = {"value": None}

def _get_token():
    if _token["value"] and time.time() < _token["expires_at"]:
        return _token["value"]
    res = requests.post(f"{BASE}/oauth2/token", data={
        "grant_type": "client_credentials",
        "client_id": CLIENT_ID,
        "client_secret": CLIENT_SECRET,
    }, timeout=10)
    data = res.json()
    _token["value"] = data["access_token"]
    _token["expires_at"] = time.time() + int(data.get("expires_in", 3600)) - 60
    return _token["value"]

def _account_seq():
    if _account["value"]:
        return _account["value"]
    r = requests.get(f"{BASE}/api/v1/accounts",
                     headers={"Authorization": f"Bearer {_get_token()}"}, timeout=10)
    body = r.json()
    items = body if isinstance(body, list) else (body.get("result") or body.get("data") or [])
    if isinstance(items, dict):
        items = [items]
    for it in items:
        for k in ("accountSeq", "accountNo", "id"):
            if isinstance(it, dict) and k in it:
                _account["value"] = it[k]
                return it[k]
    return None

def _get(path, params=None, with_account=False):
    headers = {"Authorization": f"Bearer {_get_token()}"}
    if with_account:
        headers["X-Tossinvest-Account"] = str(_account_seq())
    r = requests.get(f"{BASE}{path}", params=params or {}, headers=headers, timeout=10)
    if r.status_code != 200:
        hint = "허용 IP 등록을 확인하세요." if r.status_code == 403 else ""
        return f"[실패] HTTP {r.status_code} {r.text[:300]} {hint}"
    return json.dumps(r.json(), ensure_ascii=False, indent=2)

@mcp.tool()
def toss_price(symbols: str) -> str:
    """종목 현재가 조회. 국내는 종목코드(005930), 미국은 티커(AAPL)."""
    return _get("/api/v1/prices", {"symbols": symbols})

@mcp.tool()
def toss_holdings() -> str:
    """내 보유 주식과 평가금액, 손익 조회."""
    return _get("/api/v1/holdings", with_account=True)

@mcp.tool()
def toss_buying_power() -> str:
    """매수 가능 금액 조회."""
    return _get("/api/v1/buying-power", with_account=True)

@mcp.tool()
def toss_exchange_rate() -> str:
    """원/달러 환율 조회."""
    return _get("/api/v1/exchange-rate")

if __name__ == "__main__":
    mcp.run()

라이브러리를 하나 더 설치합니다.

pip install mcp requests

⚠️ 설정 파일 — JSON 문법 함정

claude_desktop_config.json 파일에 서버를 등록해야 합니다. 파일 위치는 탐색기 주소창에 %APPDATA%\Claude를 치면 나옵니다. (스토어 버전이면 앞서 말한 깊은 경로예요.)

여기서 또 막혔습니다. 파일에 이미 다른 내용이 들어 있었는데, 제가 아래에 그냥 이어 붙였거든요. 그랬더니 이런 에러가 떴습니다.

Unexpected non-whitespace character after JSON at position ...

JSON 파일에는 최상위 덩어리가 하나만 있어야 합니다. 기존 내용이 }로 끝났는데 그 뒤에 새 {를 붙이면 두 덩어리가 되어버립니다.

올바른 방법은 기존 내용 안에 항목으로 끼워 넣는 것입니다. 파일이 비어 있다면 이대로 쓰시면 되고,

{
  "mcpServers": {
    "toss": {
      "command": "C:\\Users\\사용자명\\AppData\\Local\\Programs\\Python\\Python314\\python.exe",
      "args": ["C:\\toss\\toss_mcp_server.py"],
      "env": {
        "TOSS_CLIENT_ID": "발급받은_client_id",
        "TOSS_CLIENT_SECRET": "발급받은_client_secret"
      }
    }
  }
}

기존 내용이 있다면 마지막 항목 뒤에 쉼표를 붙이고 "mcpServers": { ... } 부분만 추가하세요. 닫는 중괄호는 늘어나지 않습니다.

주의할 점 세 가지

  • 경로의 역슬래시는 반드시 두 개(\\)입니다. 하나면 인식되지 않습니다.
  • command에는 python만 쓰지 말고 아까 확인한 전체 경로를 넣으세요. 앱이 어느 파이썬을 집을지 알 수 없거든요.
  • 메모장으로 저장하면 파일명이 .json.txt가 되기 쉽습니다. 탐색기에서 보기 → 파일 확장명에 체크해서 확인하세요.

완전 종료 후 재시작

창의 X만 눌러서는 백그라운드에 남습니다. 작업 표시줄 트레이에서 클로드를 우클릭해 완전히 종료한 뒤 다시 실행하세요.

설정 → 커넥터(또는 개발자) 메뉴에서 toss 서버가 running으로 표시되면 성공입니다.


5단계 — 실제로 써보기

이제 클로드 데스크톱에서 그냥 말로 물어보면 됩니다.

  • “내 보유 주식 알려줘”
  • “지금 원달러 환율 얼마야?”
  • “내 계좌에서 현금 비중이 몇 퍼센트야?”
  • “QLD 평단이 얼만데, 여기서 10% 더 빠지면 평가손익이 어떻게 돼?”

처음 실행할 때는 도구 사용 허가를 물어봅니다. 승인하시면 됩니다.

저는 매매일기 쓸 때 제일 유용했습니다. 그동안 계좌 화면을 보면서 수량과 평단을 손으로 옮겨 적었는데, 이제 “오늘 잔고 조회해서 표로 정리해줘” 한 줄이면 끝납니다. 숫자 옮기다 틀릴 일도 없어졌고요.

위에 사진이 제 토스증권 계좌를 클로드와 연결해서 작업 중인 환경입니다.


왜 클로드로 했나, 다른 AI는 안 되나

이 글은 클로드 기준으로 썼는데, 이유가 있습니다.

MCP라는 규격 자체를 앤트로픽(클로드 만든 회사)이 만들었습니다. 그래서 클로드 데스크톱 앱이 가장 먼저, 가장 단순하게 지원합니다. 설정 파일 하나에 몇 줄 적으면 끝이고 별도 플러그인이 필요 없어요. 처음 해보는 입장에서는 변수가 적은 쪽이 낫다고 판단했습니다.

그렇다고 클로드 전용은 아닙니다. MCP는 특정 회사가 독점하는 게 아니라 공개된 표준이고, 다른 AI 도구와 코드 에디터들도 지원을 추가해 왔습니다.

여기서 중요한 게 하나 있습니다. 우리가 만든 서버 코드는 특정 AI를 위한 게 아닙니다. toss_mcp_server.py는 그냥 “토스 계좌를 조회하는 리모컨”일 뿐이에요. 그 리모컨을 누가 쥐느냐만 달라지는 겁니다.

그래서 다른 AI로 옮기고 싶다면 서버 코드는 그대로 두고 클라이언트 쪽 설정만 바꾸면 됩니다. 파이썬 경로와 파일 경로, API 키를 넘기는 부분은 어느 도구든 비슷한 형태거든요.

다만 도구마다 다른 점이 있으니 미리 알아두세요.

  • 설정 파일의 위치와 이름이 다릅니다. 클로드는 claude_desktop_config.json이지만 다른 도구는 다른 경로를 씁니다.
  • 지원 여부와 범위가 계속 바뀝니다. 이 분야는 변화가 빨라서, 쓰시려는 도구의 공식 문서를 한 번 확인하시는 게 정확합니다.
  • 웹 브라우저 버전은 대체로 안 됩니다. 앞에서 설명한 이유와 같습니다. 내 PC에서 도는 프로그램에 접근해야 하니 데스크톱 앱이나 로컬에서 실행되는 도구여야 합니다.

정리하면, 어려운 부분은 이미 다 끝났습니다. 키 발급하고 서버 코드 만든 것까지가 90%고, 어느 AI에 붙이느냐는 나머지 10%입니다.


왜 주문 기능은 넣지 않았나

눈치채신 분도 있겠지만, 위 코드에는 조회 도구만 있고 주문 도구가 없습니다. 일부러 뺐습니다.

이유가 두 가지입니다.

첫째, AI는 틀릴 수 있습니다. 평소에는 애교로 넘어갈 실수가, 실제 주문으로 이어지는 순간 돈이 됩니다. 제가 선반영 글에서 썼듯이 조회와 분석까지는 맡겨도 매매 판단은 다른 이야기예요.

GET 요청만 보내는 구조라 주문이 원천적으로 불가능함

둘째, 구조적으로 막아두는 게 확실합니다. 이 서버는 HTTP GET 요청만 보냅니다. 토스에서 주문 생성·정정·취소는 전부 POST나 DELETE 방식이라, 이 코드로는 애초에 주문을 낼 방법이 없습니다.

설정으로 끄는 것과 길 자체를 없애는 건 다릅니다. 설정은 실수로 켤 수 있지만, 없는 길은 켤 수가 없으니까요. 저는 후자가 마음이 편하더라구요.


해보고 나서 느낀 한계

주문 유형이 제한적입니다. 토스 API는 지정가와 시장가만 지원하고 LOC는 없습니다. 무한매수법처럼 LOC 주문이 핵심인 전략은 그대로 옮기기 어렵습니다. 반면 리밸런싱 주기가 긴 전략은 지정가만으로도 충분하고요.

실시간 스트리밍이 아닙니다. 호출한 그 시점의 값을 가져오는 방식이라, 초 단위로 반응해야 하는 매매에는 맞지 않습니다.

호출 제한이 있습니다. API 종류별로 초당 요청 수가 정해져 있어서, 무작정 반복 호출하면 429 에러가 납니다.


막히기 쉬운 곳 정리

제가 헤맨 순서대로 정리하면 이렇습니다. 이것만 피해도 30분이면 끝납니다.

증상원인해결
앱에 Open API 메뉴가 없음모바일 앱에는 없음PC 웹(WTS) 설정에서 진입
Client Secret을 다시 못 봄최초 1회만 표시재발급 후 즉시 저장
403 에러허용 IP 미등록내 IP 확인 후 등록
파이썬 경로가 여러 개나머지는 껍데기Programs\Python\... 경로 사용
설정을 고쳐도 인식 안 됨스토어 버전의 격리된 경로일반 설치 버전으로 재설치
JSON 파싱 에러덩어리가 두 개가 됨기존 내용 안에 항목으로 삽입
서버 목록에 안 뜸앱이 완전히 안 꺼짐트레이에서 종료 후 재실행

마치며

솔직히 중간에 몇 번 접을 뻔했습니다. 특히 스토어 버전 문제는 원인을 찾기 전까지 뭐가 잘못됐는지 짐작조차 안 되더라구요.

그런데 다 연결하고 나서 “내 잔고 알려줘”라고 쳤을 때 실제 숫자가 튀어나오는 걸 보니 꽤 재밌었습니다. 증권사 API 글을 쓸 때만 해도 “이런 게 된다더라” 수준이었는데, 직접 해보니 확실히 다르네요.

다음에는 조회를 넘어서 자동매매 쪽을 다뤄볼까 합니다. 다만 그건 훨씬 조심스럽게 접근해야 할 영역이라, 실제 주문을 내지 않고 기록만 남기는 방식부터 시작해보려고 합니다. 그 과정도 정리해서 올리겠습니다.

읽어주셔서 감사합니다.


※ 본 글은 특정 상품이나 서비스 추천이 아닙니다. API 키는 본인 계좌에 대한 접근 권한이므로 절대 외부에 노출하지 마시고, 코드나 화면을 공유할 때 키가 포함되지 않았는지 반드시 확인하세요. API 사양과 화면 구성은 작성 시점 기준이며 이후 변경될 수 있습니다. 자동화된 매매는 예기치 않은 손실로 이어질 수 있으며, 그 책임은 이용자 본인에게 있습니다.

댓글 남기기