Scopus MCP Server
Provides tools to search Scopus for academic articles and retrieve detailed metadata, abstracts, citation counts, and DOI links for individual articles.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Scopus MCP Serverfind peer-reviewed articles on climate change adaptation"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 |
|
| Up to |
|
| Full metadata for one article: everything above plus author keywords, subject areas, open-access flag, aggregation type |
|
| Just the abstract text for one article, plus |
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 bysearch_scopus.Abstract Retrieval API (
GET /content/abstract/scopus_id/{id}) — used byget_article_detailsandget_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.jsonPrerequisites
Node.js 18 or later (uses the built-in global
fetch). Check withnode -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 .envEdit .env and set your key:
SCOPUS_API_KEY=your_real_key_hereSCOPUS_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 |
| ✅ | — | Your Elsevier Scopus API key |
| optional | — | Institutional Token, if your key needs one for off-campus access |
| optional |
| Override for testing against a proxy/mock |
| optional |
| Per-request timeout |
| optional |
|
|
| HTTP mode only |
| Port for |
| HTTP mode only |
| Bind address for |
| HTTP mode, strongly recommended | — | If set, |
| HTTP mode, optional | — | Comma-separated |
Test connectivity first
Before wiring the server into any MCP client, verify the Scopus API key and network path work:
npm run test:connectionThis 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 serverThe 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=debugfor more detail, orLOG_LEVEL=errorto 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
Push this repo (or just the
mcp-server/folder) to GitHub.In the Render dashboard: New → Web Service, connect the repo, set root directory to
mcp-serverif it's a subfolder of a larger repo.Build command:
npm install && npm run buildStart command:
npm run start:httpUnder 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
Render sets
PORTautomatically —httpServer.tsreads it, no action needed.Deploy. Health check path:
/healthz.
Railway
New Project → Deploy from GitHub repo, set the service root to
mcp-serverif needed.Railway auto-detects Node; if it doesn't run the right command, set:
Build command:
npm install && npm run buildStart command:
npm run start:http
In Variables, add
SCOPUS_API_KEYandMCP_HTTP_AUTH_TOKENas above.Railway injects
PORTautomatically.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 real0.0.0.0deployment, setMCP_ALLOWED_HOSTSto your platform's hostname.Rotate
SCOPUS_API_KEYandMCP_HTTP_AUTH_TOKENvia 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 |
|
|
| Invalid key, or key lacks Scopus Search entitlements, or missing |
| Elsevier's per-key rate/quota limit hit — back off and retry after |
| The |
| No internet access from this machine/host, corporate proxy blocking |
Tool calls silently do nothing in a stdio client | Something wrote to stdout — check you haven't added a stray |
License
MIT
Maintenance
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
- AlicenseAqualityDmaintenanceProvides 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.538MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to search and retrieve real academic papers from Scopus, preventing citation hallucination by providing accurate paper metadata, author info, and citation analysis.3MIT
- FlicenseAqualityDmaintenanceEnables searching and retrieving academic papers, authors, citations, and recommendations from Semantic Scholar via MCP.9
- AlicenseAqualityBmaintenanceEnables AI agents to search and retrieve academic papers, author profiles, and citation data from the Scopus database via MCP tools.7MIT
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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