Skip to main content
Glama
tbaraniuk

arxiv-agent-mcp

by tbaraniuk

arXiv Research-Concept Companion

AI/ML 학습 보조 에이전트(KSE Agentic Lab 과제)입니다. Obsidian 보관소에서 개념 요약 노트를 읽고, 관련 arXiv 논문을 찾고, 각각을 주제 관련성과 연령 보정 인용 영향도로 채점한 다음, 통과한 후보가 기반으로 삼는 정립된 논문들을 찾아 그 결과를 다시 보관소에 써 넣습니다.

  • 기존 MCP 서버(Part A): Obsidian Local REST API MCP.

  • 커스텀 MCP 서버(Part B): custom_server/ — FastMCP 앱으로, 공개 arXiv 및 OpenAlex API(인증 불필요)를 대상으로 하는 도구 3개를 제공합니다.

  • 에이전트: agent/ — OpenRouter 기반 PydanticAI Agent이며, 두 MCP 연결을 도구 세트로 보유하고 LangGraph 상태 머신이 오케스트레이션합니다.

사전 요구 사항

  • Python 3.12+, uv.

  • OpenRouter API 키.

  • Obsidian에 Local REST API 커뮤니티 플러그인이 설치·실행 중이어야 하며, Obsidian과 통신하는 MCP 서버(어느 Obsidian Local REST API MCP 구현이든 무방 — 실행 명령은 아래에서 설정 가능)가 있어야 합니다.

Related MCP server: arxiv-mcp

설치

uv sync
cp .env.example .env

.env 작성:

변수

의미

OPENROUTER_API_KEY

OpenRouter 키 — 에이전트와 score_paper_relevance에서 사용합니다.

OPENROUTER_MODEL

모델 slug입니다. 예: openai/gpt-4o-mini.

OBSIDIAN_API_KEY / OBSIDIAN_BASE_URL

Local REST API 플러그인 자격 증명입니다.

OBSIDIAN_MCP_COMMAND

Obsidian MCP 서버 구동에 필요한 인자를 공백으로 구분한 argv입니다. 예: npx -y <obsidian-mcp-package>.

RELEVANCE_PASS_THRESHOLD

필터를 통과하기 위한 최소 관련성 점수(0–1)입니다. 기본값 0.5.

CITATIONS_PER_YEAR_THRESHOLD

영향력 검사를 통과하기 위한 최소 연간 인용 수입니다. 기본값 5.

NEW_PAPER_AGE_EXEMPT_YEARS

이보다 최근 평가 미만인 논문은 영향력 검사에서 면제됩니다. 기본값 1.

실행

하나의 uv 프로젝트를 공유하는 두 개의 독립 프로세스:

# process 1 — the custom MCP server (arXiv + OpenAlex)
uv run python -m custom_server.server

# process 2 — the agent (connects to both MCP servers), driven by a free-text prompt
uv run python -m agent.graph "Find papers related to my 'Transformers Concept Note'"

agent/graph.pycustom_server/server.py 자체를 stdio 서브프로세스로 직접 실행하므로, 프로세스 2는 프로세스 1이 이미 실행 중일 필요가 없습니다 — 위의 두 명령은 각각 독립적으로 시작할 수 있음을 보여줄 뿐입니다.

프롬프트는 노트 제목을 그대로 쓴 것이 아닙니다 — 에이전트의 첫 단계(parse_prompt)는 LLM 호출을 이용해 프롬프트가 어느 Obsidian 노트를 가리키는지 식별합니다. 만약 노트를 찾지 못하면 Obsidian을 건드리지 않고 즉시 실행을 중단하고 프롬프트에 Obsidian 노트나 페이지가 지정되지 않았습니다."라는 메시지를 출력합니다. 노트를 찾았는데 그 안에서 충분한 개념 키워드(min_keywords 미만, 기본값 2)가 나오지 않으면, 그 노트를 읽은 뒤 실행을 멈추고 arXiv 검색 대신 "정보 부족" 메시지를 출력합니다.

