flonat-research 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/domain-reviewer.md +336 -0
- package/.claude/agents/fixer.md +226 -0
- package/.claude/agents/paper-critic.md +370 -0
- package/.claude/agents/peer-reviewer.md +289 -0
- package/.claude/agents/proposal-reviewer.md +215 -0
- package/.claude/agents/referee2-reviewer.md +367 -0
- package/.claude/agents/references/journal-referee-profiles.md +354 -0
- package/.claude/agents/references/paper-critic/council-personas.md +77 -0
- package/.claude/agents/references/paper-critic/council-prompts.md +198 -0
- package/.claude/agents/references/peer-reviewer/report-template.md +199 -0
- package/.claude/agents/references/peer-reviewer/sa-prompts.md +260 -0
- package/.claude/agents/references/peer-reviewer/security-scan.md +188 -0
- package/.claude/agents/references/proposal-reviewer/report-template.md +144 -0
- package/.claude/agents/references/proposal-reviewer/sa-prompts.md +149 -0
- package/.claude/agents/references/referee-config.md +114 -0
- package/.claude/agents/references/referee2-reviewer/audit-checklists.md +287 -0
- package/.claude/agents/references/referee2-reviewer/report-template.md +334 -0
- package/.claude/rules/design-before-results.md +52 -0
- package/.claude/rules/ignore-agents-md.md +17 -0
- package/.claude/rules/ignore-gemini-md.md +17 -0
- package/.claude/rules/lean-claude-md.md +45 -0
- package/.claude/rules/learn-tags.md +99 -0
- package/.claude/rules/overleaf-separation.md +67 -0
- package/.claude/rules/plan-first.md +175 -0
- package/.claude/rules/read-docs-first.md +50 -0
- package/.claude/rules/scope-discipline.md +28 -0
- package/.claude/settings.json +125 -0
- package/.context/current-focus.md +33 -0
- package/.context/preferences/priorities.md +36 -0
- package/.context/preferences/task-naming.md +28 -0
- package/.context/profile.md +29 -0
- package/.context/projects/_index.md +41 -0
- package/.context/projects/papers/nudge-exp.md +22 -0
- package/.context/projects/papers/uncertainty.md +31 -0
- package/.context/resources/claude-scientific-writer-review.md +48 -0
- package/.context/resources/cunningham-multi-analyst-agents.md +104 -0
- package/.context/resources/cunningham-multilang-code-audit.md +62 -0
- package/.context/resources/google-ai-co-scientist-review.md +72 -0
- package/.context/resources/karpathy-llm-council-review.md +58 -0
- package/.context/resources/multi-coder-reliability-protocol.md +175 -0
- package/.context/resources/pedro-santanna-takeaways.md +96 -0
- package/.context/resources/venue-rankings/abs_ajg_2024.csv +1823 -0
- package/.context/resources/venue-rankings/abs_ajg_2024_econ.csv +356 -0
- package/.context/resources/venue-rankings/cabs_4_4star_theory.csv +40 -0
- package/.context/resources/venue-rankings/core_2026.csv +801 -0
- package/.context/resources/venue-rankings.md +147 -0
- package/.context/workflows/README.md +69 -0
- package/.context/workflows/daily-review.md +91 -0
- package/.context/workflows/meeting-actions.md +108 -0
- package/.context/workflows/replication-protocol.md +155 -0
- package/.context/workflows/weekly-review.md +113 -0
- package/.mcp-server-biblio/formatters.py +158 -0
- package/.mcp-server-biblio/pyproject.toml +11 -0
- package/.mcp-server-biblio/server.py +678 -0
- package/.mcp-server-biblio/sources/__init__.py +14 -0
- package/.mcp-server-biblio/sources/base.py +73 -0
- package/.mcp-server-biblio/sources/formatters.py +83 -0
- package/.mcp-server-biblio/sources/models.py +22 -0
- package/.mcp-server-biblio/sources/multi_source.py +243 -0
- package/.mcp-server-biblio/sources/openalex_source.py +183 -0
- package/.mcp-server-biblio/sources/scopus_source.py +309 -0
- package/.mcp-server-biblio/sources/wos_source.py +508 -0
- package/.mcp-server-biblio/uv.lock +896 -0
- package/.scripts/README.md +161 -0
- package/.scripts/ai_pattern_density.py +446 -0
- package/.scripts/conf +445 -0
- package/.scripts/config.py +122 -0
- package/.scripts/count_inventory.py +275 -0
- package/.scripts/daily_digest.py +288 -0
- package/.scripts/done +177 -0
- package/.scripts/extract_meeting_actions.py +223 -0
- package/.scripts/focus +176 -0
- package/.scripts/generate-codex-agents-md.py +217 -0
- package/.scripts/inbox +194 -0
- package/.scripts/notion_helpers.py +325 -0
- package/.scripts/openalex/query_helpers.py +306 -0
- package/.scripts/papers +227 -0
- package/.scripts/query +223 -0
- package/.scripts/session-history.py +201 -0
- package/.scripts/skill-health.py +516 -0
- package/.scripts/skill-log-miner.py +273 -0
- package/.scripts/sync-to-codex.sh +252 -0
- package/.scripts/task +213 -0
- package/.scripts/tasks +190 -0
- package/.scripts/week +206 -0
- package/CLAUDE.md +197 -0
- package/LICENSE +21 -0
- package/MEMORY.md +38 -0
- package/README.md +269 -0
- package/docs/agents.md +44 -0
- package/docs/bibliography-setup.md +55 -0
- package/docs/council-mode.md +36 -0
- package/docs/getting-started.md +245 -0
- package/docs/hooks.md +38 -0
- package/docs/mcp-servers.md +82 -0
- package/docs/notion-setup.md +109 -0
- package/docs/rules.md +33 -0
- package/docs/scripts.md +303 -0
- package/docs/setup-overview/setup-overview.pdf +0 -0
- package/docs/skills.md +70 -0
- package/docs/system.md +159 -0
- package/hooks/block-destructive-git.sh +66 -0
- package/hooks/context-monitor.py +114 -0
- package/hooks/postcompact-restore.py +157 -0
- package/hooks/precompact-autosave.py +181 -0
- package/hooks/promise-checker.sh +124 -0
- package/hooks/protect-source-files.sh +81 -0
- package/hooks/resume-context-loader.sh +53 -0
- package/hooks/startup-context-loader.sh +102 -0
- package/package.json +51 -0
- package/packages/cli-council/.github/workflows/claude-code-review.yml +44 -0
- package/packages/cli-council/.github/workflows/claude.yml +50 -0
- package/packages/cli-council/README.md +100 -0
- package/packages/cli-council/pyproject.toml +43 -0
- package/packages/cli-council/src/cli_council/__init__.py +19 -0
- package/packages/cli-council/src/cli_council/__main__.py +185 -0
- package/packages/cli-council/src/cli_council/backends/__init__.py +8 -0
- package/packages/cli-council/src/cli_council/backends/base.py +81 -0
- package/packages/cli-council/src/cli_council/backends/claude.py +25 -0
- package/packages/cli-council/src/cli_council/backends/codex.py +27 -0
- package/packages/cli-council/src/cli_council/backends/gemini.py +26 -0
- package/packages/cli-council/src/cli_council/checkpoint.py +212 -0
- package/packages/cli-council/src/cli_council/config.py +51 -0
- package/packages/cli-council/src/cli_council/council.py +391 -0
- package/packages/cli-council/src/cli_council/models.py +46 -0
- package/packages/llm-council/.github/workflows/claude-code-review.yml +44 -0
- package/packages/llm-council/.github/workflows/claude.yml +50 -0
- package/packages/llm-council/README.md +453 -0
- package/packages/llm-council/pyproject.toml +42 -0
- package/packages/llm-council/src/llm_council/__init__.py +23 -0
- package/packages/llm-council/src/llm_council/__main__.py +259 -0
- package/packages/llm-council/src/llm_council/checkpoint.py +193 -0
- package/packages/llm-council/src/llm_council/client.py +253 -0
- package/packages/llm-council/src/llm_council/config.py +232 -0
- package/packages/llm-council/src/llm_council/council.py +482 -0
- package/packages/llm-council/src/llm_council/models.py +46 -0
- package/packages/mcp-bibliography/MEMORY.md +31 -0
- package/packages/mcp-bibliography/_app.py +226 -0
- package/packages/mcp-bibliography/formatters.py +158 -0
- package/packages/mcp-bibliography/log/2026-03-13-2100.md +35 -0
- package/packages/mcp-bibliography/pyproject.toml +15 -0
- package/packages/mcp-bibliography/run.sh +20 -0
- package/packages/mcp-bibliography/scholarly_formatters.py +83 -0
- package/packages/mcp-bibliography/server.py +1857 -0
- package/packages/mcp-bibliography/tools/__init__.py +28 -0
- package/packages/mcp-bibliography/tools/_registry.py +19 -0
- package/packages/mcp-bibliography/tools/altmetric.py +107 -0
- package/packages/mcp-bibliography/tools/core.py +92 -0
- package/packages/mcp-bibliography/tools/dblp.py +52 -0
- package/packages/mcp-bibliography/tools/openalex.py +296 -0
- package/packages/mcp-bibliography/tools/opencitations.py +102 -0
- package/packages/mcp-bibliography/tools/openreview.py +179 -0
- package/packages/mcp-bibliography/tools/orcid.py +131 -0
- package/packages/mcp-bibliography/tools/scholarly.py +575 -0
- package/packages/mcp-bibliography/tools/unpaywall.py +63 -0
- package/packages/mcp-bibliography/tools/zenodo.py +123 -0
- package/packages/mcp-bibliography/uv.lock +711 -0
- package/scripts/setup.sh +143 -0
- package/skills/beamer-deck/SKILL.md +199 -0
- package/skills/beamer-deck/references/quality-rubric.md +54 -0
- package/skills/beamer-deck/references/review-prompts.md +106 -0
- package/skills/bib-validate/SKILL.md +261 -0
- package/skills/bib-validate/references/council-mode.md +34 -0
- package/skills/bib-validate/references/deep-verify.md +79 -0
- package/skills/bib-validate/references/fix-mode.md +36 -0
- package/skills/bib-validate/references/openalex-verification.md +45 -0
- package/skills/bib-validate/references/preprint-check.md +31 -0
- package/skills/bib-validate/references/ref-manager-crossref.md +41 -0
- package/skills/bib-validate/references/report-template.md +82 -0
- package/skills/code-archaeology/SKILL.md +141 -0
- package/skills/code-review/SKILL.md +265 -0
- package/skills/code-review/references/quality-rubric.md +67 -0
- package/skills/consolidate-memory/SKILL.md +208 -0
- package/skills/context-status/SKILL.md +126 -0
- package/skills/creation-guard/SKILL.md +230 -0
- package/skills/devils-advocate/SKILL.md +130 -0
- package/skills/devils-advocate/references/competing-hypotheses.md +83 -0
- package/skills/init-project/SKILL.md +115 -0
- package/skills/init-project-course/references/memory-and-settings.md +92 -0
- package/skills/init-project-course/references/organise-templates.md +94 -0
- package/skills/init-project-course/skill.md +147 -0
- package/skills/init-project-light/skill.md +139 -0
- package/skills/init-project-research/SKILL.md +368 -0
- package/skills/init-project-research/references/atlas-pipeline-sync.md +70 -0
- package/skills/init-project-research/references/atlas-schema.md +81 -0
- package/skills/init-project-research/references/confirmation-report.md +39 -0
- package/skills/init-project-research/references/domain-profile-template.md +104 -0
- package/skills/init-project-research/references/interview-round3.md +34 -0
- package/skills/init-project-research/references/literature-discovery.md +43 -0
- package/skills/init-project-research/references/scaffold-details.md +197 -0
- package/skills/init-project-research/templates/field-calibration.md +60 -0
- package/skills/init-project-research/templates/pipeline-manifest.md +63 -0
- package/skills/init-project-research/templates/run-all.sh +116 -0
- package/skills/init-project-research/templates/seed-files.md +337 -0
- package/skills/insights-deck/SKILL.md +151 -0
- package/skills/interview-me/SKILL.md +157 -0
- package/skills/latex/SKILL.md +141 -0
- package/skills/latex/references/latex-configs.md +183 -0
- package/skills/latex-autofix/SKILL.md +230 -0
- package/skills/latex-autofix/references/known-errors.md +183 -0
- package/skills/latex-autofix/references/quality-rubric.md +50 -0
- package/skills/latex-health-check/SKILL.md +161 -0
- package/skills/learn/SKILL.md +220 -0
- package/skills/learn/scripts/validate_skill.py +265 -0
- package/skills/lessons-learned/SKILL.md +201 -0
- package/skills/literature/SKILL.md +335 -0
- package/skills/literature/references/agent-templates.md +393 -0
- package/skills/literature/references/bibliometric-apis.md +44 -0
- package/skills/literature/references/cli-council-search.md +79 -0
- package/skills/literature/references/openalex-api-guide.md +371 -0
- package/skills/literature/references/openalex-common-queries.md +381 -0
- package/skills/literature/references/openalex-workflows.md +248 -0
- package/skills/literature/references/reference-manager-sync.md +36 -0
- package/skills/literature/references/scopus-api-guide.md +208 -0
- package/skills/literature/references/wos-api-guide.md +308 -0
- package/skills/multi-perspective/SKILL.md +311 -0
- package/skills/multi-perspective/references/computational-many-analysts.md +77 -0
- package/skills/pipeline-manifest/SKILL.md +226 -0
- package/skills/pre-submission-report/SKILL.md +153 -0
- package/skills/process-reviews/SKILL.md +244 -0
- package/skills/process-reviews/references/rr-routing.md +101 -0
- package/skills/project-deck/SKILL.md +87 -0
- package/skills/project-safety/SKILL.md +135 -0
- package/skills/proofread/SKILL.md +254 -0
- package/skills/proofread/references/quality-rubric.md +104 -0
- package/skills/python-env/SKILL.md +57 -0
- package/skills/quarto-deck/SKILL.md +226 -0
- package/skills/quarto-deck/references/markdown-format.md +143 -0
- package/skills/quarto-deck/references/quality-rubric.md +54 -0
- package/skills/save-context/SKILL.md +174 -0
- package/skills/session-log/SKILL.md +98 -0
- package/skills/shared/concept-validation-gate.md +161 -0
- package/skills/shared/council-protocol.md +265 -0
- package/skills/shared/distribution-diagnostics.md +164 -0
- package/skills/shared/engagement-stratified-sampling.md +218 -0
- package/skills/shared/escalation-protocol.md +74 -0
- package/skills/shared/external-audit-protocol.md +205 -0
- package/skills/shared/intercoder-reliability.md +256 -0
- package/skills/shared/mcp-degradation.md +81 -0
- package/skills/shared/method-probing-questions.md +163 -0
- package/skills/shared/multi-language-conventions.md +143 -0
- package/skills/shared/paid-api-safety.md +174 -0
- package/skills/shared/palettes.md +90 -0
- package/skills/shared/progressive-disclosure.md +92 -0
- package/skills/shared/project-documentation-content.md +443 -0
- package/skills/shared/project-documentation-format.md +281 -0
- package/skills/shared/project-documentation.md +100 -0
- package/skills/shared/publication-output.md +138 -0
- package/skills/shared/quality-scoring.md +70 -0
- package/skills/shared/reference-resolution.md +77 -0
- package/skills/shared/research-quality-rubric.md +165 -0
- package/skills/shared/rhetoric-principles.md +54 -0
- package/skills/shared/skill-design-patterns.md +272 -0
- package/skills/shared/skill-index.md +240 -0
- package/skills/shared/system-documentation.md +334 -0
- package/skills/shared/tikz-rules.md +402 -0
- package/skills/shared/validation-tiers.md +121 -0
- package/skills/shared/venue-guides/README.md +46 -0
- package/skills/shared/venue-guides/cell_press_style.md +483 -0
- package/skills/shared/venue-guides/conferences_formatting.md +564 -0
- package/skills/shared/venue-guides/cs_conference_style.md +463 -0
- package/skills/shared/venue-guides/examples/cell_summary_example.md +247 -0
- package/skills/shared/venue-guides/examples/medical_structured_abstract.md +313 -0
- package/skills/shared/venue-guides/examples/nature_abstract_examples.md +213 -0
- package/skills/shared/venue-guides/examples/neurips_introduction_example.md +245 -0
- package/skills/shared/venue-guides/journals_formatting.md +486 -0
- package/skills/shared/venue-guides/medical_journal_styles.md +535 -0
- package/skills/shared/venue-guides/ml_conference_style.md +556 -0
- package/skills/shared/venue-guides/nature_science_style.md +405 -0
- package/skills/shared/venue-guides/reviewer_expectations.md +417 -0
- package/skills/shared/venue-guides/venue_writing_styles.md +321 -0
- package/skills/split-pdf/SKILL.md +172 -0
- package/skills/split-pdf/methodology.md +48 -0
- package/skills/sync-notion/SKILL.md +93 -0
- package/skills/system-audit/SKILL.md +157 -0
- package/skills/system-audit/references/sub-agent-prompts.md +294 -0
- package/skills/task-management/SKILL.md +131 -0
- package/skills/update-focus/SKILL.md +204 -0
- package/skills/update-project-doc/SKILL.md +194 -0
- package/skills/validate-bib/SKILL.md +242 -0
- package/skills/validate-bib/references/council-mode.md +34 -0
- package/skills/validate-bib/references/deep-verify.md +71 -0
- package/skills/validate-bib/references/openalex-verification.md +45 -0
- package/skills/validate-bib/references/preprint-check.md +31 -0
- package/skills/validate-bib/references/report-template.md +62 -0
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
# Common OpenAlex Query Examples
|
|
2
|
+
|
|
3
|
+
This document provides practical examples for common research queries using OpenAlex.
|
|
4
|
+
|
|
5
|
+
## Finding Papers by Author
|
|
6
|
+
|
|
7
|
+
**User query**: "Find papers by Albert Einstein"
|
|
8
|
+
|
|
9
|
+
**Approach**: Two-step pattern
|
|
10
|
+
1. Search for author to get ID
|
|
11
|
+
2. Filter works by author ID
|
|
12
|
+
|
|
13
|
+
**Python example**:
|
|
14
|
+
```python
|
|
15
|
+
from scripts.openalex_client import OpenAlexClient
|
|
16
|
+
from scripts.query_helpers import find_author_works
|
|
17
|
+
|
|
18
|
+
client = OpenAlexClient(email="your-email@example.edu")
|
|
19
|
+
works = find_author_works("Albert Einstein", client, limit=100)
|
|
20
|
+
|
|
21
|
+
for work in works:
|
|
22
|
+
print(f"{work['title']} ({work['publication_year']})")
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Finding Papers from an Institution
|
|
26
|
+
|
|
27
|
+
**User query**: "What papers has MIT published in the last year?"
|
|
28
|
+
|
|
29
|
+
**Approach**: Two-step pattern with date filter
|
|
30
|
+
1. Search for institution to get ID
|
|
31
|
+
2. Filter works by institution ID and year
|
|
32
|
+
|
|
33
|
+
**Python example**:
|
|
34
|
+
```python
|
|
35
|
+
from scripts.query_helpers import find_institution_works
|
|
36
|
+
|
|
37
|
+
works = find_institution_works("MIT", client, limit=200)
|
|
38
|
+
|
|
39
|
+
# Filter for recent papers
|
|
40
|
+
import datetime
|
|
41
|
+
current_year = datetime.datetime.now().year
|
|
42
|
+
recent_works = [w for w in works if w['publication_year'] == current_year]
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Highly Cited Papers on a Topic
|
|
46
|
+
|
|
47
|
+
**User query**: "Find the most cited papers on CRISPR from the last 5 years"
|
|
48
|
+
|
|
49
|
+
**Approach**: Search + filter + sort
|
|
50
|
+
|
|
51
|
+
**Python example**:
|
|
52
|
+
```python
|
|
53
|
+
works = client.search_works(
|
|
54
|
+
search="CRISPR",
|
|
55
|
+
filter_params={
|
|
56
|
+
"publication_year": ">2019"
|
|
57
|
+
},
|
|
58
|
+
sort="cited_by_count:desc",
|
|
59
|
+
per_page=100
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
for work in works['results']:
|
|
63
|
+
title = work['title']
|
|
64
|
+
citations = work['cited_by_count']
|
|
65
|
+
year = work['publication_year']
|
|
66
|
+
print(f"{title} ({year}): {citations} citations")
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Open Access Papers on a Topic
|
|
70
|
+
|
|
71
|
+
**User query**: "Find open access papers about climate change"
|
|
72
|
+
|
|
73
|
+
**Approach**: Search + OA filter
|
|
74
|
+
|
|
75
|
+
**Python example**:
|
|
76
|
+
```python
|
|
77
|
+
from scripts.query_helpers import get_open_access_papers
|
|
78
|
+
|
|
79
|
+
papers = get_open_access_papers(
|
|
80
|
+
search_term="climate change",
|
|
81
|
+
client=client,
|
|
82
|
+
oa_status="any", # or "gold", "green", "hybrid", "bronze"
|
|
83
|
+
limit=200
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
for paper in papers:
|
|
87
|
+
print(f"{paper['title']}")
|
|
88
|
+
print(f" OA Status: {paper['open_access']['oa_status']}")
|
|
89
|
+
print(f" URL: {paper['open_access']['oa_url']}")
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Publication Trends Analysis
|
|
93
|
+
|
|
94
|
+
**User query**: "Show me publication trends for machine learning over the years"
|
|
95
|
+
|
|
96
|
+
**Approach**: Use group_by to aggregate by year
|
|
97
|
+
|
|
98
|
+
**Python example**:
|
|
99
|
+
```python
|
|
100
|
+
from scripts.query_helpers import get_publication_trends
|
|
101
|
+
|
|
102
|
+
trends = get_publication_trends(
|
|
103
|
+
search_term="machine learning",
|
|
104
|
+
client=client
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
# Sort by year
|
|
108
|
+
trends_sorted = sorted(trends, key=lambda x: x['key'])
|
|
109
|
+
|
|
110
|
+
for trend in trends_sorted[-10:]: # Last 10 years
|
|
111
|
+
year = trend['key']
|
|
112
|
+
count = trend['count']
|
|
113
|
+
print(f"{year}: {count} publications")
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Analyzing Research Output
|
|
117
|
+
|
|
118
|
+
**User query**: "Analyze the research output of Stanford University from 2020-2024"
|
|
119
|
+
|
|
120
|
+
**Approach**: Multiple aggregations for comprehensive analysis
|
|
121
|
+
|
|
122
|
+
**Python example**:
|
|
123
|
+
```python
|
|
124
|
+
from scripts.query_helpers import analyze_research_output
|
|
125
|
+
|
|
126
|
+
analysis = analyze_research_output(
|
|
127
|
+
entity_type='institution',
|
|
128
|
+
entity_name='Stanford University',
|
|
129
|
+
client=client,
|
|
130
|
+
years='2020-2024'
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
print(f"Institution: {analysis['entity_name']}")
|
|
134
|
+
print(f"Total works: {analysis['total_works']}")
|
|
135
|
+
print(f"Open access: {analysis['open_access_percentage']}%")
|
|
136
|
+
print("\nTop topics:")
|
|
137
|
+
for topic in analysis['top_topics'][:5]:
|
|
138
|
+
print(f" - {topic['key_display_name']}: {topic['count']} works")
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Finding Papers by DOI (Batch)
|
|
142
|
+
|
|
143
|
+
**User query**: "Get information for these 10 DOIs: ..."
|
|
144
|
+
|
|
145
|
+
**Approach**: Batch lookup with pipe separator
|
|
146
|
+
|
|
147
|
+
**Python example**:
|
|
148
|
+
```python
|
|
149
|
+
dois = [
|
|
150
|
+
"https://doi.org/10.1371/journal.pone.0266781",
|
|
151
|
+
"https://doi.org/10.1371/journal.pone.0267149",
|
|
152
|
+
"https://doi.org/10.1038/s41586-021-03819-2",
|
|
153
|
+
# ... up to 50 DOIs
|
|
154
|
+
]
|
|
155
|
+
|
|
156
|
+
works = client.batch_lookup(
|
|
157
|
+
entity_type='works',
|
|
158
|
+
ids=dois,
|
|
159
|
+
id_field='doi'
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
for work in works:
|
|
163
|
+
print(f"{work['title']} - {work['publication_year']}")
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Random Sample of Papers
|
|
167
|
+
|
|
168
|
+
**User query**: "Give me 50 random papers from 2023"
|
|
169
|
+
|
|
170
|
+
**Approach**: Use sample parameter with seed for reproducibility
|
|
171
|
+
|
|
172
|
+
**Python example**:
|
|
173
|
+
```python
|
|
174
|
+
works = client.sample_works(
|
|
175
|
+
sample_size=50,
|
|
176
|
+
seed=42, # For reproducibility
|
|
177
|
+
filter_params={
|
|
178
|
+
"publication_year": "2023",
|
|
179
|
+
"is_oa": "true"
|
|
180
|
+
}
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
print(f"Got {len(works)} random papers from 2023")
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Papers from Multiple Institutions
|
|
187
|
+
|
|
188
|
+
**User query**: "Find papers with authors from both MIT and Stanford"
|
|
189
|
+
|
|
190
|
+
**Approach**: Use + operator for AND within same attribute
|
|
191
|
+
|
|
192
|
+
**Python example**:
|
|
193
|
+
```python
|
|
194
|
+
# First, get institution IDs
|
|
195
|
+
mit_response = client._make_request(
|
|
196
|
+
'/institutions',
|
|
197
|
+
params={'search': 'MIT', 'per-page': 1}
|
|
198
|
+
)
|
|
199
|
+
mit_id = mit_response['results'][0]['id'].split('/')[-1]
|
|
200
|
+
|
|
201
|
+
stanford_response = client._make_request(
|
|
202
|
+
'/institutions',
|
|
203
|
+
params={'search': 'Stanford', 'per-page': 1}
|
|
204
|
+
)
|
|
205
|
+
stanford_id = stanford_response['results'][0]['id'].split('/')[-1]
|
|
206
|
+
|
|
207
|
+
# Find works with authors from both institutions
|
|
208
|
+
works = client.search_works(
|
|
209
|
+
filter_params={
|
|
210
|
+
"authorships.institutions.id": f"{mit_id}+{stanford_id}"
|
|
211
|
+
},
|
|
212
|
+
per_page=100
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
print(f"Found {works['meta']['count']} collaborative papers")
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Papers in a Specific Journal
|
|
219
|
+
|
|
220
|
+
**User query**: "Get all papers from Nature published in 2023"
|
|
221
|
+
|
|
222
|
+
**Approach**: Two-step - find journal ID, then filter works
|
|
223
|
+
|
|
224
|
+
**Python example**:
|
|
225
|
+
```python
|
|
226
|
+
# Step 1: Find journal source ID
|
|
227
|
+
source_response = client._make_request(
|
|
228
|
+
'/sources',
|
|
229
|
+
params={'search': 'Nature', 'per-page': 1}
|
|
230
|
+
)
|
|
231
|
+
source = source_response['results'][0]
|
|
232
|
+
source_id = source['id'].split('/')[-1]
|
|
233
|
+
|
|
234
|
+
print(f"Found journal: {source['display_name']} (ID: {source_id})")
|
|
235
|
+
|
|
236
|
+
# Step 2: Get works from that source
|
|
237
|
+
works = client.search_works(
|
|
238
|
+
filter_params={
|
|
239
|
+
"primary_location.source.id": source_id,
|
|
240
|
+
"publication_year": "2023"
|
|
241
|
+
},
|
|
242
|
+
per_page=200
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
print(f"Found {works['meta']['count']} papers from Nature in 2023")
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Topic Analysis by Institution
|
|
249
|
+
|
|
250
|
+
**User query**: "What topics does MIT research most?"
|
|
251
|
+
|
|
252
|
+
**Approach**: Filter by institution, group by topics
|
|
253
|
+
|
|
254
|
+
**Python example**:
|
|
255
|
+
```python
|
|
256
|
+
# Get MIT ID
|
|
257
|
+
inst_response = client._make_request(
|
|
258
|
+
'/institutions',
|
|
259
|
+
params={'search': 'MIT', 'per-page': 1}
|
|
260
|
+
)
|
|
261
|
+
mit_id = inst_response['results'][0]['id'].split('/')[-1]
|
|
262
|
+
|
|
263
|
+
# Group by topics
|
|
264
|
+
topics = client.group_by(
|
|
265
|
+
entity_type='works',
|
|
266
|
+
group_field='topics.id',
|
|
267
|
+
filter_params={
|
|
268
|
+
"authorships.institutions.id": mit_id,
|
|
269
|
+
"publication_year": ">2020"
|
|
270
|
+
}
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
print("Top research topics at MIT (2020+):")
|
|
274
|
+
for i, topic in enumerate(topics[:10], 1):
|
|
275
|
+
print(f"{i}. {topic['key_display_name']}: {topic['count']} works")
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Citation Analysis
|
|
279
|
+
|
|
280
|
+
**User query**: "Find papers that cite this specific DOI"
|
|
281
|
+
|
|
282
|
+
**Approach**: Get work by DOI, then use cited_by_api_url
|
|
283
|
+
|
|
284
|
+
**Python example**:
|
|
285
|
+
```python
|
|
286
|
+
# Get the work
|
|
287
|
+
doi = "https://doi.org/10.1038/s41586-021-03819-2"
|
|
288
|
+
work = client.get_entity('works', doi)
|
|
289
|
+
|
|
290
|
+
# Get papers that cite it
|
|
291
|
+
cited_by_url = work['cited_by_api_url']
|
|
292
|
+
|
|
293
|
+
# Extract just the query part and use it
|
|
294
|
+
import requests
|
|
295
|
+
response = requests.get(cited_by_url, params={'mailto': client.email})
|
|
296
|
+
citing_works = response.json()
|
|
297
|
+
|
|
298
|
+
print(f"{work['title']}")
|
|
299
|
+
print(f"Total citations: {work['cited_by_count']}")
|
|
300
|
+
print(f"\nRecent citing papers:")
|
|
301
|
+
for citing_work in citing_works['results'][:5]:
|
|
302
|
+
print(f" - {citing_work['title']} ({citing_work['publication_year']})")
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## Large-Scale Data Extraction
|
|
306
|
+
|
|
307
|
+
**User query**: "Get all papers on quantum computing from the last 3 years"
|
|
308
|
+
|
|
309
|
+
**Approach**: Paginate through all results
|
|
310
|
+
|
|
311
|
+
**Python example**:
|
|
312
|
+
```python
|
|
313
|
+
all_papers = client.paginate_all(
|
|
314
|
+
endpoint='/works',
|
|
315
|
+
params={
|
|
316
|
+
'search': 'quantum computing',
|
|
317
|
+
'filter': 'publication_year:2022-2024'
|
|
318
|
+
},
|
|
319
|
+
max_results=10000 # Limit to prevent excessive API calls
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
print(f"Retrieved {len(all_papers)} papers")
|
|
323
|
+
|
|
324
|
+
# Save to CSV
|
|
325
|
+
import csv
|
|
326
|
+
with open('quantum_papers.csv', 'w', newline='') as f:
|
|
327
|
+
writer = csv.writer(f)
|
|
328
|
+
writer.writerow(['Title', 'Year', 'Citations', 'DOI', 'OA Status'])
|
|
329
|
+
|
|
330
|
+
for paper in all_papers:
|
|
331
|
+
writer.writerow([
|
|
332
|
+
paper['title'],
|
|
333
|
+
paper['publication_year'],
|
|
334
|
+
paper['cited_by_count'],
|
|
335
|
+
paper.get('doi', 'N/A'),
|
|
336
|
+
paper['open_access']['oa_status']
|
|
337
|
+
])
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## Complex Multi-Filter Query
|
|
341
|
+
|
|
342
|
+
**User query**: "Find recent, highly-cited, open access papers on AI from top institutions"
|
|
343
|
+
|
|
344
|
+
**Approach**: Combine multiple filters
|
|
345
|
+
|
|
346
|
+
**Python example**:
|
|
347
|
+
```python
|
|
348
|
+
# Get IDs for top institutions
|
|
349
|
+
top_institutions = ['MIT', 'Stanford', 'Oxford']
|
|
350
|
+
inst_ids = []
|
|
351
|
+
|
|
352
|
+
for inst_name in top_institutions:
|
|
353
|
+
response = client._make_request(
|
|
354
|
+
'/institutions',
|
|
355
|
+
params={'search': inst_name, 'per-page': 1}
|
|
356
|
+
)
|
|
357
|
+
if response['results']:
|
|
358
|
+
inst_id = response['results'][0]['id'].split('/')[-1]
|
|
359
|
+
inst_ids.append(inst_id)
|
|
360
|
+
|
|
361
|
+
# Combine with pipe for OR
|
|
362
|
+
inst_filter = '|'.join(inst_ids)
|
|
363
|
+
|
|
364
|
+
# Complex query
|
|
365
|
+
works = client.search_works(
|
|
366
|
+
search="artificial intelligence",
|
|
367
|
+
filter_params={
|
|
368
|
+
"publication_year": ">2022",
|
|
369
|
+
"cited_by_count": ">50",
|
|
370
|
+
"is_oa": "true",
|
|
371
|
+
"authorships.institutions.id": inst_filter
|
|
372
|
+
},
|
|
373
|
+
sort="cited_by_count:desc",
|
|
374
|
+
per_page=200
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
print(f"Found {works['meta']['count']} papers matching criteria")
|
|
378
|
+
for work in works['results'][:10]:
|
|
379
|
+
print(f"{work['title']}")
|
|
380
|
+
print(f" Citations: {work['cited_by_count']}, Year: {work['publication_year']}")
|
|
381
|
+
```
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# OpenAlex Structured Query Workflows
|
|
2
|
+
|
|
3
|
+
> Extracted from the former `/openalex-search` skill. These workflows use the shared Python client in `.scripts/openalex/openalex_client.py` and helpers in `.scripts/openalex/query_helpers.py`.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
```python
|
|
8
|
+
import sys
|
|
9
|
+
sys.path.insert(0, ".scripts/openalex")
|
|
10
|
+
from openalex_client import OpenAlexClient
|
|
11
|
+
from query_helpers import find_highly_cited_recent_papers, get_open_access_papers, \
|
|
12
|
+
find_author_works, find_institution_works, analyze_research_output, get_publication_trends
|
|
13
|
+
|
|
14
|
+
client = OpenAlexClient(email="user@example.edu")
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Install dependency: `uv pip install requests`
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## When to Use OpenAlex Queries
|
|
22
|
+
|
|
23
|
+
| Scenario | OpenAlex workflow | Full `/literature` instead? |
|
|
24
|
+
|----------|-------------------|----------------------------|
|
|
25
|
+
| Find highly-cited papers on a topic | Workflow 1 | No — quick structured query |
|
|
26
|
+
| Build a full literature review with narrative | — | Yes — use full 7-phase pipeline |
|
|
27
|
+
| Citation count / trend analysis | Workflow 4 | No — API-only |
|
|
28
|
+
| Verify a specific citation exists | Workflow 7 | Or Phase 4 of `/literature` |
|
|
29
|
+
| Author or institution research output | Workflows 2–3 | No — API-only |
|
|
30
|
+
| Find open-access versions of papers | Workflow 5 | No — API-only |
|
|
31
|
+
| Comprehensive lit search + .bib assembly | — | Yes — calls OpenAlex as Phase 2 agent |
|
|
32
|
+
| Bibliometric analysis for a paper | Workflow 6 | No — API-only |
|
|
33
|
+
|
|
34
|
+
**Rule of thumb:** Use these workflows directly when you need *structured data* (counts, rankings, trends, metadata). Use the full `/literature` pipeline when you need a *complete workflow* (search, verify, download, synthesize).
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Core Workflows
|
|
39
|
+
|
|
40
|
+
### 1. Find Highly-Cited Papers on a Topic
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
papers = find_highly_cited_recent_papers(
|
|
44
|
+
topic="multi-criteria decision making",
|
|
45
|
+
years=">2018",
|
|
46
|
+
client=client,
|
|
47
|
+
limit=50
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
for p in papers[:10]:
|
|
51
|
+
print(f"[{p['cited_by_count']}] {p['title']} ({p['publication_year']})")
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 2. Author Publication Record
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
works = find_author_works("Salvatore Greco", client=client, limit=100)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Uses the two-step pattern: search author -> get ID -> filter works by ID.
|
|
61
|
+
|
|
62
|
+
### 3. Institution Research Output
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
analysis = analyze_research_output(
|
|
66
|
+
entity_type='institution',
|
|
67
|
+
entity_name='University of Example',
|
|
68
|
+
client=client,
|
|
69
|
+
years='>2020'
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
print(f"Total works: {analysis['total_works']}")
|
|
73
|
+
print(f"Open access: {analysis['open_access_percentage']}%")
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 4. Publication Trends
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
trends = get_publication_trends(
|
|
80
|
+
search_term="human-AI collaboration",
|
|
81
|
+
client=client
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
for t in sorted(trends, key=lambda x: x['key'])[-10:]:
|
|
85
|
+
print(f"{t['key']}: {t['count']} publications")
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 5. Open-Access Paper Discovery
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
papers = get_open_access_papers(
|
|
92
|
+
search_term="staggered difference-in-differences",
|
|
93
|
+
client=client,
|
|
94
|
+
oa_status="any",
|
|
95
|
+
limit=50
|
|
96
|
+
)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 6. Citation Network (Who Cites This Paper?)
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
import requests
|
|
103
|
+
|
|
104
|
+
work = client.get_entity('works', 'https://doi.org/10.1016/j.ejor.2023.01.001')
|
|
105
|
+
citing = requests.get(
|
|
106
|
+
work['cited_by_api_url'],
|
|
107
|
+
params={'mailto': client.email, 'per-page': 200}
|
|
108
|
+
).json()['results']
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 7. Batch DOI Lookup
|
|
112
|
+
|
|
113
|
+
For verifying multiple papers at once — useful for feeding into `/bib-validate`:
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
dois = [
|
|
117
|
+
"https://doi.org/10.1016/j.ejor.2023.01.001",
|
|
118
|
+
"https://doi.org/10.1287/mnsc.2022.4321",
|
|
119
|
+
]
|
|
120
|
+
|
|
121
|
+
works = client.batch_lookup('works', dois, 'doi')
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Key API Patterns
|
|
127
|
+
|
|
128
|
+
### Filters
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
# Single year
|
|
132
|
+
filter_params={"publication_year": "2023"}
|
|
133
|
+
|
|
134
|
+
# Range
|
|
135
|
+
filter_params={"publication_year": "2020-2025"}
|
|
136
|
+
|
|
137
|
+
# Multiple conditions (AND)
|
|
138
|
+
filter_params={"publication_year": ">2020", "is_oa": "true", "cited_by_count": ">50"}
|
|
139
|
+
|
|
140
|
+
# Multiple values (OR)
|
|
141
|
+
filter_params={"authorships.institutions.id": "I123|I456"}
|
|
142
|
+
|
|
143
|
+
# Collaboration (AND within attribute)
|
|
144
|
+
filter_params={"authorships.institutions.id": "I123+I456"}
|
|
145
|
+
|
|
146
|
+
# Negation
|
|
147
|
+
filter_params={"type": "!paratext"}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Two-Step Pattern (Always for Entity Lookups)
|
|
151
|
+
|
|
152
|
+
Never filter by entity names directly — always get the ID first:
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
# Step 1: Search -> get ID
|
|
156
|
+
author_resp = client._make_request('/authors', params={'search': 'Name', 'per-page': 1})
|
|
157
|
+
author_id = author_resp['results'][0]['id'].split('/')[-1]
|
|
158
|
+
|
|
159
|
+
# Step 2: Filter by ID
|
|
160
|
+
works = client.search_works(filter_params={"authorships.author.id": author_id})
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### External IDs
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
# DOI
|
|
167
|
+
client.get_entity('works', 'https://doi.org/10.1016/j.ejor.2023.01.001')
|
|
168
|
+
|
|
169
|
+
# ORCID
|
|
170
|
+
client.get_entity('authors', 'https://orcid.org/0000-0003-1613-5981')
|
|
171
|
+
|
|
172
|
+
# ROR (institution)
|
|
173
|
+
client.get_entity('institutions', 'https://ror.org/02y3ad647')
|
|
174
|
+
|
|
175
|
+
# ISSN (journal)
|
|
176
|
+
client.get_entity('sources', 'issn:0377-2217') # [Journal]
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Output Formats
|
|
182
|
+
|
|
183
|
+
When presenting results, format as a markdown table:
|
|
184
|
+
|
|
185
|
+
```markdown
|
|
186
|
+
| # | Title | Authors | Year | Journal | Citations | DOI |
|
|
187
|
+
|---|-------|---------|------|---------|-----------|-----|
|
|
188
|
+
| 1 | ... | ... | 2024 | [Journal] | 42 | 10.1016/... |
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
For BibTeX export (to feed into project `.bib`):
|
|
192
|
+
|
|
193
|
+
```python
|
|
194
|
+
for work in papers:
|
|
195
|
+
authors = " and ".join(
|
|
196
|
+
a['author']['display_name']
|
|
197
|
+
for a in work.get('authorships', [])
|
|
198
|
+
)
|
|
199
|
+
last_name = work['authorships'][0]['author']['display_name'].split()[-1]
|
|
200
|
+
key = last_name + str(work['publication_year'])
|
|
201
|
+
print(f"@article{{{key},")
|
|
202
|
+
print(f" author = {{{authors}}},")
|
|
203
|
+
print(f" title = {{{work['title']}}},")
|
|
204
|
+
print(f" year = {{{work['publication_year']}}},")
|
|
205
|
+
if work.get('doi'):
|
|
206
|
+
print(f" doi = {{{work['doi'].replace('https://doi.org/', '')}}},")
|
|
207
|
+
print("}")
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Rate Limits
|
|
213
|
+
|
|
214
|
+
| Pool | Rate | How to access |
|
|
215
|
+
|------|------|---------------|
|
|
216
|
+
| Default | 1 req/sec, 100k/day | No email |
|
|
217
|
+
| Polite | 10 req/sec, 100k/day | Pass email to client |
|
|
218
|
+
|
|
219
|
+
Always use the polite pool.
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## MCP Server (Preferred Over Python Client)
|
|
224
|
+
|
|
225
|
+
**Always prefer MCP tools when available.** The bibliography MCP server (`packages/mcp-bibliography/`) exposes all OpenAlex functionality plus cross-source search — no Python boilerplate needed.
|
|
226
|
+
|
|
227
|
+
| Task | MCP tool (preferred) | Python client (fallback) |
|
|
228
|
+
|------|---------------------|-------------------------|
|
|
229
|
+
| Search papers by topic | `scholarly_search` (all sources) | `find_highly_cited_recent_papers()` |
|
|
230
|
+
| Look up a DOI | `openalex_lookup_doi` | `client.get_entity()` |
|
|
231
|
+
| Batch DOI verification | `scholarly_verify_dois` | Manual loop |
|
|
232
|
+
| Find similar papers | `scholarly_similar_works` | N/A |
|
|
233
|
+
| Author publications | `openalex_author_works` | `find_author_works()` |
|
|
234
|
+
| Author profile | `openalex_author_profile` | `analyze_research_output()` |
|
|
235
|
+
| Institution output | `openalex_institution_output` | `analyze_research_output()` |
|
|
236
|
+
| Publication trends | `openalex_trends` | `get_publication_trends()` |
|
|
237
|
+
| Forward citations | `openalex_citing_works` | Manual `cited_by_api_url` fetch |
|
|
238
|
+
| Check active sources | `scholarly_source_status` | N/A |
|
|
239
|
+
|
|
240
|
+
Use the Python client below only for workflows not yet exposed via MCP (custom filter combinations, batch entity lookups by non-DOI IDs). See [`docs/mcp-servers.md`](../../../docs/mcp-servers.md) for full MCP documentation.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Complementary Skills
|
|
245
|
+
|
|
246
|
+
- **`/literature`** (parent skill) — OpenAlex serves as Phase 2 Agent 3 alongside Google Scholar and Semantic Scholar. Its API returns structured metadata that web scraping often misses.
|
|
247
|
+
- **`/bib-validate`** — Use batch DOI lookup (Workflow 7) to verify metadata for flagged entries.
|
|
248
|
+
- **`/split-pdf`** — Use OA discovery (Workflow 5) to find downloadable PDFs before split-reading.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Reference Manager Sync — Phase 6c Details
|
|
2
|
+
|
|
3
|
+
> Referenced from: `literature/SKILL.md` Phase 6c
|
|
4
|
+
|
|
5
|
+
After assembling and validating the `.bib`, sync new references to the user's reference libraries. Follow the filing sequence defined in [`../shared/reference-resolution.md`](../../shared/reference-resolution.md).
|
|
6
|
+
|
|
7
|
+
## Zotero (Active Write Target)
|
|
8
|
+
|
|
9
|
+
For each new entry not marked **ALREADY IN ZOTERO** from Phase 1:
|
|
10
|
+
|
|
11
|
+
1. **Add to Zotero** — call `mcp__refpile__add_item` with full metadata (title, authors, year, journal, DOI, itemType).
|
|
12
|
+
2. **File into topic collection** — resolve the topic collection key (from Phase 1 step 6) and call `mcp__refpile__add_to_collection(collection_key=<topic_key>)`.
|
|
13
|
+
3. **Tag for review** — also call `mcp__refpile__add_to_collection` with the `_Needs Review` collection key. Items go into both the topic collection and `_Needs Review`.
|
|
14
|
+
4. **Report results** — show a summary table of what was added and which collections they were filed into.
|
|
15
|
+
|
|
16
|
+
## Paperpile (Read-Only Cross-Reference)
|
|
17
|
+
|
|
18
|
+
For each new entry not already in Paperpile:
|
|
19
|
+
|
|
20
|
+
1. **Report additions needed** — list entries that need manual import into Paperpile (Paperpile MCP is read-only; the user adds via the Paperpile app or browser extension).
|
|
21
|
+
2. **Export BibTeX** — if Paperpile has entries with better metadata than what was assembled, call `mcp__paperpile__export_bib` and use those entries instead.
|
|
22
|
+
|
|
23
|
+
## Migration Candidates
|
|
24
|
+
|
|
25
|
+
For entries found in Paperpile but not in Zotero (status `MIGRATE_TO_ZOTERO` from Phase 1):
|
|
26
|
+
|
|
27
|
+
1. **Auto-add to Zotero** using Paperpile metadata.
|
|
28
|
+
2. **File into topic collection + `_Needs Review`** per the filing sequence.
|
|
29
|
+
3. **Report** the migration count.
|
|
30
|
+
|
|
31
|
+
## Post-Run Maintenance
|
|
32
|
+
|
|
33
|
+
1. **Update `zotero-collections.md`** — increment item counts for affected collections.
|
|
34
|
+
2. **Report Paperpile gaps** — items the user should manually add to Paperpile.
|
|
35
|
+
|
|
36
|
+
**Graceful degradation:** If either MCP is unavailable, skip that source with a warning. The `.bib` file on disk is still the primary output.
|