@wentorai/research-plugins 1.0.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.
Files changed (252) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +204 -0
  3. package/curated/analysis/README.md +64 -0
  4. package/curated/domains/README.md +104 -0
  5. package/curated/literature/README.md +53 -0
  6. package/curated/research/README.md +62 -0
  7. package/curated/tools/README.md +87 -0
  8. package/curated/writing/README.md +61 -0
  9. package/index.ts +39 -0
  10. package/mcp-configs/academic-db/ChatSpatial.json +17 -0
  11. package/mcp-configs/academic-db/academia-mcp.json +17 -0
  12. package/mcp-configs/academic-db/academic-paper-explorer.json +17 -0
  13. package/mcp-configs/academic-db/academic-search-mcp-server.json +17 -0
  14. package/mcp-configs/academic-db/agentinterviews-mcp.json +17 -0
  15. package/mcp-configs/academic-db/all-in-mcp.json +17 -0
  16. package/mcp-configs/academic-db/apple-health-mcp.json +17 -0
  17. package/mcp-configs/academic-db/arxiv-latex-mcp.json +17 -0
  18. package/mcp-configs/academic-db/arxiv-mcp-server.json +17 -0
  19. package/mcp-configs/academic-db/bgpt-mcp.json +17 -0
  20. package/mcp-configs/academic-db/biomcp.json +17 -0
  21. package/mcp-configs/academic-db/biothings-mcp.json +17 -0
  22. package/mcp-configs/academic-db/catalysishub-mcp-server.json +17 -0
  23. package/mcp-configs/academic-db/clinicaltrialsgov-mcp-server.json +17 -0
  24. package/mcp-configs/academic-db/deep-research-mcp.json +17 -0
  25. package/mcp-configs/academic-db/dicom-mcp.json +17 -0
  26. package/mcp-configs/academic-db/enrichr-mcp-server.json +17 -0
  27. package/mcp-configs/academic-db/fec-mcp-server.json +17 -0
  28. package/mcp-configs/academic-db/fhir-mcp-server-themomentum.json +17 -0
  29. package/mcp-configs/academic-db/fhir-mcp.json +19 -0
  30. package/mcp-configs/academic-db/gget-mcp.json +17 -0
  31. package/mcp-configs/academic-db/google-researcher-mcp.json +17 -0
  32. package/mcp-configs/academic-db/idea-reality-mcp.json +17 -0
  33. package/mcp-configs/academic-db/legiscan-mcp.json +19 -0
  34. package/mcp-configs/academic-db/lex.json +17 -0
  35. package/mcp-configs/ai-platform/Adaptive-Graph-of-Thoughts-MCP-server.json +17 -0
  36. package/mcp-configs/ai-platform/ai-counsel.json +17 -0
  37. package/mcp-configs/ai-platform/atlas-mcp-server.json +17 -0
  38. package/mcp-configs/ai-platform/counsel-mcp.json +17 -0
  39. package/mcp-configs/ai-platform/cross-llm-mcp.json +17 -0
  40. package/mcp-configs/ai-platform/gptr-mcp.json +17 -0
  41. package/mcp-configs/browser/decipher-research-agent.json +17 -0
  42. package/mcp-configs/browser/deep-research.json +17 -0
  43. package/mcp-configs/browser/everything-claude-code.json +17 -0
  44. package/mcp-configs/browser/gpt-researcher.json +17 -0
  45. package/mcp-configs/browser/heurist-agent-framework.json +17 -0
  46. package/mcp-configs/data-platform/4everland-hosting-mcp.json +17 -0
  47. package/mcp-configs/data-platform/context-keeper.json +17 -0
  48. package/mcp-configs/data-platform/context7.json +19 -0
  49. package/mcp-configs/data-platform/contextstream-mcp.json +17 -0
  50. package/mcp-configs/data-platform/email-mcp.json +17 -0
  51. package/mcp-configs/note-knowledge/ApeRAG.json +17 -0
  52. package/mcp-configs/note-knowledge/In-Memoria.json +17 -0
  53. package/mcp-configs/note-knowledge/agent-memory.json +17 -0
  54. package/mcp-configs/note-knowledge/aimemo.json +17 -0
  55. package/mcp-configs/note-knowledge/biel-mcp.json +19 -0
  56. package/mcp-configs/note-knowledge/cognee.json +17 -0
  57. package/mcp-configs/note-knowledge/context-awesome.json +17 -0
  58. package/mcp-configs/note-knowledge/context-mcp.json +17 -0
  59. package/mcp-configs/note-knowledge/conversation-handoff-mcp.json +17 -0
  60. package/mcp-configs/note-knowledge/cortex.json +17 -0
  61. package/mcp-configs/note-knowledge/devrag.json +17 -0
  62. package/mcp-configs/note-knowledge/easy-obsidian-mcp.json +17 -0
  63. package/mcp-configs/note-knowledge/engram.json +17 -0
  64. package/mcp-configs/note-knowledge/gnosis-mcp.json +17 -0
  65. package/mcp-configs/note-knowledge/graphlit-mcp-server.json +19 -0
  66. package/mcp-configs/reference-mgr/arxiv-cli.json +17 -0
  67. package/mcp-configs/reference-mgr/arxiv-search-mcp.json +17 -0
  68. package/mcp-configs/reference-mgr/chiken.json +17 -0
  69. package/mcp-configs/reference-mgr/claude-scholar.json +17 -0
  70. package/mcp-configs/reference-mgr/devonthink-mcp.json +17 -0
  71. package/mcp-configs/registry.json +447 -0
  72. package/openclaw.plugin.json +21 -0
  73. package/package.json +61 -0
  74. package/skills/analysis/dataviz/color-accessibility-guide/SKILL.md +230 -0
  75. package/skills/analysis/dataviz/geospatial-viz-guide/SKILL.md +218 -0
  76. package/skills/analysis/dataviz/interactive-viz-guide/SKILL.md +287 -0
  77. package/skills/analysis/dataviz/network-visualization-guide/SKILL.md +195 -0
  78. package/skills/analysis/dataviz/publication-figures-guide/SKILL.md +238 -0
  79. package/skills/analysis/dataviz/python-dataviz-guide/SKILL.md +195 -0
  80. package/skills/analysis/econometrics/causal-inference-guide/SKILL.md +197 -0
  81. package/skills/analysis/econometrics/iv-regression-guide/SKILL.md +198 -0
  82. package/skills/analysis/econometrics/panel-data-guide/SKILL.md +274 -0
  83. package/skills/analysis/econometrics/robustness-checks/SKILL.md +250 -0
  84. package/skills/analysis/econometrics/stata-regression/SKILL.md +117 -0
  85. package/skills/analysis/econometrics/time-series-guide/SKILL.md +235 -0
  86. package/skills/analysis/statistics/bayesian-statistics-guide/SKILL.md +221 -0
  87. package/skills/analysis/statistics/hypothesis-testing-guide/SKILL.md +210 -0
  88. package/skills/analysis/statistics/meta-analysis-guide/SKILL.md +206 -0
  89. package/skills/analysis/statistics/nonparametric-tests-guide/SKILL.md +221 -0
  90. package/skills/analysis/statistics/power-analysis-guide/SKILL.md +240 -0
  91. package/skills/analysis/statistics/sem-guide/SKILL.md +231 -0
  92. package/skills/analysis/statistics/survival-analysis-guide/SKILL.md +195 -0
  93. package/skills/analysis/wrangling/missing-data-handling/SKILL.md +224 -0
  94. package/skills/analysis/wrangling/pandas-data-wrangling/SKILL.md +242 -0
  95. package/skills/analysis/wrangling/questionnaire-design-guide/SKILL.md +234 -0
  96. package/skills/analysis/wrangling/text-mining-guide/SKILL.md +225 -0
  97. package/skills/domains/ai-ml/computer-vision-guide/SKILL.md +213 -0
  98. package/skills/domains/ai-ml/deep-learning-papers-guide/SKILL.md +200 -0
  99. package/skills/domains/ai-ml/llm-evaluation-guide/SKILL.md +194 -0
  100. package/skills/domains/ai-ml/prompt-engineering-research/SKILL.md +233 -0
  101. package/skills/domains/ai-ml/reinforcement-learning-guide/SKILL.md +254 -0
  102. package/skills/domains/ai-ml/transformer-architecture-guide/SKILL.md +233 -0
  103. package/skills/domains/biomedical/clinical-research-guide/SKILL.md +232 -0
  104. package/skills/domains/biomedical/clinicaltrials-api/SKILL.md +177 -0
  105. package/skills/domains/biomedical/epidemiology-guide/SKILL.md +200 -0
  106. package/skills/domains/biomedical/genomics-analysis-guide/SKILL.md +270 -0
  107. package/skills/domains/business/market-analysis-guide/SKILL.md +112 -0
  108. package/skills/domains/business/strategic-management-guide/SKILL.md +154 -0
  109. package/skills/domains/chemistry/computational-chemistry-guide/SKILL.md +266 -0
  110. package/skills/domains/chemistry/retrosynthesis-guide/SKILL.md +215 -0
  111. package/skills/domains/cs/algorithms-complexity-guide/SKILL.md +194 -0
  112. package/skills/domains/cs/dblp-api/SKILL.md +129 -0
  113. package/skills/domains/cs/software-engineering-research/SKILL.md +218 -0
  114. package/skills/domains/ecology/biodiversity-data-guide/SKILL.md +296 -0
  115. package/skills/domains/ecology/conservation-biology-guide/SKILL.md +198 -0
  116. package/skills/domains/ecology/gbif-api/SKILL.md +158 -0
  117. package/skills/domains/ecology/inaturalist-api/SKILL.md +173 -0
  118. package/skills/domains/economics/behavioral-economics-guide/SKILL.md +239 -0
  119. package/skills/domains/economics/development-economics-guide/SKILL.md +181 -0
  120. package/skills/domains/economics/fred-api/SKILL.md +189 -0
  121. package/skills/domains/education/curriculum-design-guide/SKILL.md +144 -0
  122. package/skills/domains/education/learning-science-guide/SKILL.md +150 -0
  123. package/skills/domains/finance/financial-data-analysis/SKILL.md +152 -0
  124. package/skills/domains/finance/quantitative-finance-guide/SKILL.md +151 -0
  125. package/skills/domains/geoscience/climate-science-guide/SKILL.md +158 -0
  126. package/skills/domains/geoscience/gis-remote-sensing-guide/SKILL.md +129 -0
  127. package/skills/domains/humanities/digital-humanities-guide/SKILL.md +181 -0
  128. package/skills/domains/humanities/philosophy-research-guide/SKILL.md +148 -0
  129. package/skills/domains/law/courtlistener-api/SKILL.md +213 -0
  130. package/skills/domains/law/legal-research-guide/SKILL.md +250 -0
  131. package/skills/domains/math/linear-algebra-applications/SKILL.md +227 -0
  132. package/skills/domains/math/numerical-methods-guide/SKILL.md +236 -0
  133. package/skills/domains/math/oeis-api/SKILL.md +158 -0
  134. package/skills/domains/pharma/clinical-pharmacology-guide/SKILL.md +165 -0
  135. package/skills/domains/pharma/drug-development-guide/SKILL.md +177 -0
  136. package/skills/domains/physics/computational-physics-guide/SKILL.md +300 -0
  137. package/skills/domains/physics/nasa-ads-api/SKILL.md +150 -0
  138. package/skills/domains/physics/quantum-computing-guide/SKILL.md +234 -0
  139. package/skills/domains/social-science/social-research-methods/SKILL.md +194 -0
  140. package/skills/domains/social-science/survey-research-guide/SKILL.md +182 -0
  141. package/skills/literature/discovery/citation-alert-guide/SKILL.md +154 -0
  142. package/skills/literature/discovery/conference-proceedings-guide/SKILL.md +142 -0
  143. package/skills/literature/discovery/literature-mapping-guide/SKILL.md +175 -0
  144. package/skills/literature/discovery/paper-tracking-guide/SKILL.md +211 -0
  145. package/skills/literature/discovery/rss-paper-feeds/SKILL.md +214 -0
  146. package/skills/literature/discovery/semantic-scholar-recs-guide/SKILL.md +164 -0
  147. package/skills/literature/fulltext/doaj-api/SKILL.md +120 -0
  148. package/skills/literature/fulltext/interlibrary-loan-guide/SKILL.md +163 -0
  149. package/skills/literature/fulltext/open-access-guide/SKILL.md +183 -0
  150. package/skills/literature/fulltext/pmc-oai-api/SKILL.md +184 -0
  151. package/skills/literature/fulltext/preprint-servers-guide/SKILL.md +128 -0
  152. package/skills/literature/fulltext/repository-harvesting-guide/SKILL.md +207 -0
  153. package/skills/literature/fulltext/unpaywall-api/SKILL.md +113 -0
  154. package/skills/literature/metadata/altmetrics-guide/SKILL.md +132 -0
  155. package/skills/literature/metadata/citation-network-guide/SKILL.md +236 -0
  156. package/skills/literature/metadata/crossref-api/SKILL.md +133 -0
  157. package/skills/literature/metadata/datacite-api/SKILL.md +126 -0
  158. package/skills/literature/metadata/doi-resolution-guide/SKILL.md +168 -0
  159. package/skills/literature/metadata/h-index-guide/SKILL.md +183 -0
  160. package/skills/literature/metadata/journal-metrics-guide/SKILL.md +188 -0
  161. package/skills/literature/metadata/opencitations-api/SKILL.md +128 -0
  162. package/skills/literature/metadata/orcid-api/SKILL.md +136 -0
  163. package/skills/literature/metadata/orcid-integration-guide/SKILL.md +178 -0
  164. package/skills/literature/search/arxiv-api/SKILL.md +95 -0
  165. package/skills/literature/search/biorxiv-api/SKILL.md +123 -0
  166. package/skills/literature/search/boolean-search-guide/SKILL.md +199 -0
  167. package/skills/literature/search/citation-chaining-guide/SKILL.md +148 -0
  168. package/skills/literature/search/database-comparison-guide/SKILL.md +100 -0
  169. package/skills/literature/search/europe-pmc-api/SKILL.md +120 -0
  170. package/skills/literature/search/google-scholar-guide/SKILL.md +182 -0
  171. package/skills/literature/search/mesh-terms-guide/SKILL.md +164 -0
  172. package/skills/literature/search/openalex-api/SKILL.md +134 -0
  173. package/skills/literature/search/pubmed-api/SKILL.md +130 -0
  174. package/skills/literature/search/scientify-literature-survey/SKILL.md +203 -0
  175. package/skills/literature/search/semantic-scholar-api/SKILL.md +134 -0
  176. package/skills/literature/search/systematic-search-strategy/SKILL.md +214 -0
  177. package/skills/research/automation/ai-scientist-guide/SKILL.md +228 -0
  178. package/skills/research/automation/data-collection-automation/SKILL.md +248 -0
  179. package/skills/research/automation/research-workflow-automation/SKILL.md +266 -0
  180. package/skills/research/deep-research/meta-synthesis-guide/SKILL.md +174 -0
  181. package/skills/research/deep-research/research-cog/SKILL.md +153 -0
  182. package/skills/research/deep-research/scoping-review-guide/SKILL.md +217 -0
  183. package/skills/research/deep-research/systematic-review-guide/SKILL.md +250 -0
  184. package/skills/research/funding/figshare-api/SKILL.md +163 -0
  185. package/skills/research/funding/grant-writing-guide/SKILL.md +233 -0
  186. package/skills/research/funding/nsf-grant-guide/SKILL.md +206 -0
  187. package/skills/research/funding/open-science-guide/SKILL.md +255 -0
  188. package/skills/research/funding/zenodo-api/SKILL.md +174 -0
  189. package/skills/research/methodology/action-research-guide/SKILL.md +201 -0
  190. package/skills/research/methodology/experimental-design-guide/SKILL.md +236 -0
  191. package/skills/research/methodology/grad-school-guide/SKILL.md +182 -0
  192. package/skills/research/methodology/grounded-theory-guide/SKILL.md +171 -0
  193. package/skills/research/methodology/mixed-methods-guide/SKILL.md +208 -0
  194. package/skills/research/methodology/qualitative-research-guide/SKILL.md +234 -0
  195. package/skills/research/methodology/scientify-idea-generation/SKILL.md +222 -0
  196. package/skills/research/paper-review/paper-reading-assistant/SKILL.md +266 -0
  197. package/skills/research/paper-review/peer-review-guide/SKILL.md +227 -0
  198. package/skills/research/paper-review/rebuttal-writing-guide/SKILL.md +185 -0
  199. package/skills/research/paper-review/scientify-write-review-paper/SKILL.md +209 -0
  200. package/skills/tools/code-exec/jupyter-notebook-guide/SKILL.md +178 -0
  201. package/skills/tools/code-exec/python-reproducibility-guide/SKILL.md +341 -0
  202. package/skills/tools/code-exec/r-reproducibility-guide/SKILL.md +236 -0
  203. package/skills/tools/code-exec/sandbox-execution-guide/SKILL.md +221 -0
  204. package/skills/tools/diagram/mermaid-diagram-guide/SKILL.md +269 -0
  205. package/skills/tools/diagram/plantuml-guide/SKILL.md +397 -0
  206. package/skills/tools/diagram/scientific-illustration-guide/SKILL.md +225 -0
  207. package/skills/tools/document/anystyle-api/SKILL.md +199 -0
  208. package/skills/tools/document/grobid-pdf-parsing/SKILL.md +294 -0
  209. package/skills/tools/document/markdown-academic-guide/SKILL.md +217 -0
  210. package/skills/tools/document/pdf-extraction-guide/SKILL.md +321 -0
  211. package/skills/tools/knowledge-graph/knowledge-graph-construction/SKILL.md +306 -0
  212. package/skills/tools/knowledge-graph/ontology-design-guide/SKILL.md +214 -0
  213. package/skills/tools/knowledge-graph/rag-methodology-guide/SKILL.md +325 -0
  214. package/skills/tools/ocr-translate/formula-recognition-guide/SKILL.md +367 -0
  215. package/skills/tools/ocr-translate/handwriting-recognition-guide/SKILL.md +211 -0
  216. package/skills/tools/ocr-translate/latex-ocr-guide/SKILL.md +204 -0
  217. package/skills/tools/ocr-translate/multilingual-research-guide/SKILL.md +234 -0
  218. package/skills/tools/scraping/academic-web-scraping/SKILL.md +326 -0
  219. package/skills/tools/scraping/api-data-collection-guide/SKILL.md +301 -0
  220. package/skills/tools/scraping/web-scraping-ethics-guide/SKILL.md +250 -0
  221. package/skills/writing/citation/bibtex-management-guide/SKILL.md +246 -0
  222. package/skills/writing/citation/citation-style-guide/SKILL.md +248 -0
  223. package/skills/writing/citation/reference-manager-comparison/SKILL.md +208 -0
  224. package/skills/writing/citation/zotero-api/SKILL.md +188 -0
  225. package/skills/writing/composition/abstract-writing-guide/SKILL.md +188 -0
  226. package/skills/writing/composition/discussion-writing-guide/SKILL.md +194 -0
  227. package/skills/writing/composition/introduction-writing-guide/SKILL.md +194 -0
  228. package/skills/writing/composition/literature-review-writing/SKILL.md +196 -0
  229. package/skills/writing/composition/methods-section-guide/SKILL.md +185 -0
  230. package/skills/writing/composition/response-to-reviewers/SKILL.md +215 -0
  231. package/skills/writing/composition/scientific-writing-guide/SKILL.md +152 -0
  232. package/skills/writing/latex/bibliography-management-guide/SKILL.md +206 -0
  233. package/skills/writing/latex/latex-drawing-guide/SKILL.md +234 -0
  234. package/skills/writing/latex/latex-ecosystem-guide/SKILL.md +240 -0
  235. package/skills/writing/latex/math-typesetting-guide/SKILL.md +231 -0
  236. package/skills/writing/latex/overleaf-collaboration-guide/SKILL.md +211 -0
  237. package/skills/writing/latex/tikz-diagrams-guide/SKILL.md +211 -0
  238. package/skills/writing/polish/academic-translation-guide/SKILL.md +175 -0
  239. package/skills/writing/polish/academic-writing-refiner/SKILL.md +143 -0
  240. package/skills/writing/polish/ai-writing-humanizer/SKILL.md +178 -0
  241. package/skills/writing/polish/grammar-checker-guide/SKILL.md +184 -0
  242. package/skills/writing/polish/plagiarism-detection-guide/SKILL.md +167 -0
  243. package/skills/writing/templates/beamer-presentation-guide/SKILL.md +263 -0
  244. package/skills/writing/templates/conference-paper-template/SKILL.md +219 -0
  245. package/skills/writing/templates/thesis-template-guide/SKILL.md +200 -0
  246. package/skills/writing/templates/thesis-writing-guide/SKILL.md +220 -0
  247. package/src/tools/arxiv.ts +131 -0
  248. package/src/tools/crossref.ts +112 -0
  249. package/src/tools/openalex.ts +174 -0
  250. package/src/tools/pubmed.ts +166 -0
  251. package/src/tools/semantic-scholar.ts +108 -0
  252. package/src/tools/unpaywall.ts +58 -0