오프라인 / 재생 모드

커스텀 서버는 원래 세 개의 실시간 네트워크 API(arXiv, OpenAlex, OpenRouter)를 호출합니다. 그러나 CUSTOM_SERVER_OFFLINE=1로 설정하면 대신 custom_server/fixtures/에 기록된 픽스처에서 도구 제공 — 네트워크 접근이나 OPENROUTER_API_KEY가 필요 없습니다. 네트워크가 불안정한 상태에서 데모/발표할 때나 빠른 반복 작업에 유용합니다.

CUSTOM_SERVER_OFFLINE=1 uv run python -m custom_server.server

포함되는 범위: search_arxiv_papers(어떤 검색어에도 동일하게 제공되는 기록된 검색 피드 1개 — 아래 제한 사항 참조)와 GPT-3(2005.14165), ResNet(1512.03385) 두편에 대한 score_paper_relevance / find_foundational_citations입니다.

알려진 제한 사항:

  • search_arxiv_papers는 오프라인 모드에서 쿼리 무관(이하는)입니다 — 쿼리 텍스트와 관계없이 항상 동일한 기록된 피드를 반환합니다.

  • score_paper_relevancefind_foundational_citations는 위 두 기록된 논문만 인식합니다. 기록에 없는 arxiv_id는 PaperNotFoundError를 발생합니다(실제 OpenAlex 조회에서도 OpenAlex 논문이 누락될 때와 동일한 오류입니다). score_paper_relevance에 전달된 기록 외 논문 제목은 FixtureNotFoundError를 발생 — 조용히 틀린 답을 주는 대신 구별 가능한 오류를 돌려줍니다.

픽스처를 다시 만들거나 확장하려면: uv run custom_server.fixtures.record로 이용하면 기록된 arXiv/OpenAlex 응답(모두 공개 auth API)을 다시 가져오고 custom_server/fixtures/ 안의 그대로 JSON/XML 파일을 덮어씁니다. 새 논문을 추가하려면 해당 논문의 두 httpx.get 호출을 record.py에 추가하고, relevance_scores.json에도 그에 대응하는 항목을 직접 입력하세요(코드로 생성되지는 않은 자료 — 실제 OpenRouter 출력이 아닙니다. 원시 채팅 완료 응답을 그대로 저장하기엔 wire 형식의 손상 위험에 비해 이득이 없기 때문입니다. 대신 구조화된 {relevance, novelty, rationale} 필드가 PydanticAI FunctionModel을 통해 직접 재생됩니다).

테스트

uv run pytest custom_server/tests agent/tests

모든 네트워크 호출(arXiv, OpenAlex, OpenRouter)은 모킹됩니다. 테스트 중 실 시간 트래픽이 발생하지 않습니다.

도구 계약(Part C)

search_arxiv_papers (custom)

모든 종류의 일치 항목

목적

핵심 데이터 소스 도구: 주제에 대한 후보 논문을 arXiv에서 검색합니다.

모델 지향 설명

"주제에 대한 논문을 arXiv에서 검색하되, 선택적으로 카테고리와 최소 제출 날짜(since_date)로도 제한할 수 있습니다. 후보 논문을 score_paper_relevance로 각각 평가하기 전에 이 도구로 후보를 찾으세요. 유효한 검색어가 아무것도 일치하지 않으면 빈 목록을 돌려줍니다 — 그건 정상 결과이지 오류가 아닙니다."

입력

query: str, categories: list[str] = [cs.LG, cs.AI, cs.CL, stat.ML], since_date: str | None (YYYY-MM-DD), max_results: int = 10 (1–50)

출력

list[{arxiv_id, title, abstract, authors: list[str], published_date, categories: list[str]}]

오류 조건

