Skip to main content
Glama
Pratik-Pou

Scopus MCP Server

by Pratik-Pou

Scopus MCP Server

An MCP server that wraps the Elsevier Scopus API so an MCP client (Claude Desktop, Claude Code, or any other MCP host) can search for and retrieve published academic articles — useful for citation verification and writing-style analysis grounded in real, peer-reviewed sources.

Tools

Tool

Input

What it returns

search_scopus

query (author, keywords, title, or DOI), optional count (1–25, default 10)

Up to count articles: title, authors, publication year, abstract (if Scopus includes one in search results), source title, DOI, DOI URL, Scopus ID, cited-by count

get_article_details

scopusId

Full metadata for one article: everything above plus author keywords, subject areas, open-access flag, aggregation type

get_article_abstract

scopusId

Just the abstract text for one article, plus hasAbstract: false when Scopus has none on file

All responses are structured JSON (see Response shape below). Every tool returns a friendly, structured error instead of throwing when the Scopus API is unreachable, rate-limited, or given a bad ID — see Error handling.

Under the hood the server calls two Elsevier APIs:

  • Scopus Search API (GET /content/search/scopus) — used by search_scopus.

  • Abstract Retrieval API (GET /content/abstract/scopus_id/{id}) — used by get_article_details and get_article_abstract, since the Search API does not reliably return full abstracts, citation counts, or keywords.

Related MCP server: MCP-scopus

Project layout

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.json

Prerequisites

  • Node.js 18 or later (uses the built-in global fetch). Check with node -v.

  • A Scopus API key. Register a free key at the Elsevier Developer Portal. Note that Elsevier gates full-text/abstract access by IP range (institutional subscription) or Institutional Token — a key alone is enough to test connectivity and basic search, but some fields may be limited depending on your entitlements.

Setup

cd mcp-server
npm install
cp .env.example .env

Edit .env and set your key:

SCOPUS_API_KEY=your_real_key_here

SCOPUS_API_KEY is read from the environment at startup (src/scopusClient.ts); it is never hard-coded and .env is gitignored so it can't be committed by accident.

Environment variables

Variable

Required

Default

Purpose

SCOPUS_API_KEY

Your Elsevier Scopus API key

SCOPUS_INST_TOKEN

optional

Institutional Token, if your key needs one for off-campus access

SCOPUS_API_BASE_URL

optional

https://api.elsevier.com

Override for testing against a proxy/mock

SCOPUS_REQUEST_TIMEOUT_MS

optional

15000

Per-request timeout

LOG_LEVEL

optional

info

debug | info | warn | error

PORT

HTTP mode only

3000

Port for httpServer.ts (most hosts set this for you)

HOST

HTTP mode only

0.0.0.0

Bind address for httpServer.ts

MCP_HTTP_AUTH_TOKEN

HTTP mode, strongly recommended

If set, /mcp requires Authorization: Bearer <token>

MCP_ALLOWED_HOSTS

HTTP mode, optional

Comma-separated Host header allowlist (DNS-rebinding protection)

Test connectivity first

Before wiring the server into any MCP client, verify the Scopus API key and network path work:

npm run test:connection

This runs test/test-connection.ts, which calls the same client functions the tools use — but directly, without speaking the MCP protocol — against the sample query "farmland abandonment Nepal". You can pass your own query instead:

npm run test:connection -- "AUTH(Smith J) AND TITLE(remote sensing)"

It walks through all three tools in sequence (search → details → abstract for the first result) and prints ✅/❌ per step, plus a full request/response log at logs/scopus-mcp.log (see Logging). Exit code is 0 only if every step succeeded.

Running locally (stdio, for a local 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 server

The server communicates over stdio, so running it directly in a terminal will just sit there waiting for JSON-RPC on stdin — that's expected. It's meant to be launched by an MCP client.

Connect it to Claude Code

claude mcp add scopus --env SCOPUS_API_KEY=your_real_key_here -- node /absolute/path/to/mcp-server/dist/index.js

(run npm run build first so dist/index.js exists), or add it to a project's .mcp.json:

{
  "mcpServers": {
    "scopus": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-server/dist/index.js"],
      "env": { "SCOPUS_API_KEY": "your_real_key_here" }
    }
  }
}

Connect it to Claude Desktop

Add the same block to claude_desktop_config.json (%APPDATA%\Claude\claude_desktop_config.json on Windows, ~/Library/Application Support/Claude/claude_desktop_config.json on macOS), then restart Claude Desktop:

{
  "mcpServers": {
    "scopus": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-server/dist/index.js"],
      "env": { "SCOPUS_API_KEY": "your_real_key_here" }
    }
  }
}

Response shape

search_scopus example (truncated):

