portfolio-agent
Serves as the source of truth for structured data; stores decisions, portfolio state, and thesis records in MySQL.
Optional integration to export decisions and knowledge as markdown files into an Obsidian vault for human review.
Fallback LLM provider for synthesis when Claude is unavailable; runs synthesis locally via Ollama.
Optional integration for detecting chart patterns using YOLO models; purely observational track, not affecting decisions.
Click on "Install 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., "@portfolio-agentreview my portfolio"
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.
portfolio-agent
근거와 무효화 조건이 붙은 투자 판단을 내리는 개인용 의사결정 에이전트
뉴스 요약기가 아니라 의사결정 시스템이다. 모든 판단에는 근거 원문 링크와 "이 판단이 뒤집히려면 무엇이 참이어야 하는가" 가 붙는다.
개인 의사결정보조 도구다. 매매 기능은 없고(토스 API 읽기전용), 출력은 투자 권유가 아니다.
왜 이렇게 만들었나
LLM에게 포트폴리오를 물으면 그럴듯한 수치를 지어내고, 틀려도 조용하다. 이 시스템은 그 실패 모드를 구조로 막는다.
원칙 | 의미 |
🔢 수치는 LLM이 만들지 않는다 | 가격은 토스, 공시는 DART/EDGAR 원문. 계산은 |
⛔ 근거 + 무효화 조건 강제 | 근거 원문 링크와 무효화 조건이 없는 추천은 코드 게이트가 반려한다. 설득이 아니라 검증이다. |
👁️ 읽기 전용 | 주문·정정·취소 엔드포인트는 코드에 존재하지 않는다. |
📍 사실 하나당 소스 하나 | 정형 상태는 MySQL, 서술은 마크다운 vault. 중복 저장 = drift. |
🧪 관찰 트랙 격리 | 기술적 지표·뉴스 감성은 확률적 신호다. 판단 엔진에 들어가지 않고 사람이 보는 병렬 트랙으로만 존재한다. |
Related MCP server: CRASH - Cascaded Reasoning with Adaptive Step Handling
어떻게 도는가
flowchart LR
subgraph SRC["📥 sources · 읽기전용"]
T["토스증권<br/>보유·시세"]
D["DART / EDGAR<br/>공시 원문"]
end
subgraph ENG["⚙️ engines · LLM 없음"]
Q["quant<br/>집중도·상관·리스크"]
TH["thesis<br/>논지 상태머신"]
end
subgraph JUD["🧠 판단"]
B["근거 번들 E#<br/>(그라운딩 원장)"]
L["Claude Code<br/>종합"]
G{"게이트<br/>근거·무효화·수치 대조"}
end
ST[("MySQL<br/>SoT")]
V["📓 vault<br/>Obsidian 미러"]
T --> Q --> B
D --> TH --> B
B --> L --> G
G -->|"통과"| ST
G -->|"반려"| L
ST --> V
style G fill:#D97757,stroke:#8B3A2B,color:#fff
style ST fill:#4479A1,stroke:#2C5378,color:#fff게이트는 ① 인용된 근거 E#이 실제로 원장에 있는지 ② 무효화 조건이 붙었는지 ③ 수치가 원본과 일치하는지 ④ 보유 종목 전원에 판단이 있는지를 검사한다. 통과분만 저장된다.
셋업
요구사항 — Python 3.11+, MySQL 8.x (uv 권장) LLM API 키는 필요 없다. 판단 합성은 Claude Code 또는 로컬 CLI로만 실행된다.
# 1) 의존성
uv venv --python 3.12 && source .venv/bin/activate
uv pip install -e ".[dev]"
# 2) 시크릿 — MYSQL_DSN · TOSS_* · DART_API_KEY 를 채운다
cp .env.example .env
# 3) 스키마 + 점검
python -m src.cli.brief init-db
python -m src.cli.brief doctor사용
python -m src.cli.brief review # 온디맨드 심층 판단
python -m src.cli.brief review --mock # 토스 키 없이 mock 픽스처로 파이프라인 확인
python -m src.cli.brief daily # 일일 다이제스트 (코드 수치만, LLM 없음)
python -m src.cli.brief watch # 백그라운드 논지 감시 — 무효화 트리거 시에만 알림
python -m src.cli.brief retrospect # 제안 vs 실제 행동 vs 결과 회고논지 레코드가 판단의 상태머신이다. 신규 공시·실적이 들어오면 thesis.py가 무효화 조건을 점검해 status를 valid → watch → broken으로 갱신한다.
python -m src.cli.brief thesis add <TICKER> --entry-price <가격> --weight <비중> \
--thesis "<왜 샀는가 한 줄>" --assumption "<핵심 가정>" \
--cond "<서술>|price<<임계값>|broken" --cond "<질적 조건>||watch"--cond 는 설명|룰|심각도 형식이다. 룰을 비우면 코드가 아니라 사람이 판정하는 질적 조건이 된다.
.env에 OBSIDIAN_VAULT_PATH를 주면 review 성공 시 Companies/·Thesis/·Daily/·Decision/ 마크다운이 생성된다.
MySQL이 유일한 SoT이고 vault는 생성물 미러다 — 비워두면 조용히 비활성화되고(경고 없음), Obsidian 설치도 불필요하다. 보유에서 빠진 종목 문서는 삭제되지 않고 Archived로 표시되어 이력이 남는다.
판단 LLM = Claude Code
1차 경로 — Claude Code 안에서 /review. portfolio MCP 서버의 review_begin이 그라운딩 근거 번들을 만들고, Claude Code가 내부 추론으로 판단 JSON을 작성해 review_submit에 제출한다.
폴백 — 터미널 단독 실행 시 SYNTHESIS_PROVIDER=auto가 로컬 CLI를 탐지한다: claude -p → gemini → ollama → 없으면 번들만 출력. 어떤 엔진이든 게이트는 동일하다.
claude mcp add portfolio -s project -- python -m src.mcp.portfolio_server
claude mcp add sources -s project -- python -m src.mcp.sources_server
claude mcp list # 헬스 확인구조
계층은 위에서 아래로만 의존한다. 관찰 트랙(회색 점선)은 판단 경로에 닿지 않는다 — 확률적 신호가 의사결정에 새어드는 걸 구조로 막는다.
flowchart TB
subgraph L1[" ① 진입 · <i>Claude Code · 터미널</i> "]
direction LR
CLI["<b>cli/</b><br/>brief.py<br/><sub>review · daily · watch</sub>"]
MCPS["<b>mcp/</b><br/>portfolio · sources<br/><sub>stdio 서버</sub>"]
end
subgraph L2[" ② 판단 · <i>여기서만 LLM</i> "]
SYN["<b>synthesis/</b><br/>decision · prompts · llm<br/><sub>근거·무효화 게이트</sub>"]
end
subgraph L3[" ③ 도메인 · <i>LLM 없음 · 순수 코드</i> "]
direction LR
ENG["<b>engines/</b><br/>quant · thesis<br/><sub>계산 · 상태머신</sub>"]
OBSV["<b>engines/</b><br/>technical · sentiment<br/><sub>관찰 트랙 — 격리</sub>"]
end
subgraph L4[" ④ 데이터 "]
direction LR
SRC["<b>sources/</b><br/>toss · dart · edgar<br/><sub>읽기전용</sub>"]
STO["<b>storage/</b><br/>Repository → MySQL<br/><sub>정형 SoT</sub>"]
KNW["<b>knowledge/</b><br/>vault export<br/><sub>생성물 미러</sub>"]
end
CLI --> SYN
MCPS --> SYN
SYN --> ENG
ENG --> SRC
ENG --> STO
STO --> KNW
OBSV -.->|"판단 우회"| KNW
SRC -.-> OBSV
style SYN fill:#D97757,stroke:#8B3A2B,stroke-width:2px,color:#fff
style STO fill:#4479A1,stroke:#2C5378,stroke-width:2px,color:#fff
style OBSV fill:#F0F1F3,stroke:#8C959F,stroke-dasharray:4 3,color:#57606A
style KNW fill:#F0F1F3,stroke:#8C959F,color:#24292F
linkStyle 6,7 stroke:#8C959F,stroke-dasharray:4 3계층 | 모듈 | 불변식 |
① |
| MCP 서버는 stdout에 프로토콜 메시지만 — 로그는 stderr |
② |
| 근거 |
③ |
| LLM 호출이 존재하지 않는다. 같은 입력 → 같은 출력 |
④ |
| 매매 함수 없음 · 사실 하나당 소스 하나 |
테스트
pytest # 전부 오프라인 — 외부 API · LLM · MySQL 불필요 (fake/mock 기반)라이선스
이 저장소는 MIT다. 핵심 의존성(httpx · pymysql · cryptography · python-dotenv · mcp · numpy)은 전부 BSD/MIT/Apache 계열이라 충돌이 없다.
선택적 extra [yolo] 는 AGPL-3.0 이다.
차트 패턴 탐지에 쓰이는 ultralytics는 AGPL-3.0 이며, 이는 이 저장소의 MIT 와 다른 조건이다.
이 저장소는 ultralytics 코드도 모델 가중치도 포함하지 않는다 — engines/patterns.py 에서 lazy import 할 뿐이고, 미설치 시 조용히 비활성화된다.
uv pip install -e ".[yolo]" 를 실행하는 순간부터 AGPL-3.0 조건이 적용되며, 준수 책임은 설치한 쪽에 있다. AGPL 이 곤란하다면 이 extra 를 설치하지 마라 — 의사결정 코어는 YOLO 없이 완전히 동작한다 (애초에 관찰 트랙이라 판단 경로에 닿지 않는다).
[sentiment] extra(transformers, Apache-2.0)와 [technical] extra(matplotlib, PSF)는 허용적 라이선스다.
문서
설계 규율 — 행동 계약 | |
작업 백로그 | |
원본 설계 명세 | |
그라운딩 게이트 설계 | |
운영 | |
관찰 트랙 | |
토큰 예산 |
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/Daegyu519/portfolio-agent'
If you have feedback or need assistance with the MCP directory API, please join our Discord server