@wentorai/research-plugins 1.3.2 → 1.4.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/README.md +32 -56
- package/curated/analysis/README.md +1 -13
- package/curated/domains/README.md +1 -5
- package/curated/literature/README.md +1 -10
- package/curated/research/README.md +1 -18
- package/curated/tools/README.md +1 -12
- package/curated/writing/README.md +1 -5
- package/index.ts +88 -5
- package/openclaw.plugin.json +3 -12
- package/package.json +3 -5
- package/skills/analysis/statistics/SKILL.md +1 -1
- package/skills/analysis/statistics/meta-analysis-guide/SKILL.md +1 -1
- package/skills/domains/ai-ml/SKILL.md +3 -2
- package/skills/domains/ai-ml/generative-ai-guide/SKILL.md +1 -0
- package/skills/domains/ai-ml/huggingface-api/SKILL.md +251 -0
- package/skills/domains/biomedical/SKILL.md +9 -2
- package/skills/domains/biomedical/alphafold-api/SKILL.md +227 -0
- package/skills/domains/biomedical/biothings-api/SKILL.md +296 -0
- package/skills/domains/biomedical/clinicaltrials-api-v2/SKILL.md +216 -0
- package/skills/domains/biomedical/enrichr-api/SKILL.md +264 -0
- package/skills/domains/biomedical/ensembl-rest-api/SKILL.md +204 -0
- package/skills/domains/biomedical/medical-data-api/SKILL.md +197 -0
- package/skills/domains/biomedical/pdb-structure-api/SKILL.md +219 -0
- package/skills/domains/business/SKILL.md +2 -3
- package/skills/domains/chemistry/SKILL.md +3 -2
- package/skills/domains/chemistry/catalysis-hub-api/SKILL.md +171 -0
- package/skills/domains/education/SKILL.md +2 -3
- package/skills/domains/law/SKILL.md +3 -2
- package/skills/domains/law/uk-legislation-api/SKILL.md +179 -0
- package/skills/literature/fulltext/SKILL.md +3 -2
- package/skills/literature/fulltext/arxiv-latex-source/SKILL.md +195 -0
- package/skills/literature/search/SKILL.md +2 -3
- package/skills/research/automation/SKILL.md +2 -3
- package/skills/research/automation/datagen-research-guide/SKILL.md +1 -0
- package/skills/research/automation/mle-agent-guide/SKILL.md +1 -0
- package/skills/research/automation/paper-to-agent-guide/SKILL.md +1 -0
- package/skills/research/deep-research/auto-deep-research-guide/SKILL.md +1 -0
- package/skills/research/methodology/SKILL.md +1 -1
- package/skills/research/methodology/claude-scientific-guide/SKILL.md +1 -0
- package/skills/research/methodology/qualitative-research-guide/SKILL.md +1 -1
- package/skills/research/paper-review/SKILL.md +1 -1
- package/skills/research/paper-review/peer-review-guide/SKILL.md +1 -1
- package/skills/tools/knowledge-graph/SKILL.md +2 -3
- package/skills/tools/ocr-translate/zotero-pdf2zh-guide/SKILL.md +1 -0
- package/skills/writing/citation/obsidian-citation-guide/SKILL.md +1 -0
- package/skills/writing/citation/obsidian-zotero-guide/SKILL.md +1 -0
- package/skills/writing/citation/papersgpt-zotero-guide/SKILL.md +1 -0
- package/skills/writing/citation/zotero-mdnotes-guide/SKILL.md +1 -0
- package/skills/writing/citation/zotero-reference-guide/SKILL.md +1 -0
- package/skills/writing/composition/scientific-writing-resources/SKILL.md +1 -0
- package/skills/writing/latex/latex-drawing-collection/SKILL.md +1 -0
- package/skills/writing/latex/latex-templates-collection/SKILL.md +1 -0
- package/skills/writing/templates/novathesis-guide/SKILL.md +1 -0
- package/src/tools/arxiv.ts +78 -30
- package/src/tools/biorxiv.ts +142 -0
- package/src/tools/crossref.ts +60 -22
- package/src/tools/datacite.ts +188 -0
- package/src/tools/dblp.ts +125 -0
- package/src/tools/doaj.ts +82 -0
- package/src/tools/europe-pmc.ts +159 -0
- package/src/tools/hal.ts +118 -0
- package/src/tools/inspire-hep.ts +165 -0
- package/src/tools/openaire.ts +158 -0
- package/src/tools/openalex.ts +20 -15
- package/src/tools/opencitations.ts +103 -0
- package/src/tools/orcid.ts +136 -0
- package/src/tools/osf-preprints.ts +104 -0
- package/src/tools/pubmed.ts +19 -13
- package/src/tools/ror.ts +118 -0
- package/src/tools/unpaywall.ts +12 -6
- package/src/tools/util.ts +141 -0
- package/src/tools/zenodo.ts +154 -0
- package/mcp-configs/academic-db/ChatSpatial.json +0 -17
- package/mcp-configs/academic-db/academia-mcp.json +0 -17
- package/mcp-configs/academic-db/academic-paper-explorer.json +0 -17
- package/mcp-configs/academic-db/academic-search-mcp-server.json +0 -17
- package/mcp-configs/academic-db/agentinterviews-mcp.json +0 -17
- package/mcp-configs/academic-db/all-in-mcp.json +0 -17
- package/mcp-configs/academic-db/alphafold-mcp.json +0 -20
- package/mcp-configs/academic-db/apple-health-mcp.json +0 -17
- package/mcp-configs/academic-db/arxiv-latex-mcp.json +0 -17
- package/mcp-configs/academic-db/arxiv-mcp-server.json +0 -17
- package/mcp-configs/academic-db/bgpt-mcp.json +0 -17
- package/mcp-configs/academic-db/biomcp.json +0 -17
- package/mcp-configs/academic-db/biothings-mcp.json +0 -17
- package/mcp-configs/academic-db/brightspace-mcp.json +0 -21
- package/mcp-configs/academic-db/catalysishub-mcp-server.json +0 -17
- package/mcp-configs/academic-db/climatiq-mcp.json +0 -20
- package/mcp-configs/academic-db/clinicaltrialsgov-mcp-server.json +0 -17
- package/mcp-configs/academic-db/deep-research-mcp.json +0 -17
- package/mcp-configs/academic-db/dicom-mcp.json +0 -17
- package/mcp-configs/academic-db/enrichr-mcp-server.json +0 -17
- package/mcp-configs/academic-db/fec-mcp-server.json +0 -17
- package/mcp-configs/academic-db/fhir-mcp-server-themomentum.json +0 -17
- package/mcp-configs/academic-db/fhir-mcp.json +0 -19
- package/mcp-configs/academic-db/gget-mcp.json +0 -17
- package/mcp-configs/academic-db/gibs-mcp.json +0 -20
- package/mcp-configs/academic-db/gis-mcp-server.json +0 -22
- package/mcp-configs/academic-db/google-earth-engine-mcp.json +0 -21
- package/mcp-configs/academic-db/google-researcher-mcp.json +0 -17
- package/mcp-configs/academic-db/idea-reality-mcp.json +0 -17
- package/mcp-configs/academic-db/legiscan-mcp.json +0 -19
- package/mcp-configs/academic-db/lex.json +0 -17
- package/mcp-configs/academic-db/m4-clinical-mcp.json +0 -21
- package/mcp-configs/academic-db/medical-mcp.json +0 -21
- package/mcp-configs/academic-db/nexonco-mcp.json +0 -20
- package/mcp-configs/academic-db/omop-mcp.json +0 -20
- package/mcp-configs/academic-db/onekgpd-mcp.json +0 -20
- package/mcp-configs/academic-db/openedu-mcp.json +0 -20
- package/mcp-configs/academic-db/opengenes-mcp.json +0 -20
- package/mcp-configs/academic-db/openstax-mcp.json +0 -21
- package/mcp-configs/academic-db/openstreetmap-mcp.json +0 -21
- package/mcp-configs/academic-db/opentargets-mcp.json +0 -21
- package/mcp-configs/academic-db/pdb-mcp.json +0 -21
- package/mcp-configs/academic-db/smithsonian-mcp.json +0 -20
- package/mcp-configs/ai-platform/Adaptive-Graph-of-Thoughts-MCP-server.json +0 -17
- package/mcp-configs/ai-platform/ai-counsel.json +0 -17
- package/mcp-configs/ai-platform/atlas-mcp-server.json +0 -17
- package/mcp-configs/ai-platform/counsel-mcp.json +0 -17
- package/mcp-configs/ai-platform/cross-llm-mcp.json +0 -17
- package/mcp-configs/ai-platform/gptr-mcp.json +0 -17
- package/mcp-configs/ai-platform/magi-researchers.json +0 -21
- package/mcp-configs/ai-platform/mcp-academic-researcher.json +0 -22
- package/mcp-configs/ai-platform/open-paper-machine.json +0 -21
- package/mcp-configs/ai-platform/paper-intelligence.json +0 -21
- package/mcp-configs/ai-platform/paper-reader.json +0 -21
- package/mcp-configs/ai-platform/paperdebugger.json +0 -21
- package/mcp-configs/browser/decipher-research-agent.json +0 -17
- package/mcp-configs/browser/deep-research.json +0 -17
- package/mcp-configs/browser/everything-claude-code.json +0 -17
- package/mcp-configs/browser/exa-mcp.json +0 -20
- package/mcp-configs/browser/gpt-researcher.json +0 -17
- package/mcp-configs/browser/heurist-agent-framework.json +0 -17
- package/mcp-configs/browser/mcp-searxng.json +0 -21
- package/mcp-configs/browser/mcp-webresearch.json +0 -20
- package/mcp-configs/cloud-docs/confluence-mcp.json +0 -37
- package/mcp-configs/cloud-docs/google-drive-mcp.json +0 -35
- package/mcp-configs/cloud-docs/notion-mcp.json +0 -29
- package/mcp-configs/communication/discord-mcp.json +0 -29
- package/mcp-configs/communication/discourse-mcp.json +0 -21
- package/mcp-configs/communication/slack-mcp.json +0 -29
- package/mcp-configs/communication/telegram-mcp.json +0 -28
- package/mcp-configs/data-platform/4everland-hosting-mcp.json +0 -17
- package/mcp-configs/data-platform/automl-stat-mcp.json +0 -21
- package/mcp-configs/data-platform/context-keeper.json +0 -17
- package/mcp-configs/data-platform/context7.json +0 -19
- package/mcp-configs/data-platform/contextstream-mcp.json +0 -17
- package/mcp-configs/data-platform/email-mcp.json +0 -17
- package/mcp-configs/data-platform/jefferson-stats-mcp.json +0 -22
- package/mcp-configs/data-platform/mcp-excel-server.json +0 -21
- package/mcp-configs/data-platform/mcp-stata.json +0 -21
- package/mcp-configs/data-platform/mcpstack-jupyter.json +0 -21
- package/mcp-configs/data-platform/ml-mcp.json +0 -21
- package/mcp-configs/data-platform/nasdaq-data-link-mcp.json +0 -20
- package/mcp-configs/data-platform/numpy-mcp.json +0 -21
- package/mcp-configs/database/neo4j-mcp.json +0 -37
- package/mcp-configs/database/postgres-mcp.json +0 -28
- package/mcp-configs/database/sqlite-mcp.json +0 -29
- package/mcp-configs/dev-platform/geogebra-mcp.json +0 -21
- package/mcp-configs/dev-platform/github-mcp.json +0 -31
- package/mcp-configs/dev-platform/gitlab-mcp.json +0 -34
- package/mcp-configs/dev-platform/latex-mcp-server.json +0 -21
- package/mcp-configs/dev-platform/manim-mcp.json +0 -20
- package/mcp-configs/dev-platform/mcp-echarts.json +0 -20
- package/mcp-configs/dev-platform/panel-viz-mcp.json +0 -20
- package/mcp-configs/dev-platform/paperbanana.json +0 -20
- package/mcp-configs/dev-platform/texflow-mcp.json +0 -20
- package/mcp-configs/dev-platform/texmcp.json +0 -20
- package/mcp-configs/dev-platform/typst-mcp.json +0 -21
- package/mcp-configs/dev-platform/vizro-mcp.json +0 -20
- package/mcp-configs/email/email-mcp.json +0 -40
- package/mcp-configs/email/gmail-mcp.json +0 -37
- package/mcp-configs/note-knowledge/ApeRAG.json +0 -17
- package/mcp-configs/note-knowledge/In-Memoria.json +0 -17
- package/mcp-configs/note-knowledge/agent-memory.json +0 -17
- package/mcp-configs/note-knowledge/aimemo.json +0 -17
- package/mcp-configs/note-knowledge/biel-mcp.json +0 -19
- package/mcp-configs/note-knowledge/cognee.json +0 -17
- package/mcp-configs/note-knowledge/context-awesome.json +0 -17
- package/mcp-configs/note-knowledge/context-mcp.json +0 -17
- package/mcp-configs/note-knowledge/conversation-handoff-mcp.json +0 -17
- package/mcp-configs/note-knowledge/cortex.json +0 -17
- package/mcp-configs/note-knowledge/devrag.json +0 -17
- package/mcp-configs/note-knowledge/easy-obsidian-mcp.json +0 -17
- package/mcp-configs/note-knowledge/engram.json +0 -17
- package/mcp-configs/note-knowledge/gnosis-mcp.json +0 -17
- package/mcp-configs/note-knowledge/graphlit-mcp-server.json +0 -19
- package/mcp-configs/note-knowledge/local-faiss-mcp.json +0 -21
- package/mcp-configs/note-knowledge/mcp-memory-service.json +0 -21
- package/mcp-configs/note-knowledge/mcp-obsidian.json +0 -23
- package/mcp-configs/note-knowledge/mcp-ragdocs.json +0 -20
- package/mcp-configs/note-knowledge/mcp-summarizer.json +0 -21
- package/mcp-configs/note-knowledge/mediawiki-mcp.json +0 -21
- package/mcp-configs/note-knowledge/openzim-mcp.json +0 -20
- package/mcp-configs/note-knowledge/zettelkasten-mcp.json +0 -21
- package/mcp-configs/reference-mgr/academic-paper-mcp-http.json +0 -20
- package/mcp-configs/reference-mgr/academix.json +0 -20
- package/mcp-configs/reference-mgr/arxiv-cli.json +0 -17
- package/mcp-configs/reference-mgr/arxiv-research-mcp.json +0 -21
- package/mcp-configs/reference-mgr/arxiv-search-mcp.json +0 -17
- package/mcp-configs/reference-mgr/chiken.json +0 -17
- package/mcp-configs/reference-mgr/claude-scholar.json +0 -17
- package/mcp-configs/reference-mgr/devonthink-mcp.json +0 -17
- package/mcp-configs/reference-mgr/google-scholar-abstract-mcp.json +0 -19
- package/mcp-configs/reference-mgr/google-scholar-mcp.json +0 -20
- package/mcp-configs/reference-mgr/mcp-paperswithcode.json +0 -21
- package/mcp-configs/reference-mgr/mcp-scholarly.json +0 -20
- package/mcp-configs/reference-mgr/mcp-simple-arxiv.json +0 -20
- package/mcp-configs/reference-mgr/mcp-simple-pubmed.json +0 -20
- package/mcp-configs/reference-mgr/mcp-zotero.json +0 -21
- package/mcp-configs/reference-mgr/mendeley-mcp.json +0 -20
- package/mcp-configs/reference-mgr/ncbi-mcp-server.json +0 -22
- package/mcp-configs/reference-mgr/onecite.json +0 -21
- package/mcp-configs/reference-mgr/paper-search-mcp.json +0 -21
- package/mcp-configs/reference-mgr/pubmed-search-mcp.json +0 -21
- package/mcp-configs/reference-mgr/scholar-mcp.json +0 -21
- package/mcp-configs/reference-mgr/scholar-multi-mcp.json +0 -21
- package/mcp-configs/reference-mgr/seerai.json +0 -21
- package/mcp-configs/reference-mgr/semantic-scholar-fastmcp.json +0 -21
- package/mcp-configs/reference-mgr/sourcelibrary.json +0 -20
- package/mcp-configs/registry.json +0 -476
- package/mcp-configs/repository/dataverse-mcp.json +0 -33
- package/mcp-configs/repository/huggingface-mcp.json +0 -29
- package/skills/domains/business/xpert-bi-guide/SKILL.md +0 -84
- package/skills/domains/education/edumcp-guide/SKILL.md +0 -74
- package/skills/literature/search/paper-search-mcp-guide/SKILL.md +0 -107
- package/skills/research/automation/mcp-server-guide/SKILL.md +0 -211
- package/skills/tools/knowledge-graph/paperpile-notion-guide/SKILL.md +0 -84
- package/src/tools/semantic-scholar.ts +0 -66
package/src/tools/ror.ts
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
import type { OpenClawPluginApi, OpenClawPluginToolContext } from "openclaw/plugin-sdk";
|
|
3
|
+
import { toolResult, trackedFetch, isTrackedError } from "./util.js";
|
|
4
|
+
|
|
5
|
+
const BASE = "https://api.ror.org/v2";
|
|
6
|
+
|
|
7
|
+
export function createRorTools(
|
|
8
|
+
_ctx: OpenClawPluginToolContext,
|
|
9
|
+
_api: OpenClawPluginApi,
|
|
10
|
+
) {
|
|
11
|
+
return [
|
|
12
|
+
{
|
|
13
|
+
name: "search_ror",
|
|
14
|
+
label: "Search Research Organizations (ROR)",
|
|
15
|
+
description:
|
|
16
|
+
"Search the Research Organization Registry (ROR) for institutions, universities, labs, and funders. Returns canonical identifiers, locations, types, and links. Useful for affiliation disambiguation and finding institution metadata.",
|
|
17
|
+
parameters: Type.Object({
|
|
18
|
+
query: Type.String({
|
|
19
|
+
description: "Organization name or acronym to search, e.g. 'MIT', 'Max Planck', 'CNRS'",
|
|
20
|
+
}),
|
|
21
|
+
max_results: Type.Optional(
|
|
22
|
+
Type.Number({ description: "Max results (default 10, max 50)" }),
|
|
23
|
+
),
|
|
24
|
+
}),
|
|
25
|
+
execute: async (input: { query: string; max_results?: number }) => {
|
|
26
|
+
const params = new URLSearchParams({
|
|
27
|
+
query: input.query,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const tracked = await trackedFetch("ror", `${BASE}/organizations?${params}`, undefined, 10_000);
|
|
31
|
+
if (isTrackedError(tracked)) return tracked;
|
|
32
|
+
const data = await tracked.res.json();
|
|
33
|
+
|
|
34
|
+
const maxResults = Math.min(input.max_results ?? 10, 50);
|
|
35
|
+
const items = (data.items ?? []).slice(0, maxResults).map(
|
|
36
|
+
(org: Record<string, unknown>) => {
|
|
37
|
+
const names = org.names as Array<{
|
|
38
|
+
value: string;
|
|
39
|
+
types: string[];
|
|
40
|
+
lang: string | null;
|
|
41
|
+
}> | undefined;
|
|
42
|
+
const locations = org.locations as Array<{
|
|
43
|
+
geonames_details: {
|
|
44
|
+
name: string;
|
|
45
|
+
country_name: string;
|
|
46
|
+
country_code: string;
|
|
47
|
+
country_subdivision_name?: string;
|
|
48
|
+
lat: number;
|
|
49
|
+
lng: number;
|
|
50
|
+
};
|
|
51
|
+
}> | undefined;
|
|
52
|
+
const links = org.links as Array<{
|
|
53
|
+
type: string;
|
|
54
|
+
value: string;
|
|
55
|
+
}> | undefined;
|
|
56
|
+
const externalIds = org.external_ids as Array<{
|
|
57
|
+
type: string;
|
|
58
|
+
all: string[];
|
|
59
|
+
preferred: string | null;
|
|
60
|
+
}> | undefined;
|
|
61
|
+
|
|
62
|
+
// Extract the display name (ror_display type preferred, then first label)
|
|
63
|
+
const displayName = names?.find(
|
|
64
|
+
(n) => n.types.includes("ror_display"),
|
|
65
|
+
)?.value;
|
|
66
|
+
const acronym = names?.find(
|
|
67
|
+
(n) => n.types.includes("acronym"),
|
|
68
|
+
)?.value;
|
|
69
|
+
const aliases = names
|
|
70
|
+
?.filter((n) => n.types.includes("alias"))
|
|
71
|
+
.map((n) => n.value);
|
|
72
|
+
const labels = names
|
|
73
|
+
?.filter((n) => n.types.includes("label") && !n.types.includes("ror_display"))
|
|
74
|
+
.map((n) => ({ name: n.value, lang: n.lang }));
|
|
75
|
+
|
|
76
|
+
const location = locations?.[0]?.geonames_details;
|
|
77
|
+
const website = links?.find((l) => l.type === "website")?.value;
|
|
78
|
+
const wikipedia = links?.find((l) => l.type === "wikipedia")?.value;
|
|
79
|
+
|
|
80
|
+
// Extract GRID and other IDs
|
|
81
|
+
const gridId = externalIds?.find((e) => e.type === "grid")?.preferred;
|
|
82
|
+
const wikidataId = externalIds?.find((e) => e.type === "wikidata")?.preferred;
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
ror_id: org.id,
|
|
86
|
+
name: displayName ?? names?.[0]?.value,
|
|
87
|
+
acronym,
|
|
88
|
+
aliases: aliases?.length ? aliases : undefined,
|
|
89
|
+
labels: labels?.length ? labels : undefined,
|
|
90
|
+
types: org.types,
|
|
91
|
+
status: org.status,
|
|
92
|
+
established: org.established,
|
|
93
|
+
location: location
|
|
94
|
+
? {
|
|
95
|
+
city: location.name,
|
|
96
|
+
country: location.country_name,
|
|
97
|
+
country_code: location.country_code,
|
|
98
|
+
region: location.country_subdivision_name,
|
|
99
|
+
}
|
|
100
|
+
: undefined,
|
|
101
|
+
website,
|
|
102
|
+
wikipedia,
|
|
103
|
+
domains: org.domains,
|
|
104
|
+
grid_id: gridId,
|
|
105
|
+
wikidata_id: wikidataId,
|
|
106
|
+
};
|
|
107
|
+
},
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
return toolResult({
|
|
111
|
+
total_results: data.number_of_results,
|
|
112
|
+
organizations: items,
|
|
113
|
+
_source_health: { source: "ror", latency_ms: tracked.latency_ms },
|
|
114
|
+
});
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
];
|
|
118
|
+
}
|
package/src/tools/unpaywall.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Type } from "@sinclair/typebox";
|
|
2
2
|
import type { OpenClawPluginApi, OpenClawPluginToolContext } from "openclaw/plugin-sdk";
|
|
3
|
-
import { toolResult } from "./util.js";
|
|
3
|
+
import { toolResult, trackedFetch, isTrackedError } from "./util.js";
|
|
4
4
|
|
|
5
5
|
const BASE = "https://api.unpaywall.org/v2";
|
|
6
6
|
|
|
@@ -23,14 +23,19 @@ export function createUnpaywallTools(
|
|
|
23
23
|
}),
|
|
24
24
|
execute: async (input: { doi: string }) => {
|
|
25
25
|
const doi = input.doi.replace(/^https?:\/\/doi\.org\//, "");
|
|
26
|
-
const
|
|
26
|
+
const tracked = await trackedFetch(
|
|
27
|
+
"unpaywall",
|
|
27
28
|
`${BASE}/${encodeURIComponent(doi)}?email=${email}`,
|
|
28
29
|
);
|
|
29
|
-
if (
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
if (isTrackedError(tracked)) {
|
|
31
|
+
// Special handling for 404 (DOI not found)
|
|
32
|
+
if (tracked.details && typeof tracked.details === "object" && "error" in (tracked.details as Record<string, unknown>)) {
|
|
33
|
+
const errMsg = String((tracked.details as Record<string, string>).error);
|
|
34
|
+
if (errMsg.includes("404")) return toolResult({ error: "DOI not found in Unpaywall" });
|
|
35
|
+
}
|
|
36
|
+
return tracked;
|
|
32
37
|
}
|
|
33
|
-
const data = await res.json();
|
|
38
|
+
const data = await tracked.res.json();
|
|
34
39
|
|
|
35
40
|
const oaLocations = (
|
|
36
41
|
data.oa_locations as Record<string, unknown>[] | undefined
|
|
@@ -53,6 +58,7 @@ export function createUnpaywallTools(
|
|
|
53
58
|
publisher: data.publisher,
|
|
54
59
|
published_date: data.published_date,
|
|
55
60
|
oa_locations: oaLocations,
|
|
61
|
+
_source_health: { source: "unpaywall", latency_ms: tracked.latency_ms },
|
|
56
62
|
});
|
|
57
63
|
},
|
|
58
64
|
},
|
package/src/tools/util.ts
CHANGED
|
@@ -9,3 +9,144 @@ export function toolResult(data: unknown) {
|
|
|
9
9
|
const text = JSON.stringify(data, null, 2);
|
|
10
10
|
return { content: [{ type: "text" as const, text }], details: data };
|
|
11
11
|
}
|
|
12
|
+
|
|
13
|
+
// ── Source Health Tracking ───────────────────────────────────────────────
|
|
14
|
+
|
|
15
|
+
interface SourceHealthEntry {
|
|
16
|
+
source: string;
|
|
17
|
+
total_calls: number;
|
|
18
|
+
successes: number;
|
|
19
|
+
failures: number;
|
|
20
|
+
last_status: number | null;
|
|
21
|
+
last_latency_ms: number | null;
|
|
22
|
+
last_error: string | null;
|
|
23
|
+
avg_latency_ms: number;
|
|
24
|
+
last_called: string | null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const healthRegistry = new Map<string, SourceHealthEntry>();
|
|
28
|
+
|
|
29
|
+
function getOrCreateEntry(source: string): SourceHealthEntry {
|
|
30
|
+
let entry = healthRegistry.get(source);
|
|
31
|
+
if (!entry) {
|
|
32
|
+
entry = {
|
|
33
|
+
source,
|
|
34
|
+
total_calls: 0,
|
|
35
|
+
successes: 0,
|
|
36
|
+
failures: 0,
|
|
37
|
+
last_status: null,
|
|
38
|
+
last_latency_ms: null,
|
|
39
|
+
last_error: null,
|
|
40
|
+
avg_latency_ms: 0,
|
|
41
|
+
last_called: null,
|
|
42
|
+
};
|
|
43
|
+
healthRegistry.set(source, entry);
|
|
44
|
+
}
|
|
45
|
+
return entry;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function recordSuccess(entry: SourceHealthEntry, status: number, latencyMs: number) {
|
|
49
|
+
entry.total_calls++;
|
|
50
|
+
entry.successes++;
|
|
51
|
+
entry.last_status = status;
|
|
52
|
+
entry.last_latency_ms = latencyMs;
|
|
53
|
+
entry.last_error = null;
|
|
54
|
+
entry.last_called = new Date().toISOString();
|
|
55
|
+
entry.avg_latency_ms = Math.round(
|
|
56
|
+
(entry.avg_latency_ms * (entry.total_calls - 1) + latencyMs) / entry.total_calls,
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function recordFailure(entry: SourceHealthEntry, error: string, status?: number) {
|
|
61
|
+
entry.total_calls++;
|
|
62
|
+
entry.failures++;
|
|
63
|
+
entry.last_status = status ?? null;
|
|
64
|
+
entry.last_error = error;
|
|
65
|
+
entry.last_called = new Date().toISOString();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface TrackedResponse {
|
|
69
|
+
res: Response;
|
|
70
|
+
latency_ms: number;
|
|
71
|
+
source: string;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Fetch with automatic source health tracking, timeout, and error handling.
|
|
76
|
+
*
|
|
77
|
+
* @param source - Source identifier (e.g. "europe_pmc", "dblp")
|
|
78
|
+
* @param url - Request URL
|
|
79
|
+
* @param options - Fetch options
|
|
80
|
+
* @param timeoutMs - Timeout in milliseconds (default: 10000)
|
|
81
|
+
* @returns TrackedResponse on success, or a toolResult error on failure
|
|
82
|
+
*/
|
|
83
|
+
export async function trackedFetch(
|
|
84
|
+
source: string,
|
|
85
|
+
url: string,
|
|
86
|
+
options?: RequestInit,
|
|
87
|
+
timeoutMs = 10_000,
|
|
88
|
+
): Promise<TrackedResponse | ReturnType<typeof toolResult>> {
|
|
89
|
+
const entry = getOrCreateEntry(source);
|
|
90
|
+
const start = Date.now();
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
const res = await fetch(url, {
|
|
94
|
+
...options,
|
|
95
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
96
|
+
});
|
|
97
|
+
const latency = Date.now() - start;
|
|
98
|
+
|
|
99
|
+
if (!res.ok) {
|
|
100
|
+
recordFailure(entry, `HTTP ${res.status} ${res.statusText}`, res.status);
|
|
101
|
+
return toolResult({
|
|
102
|
+
error: `${source} API error: ${res.status} ${res.statusText}`,
|
|
103
|
+
_source_health: {
|
|
104
|
+
source,
|
|
105
|
+
status: res.status,
|
|
106
|
+
latency_ms: latency,
|
|
107
|
+
success_rate: entry.total_calls > 0
|
|
108
|
+
? `${Math.round((entry.successes / entry.total_calls) * 100)}%`
|
|
109
|
+
: "N/A",
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
recordSuccess(entry, res.status, latency);
|
|
115
|
+
return { res, latency_ms: latency, source };
|
|
116
|
+
} catch (err) {
|
|
117
|
+
const latency = Date.now() - start;
|
|
118
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
119
|
+
const isTimeout = message.includes("abort") || message.includes("timeout");
|
|
120
|
+
recordFailure(entry, isTimeout ? `Timeout after ${timeoutMs}ms` : message);
|
|
121
|
+
|
|
122
|
+
return toolResult({
|
|
123
|
+
error: `${source} ${isTimeout ? "timeout" : "network error"}: ${message}`,
|
|
124
|
+
_source_health: {
|
|
125
|
+
source,
|
|
126
|
+
latency_ms: latency,
|
|
127
|
+
success_rate: entry.total_calls > 0
|
|
128
|
+
? `${Math.round((entry.successes / entry.total_calls) * 100)}%`
|
|
129
|
+
: "N/A",
|
|
130
|
+
suggestion: isTimeout
|
|
131
|
+
? "This source is slow. Try a different source or reduce result count."
|
|
132
|
+
: "This source may be temporarily unavailable. Try an alternative.",
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Get health status for all tracked sources. Useful for agent decision-making.
|
|
140
|
+
*/
|
|
141
|
+
export function getSourceHealth(): SourceHealthEntry[] {
|
|
142
|
+
return Array.from(healthRegistry.values());
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Check if a tracked fetch result is an error (toolResult) or success (TrackedResponse).
|
|
147
|
+
*/
|
|
148
|
+
export function isTrackedError(
|
|
149
|
+
result: TrackedResponse | ReturnType<typeof toolResult>,
|
|
150
|
+
): result is ReturnType<typeof toolResult> {
|
|
151
|
+
return "content" in result && "details" in result;
|
|
152
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
import type { OpenClawPluginApi, OpenClawPluginToolContext } from "openclaw/plugin-sdk";
|
|
3
|
+
import { toolResult, trackedFetch, isTrackedError } from "./util.js";
|
|
4
|
+
|
|
5
|
+
const BASE = "https://zenodo.org/api";
|
|
6
|
+
|
|
7
|
+
export function createZenodoTools(
|
|
8
|
+
_ctx: OpenClawPluginToolContext,
|
|
9
|
+
_api: OpenClawPluginApi,
|
|
10
|
+
) {
|
|
11
|
+
return [
|
|
12
|
+
{
|
|
13
|
+
name: "search_zenodo",
|
|
14
|
+
label: "Search Records (Zenodo)",
|
|
15
|
+
description:
|
|
16
|
+
"Search Zenodo for open research data, software, publications, and other research outputs. Covers 3M+ records with DOIs. Uniquely includes datasets, software, presentations, and other non-publication outputs.",
|
|
17
|
+
parameters: Type.Object({
|
|
18
|
+
query: Type.String({ description: "Search query" }),
|
|
19
|
+
type: Type.Optional(
|
|
20
|
+
Type.String({
|
|
21
|
+
description:
|
|
22
|
+
"Resource type filter: 'publication', 'dataset', 'software', 'image', 'video', 'lesson', 'poster', 'presentation'",
|
|
23
|
+
}),
|
|
24
|
+
),
|
|
25
|
+
size: Type.Optional(
|
|
26
|
+
Type.Number({ description: "Max results (default 10, max 100)" }),
|
|
27
|
+
),
|
|
28
|
+
sort: Type.Optional(
|
|
29
|
+
Type.String({
|
|
30
|
+
description:
|
|
31
|
+
"Sort by: 'bestmatch' (relevance), 'mostrecent', '-mostrecent' (oldest first)",
|
|
32
|
+
}),
|
|
33
|
+
),
|
|
34
|
+
access_right: Type.Optional(
|
|
35
|
+
Type.String({
|
|
36
|
+
description: "Access filter: 'open', 'embargoed', 'restricted', 'closed'",
|
|
37
|
+
}),
|
|
38
|
+
),
|
|
39
|
+
}),
|
|
40
|
+
execute: async (input: {
|
|
41
|
+
query: string;
|
|
42
|
+
type?: string;
|
|
43
|
+
size?: number;
|
|
44
|
+
sort?: string;
|
|
45
|
+
access_right?: string;
|
|
46
|
+
}) => {
|
|
47
|
+
const params = new URLSearchParams({
|
|
48
|
+
q: input.query,
|
|
49
|
+
size: String(Math.min(input.size ?? 10, 100)),
|
|
50
|
+
});
|
|
51
|
+
if (input.type) params.set("type", input.type);
|
|
52
|
+
if (input.sort) params.set("sort", input.sort);
|
|
53
|
+
if (input.access_right) params.set("access_right", input.access_right);
|
|
54
|
+
|
|
55
|
+
const result = await trackedFetch("zenodo", `${BASE}/records?${params}`, undefined, 10_000);
|
|
56
|
+
if (isTrackedError(result)) return result;
|
|
57
|
+
const data = await result.res.json();
|
|
58
|
+
|
|
59
|
+
return toolResult({
|
|
60
|
+
total_results: data.hits?.total,
|
|
61
|
+
source: "zenodo",
|
|
62
|
+
records: data.hits?.hits?.map(
|
|
63
|
+
(h: Record<string, unknown>) => {
|
|
64
|
+
const meta = h.metadata as Record<string, unknown> | undefined;
|
|
65
|
+
const creators = meta?.creators as Array<{ name: string; affiliation?: string }> | undefined;
|
|
66
|
+
const resourceType = meta?.resource_type as Record<string, string> | undefined;
|
|
67
|
+
const license = meta?.license as Record<string, string> | undefined;
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
id: h.id,
|
|
71
|
+
doi: meta?.doi ?? h.doi,
|
|
72
|
+
title: meta?.title ?? h.title,
|
|
73
|
+
authors: creators?.map((c) => c.name),
|
|
74
|
+
year: meta?.publication_date
|
|
75
|
+
? String(meta.publication_date).slice(0, 4)
|
|
76
|
+
: undefined,
|
|
77
|
+
publication_date: meta?.publication_date,
|
|
78
|
+
resource_type: resourceType?.type,
|
|
79
|
+
access_right: meta?.access_right,
|
|
80
|
+
keywords: meta?.keywords,
|
|
81
|
+
license: license?.id,
|
|
82
|
+
description: meta?.description
|
|
83
|
+
? String(meta.description).replace(/<[^>]*>/g, "").slice(0, 300)
|
|
84
|
+
: undefined,
|
|
85
|
+
url: (h.links as Record<string, string>)?.self_html
|
|
86
|
+
?? `https://zenodo.org/records/${h.id}`,
|
|
87
|
+
source: "zenodo",
|
|
88
|
+
};
|
|
89
|
+
},
|
|
90
|
+
),
|
|
91
|
+
_latency_ms: result.latency_ms,
|
|
92
|
+
});
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: "get_zenodo_record",
|
|
97
|
+
label: "Get Record Details (Zenodo)",
|
|
98
|
+
description:
|
|
99
|
+
"Get full details of a specific Zenodo record by its numeric ID. Returns metadata, files, and download links.",
|
|
100
|
+
parameters: Type.Object({
|
|
101
|
+
record_id: Type.String({
|
|
102
|
+
description: "Zenodo record ID (numeric), e.g. '7042164'",
|
|
103
|
+
}),
|
|
104
|
+
}),
|
|
105
|
+
execute: async (input: { record_id: string }) => {
|
|
106
|
+
const id = input.record_id.replace(/\D/g, "");
|
|
107
|
+
const result = await trackedFetch("zenodo", `${BASE}/records/${id}`, undefined, 10_000);
|
|
108
|
+
if (isTrackedError(result)) return result;
|
|
109
|
+
const h = await result.res.json();
|
|
110
|
+
|
|
111
|
+
const meta = h.metadata as Record<string, unknown> | undefined;
|
|
112
|
+
const creators = meta?.creators as Array<{ name: string; affiliation?: string }> | undefined;
|
|
113
|
+
const resourceType = meta?.resource_type as Record<string, string> | undefined;
|
|
114
|
+
const license = meta?.license as Record<string, string> | undefined;
|
|
115
|
+
const files = h.files as Array<{ key: string; size: number; links?: Record<string, string> }> | undefined;
|
|
116
|
+
const stats = h.stats as Record<string, number> | undefined;
|
|
117
|
+
|
|
118
|
+
return toolResult({
|
|
119
|
+
id: h.id,
|
|
120
|
+
doi: meta?.doi ?? h.doi,
|
|
121
|
+
title: meta?.title ?? h.title,
|
|
122
|
+
authors: creators?.map((c) => c.name),
|
|
123
|
+
year: meta?.publication_date
|
|
124
|
+
? String(meta.publication_date).slice(0, 4)
|
|
125
|
+
: undefined,
|
|
126
|
+
publication_date: meta?.publication_date,
|
|
127
|
+
description: meta?.description
|
|
128
|
+
? String(meta.description).replace(/<[^>]*>/g, "")
|
|
129
|
+
: undefined,
|
|
130
|
+
resource_type: resourceType?.type,
|
|
131
|
+
access_right: meta?.access_right,
|
|
132
|
+
keywords: meta?.keywords,
|
|
133
|
+
license: license?.id,
|
|
134
|
+
version: meta?.version,
|
|
135
|
+
files: files?.map((f) => ({
|
|
136
|
+
filename: f.key,
|
|
137
|
+
size_bytes: f.size,
|
|
138
|
+
download_url: f.links?.self,
|
|
139
|
+
})),
|
|
140
|
+
stats: stats
|
|
141
|
+
? {
|
|
142
|
+
downloads: stats.downloads,
|
|
143
|
+
views: stats.views,
|
|
144
|
+
}
|
|
145
|
+
: undefined,
|
|
146
|
+
url: (h.links as Record<string, string>)?.self_html
|
|
147
|
+
?? `https://zenodo.org/records/${h.id}`,
|
|
148
|
+
source: "zenodo",
|
|
149
|
+
_latency_ms: result.latency_ms,
|
|
150
|
+
});
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
];
|
|
154
|
+
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "ChatSpatial",
|
|
3
|
-
"name": "ChatSpatial",
|
|
4
|
-
"description": "Spatial transcriptomics analysis via natural language",
|
|
5
|
-
"category": "academic-db",
|
|
6
|
-
"install": {
|
|
7
|
-
"runtime": "python",
|
|
8
|
-
"package": "ChatSpatial",
|
|
9
|
-
"command": "pip install ChatSpatial"
|
|
10
|
-
},
|
|
11
|
-
"config": {
|
|
12
|
-
"env": {}
|
|
13
|
-
},
|
|
14
|
-
"tools": ["load_data", "identify_domains", "visualize"],
|
|
15
|
-
"verified": false,
|
|
16
|
-
"source": "https://github.com/cafferychen777/ChatSpatial"
|
|
17
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "academia-mcp",
|
|
3
|
-
"name": "Academia MCP",
|
|
4
|
-
"description": "Tools for automatic scientific research",
|
|
5
|
-
"category": "academic-db",
|
|
6
|
-
"install": {
|
|
7
|
-
"runtime": "python",
|
|
8
|
-
"package": "academia-mcp",
|
|
9
|
-
"command": "pip install academia-mcp"
|
|
10
|
-
},
|
|
11
|
-
"config": {
|
|
12
|
-
"env": {}
|
|
13
|
-
},
|
|
14
|
-
"tools": ["search", "analyze"],
|
|
15
|
-
"verified": false,
|
|
16
|
-
"source": "https://github.com/IlyaGusev/academia_mcp"
|
|
17
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "academic-paper-explorer",
|
|
3
|
-
"name": "Academic Paper Explorer",
|
|
4
|
-
"description": "Academic paper discovery via arXiv and Semantic Scholar",
|
|
5
|
-
"category": "academic-db",
|
|
6
|
-
"install": {
|
|
7
|
-
"runtime": "node",
|
|
8
|
-
"package": "academic-paper-explorer",
|
|
9
|
-
"command": "npm install -g academic-paper-explorer"
|
|
10
|
-
},
|
|
11
|
-
"config": {
|
|
12
|
-
"env": {}
|
|
13
|
-
},
|
|
14
|
-
"tools": ["search", "read_paper", "find_code"],
|
|
15
|
-
"verified": false,
|
|
16
|
-
"source": "https://github.com/Leonard013/academic-paper-explorer"
|
|
17
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "academic-search-mcp-server",
|
|
3
|
-
"name": "Academic Paper Search",
|
|
4
|
-
"description": "Academic Paper Search MCP for Semantic Scholar and Crossref APIs",
|
|
5
|
-
"category": "academic-db",
|
|
6
|
-
"install": {
|
|
7
|
-
"runtime": "python",
|
|
8
|
-
"package": "academic-search-mcp-server",
|
|
9
|
-
"command": "pip install academic-search-mcp-server"
|
|
10
|
-
},
|
|
11
|
-
"config": {
|
|
12
|
-
"env": {}
|
|
13
|
-
},
|
|
14
|
-
"tools": ["search_papers", "fetch_paper_details", "search_by_topic"],
|
|
15
|
-
"verified": false,
|
|
16
|
-
"source": "https://github.com/afrise/academic-search-mcp-server"
|
|
17
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "agentinterviews-mcp",
|
|
3
|
-
"name": "Agent Interviews",
|
|
4
|
-
"description": "AI-powered qualitative research interviews at scale",
|
|
5
|
-
"category": "academic-db",
|
|
6
|
-
"install": {
|
|
7
|
-
"runtime": "python",
|
|
8
|
-
"package": "agentinterviews-mcp",
|
|
9
|
-
"command": "pip install agentinterviews-mcp"
|
|
10
|
-
},
|
|
11
|
-
"config": {
|
|
12
|
-
"env": {}
|
|
13
|
-
},
|
|
14
|
-
"tools": ["create_interviewer", "manage_project", "analyze_data"],
|
|
15
|
-
"verified": false,
|
|
16
|
-
"source": "https://github.com/thinkchainai/agentinterviews_mcp"
|
|
17
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "all-in-mcp",
|
|
3
|
-
"name": "All-in MCP",
|
|
4
|
-
"description": "Academic paper search and PDF processing",
|
|
5
|
-
"category": "academic-db",
|
|
6
|
-
"install": {
|
|
7
|
-
"runtime": "python",
|
|
8
|
-
"package": "all-in-mcp",
|
|
9
|
-
"command": "pip install all-in-mcp"
|
|
10
|
-
},
|
|
11
|
-
"config": {
|
|
12
|
-
"env": {}
|
|
13
|
-
},
|
|
14
|
-
"tools": ["search", "process_pdf"],
|
|
15
|
-
"verified": false,
|
|
16
|
-
"source": "https://github.com/isomoes/all-in-mcp"
|
|
17
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "alphafold-mcp",
|
|
3
|
-
"name": "AlphaFold MCP",
|
|
4
|
-
"description": "AlphaFold Protein Structure Database for structure prediction",
|
|
5
|
-
"category": "academic-db",
|
|
6
|
-
"install": {
|
|
7
|
-
"runtime": "node",
|
|
8
|
-
"package": "alphafold-mcp-server",
|
|
9
|
-
"command": "npm install -g alphafold-mcp-server"
|
|
10
|
-
},
|
|
11
|
-
"config": {
|
|
12
|
-
"env": {}
|
|
13
|
-
},
|
|
14
|
-
"tools": [
|
|
15
|
-
"get_structure",
|
|
16
|
-
"search_protein"
|
|
17
|
-
],
|
|
18
|
-
"verified": false,
|
|
19
|
-
"source": "https://github.com/ac3xx/AlphaFold-MCP-Server"
|
|
20
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "apple-health-mcp",
|
|
3
|
-
"name": "Apple Health Data",
|
|
4
|
-
"description": "Access exported Apple Health data with analytics",
|
|
5
|
-
"category": "academic-db",
|
|
6
|
-
"install": {
|
|
7
|
-
"runtime": "python",
|
|
8
|
-
"package": "apple-health-mcp-server",
|
|
9
|
-
"command": "pip install apple-health-mcp-server"
|
|
10
|
-
},
|
|
11
|
-
"config": {
|
|
12
|
-
"env": {}
|
|
13
|
-
},
|
|
14
|
-
"tools": ["read_health_data", "analyze_trends", "export_data"],
|
|
15
|
-
"verified": false,
|
|
16
|
-
"source": "https://github.com/the-momentum/apple-health-mcp-server"
|
|
17
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "arxiv-latex-mcp",
|
|
3
|
-
"name": "arXiv LaTeX Source",
|
|
4
|
-
"description": "Access arXiv papers via LaTeX source for better math handling",
|
|
5
|
-
"category": "academic-db",
|
|
6
|
-
"install": {
|
|
7
|
-
"runtime": "python",
|
|
8
|
-
"package": "arxiv-latex-mcp",
|
|
9
|
-
"command": "pip install arxiv-latex-mcp"
|
|
10
|
-
},
|
|
11
|
-
"config": {
|
|
12
|
-
"env": {}
|
|
13
|
-
},
|
|
14
|
-
"tools": ["get_paper_prompt", "get_paper_abstract", "list_paper_sections", "get_paper_section"],
|
|
15
|
-
"verified": false,
|
|
16
|
-
"source": "https://github.com/takashiishida/arxiv-latex-mcp"
|
|
17
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "arxiv-mcp-server",
|
|
3
|
-
"name": "arXiv Search",
|
|
4
|
-
"description": "Search ArXiv research papers",
|
|
5
|
-
"category": "academic-db",
|
|
6
|
-
"install": {
|
|
7
|
-
"runtime": "python",
|
|
8
|
-
"package": "arxiv-mcp-server",
|
|
9
|
-
"command": "pip install arxiv-mcp-server"
|
|
10
|
-
},
|
|
11
|
-
"config": {
|
|
12
|
-
"env": {}
|
|
13
|
-
},
|
|
14
|
-
"tools": ["search_arxiv"],
|
|
15
|
-
"verified": false,
|
|
16
|
-
"source": "https://github.com/blazickjp/arxiv-mcp-server"
|
|
17
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "bgpt-mcp",
|
|
3
|
-
"name": "BGPT Paper Search",
|
|
4
|
-
"description": "Search paper data from any AI tool",
|
|
5
|
-
"category": "academic-db",
|
|
6
|
-
"install": {
|
|
7
|
-
"runtime": "node",
|
|
8
|
-
"package": "bgpt-mcp",
|
|
9
|
-
"command": "npm install -g bgpt-mcp"
|
|
10
|
-
},
|
|
11
|
-
"config": {
|
|
12
|
-
"env": {}
|
|
13
|
-
},
|
|
14
|
-
"tools": ["search_papers"],
|
|
15
|
-
"verified": false,
|
|
16
|
-
"source": "https://github.com/connerlambden/bgpt-mcp"
|
|
17
|
-
}
|