{
  "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 adds keywords, subjectAreas, openAccess, and aggregationType on top of the same fields. get_article_abstract returns { scopusId, title, abstract, hasAbstract }.

Fields Scopus doesn't have for a given record come back as null (or [] for list fields, or hasAbstract: false) rather than being omitted — check for null/false before assuming a field is missing due to a bug.

Error handling

Every tool catches errors internally and returns isError: true with a structured JSON body instead of crashing the MCP connection:

{
  "error": true,
  "kind": "rate_limited",
  "message": "Scopus API rate limit exceeded (HTTP 429) for search_scopus(...). Retry after 30s.",
  "status": 429,
  "retryAfterSeconds": 30
}

kind is one of: unauthorized (bad/missing API key), rate_limited (HTTP 429), not_found (bad Scopus ID / HTTP 404), bad_request (empty query, malformed input), network_error (DNS/connection failure), timeout (exceeded SCOPUS_REQUEST_TIMEOUT_MS), or unknown. A search that succeeds but matches nothing is not an error — it returns totalResults: 0 and a human-readable message suggesting how to broaden the query.

Logging

All API calls and responses are logged for debugging:

  • Every request logs its URL (API key redacted) before it's sent.

  • Every response logs status code, elapsed time, and a 500-character body preview.

  • Logs go to stderr as single-line JSON (never stdout — stdout is reserved for the MCP protocol on the stdio transport) and are also appended to logs/scopus-mcp.log.

  • Set LOG_LEVEL=debug for more detail, or LOG_LEVEL=error to quiet things down.

Deploying to a remote/serverless platform (Render, Railway, etc.)

The stdio transport (src/index.ts) only works for MCP clients that can spawn a local process — it's not reachable over the network. To host this server remotely, use the Streamable HTTP entry point instead: src/httpServer.ts. It serves the same three tools at POST /mcp and adds a GET /healthz endpoint for the platform's health checks.

Neither Render nor Railway is truly "serverless" (no scale-to-zero cold starts mid-request) — both run this as a normal persistent Node process, which is what a stateful protocol like MCP needs. Treat "serverless platform" here as "managed Node hosting."

Render

  1. Push this repo (or just the mcp-server/ folder) to GitHub.

  2. In the Render dashboard: New → Web Service, connect the repo, set root directory to mcp-server if it's a subfolder of a larger repo.

  3. Build command: npm install && npm run build

  4. Start command: npm run start:http

  5. Under Environment, add:

    • SCOPUS_API_KEY = your key (mark it as a secret)

    • MCP_HTTP_AUTH_TOKEN = a long random string you generate (e.g. openssl rand -hex 32)

    • optionally MCP_ALLOWED_HOSTS = your Render hostname, e.g. scopus-mcp.onrender.com

  6. Render sets PORT automatically — httpServer.ts reads it, no action needed.

  7. Deploy. Health check path: /healthz.

Railway

  1. New Project → Deploy from GitHub repo, set the service root to mcp-server if needed.

  2. Railway auto-detects Node; if it doesn't run the right command, set:

    • Build command: npm install && npm run build

    • Start command: npm run start:http

  3. In Variables, add SCOPUS_API_KEY and MCP_HTTP_AUTH_TOKEN as above.

  4. Railway injects PORT automatically.

  5. Once deployed, your MCP endpoint is https://<your-app>.up.railway.app/mcp.

Connecting an MCP client to the hosted server

claude mcp add --transport http scopus https://<your-app>/mcp \
  --header "Authorization: Bearer <your MCP_HTTP_AUTH_TOKEN>"

Security notes for HTTP deployment

  • Always set MCP_HTTP_AUTH_TOKEN. Without it, anyone with the URL can call your tools and consume your Scopus API quota — the server logs a startup warning if it's unset.

  • The server binds DNS-rebinding protection automatically for localhost/127.0.0.1; for a real 0.0.0.0 deployment, set MCP_ALLOWED_HOSTS to your platform's hostname.

  • Rotate SCOPUS_API_KEY and MCP_HTTP_AUTH_TOKEN via your platform's secret manager, never by committing them to the repo.

  • Consider putting the platform's own rate limiting / a reverse-proxy in front for public deployments, on top of Elsevier's own per-key rate limits.

Troubleshooting

Symptom

Likely cause

SCOPUS_API_KEY is not set

.env missing/not loaded, or you're running in a shell that doesn't have it exported

kind: "unauthorized", HTTP 401/403

Invalid key, or key lacks Scopus Search entitlements, or missing SCOPUS_INST_TOKEN for off-campus access

kind: "rate_limited", HTTP 429

Elsevier's per-key rate/quota limit hit — back off and retry after retryAfterSeconds

kind: "not_found", HTTP 404

The scopusId doesn't exist or was mistyped

kind: "network_error" / "timeout"

No internet access from this machine/host, corporate proxy blocking api.elsevier.com, or SCOPUS_REQUEST_TIMEOUT_MS too low

Tool calls silently do nothing in a stdio client

Something wrote to stdout — check you haven't added a stray console.log; use logger (stderr) instead

License

MIT

F
license - not found
A
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Provides 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.
    5
    38
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to search and retrieve real academic papers from Scopus, preventing citation hallucination by providing accurate paper metadata, author info, and citation analysis.
    3
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI agents to search and retrieve academic papers, author profiles, and citation data from the Scopus database via MCP tools.
    7
    MIT

View all related MCP servers

Related MCP Connectors

  • Academic research MCP server for paper search, citation checks, graphs, and deep research.

  • Academic paper search, scientific literature, citation analysis, arXiv & semantic related-work.

  • Scholarly search: OpenAlex, Crossref, arXiv, OpenCitations and PubMed in one endpoint.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Pratik-Pou/scopus-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server