Scopus MCP Server
Scopus MCP Server
Ein MCP-Server, der die Elsevier-Scopus-API kapselt, sodass ein MCP-Client (Claude Desktop, Claude Code oder ein anderer MCP-Host) veröffentlichte akademische Artiel suchen und abrufen kann – nützlich für die Zitationsprüfung und die Analyse des Schreibstils auf der Grundlage echter, peer-reviewter Quellen.
Tools
Tool | Eingabe | Rückgabe |
|
| Bis zu |
|
| Vollständige Metadaten für einen Artiel: alles oben Genante plus Autoren-Schlüsselwörter, Fachgebiete, Open-Access-Kennzeichen, Aggregationstyp |
|
| Nur den Abstract-Text für einen Artiel, plus |
Alle Antworten sind strukturiertes JSON (siehe Antwortformat unten). Jedes Tool gibt einen verständlichen, strukturierten Fehler zurück, anstatt eine Ausnahme auszulösen, wenn die Scopus-API nicht erreichbar ist, die Rate begrenzt ist oder eine ungültige ID übergeben wurde – siehe Fehlerbehandlung.
Im Hintergrund ruft der Server zwei Elsevier-APIs auf:
Scopus Search API (
GET /content/search/scopus) – wird vonsearch_scopusverwendt.Abstract Retrieval API (
GET /content/abstract/scopus_id/{id}) – wird vonget_article_detailsundget_article_abstractverwendet, da die Search-API vollständige Abstracts, Zitationszahlen oder Schlüsselwörter nicht zuverlässig zurückgibt.
Related MCP server: MCP-scopus
Projektstruktur
mcp-server/
├── src/
│ ├── index.ts # stdio entry point (for local MCP clients)
│ ├── httpServer.ts # Streamable HTTP entry point (for remote deployment)
│ ├── registerTools.ts # tool definitions, shared by both entry points
│ ├── scopusClient.ts # Elsevier API client: requests, normalization, error mapping
│ ├── types.ts # TypeScript types for raw Scopus responses + normalized output
│ └── logger.ts # structured logger → stderr + logs/scopus-mcp.log
├── test/
│ └── test-connection.ts # standalone connectivity test (bypasses the MCP protocol)
├── logs/ # log file written here at runtime (gitignored)
├── .env.example
├── package.json
└── tsconfig.jsonVoraussetzungen
Node.js 18 oder höher (verwendet das eingebaute globale
fetch). Prüfen Sie mitnode -v.Ein Scopus-API-Schlüssel. Registrieren Sie einen kostenlosen Schlüssel im Elsevier Developer Portal. Beachen Sie, dass Elsevier den Zugriff auf Voltexte/Abstracts über IP-Bereiche (institutionelles Abonnement) oder In stitutionstoken beshränkt – ein Schlüssel allein reicht aus, um die Konnektivität und die grundlegende Suche zu testen, aber einige Felder können je nach Ihren Berechtigungen eingschränkt sein.
Einrichtung
cd mcp-server
npm install
cp .env.example .envBearbeiten Sie .env und setzen Sie Ihren Schlüssel:
SCOPUS_API_KEY=your_real_key_hereSCOPUS_API_KEY wird beim Start aus der Umgebung gelesen (src/scopusClient.ts); er ist niemals festkodiert und .env wird von Git ignoriert, sodass die Datei nicht versehentlich committet werden kann.
Umgebungsvariablen
Variable | Erforderlich | Standard | Zweck |
| ✅ | — | Ihr Elsevier-Scopus-API-Schlüssel |
| optional | — | In stitutionstoken, falls Ihr Schlüssel einen für den Zugriff außerhalb des Campus benötigt |
| optional |
| Übeschreibung zum Testen gegen einen Proxy/Mock |
| optional |
| Zeitüberschreitung pro Anfrage |
| optional |
| Mögliche Werte: |
| Nur HTTP-Modus |
| Port für |
| Nur HTTP-Modus |
| Bindeadresse für |
| HTTP-Modus, dringend empfolen | — | Falls gesetzt, erfordert |
| HTTP-Modus, optional | — | Kommagetrente Zulassungsliste für |
Zuerst die Konnektivität testen
Bevor Sie den Server in einen MCP-Client einbinden, vergewissern Sie sich, dass der Scopus-API-Schlüssel und der Netzwerkpfad funktioniert:
npm run test:connectionDies führt test/test-connection.ts aus, das dieselben Client-Funktionen aufruft, die auch die Tools verwenden – aber direkt, ohne das MCP-Protokoll zu sprechen – mit der Beispielabfrage "farmland abandonment Nepal". Sie können stattdessen eine eigene Abfrage übergeben:
npm run test:connection -- "AUTH(Smith J) AND TITLE(remote sensing)"Es durchläuft alle drei Tools nacheinander (Suche → Details → Abstract für das erste Ergebnis) und gibt pro Schritt ✅/❌ aus, zusätzlich zu einem vollständigen Anfrage-/Antwortprotokoll unter logs/scopus-mcp.log (siehe Protokollierung). Der Exit-Code ist nur dann 0, wenn jeder Schritt erfolgreich war.
Lokales Ausführen (stdio, für einen lokalen MCP-Client)
npm run dev # runs src/index.ts directly via tsx, no build step
# or
npm run build && npm start # compiles to dist/ then runs the compiled serverDer Server kommuniziert über stdio. Wenn Sie ihn direkt in einem Terminal ausführen, wartet er lediglich auf JSON-RPC auf stdin – das ist zu erwarten. Er ist dafür gedacht, von einem MCP-Client gestartet zu werden.
Verbindung mit Claude Code herstellen
claude mcp add scopus --env SCOPUS_API_KEY=your_real_key_here -- node /absolute/path/to/mcp-server/dist/index.js(führen Sie zuerst npm run build aus, damit dist/index.js existiert), oder fügen Sie ihn zur .mcp.json eines Projekts hinzu:
{
"mcpServers": {
"scopus": {
"command": "node",
"args": ["/absolute/path/to/mcp-server/dist/index.js"],
"env": { "SCOPUS_API_KEY": "your_real_key_here" }
}
}
}Verbindung mit Claude Desktop herstellen
Fügen Sie denselben Block zu claude_desktop_config.json hinzu (%APPDATA%\Claude\claude_desktop_config.json unter Windows, ~/Library/Application Support/Claude/claude_desktop_config.json unter macOS), und starten Sie Claude Desktop neu:
{
"mcpServers": {
"scopus": {
"command": "node",
"args": ["/absolute/path/to/mcp-server/dist/index.js"],
"env": { "SCOPUS_API_KEY": "your_real_key_here" }
}
}
}Antwortformat
Beispiel für search_scopus (gekürzt):
{
"query": "farmland abandonment Nepal",
"totalResults": 42,
"returnedResults": 10,
"articles": [
{
"scopusId": "85123456789",
"eid": "2-s2.0-85123456789",
"title": "Drivers of farmland abandonment in the mid-hills of Nepal",
"authors": ["Sharma B.", "Poudel K."],
"publicationYear": 2021,
"sourceTitle": "Land Use Policy",
"doi": "10.1016/j.landusepol.2021.105123",
"doiUrl": "https://doi.org/10.1016/j.landusepol.2021.105123",
"scopusUrl": "https://www.scopus.com/inward/record.uri?...",
"citedByCount": 17,
"abstract": null,
"documentType": "Article"
}
]
}get_article_details fügt zusätzlich zu denselben Feldern keywords, subjectAreas, openAccess und aggregationType hinzu. get_article_abstract gibt { scopusId, title, abstract, hasAbstract } zurück.
Felder, die Scopus für einen bestimmten Datensatz nicht hat, werden als null zurückgegeben (oder [] für Listenfelder, oder hasAbstract: false), anstatt ausgelassen zu werden – prüfen Sie auf null/false, bevor Sie annemen, dass ein Feld wegen eines Fehlers fehlt.
Fehlerbehandlung
Jedes Tool fängt Fehler intern ab und gibt isError: true mit einem strukturierten JSON-Body zurück, anstatt die MCP-Verbindung zum Absturz zu bringen:
{
"error": true,
"kind": "rate_limited",
"message": "Scopus API rate limit exceeded (HTTP 429) for search_scopus(...). Retry after 30s.",
"status": 429,
"retryAfterSeconds": 30
}kind ist einer der folgenden Werte: unauthorized (ungültiger/fehlender API-Schlüssel), rate_limited (HTTP 429), not_found (ungültige Scopus-ID / HTTP 404), bad_request (leere Abfrage, fehlerhafte Eingabe), network_error (DNS-/Verbindungsfehler), timeout (SCOPUS_REQUEST_TIMEOUT_MS überschritten) oder unknown. Eine Suche, die erfolgreich ist, aber nichts findet, ist kein Fehler – sie gibt totalResults: 0 und eine menschenlesbare message zurück, die Vorschläge macht, wie die Abfrage erweitert werden kann.
Protokollierung
Alle API-Aufrufe und -Antworten werden zu Debugzwecken protokolliert:
Jede Anfrage protokolliert ihre URL (API-Schlüssel geschwärzt), bevor sie gesendet wird.
Jede Antwort protokolliert Statuscode, vergangene Zeit und eine 500-Zeichen-Vorschau des Bodys.
Protokolle gehen an stderr als einzeiliges JSON (niemals stdout – stdout ist für das MCP-Protokoll auf dem stdio-Transport reserviert) und werden zusätzlich an
logs/scopus-mcp.logangehängt.Setzen Sie
LOG_LEVEL=debugfür mehr Details oderLOG_LEVEL=error, um es ruhiger zu machen.
Bereitstellung auf einer Remote-/Serverless-Plattform (Render, Railway usw.)
Der stdio-Transport (src/index.ts) funktioniert nur für MCP-Clienten, die einen lokalen Prozess starten können – er ist über das Netzwerk nicht erreichbar. Um diesen Server remote zu hosten, verwenden Sie stattdessen den Streamable HTTP-Einstiegspunkt: src/httpServer.ts. Er bedient dieselben drei Tools unter POST /mcp und fügt einen GET /healthz-Endpunkt für die Health-Checks der Plattform hinzu.
Weder Render noch Railway ist wirklich "serverless" (keine Scale-to-Zero-Kaltstarts mitten in einer Anfrage) – beide betreiben dies als normalen persistenten Node-Prozess, was ein zustandsbehaftetes Protokoll wie MCP benötigt. Behandeln Sie "serverless Plattform" hier als "verwaltetes Node-Hosting".
Render
Pushen Sie dieses Repo (oder nur den Ordner
mcp-server/) zu GitHub.Im Render-Dashboard: New → Web Service, verbinden Sie das Repo, setzen Sie root directory auf
mcp-server, wenn es ein Unterordner eines größeren Repos ist.Build command:
npm install && npm run buildStart command:
npm run start:httpUnter Environment fügen Sie hinzu:
SCOPUS_API_KEY= Ihr Schlüssel (als Geheimnis markieren)MCP_HTTP_AUTH_TOKEN= eine lange, zufällige Zeichenfolge, die Sie generieren (z. B.openssl rand -hex 32)optional
MCP_ALLOWED_HOSTS= Ihr Render-Hostname, z. B.scopus-mcp.onrender.com
Render setzt
PORTautomatisch —httpServer.tsliest ihn, keine Aktion erforderlich.Bereitstellen. Health-Check-Pfad:
/healthz.
Railway
New Project → Deploy from GitHub repo, setzen Sie den Service-Root auf
mcp-server, falls erforderlich.Railway erkennt Node automatisch; falls es nicht den richtigen Befehl ausführt, setzen Sie:
Build command:
npm install && npm run buildStart command:
npm run start:http
Unter Variables fügen Sie
SCOPUS_API_KEYundMCP_HTTP_AUTH_TOKENwie oben hinzu.Railway injiziert
PORTautomatisch.Nach der Bereitstellung ist Ihr MCP-Endpunkt
https://<your-app>.up.railway.app/mcp.
Verbinden eines MCP-Clients mit dem gehosteten Server
claude mcp add --transport http scopus https://<your-app>/mcp \
--header "Authorization: Bearer <your MCP_HTTP_AUTH_TOKEN>"Sicherheitshinweise für die HTTP-Bereitstellung
Setzen Sie
MCP_HTTP_AUTH_TOKENimmer. Ohne ihn kann jeder mit der URL Ihre Tools aufrufen und Ihr Scopus-API-Kontingent verbrauchen – der Server protokolliert eine Startwarnung, falls er nicht gesetzt ist.Der Server bindet DNS-Rebinding-Schutz automatisch für
localhost/127.0.0.1; für eine echte0.0.0.0- Bereitstellung setzen SieMCP_ALLOWED_HOSTSauf den Hostnamen Ihrer Plattform.Rotieren Sie
SCOPUS_API_KEYundMCP_HTTP_AUTH_TOKENüber den Secret-Manager Ihrer Plattform, niemals durch Committen in das Repo.Ziehen Sie in Erwägung, das eigene Rate-Limiting der Plattform / einen Reverse-Proxy für öffentliche Bereitstellungen vorzuschalten, zusätzlich zu den eigenen Pro-Schlüssel-Rate-Limits von Elsevier.
Fehlerbehebung
Symptom | Wahrscheinliche Ursache |
|
|
| Ungültiger Schlüssel, oder der Schlüssel hat keine Scopus-Search-Berechtigungen, oder |
| Das Pro-Schlüssel-Rate-/Kontingent-Limit von Elsevier wurde erreicht – warten Sie und versuchen Sie es nach |
| Die |
| Kein Internetzugriff von diesem Rechner/Host, Unternehmens-Proxy blockiert |
Lizenz
MIT
Available Tools
3 toolsget_article_abstractA
Retrieve just the abstract text for a single Scopus article by its Scopus ID. Returns hasAbstract:false with a null abstract when Scopus has no abstract on file for the article (this is common for older or non-English-language records).
| Name | Required | Description | Default |
|---|---|---|---|
| scopusId | Yes | The Scopus ID of the article, e.g. "85123456789". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden of behavioral disclosure. It usefully documents an important edge case: missing abstracts return hasAbstract:false with a null abstract, common for older or non-English-language records. It does not cover invalid-ID behavior, but for a simple read operation this is a reasonable level of transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. The main purpose is front-loaded, and the second sentence adds valuable edge-case behavior without being verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter tool with no output schema, the description covers the main purpose and a key edge case. It partially describes the return contract via hasAbstract and abstract, though it does not mention invalid-ID behavior. Overall, the core information needed to call the tool correctly is present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter has full schema coverage with a description and example. The tool description adds no parameter-specific meaning beyond what the schema already provides, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Retrieve just the abstract text for a single Scopus article by its Scopus ID.' The qualifiers 'just' and 'single' clearly distinguish this from the sibling tools search_scopus and get_article_details.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use this tool: when only the abstract is needed and a Scopus ID is already known. However, it does not explicitly mention alternatives or exclusions, such as using search_scopus to find the ID or get_article_details for full metadata.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_article_detailsA
Retrieve full metadata for a single Scopus article by its Scopus ID, including title, authors, publication year, source title, DOI, citation count, author keywords, subject areas, and abstract (when available). Use the scopusId returned by search_scopus.
| Name | Required | Description | Default |
|---|---|---|---|
| scopusId | Yes | The Scopus ID of the article, e.g. "85123456789" (the "SCOPUS_ID:" prefix, if present, is stripped automatically). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It describes what the call returns, including the conditional 'abstract (when available),' which clarifies a key edge case. It does not discuss auth, rate limits, or invalid-ID behavior, but the enumerated output is enough for this simple read operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one sentence with no filler. The core action and ID source are front-loaded, and the field list is an efficient way to convey the return shape.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter lookup with no output schema, the description covers the essential context: what to provide, where to get it, and what metadata will come back. It could add behavior for missing/unknown IDs, but nothing critical is missing for normal invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already describes scopusId and the automatic prefix stripping, so the baseline is high. The description adds provenance semantics by telling the agent to use a scopusId returned by search_scopus, which is useful information not present in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource: 'Retrieve full metadata for a single Scopus article by its Scopus ID.' The enumeration of fields (title, authors, DOI, citation count, etc.) makes the purpose concrete and distinct from a search or abstract-only tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit usage pointer: 'Use the scopusId returned by search_scopus,' which tells the agent where the required ID comes from. It does not explicitly say when to prefer the sibling get_article_abstract over this tool, so it stops short of full exclusion guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_scopusA
Search Scopus for published academic articles by author name, keywords, title, or DOI. Returns up to count (default 10, max 25) results with title, authors, publication year, abstract (when Scopus provides one in search results), source title, DOI, and Scopus ID. Use this first to find candidate articles, then call get_article_details or get_article_abstract with a returned scopusId for full metadata.
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | Number of results to return (default 10, max 25). | |
| query | Yes | Search query. Supports free text (e.g. "farmland abandonment Nepal") or Scopus field-search syntax (e.g. "AUTH(Smith J)", "TITLE(remote sensing)", "DOI(10.1000/xyz123)"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden of behavioral disclosure. It covers the return payload, count defaults and limits, and the conditional presence of abstracts. It does not mention rate limits, auth requirements, or explicit read-only status, but for a search tool the core behavior is well disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no filler. It front-loads the purpose, then the return contract, then the follow-up workflow—every sentence adds value and is easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Even without an output schema, the description lists the returned fields, count constraints, and a nuanced caveat about abstract availability. The tool has only two simple parameters, and the description gives an agent enough context to invoke it correctly and interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description reiterates the query modes and count behavior already present in the schema without adding significant new parameter meaning beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Search'), a clear resource ('Scopus'), and identifies the search facets: author name, keywords, title, or DOI. It also distinguishes itself from siblings by describing candidate-finding versus get_article_details/get_article_abstract metadata retrieval.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states the intended workflow: 'Use this first to find candidate articles, then call get_article_details or get_article_abstract with a returned scopusId for full metadata.' This tells an agent exactly when to use this tool and how to proceed afterward.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v1.0.0- First observed
get_article_abstract - First observed
get_article_details - First observed
search_scopus
TDQS
Scored across 3 tools
The three tools have clearly distinct primary actions: searching versus retrieving by Scopus ID. However, get_article_details and get_article_abstract overlap since details also includes the abstract when available, which could cause minor confusion about which to call.
All tool names follow a consistent verb_noun pattern: search_scopus, get_article_details, get_article_abstract. The get_article_* prefix for the two retrieval tools reinforces a predictable structure.
Three tools is on the small side but appropriately scoped for a simple search-and-retrieve workflow. The count feels slightly thin for a general-purpose Scopus API wrapper, but each tool serves a necessary step in the primary flow.
The core lifecycle of discovering articles and retrieving full metadata or abstracts is covered, with no dead ends. Minor gaps exist, such as no direct citation-list or author-detail endpoints, but these are reasonable omissions given the stated purpose.
Maintenance
Related MCP Connectors
Academic research MCP server for paper search, citation checks, graphs, and deep research.
Scrape arXiv, OpenAlex and Crossref papers by author, topic, journal or DOI. Pay per row.
Academic paper search, scientific literature, citation analysis, arXiv & semantic related-work.
Scholarly search: OpenAlex, Crossref, arXiv, OpenCitations and PubMed in one endpoint.
Related MCP Servers
- AlicenseAqualityFmaintenanceProvides access to the Elsevier Scopus API, enabling AI assistants to search for academic papers, retrieve detailed abstracts, and look up author profiles. It facilitates bibliometric research and scholarly data analysis through natural language commands.588 PyPI50MIT
- AlicenseAqualityDmaintenanceEnables AI assistants to search and retrieve real academic papers from Scopus, preventing citation hallucination by providing accurate paper metadata, author info, and citation analysis.153MIT
- AlicenseAqualityDmaintenanceEnables AI agents to search and retrieve academic papers, author profiles, and citation data from the Scopus database via MCP tools.7MIT
- AlicenseNot gradedqualityDmaintenanceEnables searching Elsevier's Scopus database for scientific literature, retrieving abstracts and metadata, and exporting results in RIS or BibTeX format.15 PyPI1MIT