로컬에서 실행하는 MCP 기반 연구 워크스페이스입니다.
논문 검색 → 필터링/랭킹 → PDF 다운로드 → 텍스트/이미지 추출 → 섹션 분석 → 최종 리포트 생성 → 그래프 탐색 → 노트 저장/외부 연동
현재 코드 기준으로 이 레포는 크게 세 계층으로 나뉩니다.
mcp-server: 실제 도구 실행 계층. PDF 처리, arXiv 검색/다운로드, 랭킹, 리포트, Notion/Discord 연동, 백그라운드 파이프라인 API를 제공합니다.agent: OpenAI 기반 오케스트레이션 계층. MCP 도구 스키마를 읽고, 계획/도구 호출/응답 생성을 담당합니다.web: React/Vite UI. 그래프, 랭킹 리스트, 노트 페이지, 계정 설정, 채팅 팝업, 파이프라인 실행 화면을 제공합니다.
- arXiv 검색 / 상세 조회 / PDF 다운로드
- NeurIPS 2025 / ICLR 2025 논문 탐색 및 랭킹
- 로컬
./pdf/폴더에 넣은 PDF를 바로 분석 대상으로 사용
- PDF 목록 조회
- 텍스트 추출
- 이미지 추출
- 텍스트+이미지 통합 추출(
extract_all) - 전체 PDF 일괄 처리(
process_all_pdfs) - PDF 메타데이터 조회
- 추출 텍스트 재로딩
- 추출 텍스트에서 GitHub 링크 자동 탐지
- 사용자 프로필(
users/profile.json) 기반 추천 - 하드 필터:
- 이미 읽은 논문 제외
- 블랙리스트 키워드 제외
- 연도 조건 필터링
- 시맨틱 유사도 계산
- 6차원 메트릭 평가
- 최종 Top-K 선정
- 필요 시 contrastive paper 추천
- 로컬 PDF 파이프라인: 선택한 PDF들을 백그라운드에서 분석
- 컨퍼런스 파이프라인: arXiv 또는 NeurIPS에서 검색→랭킹→다운로드→추출→분석을 자동 실행
- 분석 모드:
quickstandarddeep
- 전체 요약 리포트 생성
- 섹션 헤딩 추출
- 전략 기반 섹션 선택
- 섹션별 분석
- 논문 QA
- 최종 종합 리포트 생성
- Discord full/summary 알림 전송
- Global Paper Graph
- Paper Reference Graph
- 기존 노드에 점진적으로 reference subgraph를 확장하는 방식 지원
- 논문별 노트 페이지
- 섹션별 노트
- 번역 / 분석 / QA 결과를 별도 페이지 상태로 저장
- 자동 저장(localStorage + 파일 시스템)
- Notion으로 저장 가능
- OpenAI API: 에이전트 추론, 번역, 리포트, 채팅
- Tavily API: 실시간 웹 검색
- Notion OAuth: 노트 저장
- Discord Webhook: full/summary 알림
- 프롬프트/응답 JSONL 로깅
output/agent_status/*.json상태 파일output/agent_reports/최종 리포트- 논문별 출력 산출물 영속화
flowchart LR
B[Browser] --> W[web<br/>React + Vite]
W -->|/api proxy| M[mcp-server<br/>FastAPI + MCP Tools]
W -->|/api/chat| A[agent<br/>FastAPI + OpenAI]
A -->|tool schema + execute| M
M --> PDF[(./pdf)]
M --> OUT[(./output)]
W --> OUT
W --> DATA[(./data)]
A --> OUT
- 사용자는
http://localhost:3000에서 UI를 엽니다. - 웹 UI는 대부분의 작업을
'/api' -> mcp-server로 프록시합니다. - 채팅은
'/api/chat'을 통해research-agent:8001/chat으로 전달됩니다. - Agent는 MCP 서버의
/tools/schema를 읽고, 필요한 도구를 호출하며 응답을 생성합니다. - 산출물은
./output/아래에 누적 저장됩니다.
Research_agent/
├─ agent/ # LLM 오케스트레이션 계층
│ ├─ client.py # OpenAI 툴 호출 루프
│ ├─ server.py # /chat, /health FastAPI 서버
│ ├─ planner.py # 계획 생성
│ ├─ executor.py # 의존성 기반 실행기
│ └─ memory.py # 대화/툴 호출/플랜 상태 저장
├─ mcp/ # MCP 도구와 서버
│ ├─ server.py # /tools, /pdf/*, /agent/*, /notion/* 등
│ ├─ registry.py # mcp/tools 자동 발견/등록 SSOT
│ └─ tools/ # PDF, arXiv, rank, graph, notion, web search 등
├─ web/ # React + Vite 프론트엔드
│ ├─ pages/ # Home / Graph / Note / ICLR / NeurIPS 페이지
│ ├─ components/ # 사이드바, 랭킹 리스트, 채팅, 계정 설정 등
│ ├─ lib/mcp.ts # MCP REST client
│ └─ vite.config.ts # /api 프록시 + 로컬 파일/메타데이터 미들웨어
├─ data/ # 컨퍼런스 CSV, 사전 계산된 임베딩/유사도/클러스터
├─ instruction/ # 도구/파이프라인 문서
├─ pdf/ # 입력 PDF 저장소
├─ output/ # 추출/리포트/상태/프로필/런타임 설정 저장
├─ runtime/ # 서비스 설정 로딩 코드
├─ logs/ # LLM 프롬프트/응답 로그
├─ tests/ # 통합/랭킹/번역 테스트
├─ requirements/ # Python requirements 분리
├─ docker/ # 각 서비스용 Dockerfile 및 엔트리포인트
└─ docker-compose.yml # 3개 서비스 스택 정의
필수:
- Docker Engine + Docker Compose v2
- OpenAI API Key
선택:
- Tavily API Key (실시간 웹 검색이 필요할 때)
- Notion 연결
- Discord Webhook
docker compose builddocker compose up -d mcp-server web이 조합으로 가능한 것:
- PDF 처리
- 그래프 탐색
- 랭킹 페이지
- 노트/리포트 UI
- 계정 설정
- 대부분의 MCP 직접 호출 기반 기능
주의:
- 채팅 팝업은
agent서비스가 없으면 동작하지 않습니다. - UI는 열리지만,
/api/chat은 Agent 서버에 포워딩되므로 agent 컨테이너가 내려가 있으면 채팅 응답에 unavailable 메시지가 뜹니다.
docker compose up -d mcp-server web agent또는 이미 최소 스택을 올렸다면:
docker compose up -d agentdocker compose ps
docker compose logs -f mcp-server
docker compose logs -f web
docker compose logs -f agent헬스체크:
curl http://localhost:8000/health
curl http://localhost:8000/tools
curl http://localhost:8000/tools/schema
curl http://localhost:8001/health- 브라우저에서
http://localhost:3000접속 - 우상단 Account 버튼 클릭
- 필요한 키 저장
- OpenAI API Key
- Tavily API Key (선택)
- 필요하면 Notion 연결
- 필요하면 Discord webhook 저장
비밀 키는 .env에서 읽지 않습니다.
웹 UI에서 저장한 값은 아래 파일에 저장됩니다.
output/_runtime/service_settings.json
특징:
- MCP 서버와 Agent가 런타임에 이 파일을 읽음
- 저장 후 재시작이 필요 없음
- Git에 커밋하지 않는 것이 맞음
분석할 PDF를 아래 폴더에 넣습니다.
./pdf/
하위 폴더도 사용할 수 있습니다.
예: ./pdf/neurips2025/*.pdf
docker compose down출력 산출물(./output)과 입력 PDF(./pdf)는 bind mount이므로 유지됩니다.
| 서비스 | 포트 | 역할 | 주요 볼륨 |
|---|---|---|---|
mcp-server |
8000 |
도구 실행 / REST API / 백그라운드 잡 시작점 | ./pdf, ./output, ./tests, ./data |
agent |
8001 |
OpenAI 기반 에이전트 채팅/도구 오케스트레이션 | ./pdf:ro, ./output:ro |
web |
3000 |
React/Vite UI | ./web, ./output, ./pdf:ro, ./data:ro, web_node_modules |
mcp-serverPDF_DIR=/data/pdfOUTPUT_DIR=/data/output- 헬스체크 포함
agentMCP_SERVER_URL=http://mcp-server:8000mcp-server헬스 후 기동
webMCP_SERVER_URL=http://mcp-server:8000npm install이 필요하면 자동 수행 후npm run dev
mcp-server:python:3.11-slimagent:python:3.11-slimweb:node:20-alpine
./pdf/에 논문 PDF를 넣음- UI에서 해당 논문 열기
- 필요 시
process_all_pdfs또는 개별 추출 실행 - Note 페이지에서 섹션 헤딩 추출
- 번역/분석/QA/리포트 생성
- 결과를 로컬 파일 및 Notion에 저장
PDF 목록:
curl http://localhost:8000/pdf/list개별 PDF 추출:
curl -X POST "http://localhost:8000/pdf/extract?filename=your_paper.pdf"전체 PDF 일괄 처리:
curl http://localhost:8000/pdf/process-allNotePage는 논문별 노트 워크스페이스입니다.- 추출 텍스트에서 정규식 기반으로 목차/소목차를 추출합니다.
- 정규식 실패 시 채팅(
/api/chat)을 이용한 LLM fallback이 있습니다. - 노트는:
- localStorage에 캐시되고
- 파일 시스템에도 자동 저장됩니다.
- 노트 페이지 상태는
manual,translation,analysis,qa처럼 분리되어 관리됩니다.
- 사용자 프로필 설정
- arXiv 검색
- 하드 필터 적용
- semantic score 계산
- paper metrics 평가
- 최종 Top-K 랭킹
- 필요 시 다운로드/분석
arXiv 검색을 랭킹용 입력 형식으로 변환:
curl -X POST http://localhost:8000/arxiv/search-for-ranking \
-H "Content-Type: application/json" \
-d '{
"query": "diffusion policy",
"max_results": 50
}'풀 랭크 파이프라인:
curl -X POST http://localhost:8000/rank-filter/execute-pipeline \
-H "Content-Type: application/json" \
-d '{
"query": "diffusion policy",
"max_results": 50,
"purpose": "general",
"ranking_mode": "balanced",
"top_k": 5,
"include_contrastive": false,
"contrastive_type": "method",
"profile_path": "users/profile.json"
}'사용자 프로필은 아래 정보를 다룹니다.
interests.primaryinterests.secondaryinterests.exploratorykeywords.must_includekeywords.exclude.hardkeywords.exclude.softpreferred_authorspreferred_institutionsconstraints.min_yearconstraints.require_codeconstraints.exclude_local_paperspurposeranking_modetop_kinclude_contrastivecontrastive_type
general: 일반적인 추천literature_review: 서베이/관련연구 조사implementation: 구현 가능성 중시idea_generation: 최신성/탐색성 중시
balancednoveltypracticalitydiversity
methodassumptiondomain
http://localhost:3000/neurips2025http://localhost:3000/iclr2025
- 컨퍼런스 전용 검색/랭킹 페이지가 따로 존재합니다.
./data/아래의 CSV와 사전 계산된 embedding/similarity/cluster 데이터를 활용합니다.- UI는
/api/neurips/papers,/api/neurips/similarities,/api/neurips/clusters,/api/iclr/papers,/api/iclr/similarities,/api/iclr/clusters를 사용합니다.
두 페이지 모두 대체로 아래 순서를 사용합니다.
- 컨퍼런스 검색
apply_hard_filterscalculate_semantic_scoresevaluate_paper_metricsrank_and_select_top_k
즉, 단순 CSV 정렬이 아니라 프로필 기반 랭킹 파이프라인이 붙어 있습니다.
선택한 로컬 PDF들에 대해 백그라운드 분석 시작:
curl -X POST http://localhost:8000/agent/run \
-H "Content-Type: application/json" \
-d '{
"arguments": {
"paper_ids": ["your_paper.pdf"],
"goal": "general understanding",
"analysis_mode": "quick",
"source": "local",
"discord_webhook_full": "",
"discord_webhook_summary": ""
}
}'반환:
job_id- 상태 URL
arXiv 또는 NeurIPS 대상:
curl -X POST http://localhost:8000/agent/conference-pipeline \
-H "Content-Type: application/json" \
-d '{
"source": "arxiv",
"query": "transformer attention",
"top_k": 3,
"goal": "latest methods overview",
"analysis_mode": "standard",
"discord_webhook_full": "",
"discord_webhook_summary": "",
"profile_path": "users/profile.json"
}'주의:
source는 현재arxiv또는neurips- 서버에서
top_k는 1~5 사이로 clamp - 응답은 즉시 반환되고, 실제 처리는 백그라운드에서 진행
curl http://localhost:8000/agent/status/<job_id>
curl http://localhost:8000/agent/jobs로컬/컨퍼런스 파이프라인은 대체로 아래 과정을 거칩니다.
- 입력 논문/검색결과 준비
- PDF 추출(
extract_all) - 전체 리포트 생성(
generate_report) - abstract/section 추출
- 분석 전략 결정
- 전략 기반 섹션 분석
- executive summary 생성
- 최종 report 조립
output/agent_reports/저장- Discord full/summary 전송(설정되어 있으면)
experiment_focusedmethodology_focusedformula_heavyimplementation_focusedcomparison_focused
웹 UI의 LLM Chat Popup은 연구 조수 역할을 합니다.
가능한 용도:
- 논문 비교
- 다음에 읽을 논문 추천
- 특정 주제 요약
- 섹션/실험 해석
- 목차 추출 fallback
- 채팅은
/api/chat을 통해research-agent:8001/chat으로 전달됩니다. - 따라서
agent컨테이너가 반드시 실행 중이어야 합니다.
라우트:
/graph
기능:
- 전체 논문 그래프 로딩
- graph/list 뷰 전환
- 전역 그래프 재구성
라우트:
/paper/:paperId
기능:
- 특정 논문 중심 reference subgraph 생성
- 기존 노드에 대해 incremental expand 지원
- 논문별 reference 관련 산출물(
reference_titles.json등) 활용
UI에는 ReportViewer가 있습니다.
흐름:
get_report- 없으면
generate_report - 다시
get_report - 존재하면 표시
즉, 리포트가 아직 없으면 조회 시점에 자동 생성될 수 있습니다.
- Account 모달에서 Notion OAuth 시작
- 팝업 기반 연결 완료
- 연결 상태는 런타임 설정 파일에 저장
/notion/status/notion/oauth/start/notion/oauth/callback/notion/disconnect/notion/pages/search/notion/pages/notion/save
- Note 페이지의
NotionSaveModal - 특정 논문 노트를 기존 페이지에 append 또는 새 페이지로 저장
Discord 설정은 런타임 저장 방식으로 관리됩니다.
API:
GET /config/discordPOST /config/discord
파이프라인 인자:
discord_webhook_fulldiscord_webhook_summary
용도:
- 긴 full report 전송
- 짧은 summary report 전송
추가로 notification 도구를 통해 테스트 전송도 가능합니다.
현재 web/App.tsx 기준 주요 라우트:
| 라우트 | 화면 |
|---|---|
/ |
HomePage |
/graph |
GlobalGraphPage |
/paper/:paperId |
PaperGraphPage |
/neurips2025 |
NeurIPS2025Page |
/iclr2025 |
ICLR2025Page |
/note/:paperId |
NotePage |
공통 컴포넌트:
NavBarLLMChatPopupPipelineModalAccountSettingsModal
web/vite.config.ts는 단순 Vite 설정이 아니라, 실제 워크스페이스 동작에 중요한 미들웨어를 포함합니다.
'/api'→MCP_SERVER_URL(기본http://localhost:8000)- 경로 rewrite:
/api/foo→/foo
POST /api/chat→http://research-agent:8001/chatGET /api/neurips/papersGET /api/neurips/similaritiesGET /api/neurips/clustersGET /api/iclr/papersGET /api/iclr/similaritiesGET /api/iclr/clustersGET /output/*→/app/output파일 직접 서빙GET /pdf/*→/app/pdf파일 직접 서빙
즉, 웹 컨테이너는 단순 정적 프런트엔드가 아니라, 컨퍼런스 메타데이터와 로컬 산출물을 함께 제공하는 개발 서버 역할을 합니다.
GET /GET /healthGET /toolsGET /tools/schemaGET /tools/{tool_name}POST /tools/{tool_name}/execute
GET /pdf/listPOST /pdf/extractGET /pdf/process-all
GET /arxiv/searchPOST /arxiv/search-for-ranking
GET /reports/{paper_id}POST /paper/interpret
POST /agent/runPOST /agent/conference-pipelineGET /agent/status/{job_id}GET /agent/jobs
GET /rank-filter/profilePOST /rank-filter/profilePOST /rank-filter/execute-pipeline
GET /config/credentialsPOST /config/credentialsGET /config/discordPOST /config/discordGET /notion/statusGET /notion/oauth/startPOST /notion/disconnectGET /notion/pages/searchGET /notion/pagesPOST /notion/save
agent/는 단순 REST wrapper가 아니라, 별도 오케스트레이션 레이어입니다.
AgentClientMemoryPlannerExecutor
- MCP 서버의
/tools/schema에서 도구 정의 로드 - OpenAI에 시스템 프롬프트 + 툴 스키마 전달
- LLM이 도구 호출을 선택
- Agent가 MCP에 실제 실행 요청
- 결과를 다시 LLM에 전달
- 최종 응답 반환
- 대화 이력
- 도구 호출 이력
- 현재 플랜
- intermediate result
- context
현재 코드상 기본 모델은 gpt-4o입니다.
list_pdfsextract_textextract_imagesextract_allprocess_all_pdfsget_pdf_inforead_extracted_textcheck_github_link
arxiv_searcharxiv_get_paperarxiv_download
web_searchweb_get_contentweb_research
update_user_profileapply_hard_filterscalculate_semantic_scoresevaluate_paper_metricsrank_and_select_top_k
run_research_agentrun_conference_pipelineextract_paper_sectionsgenerate_reportanalyze_sectionpaper_qasend_discord_notification
현재 mcp/tools/ 디렉터리에는 아래 모듈들이 있습니다.
arxiv.pychapter_headings.pyiclr_pipeline.pyiclr_search.pyneurips2025_pdf.pyneurips_adapter.pyneurips_pipeline.pyneurips_search.pynotification.pynotion.pypage_analyzer.pypaper_graph.pypdf.pypodcast.pyrag_qa.pyrank_filter.pyrefer.pyreport.pyresearch_agent.pyservey.pytranslate.pyweb_search.py
정확한 등록 결과와 파라미터 스키마는 런타임 기준
/tools와/tools/schema가 source of truth 입니다.
mcp/registry.py가 이 디렉터리의 도구를 자동으로 발견/등록합니다.
pdf/
output/_runtime/service_settings.json
일반적으로 아래와 같은 파일이 생성될 수 있습니다.
output/<paper_id>/
├─ extracted_text.json
├─ extracted_text.txt
├─ image_metadata.json
├─ images/
├─ notes 관련 파일
├─ report 관련 파일
└─ reference/graph 관련 파일
output/agent_reports/
output/agent_status/
output/rankings/
output/users/
logs/prompts/*.jsonl
mcp-server 이미지에는 pytest 관련 의존성이 포함되어 있으므로 컨테이너 안에서 실행할 수 있습니다.
docker compose exec mcp-server pytest tests -q현재 테스트 파일:
tests/test_neurips_integration.pytests/test_rank_filter.pytests/test_translate.py
모델 호출은 카테고리별 JSONL로 남습니다.
logs/prompts/
런타임에 어떤 도구가 실제 등록되었는지 보려면:
curl http://localhost:8000/tools
curl http://localhost:8000/tools/schema원인:
agent컨테이너가 실행 중이 아님
해결:
docker compose up -d agent
curl http://localhost:8001/health확인:
- 파일이 실제로
./pdf/아래 있는지 - 확장자가
.pdf인지 - 컨테이너 마운트가 정상인지
curl http://localhost:8000/pdf/list결과에 보이는지
확인:
./output/에 파일이 생성되는지- 웹 컨테이너가
/output을 서빙 중인지 - 브라우저에서
/output/...경로가 404인지
확인:
./data/embeddings_Neu/./data/embeddings_ICLR/- 관련 JSON 파일이 존재하는지
해결:
docker compose build web
docker compose up -d web웹 엔트리포인트는 node_modules가 없거나 일부 패키지가 빠지면 자동으로 npm install을 수행합니다.
다음 경로는 커밋하지 않는 것이 맞습니다.
output/_runtime/
이 안에는 다음이 포함될 수 있습니다.
- OpenAI API Key
- Tavily API Key
- Notion OAuth state/connection
- Discord webhook 설정
Research Agent는 로컬 Docker 환경에서 실행되는 논문 연구 워크스페이스로, MCP 도구 서버(mcp-server), OpenAI 오케스트레이터(agent), React UI(web)를 결합해 검색·랭킹·다운로드·추출·분석·리포트·그래프·노트·외부 연동을 하나의 흐름으로 제공한다.