잘못된 카테고리 코드, 형식이 잘못된 since_date, 또는 [1, 50] 범위를 벗어난 max_results는 네트워크 호출 이전에 ValueError를 발생시킵니다. 상위 HTTP에서 오류가 발생하면 raise_for_status()로 전파됩니다. 결과가 0이어도 정상적인 빈 목록이며 오류 아닙니다.

부작용

없음 — export.arxiv.org에 대한 읽기 전용 HTTPS GET입니다.

예시

search_arxiv_papers(query="transformer attention", max_results=5) → 초록이 포함된 후보 논문 5개.

score_paper_relevance(custom)

목적

평가 도구: 후보 논문이 주제에 얼마나 부합하는지, 인용 기록이연령 보정 기준충족하는지 판단합니다.

모델 지시 설명

"개념 요약에 대해 논문이 얼마나 관련 있고새로운지 점수를 매기고, 그 인용 기록이 최소 기준(연간 인용 수, 1년 미만인 새 논문은 제외)을 통과하는지 확인합니다. search_arxiv_papers에서 얻은 각 후보에 이 도구를 적용해 그 논문이 읽기 목록에 들어가야 하는지 결정하세요. 만약 해당 논문의 OpenAlex 기록이 없거나, 기본이 되는 관련성-채점 모델 호출이 실패하면 오류를 발생시킵니다."

입력

개요: concept, paper: {arxiv_id, title, abstract}

출력

{relevance: float, novelty: float, citation_count: int, publication_year: int, citations_per_year: float, impact_pass: bool, rationale: str}

오류 조건

OpenAlex에 arXiv DOI가 해당 DOI에 없으면 PaperNotFoundError(custom_server.openalex에서) — found-but-not-cited 논문의 유효한 citation_count: 0과는 다른 사항입니다. 재시도 후에도 OpenRouter 호출의 구조화된 내용이 스키마 검증에 실패하면 UnexpectedModelBehavior가 발생됩니다.

부작용

읽기 전용: OpenAlex GET 1회, OpenRouter 채팅 완료 호출 1회.

예시

score_paper_relevance(concept_summary="attention mechanisms in NLP", 도서={...}){relevance: 0.92, novelty: 0.6, citation_count: 84331, impact_pass: True, ...}

find_foundational_citations (커스텀)

목적

인용 그래프 분석: 논문 하나가 주어지면, 해당 논문이 기반으로 하는 잘 정립된 연구를 표면화하기 위해 그 자체의 참고문헌을 인용 횟수로 정렬합니다. search_arxiv_papers와는 별개입니다 — 특정 논문의 참고문헌 목록을 분석하는 일이지, 키워드 검색이 아닙니다.

모델 지향 설명

"논문 하나의 arXiv ID가 주어지면 가장 많이 인용된 참고문헌들 — 즉 그 논문이 기반하는 잘 정립된 선행 연구 — 을 반환합니다. 읽을 논문을 고른 뒤, 그 뒤에 있는 배경 문헌을 드러내기 위해 사용하세요. 참고문헌이 등록되지 않은 논문은 빈 목록을 반환합니다 — 오류가 아니라 정상적인 결과입니다."

입력

arxiv_id: str, max_results: int = 3 (1–3)

출력

list[{openalex_id, title, cited_by_count, publication_year}], cited_by_count 내림차순으로 정렬, 상위 max_results

오류 조건

max_results[1, 3] 범위 밖이면 ValueError. OpenAlex에 해당 arXiv ID의 레코드가 없으면 PaperNotFoundError. 참고문헌이 존재하지 않는 논문은 [] 반환 — 유효한 결과일 뿐, 오류가 아닙니다.

부작용

읽기 전용 — OpenAlex 논문 조회 1회 + OpenAlex works 일괄 조회(요청당 50개 ID chunk 단위) 1회 이상.

예시

find_foundational_citations(arxiv_id="2005.14165", max_results=3) → GPT-3가 참조하는 가장 많이 인용된 3편.