@@ -0,0 +1,166 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ import type { OpenClawPluginApi, OpenClawPluginToolContext } from "openclaw/plugin-sdk";
3
+
4
+ const EUTILS = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils";
5
+
6
+ export function createPubMedTools(
7
+ _ctx: OpenClawPluginToolContext,
8
+ _api: OpenClawPluginApi,
9
+ ) {
10
+ return [
11
+ {
12
+ name: "search_pubmed",
13
+ description:
14
+ "Search PubMed biomedical literature database. Covers 36M+ citations from MEDLINE, life science journals, and online books.",
15
+ inputSchema: Type.Object({
16
+ query: Type.String({
17
+ description:
18
+ "PubMed search query. Supports MeSH terms and field tags, e.g. 'CRISPR[Title] AND 2024[PDAT]'",
19
+ }),
20
+ max_results: Type.Optional(
21
+ Type.Number({ description: "Max results (default 10, max 100)" }),
22
+ ),
23
+ sort: Type.Optional(
24
+ Type.String({
25
+ description: "Sort by: 'relevance' or 'pub_date'",
26
+ }),
27
+ ),
28
+ min_date: Type.Optional(
29
+ Type.String({ description: "Min publication date (YYYY/MM/DD)" }),
30
+ ),
31
+ max_date: Type.Optional(
32
+ Type.String({ description: "Max publication date (YYYY/MM/DD)" }),
33
+ ),
34
+ }),
35
+ handler: async (input: {
36
+ query: string;
37
+ max_results?: number;
38
+ sort?: string;
39
+ min_date?: string;
40
+ max_date?: string;
41
+ }) => {
42
+ const searchParams = new URLSearchParams({
43
+ db: "pubmed",
44
+ term: input.query,
45
+ retmax: String(Math.min(input.max_results ?? 10, 100)),
46
+ retmode: "json",
47
+ sort: input.sort ?? "relevance",
48
+ usehistory: "y",
49
+ });
50
+ if (input.min_date) searchParams.set("mindate", input.min_date);
51
+ if (input.max_date) searchParams.set("maxdate", input.max_date);
52
+ if (input.min_date || input.max_date) searchParams.set("datetype", "pdat");
53
+
54
+ const searchRes = await fetch(`${EUTILS}/esearch.fcgi?${searchParams}`);
55
+ if (!searchRes.ok)
56
+ return { error: `Search error: ${searchRes.status} ${searchRes.statusText}` };
57
+ const searchData = await searchRes.json();
58
+ const ids: string[] = searchData.esearchresult?.idlist ?? [];
59
+
60
+ if (ids.length === 0) return { total_count: searchData.esearchresult?.count ?? 0, articles: [] };
61
+
62
+ const summaryParams = new URLSearchParams({
63
+ db: "pubmed",
64
+ id: ids.join(","),
65
+ retmode: "json",
66
+ });
67
+ const summaryRes = await fetch(`${EUTILS}/esummary.fcgi?${summaryParams}`);
68
+ if (!summaryRes.ok)
69
+ return { error: `Summary error: ${summaryRes.status} ${summaryRes.statusText}` };
70
+ const summaryData = await summaryRes.json();
71
+
72
+ const articles = ids.map((id) => {
73
+ const doc = summaryData.result?.[id];
74
+ if (!doc) return { pmid: id };
75
+ return {
76
+ pmid: id,
77
+ title: doc.title,
78
+ authors: doc.authors
79
+ ?.slice(0, 5)
80
+ .map((a: Record<string, string>) => a.name),
81
+ source: doc.source,
82
+ pub_date: doc.pubdate,
83
+ doi: doc.elocationid?.replace("doi: ", ""),
84
+ pmc: doc.articleids?.find(
85
+ (a: Record<string, string>) => a.idtype === "pmc",
86
+ )?.value,
87
+ };
88
+ });
89
+
90
+ return {
91
+ total_count: parseInt(searchData.esearchresult?.count ?? "0", 10),
92
+ articles,
93
+ };
94
+ },
95
+ },
96
+ {
97
+ name: "get_article",
98
+ description:
99
+ "Get detailed article metadata from PubMed by PMID, including abstract.",
100
+ inputSchema: Type.Object({
101
+ pmid: Type.String({ description: "PubMed ID (numeric string)" }),
102
+ }),
103
+ handler: async (input: { pmid: string }) => {
104
+ const params = new URLSearchParams({
105
+ db: "pubmed",
106
+ id: input.pmid,
107
+ retmode: "xml",
108
+ });
109
+ const res = await fetch(`${EUTILS}/efetch.fcgi?${params}`);
110
+ if (!res.ok) return { error: `API error: ${res.status} ${res.statusText}` };
111
+ const xml = await res.text();
112
+
113
+ const getText = (tag: string) => {
114
+ const m = xml.match(new RegExp(`<${tag}>([\\s\\S]*?)</${tag}>`));
115
+ return m ? m[1].trim() : "";
116
+ };
117
+
118
+ const getAbstract = () => {
119
+ const m = xml.match(/<AbstractText[^>]*>([\s\S]*?)<\/AbstractText>/g);
120
+ if (!m) return "";
121
+ return m
122
+ .map((s) => s.replace(/<\/?AbstractText[^>]*>/g, "").trim())
123
+ .join(" ");
124
+ };
125
+
126
+ const getAuthors = () => {
127
+ const authors: string[] = [];
128
+ const re = /<Author[^>]*>[\s\S]*?<LastName>([\s\S]*?)<\/LastName>[\s\S]*?<ForeName>([\s\S]*?)<\/ForeName>[\s\S]*?<\/Author>/g;
129
+ let m;
130
+ while ((m = re.exec(xml)) !== null) {
131
+ authors.push(`${m[2].trim()} ${m[1].trim()}`);
132
+ }
133
+ return authors;
134
+ };
135
+
136
+ const getMesh = () => {
137
+ const terms: string[] = [];
138
+ const re = /<DescriptorName[^>]*>([\s\S]*?)<\/DescriptorName>/g;
139
+ let m;
140
+ while ((m = re.exec(xml)) !== null) terms.push(m[1].trim());
141
+ return terms;
142
+ };
143
+
144
+ const doi =
145
+ xml.match(/<ArticleId IdType="doi">([\s\S]*?)<\/ArticleId>/)?.[1]?.trim() ??
146
+ "";
147
+ const pmc =
148
+ xml.match(/<ArticleId IdType="pmc">([\s\S]*?)<\/ArticleId>/)?.[1]?.trim() ??
149
+ "";
150
+
151
+ return {
152
+ pmid: input.pmid,
153
+ title: getText("ArticleTitle"),
154
+ abstract: getAbstract(),
155
+ authors: getAuthors(),
156
+ journal: getText("Title"),
157
+ pub_date: `${getText("Year")}-${getText("Month")}`,
158
+ doi,
159
+ pmc,
160
+ mesh_terms: getMesh(),
161
+ url: `https://pubmed.ncbi.nlm.nih.gov/${input.pmid}/`,
162
+ };
163
+ },
164
+ },
165
+ ];
166
+ }
@@ -0,0 +1,108 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ import type { OpenClawPluginApi, OpenClawPluginToolContext } from "openclaw/plugin-sdk";
3
+
4
+ const BASE = "https://api.semanticscholar.org/graph/v1";
5
+
6
+ export function createSemanticScholarTools(
7
+ ctx: OpenClawPluginToolContext,
8
+ api: OpenClawPluginApi,
9
+ ) {
10
+ const apiKey =
11
+ ctx.config?.get?.("plugins.entries.research-plugins.semanticScholarApiKey") ?? "";
12
+
13
+ const headers: Record<string, string> = apiKey ? { "x-api-key": apiKey } : {};
14
+
15
+ return [
16
+ {
17
+ name: "search_papers",
18
+ description:
19
+ "Search academic papers on Semantic Scholar. Returns titles, abstracts, authors, citation counts.",
20
+ inputSchema: Type.Object({
21
+ query: Type.String({ description: "Search query keywords" }),
22
+ limit: Type.Optional(
23
+ Type.Number({ description: "Max results to return (default 10, max 100)" }),
24
+ ),
25
+ year: Type.Optional(
26
+ Type.String({ description: "Year filter, e.g. '2024' or '2020-2024'" }),
27
+ ),
28
+ fields_of_study: Type.Optional(
29
+ Type.String({
30
+ description:
31
+ "Comma-separated fields, e.g. 'Computer Science,Mathematics'",
32
+ }),
33
+ ),
34
+ open_access_only: Type.Optional(
35
+ Type.Boolean({ description: "Only return open access papers" }),
36
+ ),
37
+ }),
38
+ handler: async (input: {
39
+ query: string;
40
+ limit?: number;
41
+ year?: string;
42
+ fields_of_study?: string;
43
+ open_access_only?: boolean;
44
+ }) => {
45
+ const params = new URLSearchParams({
46
+ query: input.query,
47
+ limit: String(Math.min(input.limit ?? 10, 100)),
48
+ fields:
49
+ "title,abstract,authors,year,citationCount,referenceCount,url,isOpenAccess,openAccessPdf",
50
+ });
51
+ if (input.year) params.set("year", input.year);
52
+ if (input.fields_of_study)
53
+ params.set("fieldsOfStudy", input.fields_of_study);
54
+ if (input.open_access_only) params.set("openAccessPdf", "");
55
+
56
+ const res = await fetch(`${BASE}/paper/search?${params}`, { headers });
57
+ if (!res.ok) return { error: `API error: ${res.status} ${res.statusText}` };
58
+ return res.json();
59
+ },
60
+ },
61
+ {
62
+ name: "get_paper",
63
+ description:
64
+ "Get detailed information about a specific paper by its Semantic Scholar ID, DOI, or ArXiv ID.",
65
+ inputSchema: Type.Object({
66
+ paper_id: Type.String({
67
+ description:
68
+ "Paper identifier: Semantic Scholar ID, DOI (e.g. '10.1234/...'), or ArXiv ID (e.g. 'arXiv:2301.00001')",
69
+ }),
70
+ }),
71
+ handler: async (input: { paper_id: string }) => {
72
+ const fields =
73
+ "title,abstract,authors,year,citationCount,referenceCount,tldr,url,venue,isOpenAccess,openAccessPdf,fieldsOfStudy,publicationDate";
74
+ const res = await fetch(
75
+ `${BASE}/paper/${encodeURIComponent(input.paper_id)}?fields=${fields}`,
76
+ { headers },
77
+ );
78
+ if (!res.ok) return { error: `API error: ${res.status} ${res.statusText}` };
79
+ return res.json();
80
+ },
81
+ },
82
+ {
83
+ name: "get_citations",
84
+ description:
85
+ "Get papers that cite a given paper. Useful for forward citation tracking.",
86
+ inputSchema: Type.Object({
87
+ paper_id: Type.String({ description: "Paper identifier (S2 ID, DOI, or ArXiv ID)" }),
88
+ limit: Type.Optional(
89
+ Type.Number({ description: "Max citations to return (default 20, max 100)" }),
90
+ ),
91
+ offset: Type.Optional(
92
+ Type.Number({ description: "Pagination offset" }),
93
+ ),
94
+ }),
95
+ handler: async (input: { paper_id: string; limit?: number; offset?: number }) => {
96
+ const fields = "title,authors,year,citationCount,url,abstract";
97
+ const limit = Math.min(input.limit ?? 20, 100);
98
+ const offset = input.offset ?? 0;
99
+ const res = await fetch(
100
+ `${BASE}/paper/${encodeURIComponent(input.paper_id)}/citations?fields=${fields}&limit=${limit}&offset=${offset}`,
101
+ { headers },
102
+ );
103
+ if (!res.ok) return { error: `API error: ${res.status} ${res.statusText}` };
104
+ return res.json();
105
+ },
106
+ },
107
+ ];
108
+ }
@@ -0,0 +1,58 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ import type { OpenClawPluginApi, OpenClawPluginToolContext } from "openclaw/plugin-sdk";
3
+
4
+ const BASE = "https://api.unpaywall.org/v2";
5
+
6
+ export function createUnpaywallTools(
7
+ _ctx: OpenClawPluginToolContext,
8
+ _api: OpenClawPluginApi,
9
+ ) {
10
+ const email = "research-plugins@wentor.ai";
11
+
12
+ return [
13
+ {
14
+ name: "find_oa_version",
15
+ description:
16
+ "Find open access versions of a paper by DOI using Unpaywall. Returns free PDF links from repositories, preprint servers, and publisher OA pages.",
17
+ inputSchema: Type.Object({
18
+ doi: Type.String({
19
+ description: "DOI of the paper, e.g. '10.1038/nature12373'",
20
+ }),
21
+ }),
22
+ handler: async (input: { doi: string }) => {
23
+ const doi = input.doi.replace(/^https?:\/\/doi\.org\//, "");
24
+ const res = await fetch(
25
+ `${BASE}/${encodeURIComponent(doi)}?email=${email}`,
26
+ );
27
+ if (!res.ok) {
28
+ if (res.status === 404) return { error: "DOI not found in Unpaywall" };
29
+ return { error: `API error: ${res.status} ${res.statusText}` };
30
+ }
31
+ const data = await res.json();
32
+
33
+ const oaLocations = (
34
+ data.oa_locations as Record<string, unknown>[] | undefined
35
+ )?.map((loc) => ({
36
+ url: loc.url,
37
+ url_for_pdf: loc.url_for_pdf,
38
+ host_type: loc.host_type,
39
+ license: loc.license,
40
+ version: loc.version,
41
+ }));
42
+
43
+ return {
44
+ doi: data.doi,
45
+ title: data.title,
46
+ is_oa: data.is_oa,
47
+ oa_status: data.oa_status,
48
+ best_oa_url: data.best_oa_location?.url,
49
+ best_oa_pdf: data.best_oa_location?.url_for_pdf,
50
+ journal: data.journal_name,
51
+ publisher: data.publisher,
52
+ published_date: data.published_date,
53
+ oa_locations: oaLocations,
54
+ };
55
+ },
56
+ },
57
+ ];
58
+ }