citeguard
citeguard
철회된 논문은 철회된 뒤에도 수년간 인용됩니다. 2010년에 철회된 MMR 백신과 자폐증을 연결한 Andrew Wakefield의 사기성 1998년 논문은, 그 철회 이후에도 쉽게 알 도리가 없었던 연구자들에 의해 천 번 이상 인용되었습니다. 2026년 JMIR 연구는 무료로 제공되는 AI 도구가 "철회된 문헌을 확실한 표시할 수 없다"고 밝혔습니다. AI 기반 연구와 작성이 폭발적으로 늘어나던 바로 그 시기에 말입니다. citeguard는 그 공백을 메웁니다: 인용이 논문, 요약, 또는 리뷰에 들어가기 전에 Crossref, 무료·API 키 불필요.에서 인용을 확인하는 것입니다.
세 가지 인터페이스, 하나의 검증된 검출 알고리즘:
인터페이스 | 대상 | 위치 |
Python library + CLI | 학술 저자, 스크립트 | |
MCP server | 연구/작성을 수행하는 AI 에이전트 | |
GitHub Action | 실험실 또는 저널 저장소의 CI |
이렇게 만들어진 이유
검출 로직을 문서에서 추즉한 것이 아니라 Crossref의 실제 API를 쿼마 알려진 사례를 조회하고 실제 응답 구조를 읽은 뒤, 저장된 실제 응답(파이썬과 TypeScript 구현이 모두 공유하며 tests/fixtures/에 커밋되어 있음)을 대상으로 테스트를 작성하는 방식으로 기반을 삼았습니다. 두 편의 실제 논문이 그 최종 판단 기준(ground truth)을 제공합니다:
Wakefield et al., 1998, The Lancet (MMR-자폐증 논문): 출판사 자체 Crossref 메타데이터에는 구조화된 철회 데이터가 없습니다 —
update-to확인만으로는 결과가 조용히 놓치게 됩니다. 실제로 신호를 전하는 것은 별개의updated-by필드인데, Crossref가 그 철회(및 이전의 2004년 수정) 정보를 Retraction Watch database to itself에서 소급해서 채워 넣었습니다. 이 필드를 놓치면 의학계에서 가장 유명한 철회 논문 놓치는 셈이었습니다.Mehra et al., 2020, The Lancet (Surgisphere 관련 COVID/하이드로클로로퀸 논문): 이 논문에서는 출판사가
update-to를 통해 구조화 데이터를 직접 첨부했습니다. 다른 필드, 다른 출처, 동일한 기본 사실입니다.Watson & Crick, 1953, Nature 은(는) 초기 테스트 스위트 전반에서 깨끗한 대조군으로 쓰입니다. 확실히-실재하고 분명히-철회되지 않은 논문이며, 결코 플래그로 표시되지 않아야 합니다.
그래서 검사기는 순서대로 세 가지 독립적인 신호를 봅니다: update-to(출판사가 직접 선언), updated-by(주로 Retraction Watch 소스에서 와서 출판사가 놓친 회수 사항을 채우는 신호), 그리고 두 쪽 어느 필드에도 구조화 메타데이터가 없는 오래되었거나 연결되지 않은 사례를 위한 제목 접두어 폴백("RETRACTED:", "WITHDRAWN:" 등)입니다. 각 신호는 적절한 심각도로 매핑됩니다 — "Expression of Concern:" 제목은 철회와 같은 뜻이 아니며, 이 구분을 무너뜨린 이 코드의 이전 버전은 합성 데이터가 아니라실제 제목을 대상으로 한 테스트에서 잡아낸 버그입니다. 상세 설명이 모두 포함된 구현 실행 방식는 src/citeguard/analyze.py를 참고하세요.
Related MCP server: Citation Guard
빠른 시작
CLI:
pip install -e .
citeguard doi 10.1016/S0140-6736(97)11096-0
citeguard file references.bib --fail-on retracted # for CI, see belowMCP server (클라이언트 설정에 추가하세요, 예: .mcp.json):
{ "mcpServers": { "citeguard": { "command": "node", "args": ["/path/to/citeguard/mcp-server/dist/index.js"] } } }GitHub Action (다른 저장소의 workflow에서):
- uses: wedo911/citeguard@main
with:
path: references.bib
fail-on: concern # never | retracted | concern | corrected이 것은 아닌 것
논문의 내용이 올바르다는 증거가 아닙니다. 단지 철회 여부만 확인하며, 철회되지 않은 논문의 연구 결과가 옳은지는 확인하지 않습니다.
포괄적이지 않습니다. 제목 접두사 휴리스틱은 테스트에서 다룬 출판사 관례만 잡아냅니다; 깨끗한 결과는 "알려진 신호를 찾지 못함"을 뜻하는 것이지 "확실히 철회된 적 없음"을 보장하지 않습니다.
대량 수집 도구가 아닙니다. 실제 표 항으로 인용되지 않은 텍스트 내에도 쓰일 수 있는 수십 개 인용 정도의 실제 참고 문헌 규모에 맞춰 설계되었으며, Crossref 요청 사이에 작은 고정 지연 및 선택적인 영구 캐시(
src/citeguard/cache.py)를 포함합니다 — 무료 공공 서비스에 대한 좋은 API 시민 정신이지, 수백만 개의 DOI를 스캔하는 도구가 아닙니다.
테스트 실행
# Python (55 tests, including against the real fixtures above)
pip install -e ".[dev]" && pytest -v
# MCP server (17 tests against the same real fixtures)
cd mcp-server && npm install && npm run build && npm test두 테스트 호츤 모두 네트워크 없이 결정적으로 동작합니다 — 저장된 실제 API 응답을 대상으로 실행하고 라이브 호출을 하지 않으므로 빠르고 Crossref에 연결되어 있지 않아도 됩니다. 실제 라이브 전체 (실제 CLI와 실제 MCP 도구, 실제 API에 요청)는 개발 중 손으로 별도 확인했습니다. GitHub Action에는 별도 CI 작업(action-smoke-test)이 있으며, push 시마다 실제 composite action을 알려진-철회 및 알려진-정상 참고 독서 목록에 대해 실행합니다. 따라서 기본 라이브러리 뿐 아니라 Action 자체도 라이브 API에 대해 지속적으로 검증됩니다.
기여하기
새 신호 유형, 출판사 제목 관례 추가, false-positive 보고를 늘 환영합니다. 사례를 추가할 때는 가능하면 합성 픽수보다 실제로 인용된 Crossref 픽스처를 더 선호하세요 — 개발 중 이 프로젝트의 테스트 실행이 두 실제 버그(DOI 요청 경로의 URL 인코딩 버그와 구조가 잘못된 @comment 블록을 분석할 때 인접 항목을 삼켜 버릴 수 있던 BibTeX 파서)를 찾은 것은 그 방식이었습니다.
라이선스
MIT — LICENSE 참고.
Available Tools
2 toolscheck_citationCheck a Citation for RetractionARead-onlyIdempotent
Check a single DOI against Crossref for retraction, correction, or expression-of-concern status. Use this before citing a paper in a document, summary, or literature review -- retracted papers (including fraudulent or debunked ones) continue to be cited for years after retraction, often because whoever is citing them has no easy way to check. This tool checks three independent signal sources: publisher-asserted updates, Crossref's ingested Retraction Watch data (which catches many retractions the publisher's own metadata misses), and a title-prefix fallback ("RETRACTED:", etc.) for older or unlinked cases.
Args:
doi (string): a DOI, with or without a "https://doi.org/" prefix.
Returns: For JSON format: { "doi": string, "verdict": "retracted" | "concern" | "corrected" | "clean" | "not_found" | "error", "title": string | null, "signals": [ { "type": string, "source": string, "label": string | null, "noticeDoi": string | null, "date": string | null } ], "error": string | null }
Examples:
Use when: about to cite a paper in a summary, report, or literature review -- check it first
Use when: reviewing someone else's bibliography for outdated or unreliable sources
Don't use when: you need to verify a claim's accuracy generally -- this only checks retraction status, not whether the paper's content is correct
Error Handling:
A DOI Crossref doesn't recognize returns verdict "not_found", not an error -- it may still be a real paper Crossref just doesn't index (e.g. some preprints), not necessarily an invalid citation.
| Name | Required | Description | Default |
|---|---|---|---|
| doi | Yes | A DOI, e.g. "10.1016/S0140-6736(97)11096-0" (with or without a "https://doi.org/" prefix). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, open-world, idempotent, and non-destructive behavior, and the description adds substantial context beyond that: three independent signal sources, Retraction Watch ingestion, title-prefix fallback, and the important distinction that an unrecognized DOI returns 'not_found' rather than 'error'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the tool's purpose and well-organized into usage, signal sources, arguments, returns, examples, and error handling. The message is somewhat long for a one-parameter tool, with mild motivational padding about retracted papers continuing to be cited, but the structure is clear and every section is operationally useful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete given the tool's complexity and missing output schema: it documents the return shape, verdict enum values, signal structure, and key error-handling behavior. Annotations cover the safety profile, so no critical behavioral or call-routing information is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for the single DOI parameter, and the description repeats the same prefix flexibility already documented in the schema. No additional syntax, constraints, or examples beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
State a specific verb and resource ('Check a single DOI against Crossref') and names the exact statuses checked. The word 'single' distinguishes it from the sibling batch tool check_citations without needing to open either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use guidance ('before citing a paper') and a clear when-not-to-use case ('verify a claim's accuracy generally'). It does not explicitly name the sibling check_citations as the alternative for multiple DOIs, so the alternative routing is only implied by the singular scope.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_citationsCheck All Citations in a Block of TextARead-onlyIdempotent
Extract every DOI found in a block of text (a reference list, a paper draft, an exported bibliography) and check each one for retraction/correction/expression-of-concern status via Crossref. Use this to sanity-check a whole reference list at once before finalizing a document, rather than checking citations one at a time.
Finds DOIs in any form: bare ("10.1016/S0140-6736(97)11096-0"), as a doi.org URL, or embedded in a formatted citation. Up to 50 unique DOIs are checked per call; if more are found, only the first 50 (in order of first appearance) are checked and the response says so.
Args:
text (string, 1-200000 chars): the text to scan.
Returns: For JSON format: { "totalFound": number, "checked": number, "truncated": boolean, "results": [ { "doi": string, "verdict": string, "title": string|null, "signals": [...], "error": string|null } ] }
Examples:
Use when: finishing a literature review or research summary -- paste the whole reference list to check it in one call
Don't use when: checking just one citation you already have the DOI for -- use check_citation instead, it's simpler
Error Handling:
Returns an error if text is empty or exceeds 200000 characters. Text with no DOI-shaped substrings returns totalFound: 0, not an error.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Free text to scan for DOIs -- a reference list, a paper draft with inline citations, or a bibliography exported as plain text. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Although annotations already cover readOnly, idempotent, non-destructive, and openWorld behavior, the description adds substantial behavioral detail beyond them: Crossref lookup semantics, support for bare/doi.org/formatted DOIs, a 50-unique-DOI cap with first-in-order truncation, and explicit error conditions for empty/overlong text and no-DOI text.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with purpose and primary use, then organized into Args, Returns, Examples, and Error Handling. Every section earns its place by explaining batch behavior, output shape, or edge cases that an agent otherwise could not infer.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with no output schema, the description supplies the missing return shape, truncation behavior, and error handling. Combined with annotations and a fully documented schema, an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single text parameter is already documented in the schema with min/max length and examples. The description's Args section largely restates the schema, so it does not materially deepen parameter semantics beyond what is already structured.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb+resource: extract every DOI in a block of text and check each for retraction/correction/expression-of-concern status via Crossref. It explicitly distinguishes this batch tool from the sibling check_citation by contrasting whole-list checking with one-at-a-time checking.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states exactly when to use this tool ('finishing a literature review or research summary -- paste the whole reference list') and when not to ('checking just one citation you already have the DOI for -- use check_citation instead'). The alternative tool is named and the condition for selecting it is stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.1.2- First observed
check_citation - First observed
check_citations
TDQS
Scored across 2 tools
check_citations (bulk scan of text) and check_citation (single DOI) have overlapping purposes, and the near-identical singular/plural names invite misselection. However, each description explicitly cross-references the other with 'use X instead' guidance, so an agent can reliably choose the right one.
Both tools use consistent snake_case with a clear verb_noun shape, and the singular/plural convention neatly signals single vs. bulk behavior. The only downside is that the two names differ by a single character, which is a mild collision risk.
Two tools is on the thin side, but the domain (checking retraction status of DOIs) is genuinely narrow and the single/bulk split is the one meaningful axis of variation. Nothing feels gratuitous, though a third tool would be hard to justify.
The surface covers the core lifecycle: check one DOI, check many DOIs in a block of text, with defined verdicts and error handling. A minor gap is the absence of any way to resolve a citation lacking a DOI (e.g. by title/author) into a checkable identifier.
Maintenance
Related MCP Connectors
Catch AI-fabricated citations (real DOI + fake title). Retraction, open-access, 10,000+ CSL styles.
Checks AI-written references against Crossref, PubMed and OpenAlex. Formats citations, PRISMA.
Real-time fact-check, citation verification, and source-freshness for AI agents.
Live web checks for AI agents: sitemaps, robots.txt, URL status, broken links, feeds, citations.
Related MCP Servers
- AlicenseAqualityDmaintenancePrevents citation hallucination by verifying academic citations against CrossRef's database of 150+ million publications before they can be mentioned, ensuring every citation includes a valid DOI.316MIT
- AlicenseNot gradedqualityDmaintenanceVerifies citations in reference lists by checking DOIs against public registries to catch AI-hallucinated or mismatched citations.MIT

CiteStamp MCP serverofficial
AlicenseNot gradedqualityBmaintenanceGround citations before your agent emits them by checking references against public scholarly registries and flagging hallucinated or retracted ones.MIT- AlicenseAqualityCmaintenanceProvides MCP tools to check reference lists for retracted or problematic citations, retrieve nuanced editorial statuses with evidence, and monitor institutions for newly flagged papers using open data from OpenAlex, Retraction Watch, and Crossref.327 PyPIMIT