참조 확인 해석

Obsidian 호출 전에, parse_prompt이 사용자의 자유 형식 프롬프트가 암시하는 노트 제목을 식별해 달라고 PydanticAI 에이전트(일반 LLM 사고 방식이며 MCP 호출이 아닌)께 요청한다. 그 어떤 것도 식별되지 않으면 흐름은 "정보 부족(중요 information)" 상태로 중단하고, Obsidian을 아예 발생시키지 않는다.

읽기

에이전트가 parse_– 별표서 얻은 note_title이라는 제목의 노트를 읽어 순수 텍스트로 돌려주도록 시킴 — 그 내용이 text input, 즉 concept_text가 되어 키워드 추출과 관련성 점수에 들어간다.

쓰기

compose_note_content가 생성한 마크다운으로 "{note_title} — weight" — 정확히는 "{note_title} — Related Papers"라는 제목의 노트를 만들거나 덮어쓰도록 에이전트를 안내한다 — 두 MCP 서버를 잇는 내부 고리를 시각적으로 닫는 효과가 여기서 나타난다.

오류 조건

플러그인이 중지되었거나, API 키가 잘못되었거나, 노트가 없는 경우는 조용한 빈 결과로 나타나지 않고, MCP 서버가내어놓는 구분 가능한 도구-호출 실패로서 나타난다.

설계 근거

  • 왜 Obsidian인가: 과제에서 에이전트가 읽고 동시에 쓸 수 있는 기존 MCP 서버가 필요하다. 학생 지식의 개념 노트는 "내가 이미 아는 것은?"라는 입력으로 자연스럽고, 통과한 후보를 다시 기록해 볼트 안에서 이 연결고리가 명확하게 보이게 닫힌다.

  • 왜 로그인 장벽이 있는 사이트 대신 arXiv + OpenAlex인가: 처음 고려했던 KSE 스케줄/Moodle 자료는 모두 개인 로그인이 필요한 반면, 과제의 공개 API 규칙이 이러들을 배제한다. arXiv와 OpenAlex는 공개적이고 인증이 필요 없으며, "관령성 + 바력"(relevance + impact) 영역을 직접 지원한다.

  • 왜 관련성을 임베딩이 아닌 LLM으로 판정하는가: 서버공개 상에서 OpenRouter는 임베딩 엔드포인트가 없다(라이브 모델 카탈로그와 대조로 확인). 그래서 score_paper_relevance는 벡터 유사도 대신 PydanticAI 구조화 출력 호출을 써서, 프로젝트가 어차피 사용하는 단일 모델 자격 증명을 그대로 재사용한다.

  • find_foundational_citations가 "OpenAlex로 다시 검색"이 아닌가: 이건 특정 논문의 참고 리스트 하나를 받아 그것을 인용충격으로 정렬한다 — 과제 자체의 예시들이 활용하는 와 대안, 통제된 지표 비교와 같은 종류다. 키워드 중심의 search_arxiv_papers와는 목적도 처리 단계도 다르다.

  • 필터링은 4번째 툴이 아니라 단순 파이썬이다: agent/graph.pyfilter_candidates_node 안에서 이루어지는 "관련성 임계값 + impact_pass" is filtering은 이미 점수가 부과된 데이터에 대해 결정적인 후처리일 뿐 새 도메인 로직이 아니다 — 그것을 툴로 만들면 단지 if 문을 하나 덧본 셈이 된다.

  • 절충과 제한: 커스텀 서버의 오프라인/리플레이 모드(위의 "오프라인 / 재생 모드" 참조)는 레코딩되어 있는 논문 2편과 어떤 질의에든 무관한 arXiv 검색을 커버한다 — 임의의 질의를 일반적으로 기록하거나 재생하는 기능은 아니다. agent/의 자체 Obsidian 및 OpenRouter 호출은 그 모드의 지원을 받지 않으며 실제 온라인 연결이 그대로 필요하다. 영향력/관련성 임계값은 .env 파일의 값이라, 요청 때마다 런타임으로 조정할 수는 없다.

