KAVEN โ Korean AI-based Vigilance for Event Navigation
AIS(ํด์)ยทADS-B(ํญ๊ณต)ยท๋ด์คยท์์ ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ณ , LLM ๋ถ์๊ณผ ์ค๋ณต ์ ๊ฑฐ๋ฅผ ๊ฑฐ์ณ severity(1โ5) ์ด๋ฒคํธ๋ฅผ ์์ฑํ๋ ์ง์ ํ ์กฐ๊ธฐ๊ฒฝ๋ณด ์์คํ ์ ๋๋ค. ํ ๋ ๊ทธ๋จ ๊ฒฝ๋ณด, Palantir ์คํ์ผ ์น ์์ ์ฝ์(Ops Console), ๊ทธ๋ฆฌ๊ณ AI ์์ด์ ํธ ์ฐ๋(MCP + REST)์ ์ ๊ณตํฉ๋๋ค.
ํ์ฌ ๋ฒ์ : 0.0.21 ยท ๋ณ๊ฒฝ ์ด๋ ฅ: docs/release-notes.md ยท ๋ผ์ด์ ์ค: MIT
์ง๋๋ ๋ด์ฅ ๋ฒกํฐ ์๋๋งต(Natural Earth 110m + ๋ก์ปฌ ๋ฒ๋ค Leaflet)์ผ๋ก ๋ ๋๋ง๋ฉ๋๋ค โ CDNยทํ์ผ ์๋ฒ ์์ด ์คํ๋ผ์ธ์์๋ ํญ์ ๋์ผํ๊ฒ ๋์ํฉ๋๋ค.
COP (Common Operating Picture) โ ๋ฒกํฐ ์๋๋งต + ๊ฐ์๊ตฌ์ญ ์ค๋ฒ๋ ์ด + severity ๋ง์ปค + 24์๊ฐ ํ์๋ผ์ธ + ์ง์ญ ๋์์(7์ผ ์คํํฌ๋ผ์ธ):
AO ์ค โ ๊ฐ์๊ตฌ์ญ ํ๋ (ํ๋ฐ๋ ADS-B ๊ตฌ์ญ + S5 ์ด๋ฒคํธ ๋ง์ปค):
Event Feed โ ํํฐยท์ ๋ ฌ ๊ฐ๋ฅํ ์ด๋ฒคํธ ํธ๋ฆฌ์์ง ํ ์ด๋ธ + ์ธ์คํํฐ(๋ถ์ ๊ทผ๊ฑฐยท์ํฅ ์์ฐยท์ถ์ฒ):
| Intel Report | Asset Impact |
|---|---|
![]() |
![]() |
| ๊ท์น ๊ธฐ๋ฐ ์ผ์ผ ๋ธ๋ฆฌํ (LLM/API ํค ๋ถํ์) | ์์ฐ๋ณ 7์ผ severity ํํธ๋งต + ์ ํธ ๋ถํฌ |
Command Palette (Ctrl+K) |
System / Collection |
|---|---|
![]() |
![]() |
| ์ง์ญยท์ด๋ฒคํธยท์์ฐยท๋ทฐยท์ก์ ํตํฉ ๊ฒ์ | ๊ฐ์๊ตฌ์ญ/ํผ๋/ํค์๋ ์์ง ์ํ ๋ณด๋ |
Settings โ zcode ์คํ์ผ ์ค์ ์ฝ์ (์ข์ธก ๋ด๋น: ์ฝ์/๋ชจ๋ธ/์์งยท๋ฐ์ดํฐ ๊ทธ๋ฃน, ์ ํ ํญ ์ ์ง):
ํค๋ณด๋ ๋จ์ถํค โ ? ํค๋ก ์ฝ์ ์์์ ์ธ์ ๋ ํ์ธ:
- ์ฃผ์ ๊ธฐ๋ฅ
- ์์คํ ์ํคํ ์ฒ
- ๋น ๋ฅธ ์์
- ์น ์์ ์ฝ์
- AI ์์ด์ ํธ ์ฐ๋
- ์ค์
- API ์์ฝ
- ํ๋ก์ ํธ ๊ตฌ์กฐ
- ํ ์คํธ
- ์ด์ / ํธ๋ฌ๋ธ์ํ
- ๋ฌธ์ยท๊ธฐ์ฌยท๋ผ์ด์ ์ค
- 4์ฑ๋ ์์ง โ AIS ์ ๋ฐ(ํธ๋ฅด๋ฌด์ฆยท๋ง๋ผ์นด ๋ฑ), ADS-B ํญ๊ณต(์ค๋ยท๋๋งยทํ๋ฐ๋),
๋ด์ค RSS(๊ธฐ๋ณธ 13๊ฐ ๋ฌด๋ฃยทํ์ด์ ์๋ ๊ณต๊ฐ ํผ๋: AP/BBC/Al Jazeera/Guardian/
DW/France 24/UN News/CNA/gCaptain/OilPrice/Google News + SearxNG),
์์
๊ฒ์. ๊ฐ์๊ตฌ์ญยทํผ๋ยทํค์๋๋
์ ๋ถ ์ค์ ํ์ผ๋ก ๊ด๋ฆฌํ๋ฉฐ ํญ๋ชฉ๋ณ
enabledํ ๊ธ ์ง์. - LLM ๋ถ์ + ๊ท์น ํด๋ฐฑ โ OpenAI ํธํ(๋ก์ปฌ LLM ํฌํจ) โ Gemini โ Anthropic
(API ํค ๋๋ ๊ตฌ๋
OAuth) โ CLI ๊ตฌ๋
๋ธ๋ฆฌ์ง(Claude Code/Codex/
Cursor Agent/Gemini CLI) โ ๊ท์น ๊ธฐ๋ฐ ์์๋ก ํด๋ฐฑ. ์ถ๋ ฅ:
event,severity(1-5),category,signal,confidence,affected_assets,source_url๋ฑ. - ๊ตฌ๋ (OAuth) ๋ชจ๋ธ ์ฐ๊ฒฐ โ API ํค ์์ด Claude Pro/MaxยทChatGPT Plus/Proยท CursorยทGoogle ๊ณ์ ๊ตฌ๋ ์ผ๋ก ๋ถ์ ๋ชจ๋ธ ์ฌ์ฉ (ยง3.3). GLM(์งํธ)ยทKimi๋ ํธํ ์๋ํฌ์ธํธ๋ก ์ง์.
- ์ ๋ ฅ ๊ธฐ์ค ์ค๋ณต ์ ๊ฑฐ โ ์ ์๊ทน(์ ๊ท ๋ด์ค URL, AIS/ADS-B anomaly)์ด ์์ผ๋ฉด LLM ํธ์ถยท๋ฐ์ก ์์ฒด๋ฅผ ์คํต. ํ ์คํธ/์์น/URL ์ ์ฌ๋ ๊ธฐ๋ฐ ์ด๋ฒคํธ ๋ณํฉ.
- ํ ๋ ๊ทธ๋จ ๊ฒฝ๋ณด โ severity ๊ธฐ์ค ๋ฐ์ก, ๊ธด๊ธ(5) ๋ณ๋ ํค๋.
- ์น ์์ ์ฝ์ โ ๋ค์ค ํจ๋ ์ธํ
๋ฆฌ์ ์ค ์ฝ์(์ ์คํฌ๋ฆฐ์ท). ์ค์๊ฐ SSE,
ํค๋ณด๋ ์ค์ฌ ์ด์ฉ, ์ํ ์ง์์ฑ(localStorage), ํ๊ตญ์ด/์์ด ์ ํ,
์ถ์ ์์ฐ ์ปค์คํฐ๋ง์ด์ง(Settings ๋ทฐ์์ ํธ์ง โ
config.json์ ์ฅ). - AI ์์ด์ ํธ ์ฐ๋ โ ์์กด์ฑ ์๋ stdio MCP ์๋ฒ(๋๊ตฌ 8๊ฐ) +
/agent/*REST. ์์ด์ ํธ๊ฐ ์ํฉ ์์ฝยท์ด๋ฒคํธ ์ฟผ๋ฆฌยทLLM ๋ธ๋ฆฌํ์ ๋๊ตฌ๋ก ์๋น ๊ฐ๋ฅ. - ์ผ์ผ ๋ฆฌํฌํธ โ JSONL ๋ก๊ทธ์์ ๊ท์น ๊ธฐ๋ฐ์ผ๋ก ์ง์ญ/์นดํ ๊ณ ๋ฆฌ/์์ฐ ์ง๊ณ + ๋งํฌ๋ค์ด ๋ธ๋ฆฌํ ์๋ ์์ฑ (API ํค ๋ถํ์).
- ๋ก์ปฌ ์ฐ์ ์ ์ฅ โ JSONL ๋ก๊ทธ๊ฐ ์๋ณธ. ์ธ๋ถ ์ ์ก(Convex)์
CONVEX_SITE_URL๋ช ์ ์ค์ ์์๋ง opt-in (์ด์ #7 ์ ์ฑ ).
โโ ์์ง(collectors) โโโโโโโโโโโโโโ
โ AIS โ ADS-B โ News โ Social โ config.json (๊ฐ์๊ตฌ์ญ/ํผ๋/ํค์๋, enabled ํ ๊ธ)
โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโ
โผ
์
๋ ฅ ๊ฒ์ดํ
(์ ์๊ทน ์์ผ๋ฉด ์คํต)
โผ
โโ ๋ถ์(analyzer) โโโโโโโโโโโโโโโโ
โ OpenAIํธํ โ Gemini โ Anthropicโ โ ๊ท์น ๊ธฐ๋ฐ ํด๋ฐฑ
โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโ
โผ
์ค๋ณต ์ ๊ฑฐ(dedup) โ severity ์ด๋ฒคํธ
โผ
โโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โผ โผ โผ
ํ
๋ ๊ทธ๋จ ๊ฒฝ๋ณด JSONL ๋ก๊ทธ (๋ก์ปฌ ์๋ณธ) Convex ์
๋ก๋(opt-in)
โ
โผ src/kaven/ ์ฝ์ด (log_store ยท ops_summary ยท aggregates ยท agent_service)
โโโโโโโโโโโดโโโโโโโโโโโ
โผ โผ
FastAPI ์น API MCP ์๋ฒ (stdio)
(webapp/backend) (python -m src.kaven.mcp_server)
โผ โผ
Ops Console SPA AI ์์ด์ ํธ (Claude Code / Desktop ๋ฑ)
- ๋๋ฉ์ธ ๋ก์ง์ ์ ๋ถ
src/kaven/์ฝ์ด์ ์๊ณ , ์น ๋ผ์ฐํฐ์ MCP ์๋ฒ๋ ์์ ์ด๋ํฐ ๊ณ์ธต์ ๋๋ค. ๊ฐ์ ํจ์๊ฐ HTTP์ MCP ์์ชฝ์์ ์ฌ์ฌ์ฉ๋ฉ๋๋ค.
python3 -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install -r requirements.txt # ์ด์
pip install -r requirements-dev.txt # ๊ฐ๋ฐ(+pytest/ruff/mypy)Kaven์ src/kaven/.env๋ฅผ ์๋ ๋ก๋ํฉ๋๋ค. ๋ชจ๋ ํค๋ ์ ํ์ด๋ฉฐ, ์์ผ๋ฉด
์๋ฎฌ๋ ์ด์
/๋น์ธ์ฆ/๊ท์น ๊ธฐ๋ฐ ๋ชจ๋๋ก ๋์ํฉ๋๋ค.
cat > src/kaven/.env <<'ENV'
# ===== ์์ง =====
OPENSKY_CLIENT_ID=
OPENSKY_CLIENT_SECRET=
AISSTREAM_API_KEY=
SEARXNG_URL=http://localhost:8080
# ===== ๋ถ์ (ํ๋๋ง ์์ด๋ ๋จ; ์์ผ๋ฉด ๊ตฌ๋
CLI โ ๊ท์น ๊ธฐ๋ฐ) =====
OPENAI_BASE_URL=
OPENAI_API_KEY=
OPENAI_MODEL=
GEMINI_API_KEY=
ANTHROPIC_API_KEY=
# ๊ตฌ๋
(OAuth) โ API ํค ๋์ (ยง3.3): ANTHROPIC_AUTH_TOKEN ๋๋ `ant auth login`
ANTHROPIC_AUTH_TOKEN=
ANTHROPIC_BASE_URL=
ANTHROPIC_MODEL=
# ===== ์๋ฆผ =====
TELEGRAM_BOT_TOKEN=
TELEGRAM_CHAT_ID=
TELEGRAM_TOPIC_MAVEN=
TELEGRAM_USER_DM=
# ===== ์๊ฒฉ ๋ฐฑ์
(opt-in โ ๋ฏธ์ค์ ์ ์ธ๋ถ ์ ์ก ์์ ๋นํ์ฑ) =====
CONVEX_SITE_URL=
CONVEX_EVENT_PATH=/addKavenRun
ENV๋ณด์:
.env๋ ์ ๋ ์ปค๋ฐํ์ง ๋ง์ธ์.CONVEX_SITE_URL๋ฏธ์ค์ ์ ์ด๋ฒคํธ๋ ์ด๋ค ์ธ๋ถ ์๋ํฌ์ธํธ๋ก๋ ์ ์ก๋์ง ์์ต๋๋ค.
API ํค ๋์ ์ด๋ฏธ ์ฐ๊ณ ์๋ ๊ตฌ๋
์ผ๋ก ๋ถ์ ๋ชจ๋ธ์ ์ฐ๊ฒฐํ ์ ์์ต๋๋ค.
๋ชจ๋ ํคยทํ ํฐยท์๋ํฌ์ธํธ๋ ํ๊ฒฝ๋ณ์ ๋์ ์ฝ์ Settings โ ๋ชจ๋ธ ๊ณต๊ธ์
์นด๋์์ ์ง์ ์
๋ ฅยท์ ์ฅํ ์๋ ์์ต๋๋ค (config.json์ ์ ์ฅ, ๋์ผ ํญ๋ชฉ์
ํ๊ฒฝ๋ณ์๊ฐ ์์ผ๋ฉด ํ๊ฒฝ๋ณ์ ์ฐ์ , ์ฐ๊ฒฐ ํด์ ๋ฒํผ์ผ๋ก ์ญ์ ).
Anthropic ์ง์ ์ฐ๊ฒฐ (์ฐ์ ์์: ANTHROPIC_API_KEY โ OAuth):
| ๊ตฌ๋ | ๋ฐฉ๋ฒ |
|---|---|
| Claude Pro/Max | ant auth login ํ ๋ฒ์ด๋ฉด ๋ โ Kaven์ด ant CLI ํ๋กํ์์ ๋จ๊ธฐ ํ ํฐ์ ์๋ ๋ฐ๊ธ (๋๋ ANTHROPIC_AUTH_TOKEN์ OAuth ํ ํฐ ์ง์ ์ง์ ) |
| GLM (์งํธ/Z.ai) | ANTHROPIC_BASE_URL=https://open.bigmodel.cn/api/anthropic + ๊ตฌ๋
ํค |
| Kimi (Moonshot) | ANTHROPIC_BASE_URL=https://api.moonshot.ai/anthropic + ๊ตฌ๋
ํค |
๋ชจ๋ธ์ ANTHROPIC_MODEL๋ก ์ง์ (๊ธฐ๋ณธ claude-sonnet-5).
CLI ๊ตฌ๋
๋ธ๋ฆฌ์ง โ ๋ก๊ทธ์ธ๋ ๊ณต์ CLI์ ๋ถ์ ํ๋กฌํํธ๋ฅผ ์์ํฉ๋๋ค.
์ค์นยท๋ก๊ทธ์ธ๋ง ๋์ด ์์ผ๋ฉด ์๋ ๊ฐ์ง๋๋ฉฐ, Settings โ ๋ชจ๋ธ ๊ณต๊ธ์์์
ํ์ฑ/๋นํ์ฑยท๋ช
๋ น ํธ์งยท์ปค์คํ
๊ณต๊ธ์ ์ถ๊ฐ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
์ค์น๋ CLI๋ ์นด๋์ ์ฐ๊ฒฐ(๋ก๊ทธ์ธ) ๋ฒํผ์ผ๋ก OAuth ๋ก๊ทธ์ธ ํ๋ก์ฐ๋ฅผ ๋ฐ๋ก
์คํํ ์ ์์ต๋๋ค โ ๋ฐฑ์๋ ๋จธ์ ์์ ์ ํฐ๋ฏธ๋ ์ฐฝ์ด ์ด๋ฆฌ๊ฑฐ๋(๋ฐ์คํฌํฑ),
ํค๋๋ฆฌ์ค ํ๊ฒฝ์ด๋ฉด ๋ก๊ทธ์ธ URL์ ์ถ์ถํด ๋ธ๋ผ์ฐ์ ์ ํญ์ผ๋ก ์ฝ๋๋ค
(POST /cli/{id}/login, ๋ก๊ทธ์ธ ๋ช
๋ น์ login_command ํ๋๋ก ์ปค์คํฐ๋ง์ด์ฆ):
| ๊ตฌ๋ | CLI | ๊ธฐ๋ณธ ๋ช ๋ น |
|---|---|---|
| Claude Pro/Max | Claude Code | claude -p --output-format text |
| ChatGPT Plus/Pro | OpenAI Codex | codex exec |
| Cursor | Cursor Agent | cursor-agent -p --output-format text |
| Google ๊ณ์ | Gemini CLI | gemini -p |
KAVEN_CLI_PROVIDER๋ก ํน์ ๋ธ๋ฆฌ์ง๋ง ์ฌ์ฉ(id)ํ๊ฑฐ๋ ์ ์ฒด ๋นํ์ฑ(off)ํ ์
์์ต๋๋ค. Grok ๋ฑ ๊ณต์ API ๊ตฌ๋
๊ฒฝ๋ก๊ฐ ์๋ ์๋น์ค๋ ํด๋น CLI๊ฐ ์๋ค๋ฉด
์ปค์คํ
๊ณต๊ธ์๋ก ๋ฑ๋กํด ์ธ ์ ์์ต๋๋ค (Grok์ xAI API ํค๋ฅผ
OPENAI_BASE_URL=https://api.x.ai/v1๋ก ์ฐ๊ฒฐํ๋ ๋ฐฉ๋ฒ๋ ์์).
์ฐ๊ฒฐ ์ํ๋ ์ฝ์ Settings โ ๋ชจ๋ธ ๊ณต๊ธ์ ๋๋ GET /health์
analysis ํ๋์์ ํ์ธํฉ๋๋ค (๋น๋ฐ๊ฐ์ ๋
ธ์ถ๋์ง ์์).
python src/kaven/kaven.py --once # 1ํ ์คํ
python src/kaven/kaven.py --watch # ๊ฐ์ ๋ชจ๋ (๊ธฐ๋ณธ 5๋ถ)
python src/kaven/kaven.py --watch --interval 10# ๋ฐฑ์๋ (FastAPI)
uvicorn webapp.backend.app:app --reload --port 8000
# ํ๋ก ํธ์๋ (์ ์ ํ์ผ)
python -m http.server 8080 --directory webapp/frontend์ ์: http://127.0.0.1:8080 โ API ์ฃผ์๊ฐ ๋ค๋ฅด๋ฉด ?api=http://ํธ์คํธ:8000์ผ๋ก override.
| ๋ทฐ | ๋ด์ฉ |
|---|---|
| COP | ๋ด์ฅ ๋ฒกํฐ ์๋๋งต(Natural Earth, ์คํ๋ผ์ธ ๋์) ์ ๊ฐ์๊ตฌ์ญ ๋ฐ์คยทseverity ๋ง์ปคยทํ์ค ๋ง + 24h ์ด๋ฒคํธ ํ์๋ผ์ธ |
| Event Feed | severity/์นดํ ๊ณ ๋ฆฌ/์ ํธ/ํ ์คํธ ํํฐ + Time/Sev ์ ๋ ฌ ํ ์ด๋ธ |
| Intel Report | ์ผ์ผ ๋ธ๋ฆฌํ ๋งํฌ๋ค์ด (๋ ์ง ์ ํ) |
| Asset Impact | ์์ฐ๋ณ 7์ผ severity ํํธ๋งต + ์ ํธ ๋ถํฌ |
| System | ์์ง ํ์ดํ๋ผ์ธ/๊ฐ์๊ตฌ์ญ/ํผ๋/ํค์๋ ์ํ ๋ณด๋ |
| Settings | zcode ์คํ์ผ ์ข์ธก ๋ด๋น(์ฝ์/๋ชจ๋ธ/์์ง ๊ทธ๋ฃน): ์ธ์ดยท์ฝ์ ํ๊ฒฝ์ค์ + ๋ชจ๋ธ ๊ณต๊ธ์ ํจ๋(Direct API ํคยทํ ํฐ ์นด๋ ์
๋ ฅ/์ฐ๊ฒฐ ํด์ + CLI ๊ตฌ๋
๋ธ๋ฆฌ์ง ํธ์ง) + ์๋ฒ ์ค์ ์ ์น์
ํธ์ง๊ธฐ(์์ฐ/๊ฐ์์ง์ญ/AISยทADS-B ๊ตฌ์ญ/๋ด์ค ํผ๋/ํค์๋ โ config.json ์ ์ฅ) |
๊ณตํต: ์ข์ธก AO ์์น๋ฆฌ์คํธ(S0 ์ง์ญ์ +n QUIET ์ ๊ธฐ, ๏ผ ๋ฒํผ์ผ๋ก AO ์ถ๊ฐยทํธ์ง, ์์ฐ ํด๋ฆญ โ Feed ํํฐ),
์ฐ์ธก ์ธ์คํํฐ(์ด๋ฒคํธ ์์ธยท์ง์ญ ๋์์ยท7์ผ ์คํํฌ๋ผ์ธยทJSON ๋ณต์ฌ),
์๋จ THREATCONยทSYNC ์ ์ ๋ยทUTC/KST ์๊ณยทLIVE(SSE) ํ ๊ธ.
| ํค | ๋์ |
|---|---|
1โ6 |
๋ทฐ ์ ํ (COP / Feed / Intel / Assets / System / Settings) |
Ctrl+K, / |
์ปค๋งจ๋ ํ๋ ํธ (๊ฒ์ยท์ด๋ยท์ก์ ) |
J / K |
๋ค์ / ์ด์ ์ด๋ฒคํธ ์ ํ |
F |
Feed ์ด๋ + ํ ์คํธ ํํฐ ํฌ์ปค์ค |
R |
์์ง ํ์ดํ๋ผ์ธ 1ํ ์คํ |
L |
LIVE(SSE) ์คํธ๋ฆผ ํ ๊ธ |
Esc |
์ ํ ํด์ / ์ค๋ฒ๋ ์ด ๋ซ๊ธฐ |
? |
๋จ์ถํค ๋์๋ง |
๋ทฐยทํํฐยท์ ๋ ฌยทLIVE ์ํยท์ธ์ด๋ localStorage์ ์ ์ฅ๋์ด ์๋ก๊ณ ์นจ ํ ๋ณต์๋ฉ๋๋ค.
- Settings ๋ทฐ(๋จ์ถํค
6) ๋๋ ์ปค๋งจ๋ ํ๋ ํธ์ "Toggle language"๋ก ์ ํ. - ์ ํ ์ ์ง์ญ๋ช ยท์ง์ญ ์ค๋ช ยท๋์๋งยทํดํยท์ค์ ๋ผ๋ฒจ์ด ํด๋น ์ธ์ด๋ก ํ์๋ฉ๋๋ค (์ฝ์ ํฌ๋กฌ์ mono ๋ ์ด๋ธ์ ๋์์ธ์ ์์ชฝ ๋ชจ๋ ์๋ฌธ ์ ์ง).
- Intel ๋ฆฌํฌํธ๋ ๊ท์น ๊ธฐ๋ฐ์ผ๋ก ํ๊ตญ์ด๋ก ์์ฑ๋ฉ๋๋ค.
์ธ๋ถ SDK ์์กด์ฑ ์๋ stdio MCP ์๋ฒ๋ฅผ ๋ด์ฅํฉ๋๋ค. ๋ก๊ทธ ๋๋ ํฐ๋ฆฌ๋ง ์ฝ์ผ๋ฏ๋ก
API ํค ์์ด ๋์ํฉ๋๋ค(kaven_run_collection ์ ์ธ).
# Claude Code (์ ์ฅ์ ๋ฃจํธ์์)
claude mcp add kaven -- python -m src.kaven.mcp_server// claude_desktop_config.json
{
"mcpServers": {
"kaven": {
"command": "python",
"args": ["-m", "src.kaven.mcp_server"],
"cwd": "/path/to/kaven"
}
}
}| ๋๊ตฌ | ์ค๋ช |
|---|---|
kaven_ops_summary |
ํตํฉ ์ํฉ ์์ฝ (์ํ ์์คยท์ง์ญยท์ด๋ฒคํธยท์์ฐยท๊ฐ์๊ตฌ์ญ) |
kaven_events |
ํํํ ์ด๋ฒคํธ ์ฟผ๋ฆฌ (severity/์ง์ญ/์นดํ ๊ณ ๋ฆฌ/์ ํธ/ํค์๋ ํํฐ) |
kaven_agent_context |
LLM ํ๋กฌํํธ ์ฃผ์ ์ฉ ์์ถ ๋งํฌ๋ค์ด ๋ธ๋ฆฌํ |
kaven_region |
์ง์ญ ์์ธ + ์ต๊ทผ N์ผ severity ํ์คํ ๋ฆฌ |
kaven_daily_report |
๊ท์น ๊ธฐ๋ฐ ์ผ์ผ ๋ธ๋ฆฌํ (๋งํฌ๋ค์ด) |
kaven_portfolio |
์์ฐ๋ณ ํฌ์ ์ํฅ ์ง๊ณ |
kaven_config |
์์ง ์ค์ ์กฐํ |
kaven_run_collection |
์์ง ํ์ดํ๋ผ์ธ 1ํ ์ฆ์ ์คํ |
curl http://127.0.0.1:8000/agent/manifest # ๋์ค์ปค๋ฒ๋ฆฌ ์นดํ๋ก๊ทธ
curl "http://127.0.0.1:8000/agent/context?severity_min=3" # LLM ๋ธ๋ฆฌํ
curl "http://127.0.0.1:8000/agent/events?region=korea&severity_min=4"์ด๋ฒคํธ ์คํค๋ง ์ดํ(์ง์ญ ์ฝ๋ยท์นดํ
๊ณ ๋ฆฌยท์ ํธยทseverity ์๋ฏธ)๋
/agent/manifest์ vocabulary ํ๋๋ฅผ ์ฐธ์กฐํ์ธ์.
์ฝ์์ ์ปค๋งจ๋ ํ๋ ํธ์๋ "Copy ops briefing (LLM context)" ์ก์
์ด ์์ต๋๋ค.
ํ์ ์์: KAVEN_CONFIG ํ๊ฒฝ๋ณ์ ๊ฒฝ๋ก โ src/kaven/config.json โ ๋ด์ฅ ๊ธฐ๋ณธ๊ฐ.
cp src/kaven/config.example.json src/kaven/config.json # ํธ์ง ํ ์ฌ์์์ง์ ์น์
: ais_zones, adsb_zones, news_feeds, news_keywords,
social_keywords, assets, regions, cli_providers.
๊ฐ ํญ๋ชฉ์ enabled: false๋ก ์์ง/์ง๊ณ์์ ์ ์ธ
(ํ์ผ์๋ ์ ์ง), ํน์ ์น์
๋ง ๋ฃ์ผ๋ฉด ํด๋น ์น์
๋ง ์นํ๋ฉ๋๋ค.
ํ์ฌ ๋ก๋ ์ํ๋ GET /config์ผ๋ก ํ์ธ.
์ง์ ์น์
์ ์ฒด๊ฐ ์ฝ์ Settings ๋ทฐ์์ ์ง์ ํธ์ง ๊ฐ๋ฅํฉ๋๋ค
(PUT /config/{section}, ์น์
๋ณ ๊ฒ์ฆ: ์ขํ ๋ฒ์, URL ์คํด, ์ ํ ํ์ดํธ๋ฆฌ์คํธ,
์ค๋ณต ๊ธ์ง). ์น์
๋ณ ์๋ฏธ:
| ์น์ | ๋ฐ์ ์ง์ |
|---|---|
assets |
ํฌํธํด๋ฆฌ์ค/์์น๋ฆฌ์คํธ ์์ฐ ๋ฉํ. ๋ฏธ๋ฑ๋ก ์์ฐ์ type: other๋ก ํ์, enabled: false๋ ์ง๊ณ ์ ์ธ |
regions |
๊ฐ์ ์ง์ญ(AO) โ ์ฝ๋/์ด๋ฆ(ํยท์)/์ขํ/์ค๋ช . ์ง๋ยท์์น๋ฆฌ์คํธยท๊ฐ์ด๋ยท์์ด์ ํธ ์ดํ์ ๋ฐ์. ์ ์ง์ญ ์ถ๊ฐ ๊ฐ๋ฅ |
ais_zones / adsb_zones |
ํด์/๊ณต์ญ ๊ฐ์๊ตฌ์ญ bounding box + ์ง๋ ์ค๋ฒ๋ ์ด |
news_feeds / news_keywords / social_keywords |
์์ง๊ธฐ ์์ค/๊ฒ์์ด |
cli_providers |
AI CLI ๊ตฌ๋ ๋ธ๋ฆฌ์ง โ ์ด๋ฆ/๋ช ๋ น(ํ๋กฌํํธ๋ ๋ง์ง๋ง ์ธ์๋ก ์ ๋ฌ). Settings โ ๋ชจ๋ธ ๊ณต๊ธ์์์ ํธ์ง |
์ฐธ๊ณ :
regions์ ์ ์ง์ญ(AO)์ ์ถ๊ฐํ๋ฉด ์ง๋ยท์์น๋ฆฌ์คํธยท์์ด์ ํธ ์ดํ (/agent/manifest)๋ ๋ฌผ๋ก ๋ถ์๊ธฐ(LLM) ํ๋กฌํํธ์ ์ง์ญ ์ฝ๋ ์ดํ์๋ ์ฆ์ ๋ฐ์๋์ด, ๋ค์ ์์ง run๋ถํฐ ํด๋น ์ฝ๋๋ก ์ด๋ฒคํธ๊ฐ ๋ถ๋ฅ๋ ์ ์์ต๋๋ค. ์ฝ์ ์์น๋ฆฌ์คํธ์ AREAS OF OPERATION ํค๋๏ผ๋ฒํผ์ผ๋ก ํธ์ง ํ๋ฉด์ ๋ฐ๋ก ์ด๋ํ ์ ์์ต๋๋ค. ์ AO๋ ์ด๋ฒคํธ๊ฐ ์๊ธฐ๊ธฐ ์ ๊น์ง S0์ด๋ฏ๋ก+n QUIET์ ํ ์์ ํ์๋ฉ๋๋ค.
{
"ais_zones": [
{"id": "hormuz", "name": "ํธ๋ฅด๋ฌด์ฆ ํดํ", "enabled": true,
"lat_min": 25.5, "lat_max": 27.0, "lon_min": 56.0, "lon_max": 57.5,
"baseline_ships": 50}
]
}| ๋ณ์ | ์ฉ๋ | ๊ธฐ๋ณธ๊ฐ |
|---|---|---|
KAVEN_CONFIG |
์ค์ ํ์ผ ๊ฒฝ๋ก override | src/kaven/config.json |
KAVEN_LOG_DIR |
JSONL ๋ก๊ทธ ๋๋ ํฐ๋ฆฌ (์ฝ๊ธฐ/์ฐ๊ธฐ ๊ณตํต) | src/kaven/logs |
SEARXNG_URL |
๋ด์ค/์์ ๊ฒ์ ์์ง | http://localhost:8080 |
OPENAI_BASE_URL ์ธ |
๋ถ์ LLM (ยง3.2 ์ฐธ์กฐ) | ๊ท์น ๊ธฐ๋ฐ ํด๋ฐฑ |
ANTHROPIC_AUTH_TOKEN |
๊ตฌ๋
OAuth ํ ํฐ (๋๋ ant auth login ํ๋กํ ์๋ ์ฌ์ฉ) |
โ |
ANTHROPIC_BASE_URL |
Anthropic ํธํ ์๋ํฌ์ธํธ (GLM/Kimi ๋ฑ) | api.anthropic.com |
ANTHROPIC_MODEL |
Anthropic ๊ณ์ด ๋ถ์ ๋ชจ๋ธ | claude-sonnet-5 |
KAVEN_CLI_PROVIDER |
CLI ๋ธ๋ฆฌ์ง ์ ํ โ auto/off/ํน์ id |
auto |
TELEGRAM_* |
๊ฒฝ๋ณด ๋ฐ์ก | ๋ฏธ๋ฐ์ก |
CONVEX_SITE_URL |
์๊ฒฉ ๋ฐฑ์ opt-in | ๋นํ์ฑ |
FastAPI ๋ฌธ์: GET /docs (Swagger UI), GET /openapi.json
| ์๋ํฌ์ธํธ | ์ค๋ช |
|---|---|
GET /health |
ํฌ์ค์ฒดํฌ + ๋ฒ์ + ๋ถ์ ๋ฐฑ์๋ ์ํ(analysis โ ์ธ์ฆ ๋ชจ๋/CLI ์ค์น ์ฌ๋ถ, ๋น๋ฐ๊ฐ ๋ฏธ๋
ธ์ถ) |
GET /ops/summary?date= |
์ฝ์์ฉ ํตํฉ ์์ฝ (์ง์ญ+์ด๋ฒคํธ+์์ฐ+๊ฐ์๊ตฌ์ญ) |
GET /agent/manifest ยท /agent/context ยท /agent/events |
AI ์์ด์ ํธ ์ฐ๋ (ยง5) |
GET /runs ยท /runs/latest ยท /runs/files ยท /runs/dates |
์คํ ๋ก๊ทธ ์กฐํ (+ํํฐ) |
POST /runs/once |
์์ง ํ์ดํ๋ผ์ธ 1ํ ์คํ |
GET /runs/stream |
SSE ์ค์๊ฐ run ์คํธ๋ฆผ |
GET /report ยท /report/dates ยท /report/{YYYYMMDD} |
์ผ์ผ ๋ฆฌํฌํธ |
GET /guide ยท /guide/{region}?days= |
์ง์ญ ๊ฐ์ด๋ + ํ์คํ ๋ฆฌ |
GET /map/data |
์ง๋ ๋ง์ปค ๋ฐ์ดํฐ |
GET /portfolio ยท /portfolio/{asset} |
์์ฐ ์ํฅ ์ง๊ณ |
GET /config |
์์ง ์ค์ ์กฐํ |
PUT /config/{section} |
์ค์ ์น์ ์ ์ฅ โ assets/regions/ais_zones/adsb_zones/news_feeds/news_keywords/social_keywords/cli_providers (Settings ๋ทฐ๊ฐ ์ฌ์ฉ) |
PUT /config/credentials |
๋ชจ๋ธ ํคยทํ ํฐ ์ ์ฅ/์ญ์ (Settings โ ๋ชจ๋ธ ๊ณต๊ธ์ ์นด๋. ๋น ๊ฐ = ์ฐ๊ฒฐ ํด์ . GET /config ์๋ต์ ๋ฏธ๋
ธ์ถ, ํ๊ฒฝ๋ณ์ ์ฐ์ ) |
POST /cli/{id}/login |
CLI ๋ธ๋ฆฌ์ง OAuth ๋ก๊ทธ์ธ ์คํ โ ๋ฐฑ์๋ ๋จธ์ ์์ ํฐ๋ฏธ๋ ์ฐฝ ๋๋ ๋ก๊ทธ์ธ URL ์ถ์ถ (Settings ์ฐ๊ฒฐ ๋ฒํผ์ด ์ฌ์ฉ) |
src/kaven/
โโโ kaven.py # ๋ฉ์ธ ์คํ๊ธฐ (--once / --watch), dedup, ๋ฐ์ก, ์ ์ฅ
โโโ collectors/ # ais / adsb / news / social ์์ง๊ธฐ
โโโ analyzer.py # LLM ๋ถ์ ์์ง (๋ค๋จ๊ณ ํด๋ฐฑ)
โโโ anthropic_auth.py # Anthropic ์ธ์ฆ ํด์ (API ํค / ๊ตฌ๋
OAuth / ant CLI)
โโโ cli_providers.py # CLI ๊ตฌ๋
๋ธ๋ฆฌ์ง (claude/codex/cursor-agent/gemini)
โโโ signal_generator.py # ํ
๋ ๊ทธ๋จ ๊ฒฝ๋ณด
โโโ config_loader.py # ๊ฐ์๊ตฌ์ญ/ํผ๋/ํค์๋ ์ค์ ๋ก๋
โโโ log_store.py # JSONL ๋ก๊ทธ ์ก์ธ์ค ๋จ์ผ ์์ค (KAVEN_LOG_DIR)
โโโ regions.py # ์ง์ญ ๋ฉํ๋ฐ์ดํฐ + ์คํค๋ง ์ดํ ๋จ์ผ ์์ค
โโโ ops_summary.py # COP ํตํฉ ์ง๊ณ
โโโ aggregates.py # ๊ฐ์ด๋/์ง๋/ํฌํธํด๋ฆฌ์ค ์ง๊ณ
โโโ report_generator.py # ๊ท์น ๊ธฐ๋ฐ ์ผ์ผ ๋ฆฌํฌํธ
โโโ agent_service.py # ์์ด์ ํธ ์ฟผ๋ฆฌยท์ปจํ
์คํธยท๋งค๋ํ์คํธ
โโโ mcp_server.py # stdio MCP ์๋ฒ (์์กด์ฑ ์์)
webapp/
โโโ backend/app.py # FastAPI ์ฑ ์กฐ๋ฆฝ (CORS + ๋ผ์ฐํฐ ์ฐ๊ฒฐ๋ง)
โโโ backend/routers/ # system / runs / ops / agent / intel / portfolio
โโโ frontend/index.html # Ops Console SPA (๋จ์ผ ํ์ผ, vanilla JS)
tests/ # pytest (์์ด์ ํธ/MCP/์ง๊ณ/์ค์ /dedup ๋ฑ)
docs/ # release-notes, ์ด์ ๋ฌธ์, README ์ด๋ฏธ์ง
deploy/ # Dockerfile, docker-compose, systemd ์ ๋
make test # ์ ์ฒด
make test-kaven # ํต์ฌ(dedup/policy)
pytest -q # ์ง์ ์คํ
ruff check . # ๋ฆฐํธ์ฐธ๊ณ :
test_kaven_log_replay_integration.py1๊ฑด์ v0.0.05 ์ ์ฅ์ ์์ ์์ (์ด์ ๋ก๊ทธ ์ถ์ ํด์ )์ผ๋ก ์ํ ๋ก๊ทธ๊ฐ ์๋ ํ๊ฒฝ์์ ์คํจํฉ๋๋ค โ ๊ธฐ์กด ์๋ ค์ง ์ด์๋ก ์ฝ๋ ๊ฒฐํจ์ด ์๋๋๋ค.
- ๋ก๊ทธ:
src/kaven/logs/kaven_YYYYMMDD.jsonl(๊ตฌmaven_*.jsonl์ฝ๊ธฐ ํธํ), dedup ์บ์sent_cache.json.KAVEN_LOG_DIR๋ก ์์น ๋ณ๊ฒฝ ๊ฐ๋ฅ. - ์ธํ๋ผ ์์:
docker run --rm -d --name searxng -p 8080:8080 searxng/searxng # ๊ฒ์ ์์ง cd deploy/docker && docker compose up -d # compose ์ค์บํด๋
- ์์ฃผ ๋ฐ์ํ๋ ๋ฌธ์
TELEGRAM_CHAT_ID๋ฅผ ์จ์ผ ํจ (CHAT_ID์๋) โ ์์ธ:docs/telegram-faq.md.env๋ ๋ฃจํธ๊ฐ ์๋๋ผsrc/kaven/.env์ ์์ด์ผ ์๋ ๋ก๋๋จ- SearxNG ๋ฏธ๊ตฌ๋ ์ ๋ด์ค/์์ ์์ง ์ ํ
CONVEX_SITE_URL ๋ฏธ์ค์ โ ์ธ๋ถ ์ ์ก ์คํต๋ก๊ทธ๋ ์ ์ ๋์ (opt-in ์ ์ฑ )- ์ฝ์ ์ง๋๋ ๋ก์ปฌ ๋ฒ๋ค(Leaflet + Natural Earth)๋ก ๋ ๋๋ง๋๋ฏ๋ก ์ธํฐ๋ท ์ฐ๊ฒฐ์ด ํ์ ์์. ๊ธฐ๋ฐ ์ง๋ ๋ฐ์ดํฐ: Natural Earth (public domain)
- ๋ณ๊ฒฝ ์ด๋ ฅ:
docs/release-notes.md(๋ฒ์ ์ ์ฑ : ๋ชจ๋ ์ ๋ฐ์ดํธ๋ง๋ค ๋ฒ์ ์์น) - ์น์ฑ ์์ธ:
webapp/README.mdยท ์ฝ์ด ์์ธ:src/kaven/README.md - ์ด์ ์ฒดํฌ๋ฆฌ์คํธ:
docs/webapp-checklist.mdยท ํ ๋ ๊ทธ๋จ:docs/telegram-faq.md - ๊ธฐ์ฌ: ๊ธฐ๋ฅ ๋ธ๋์น โ
pytest -qยทruff check .ํต๊ณผ โ ๋ฌธ์/๋ฆด๋ฆฌ์ค ๋ ธํธ ๊ฐฑ์ โ PR (๋ณ๊ฒฝ ์ด์ ยทํ ์คํธ ๊ฒฐ๊ณผยท์ด์ ์ํฅ ๋ช ์) - ๋ผ์ด์ ์ค: MIT โ ์์ ๋ก์ด ์ฌ์ฉ/์์ /์ฌ๋ฐฐํฌ, ์ ์๊ถ ๊ณ ์ง ์ ์ง