연기된 사항(flagged, 不是 포기)

  • 하드코딩된 임계값을 .env를 넘어선 더 풍부한 런타임 유연성으로 노출시키는 것.

데모 / 방어 체크리스트

  • uv run python -m custom_server.server가 단독 실행되고, 원시 MCP 클라이언트의 list_tools 3개 도구가 모두 표시됩니다.

  • uv run pytest custom_server/tests agent/tests — 전체 통과, AI액세스는 모두 mock 처리되어 있습니다.

  • CUSTOM_SERVER_OFFLINE=1 uv run python -m custom_server.server — 실 네트에 연결할 wait, API 키 없이 3개 도구 호출을 모두 처리 가능한 것을 볼 수 있습니다(위 "오프라인/재생 모드" 참고).

  • 데모 볼트 노트에 개념 요약(예: "attention mechanisms")을 채워넣고 'Transformers Concept Note'로 명명한다.

  • uv run python -m agent.graph "Find papers 관련 to my 'Transformers Concept Note'" — 라이브 실행 전체: 노트 참조를 맞는지, 노트를 읽고, arXiv를 검색하고, 후보를 점수화하며, 필터링하고, 기반 인용을 찾고, "<note> — Related Papers"라고 하는 write-back을 금고다.

  • 최종 결과를 만드는 데 두 MCP 연결이 모두 기여하는 것을 보여줍니다: write-back된 노트가 arXiv/OpenAlex 데이터(커스텀 서버)와 사용자의 원본 개념 노트 내용(Obsidian)을 모두 인용합니다.

  • 정보 부족 데모: 노트 제목을 명명하지 않는 프롬프트(예: "What's a transformer?")로 시연 — Obsidian 호출 없이 에이전트가 멈추며 "Not enough information..."을 출력함을 보여준다. 이어서 내용이 거의 비어 있는 노트로 실행 — 노트를 읽고 arXiv를 호출하기 전에 멈추는 것을 보여준다.

  • Obsidian 실패 데모: Local REST API 플러그인을 중지시키거나(또는 잘못된 OBSIDIAN_API_KEY/존재하지 않는 노트 제목을 사용) — 에이전트가 빈 결과를 만악한 조용한 실패 대신 뚜렷이 구분되는 하나의 오류를 내는지 보여준다.

  • 커스텀 서버 실패 데모: 유효하지 않은 카테고리로 search_arxiv_papers를 호출하거나, OpenAlex에 없는 arXiv ID로 find_foundational_citations를 호출 — 정상 빈 결과와 구분되어 각각 ValueError/PaperNotFoundError가 나는 것을 보여준다.


Install Server
A
license - permissive license
A
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    This MCP server enables users to search for scientific papers on arXiv and retrieve detailed metadata for specific papers. It provides tools to perform search queries and fetch in-depth information using paper IDs.
    3
    Apache 2.0
  • F
    license
    A
    quality
    D
    maintenance
    A streamlined MCP server that connects AI assistants to arXiv's vast collection of academic papers, enabling search, retrieval, and analysis of research papers.
    7
    1
  • F
    license
    Not graded
    quality
    D
    maintenance
    An advanced scholarly research MCP server that enables AI assistants to discover, fetch, process, and manage academic papers across multiple sources like arXiv, PubMed, and Semantic Scholar, with capabilities for summarization, citation analysis, and concept relationship extraction.
    1

View all related MCP servers

Related MCP Connectors

  • Academic research MCP server for paper search, citation checks, graphs, and deep research.

  • Driflyte MCP server which lets AI assistants query topic-specific knowledge from web and GitHub.

  • An MCP server for deep research or task groups

View all MCP Connectors

Latest Blog Posts

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/tbaraniuk/arxiv-agent-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server