Skip to main content
Glama
Scopus MCP Server

Scopus MCP Server

by Pratik-Pou

Scopus MCP Server

Elsevier Scopus API をラップする MCP サーバーで、MCP クライアント(Claude Desktop、Claude Code、その他の MCP ホスト)が査読済みの学術記事を検索・取得できるようにします。実際の査読済みソースに基づいた引用検証や文体分析に役立ちます。

Tools

Tool

Input

What it returns

search_scopus

query(著者、キーワード、タイトル、DOI)、オプションの count(1〜25、デフォルト10)

最大 count 件の記事:タイトル、著者、発行年、抄録(Scopus の検索結果に含まれる場合)、ソースタイトル、DOI、DOI URL、Scopus ID、被引用数

get_article_details

scopusId

1件の記事の完全なメタデータ:上記のすべてに加え、著者キーワード、主題分野、オープンアクセスフラグ、集約タイプ

get_article_abstract

scopusId

1件の記事の抄録テキストのみ。Scopus に抄録がない場合は hasAbstract: false を返します

すべてのレスポンスは構造化された JSON です(下記の レスポンス形式 を参照)。各ツールは、Scopus API が到達不能、レート制限、または不正な ID が指定された場合に例外を投げる代わりに、親しみやすい構造化エラーを返します(エラーハンドリング を参照)。

内部では、サーバーは2つの Elsevier API を呼び出します:

  • Scopus Search API(GET /content/search/scopus)— search_scopus で使用。

  • Abstract Retrieval API(GET /content/abstract/scopus_id/{id})— get_article_details と get_article_abstract で使用。Search API は完全な抄録、被引用数、キーワードを確実に返さないためです。

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 以降(組み込みのグローバル fetch を使用)。node -v で確認してください。

  • Scopus API キー。 Elsevier Developer Portal で無料キーを登録してください。Elsevier はフルテキスト/抄録へのアクセスを IP 範囲(機関購読)または Institutional Token で制限していることに注意してください。キーだけでも接続テストと基本的な検索には十分ですが、一部のフィールドは権限によって制限される場合があります。

Setup

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

.env を編集してキーを設定してください:

SCOPUS_API_KEY=your_real_key_here

SCOPUS_API_KEY は起動時に環境から読み取られます(src/scopusClient.ts)。ハードコードされることはなく、.env は gitignore されているため、誤ってコミットされることはありません。

Environment variables

Variable

Required

Default

Purpose

SCOPUS_API_KEY

✅

—

あなたの Elsevier Scopus API キー

SCOPUS_INST_TOKEN

任意

—

機関トークン。キーがキャンパス外アクセスに必要とする場合

SCOPUS_API_BASE_URL

任意

https://api.elsevier.com

プロキシ/モックに対するテスト用の上書き

SCOPUS_REQUEST_TIMEOUT_MS

任意

15000

リクエストごとのタイムアウト

LOG_LEVEL

任意

info

debug | info | warn | error

PORT

HTTP モードのみ

3000

httpServer.ts のポート(ほとんどのホストが自動設定)

HOST

HTTP モードのみ

0.0.0.0

httpServer.ts のバインドアドレス

MCP_HTTP_AUTH_TOKEN

HTTP モード、強く推奨

—

設定すると、/mcp は Authorization: Bearer <token> を要求します

MCP_ALLOWED_HOSTS

HTTP モード、任意

—

カンマ区切りの Host ヘッダー許可リスト(DNS リバインディング保護)

Test connectivity first

サーバーを MCP クライアントに接続する前に、Scopus API キーとネットワーク経路が機能することを確認してください:

npm run test:connection

これは test/test-connection.ts を実行し、ツールが使用するのと同じクライアント関数を、MCP プロトコルを介さずに直接、サンプルクエリ "farmland abandonment Nepal" に対して呼び出します。代わりに独自のクエリを渡すこともできます:

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

3つのツールすべてを順番に(検索 → 詳細 → 最初の結果の抄録)実行し、各ステップで ✅/❌ を表示します。また、logs/scopus-mcp.log に完全なリクエスト/レスポンスログを出力します(ロギング を参照)。終了コードが 0 になるのは、すべてのステップが成功した場合のみです。

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

サーバーは stdio で通信するため、ターミナルで直接実行すると、stdin で JSON-RPC を待ち続けるだけです。これは想定どおりです。MCP クライアントによって起動されることを意図しています。

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

(最初に npm run build を実行して dist/index.js を生成してください)、またはプロジェクトの .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

同じブロックを claude_desktop_config.json に追加します(Windows では %APPDATA%\Claude\claude_desktop_config.json、macOS では ~/Library/Application Support/Claude/claude_desktop_config.json)。その後、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 の例(省略):

{
  "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 は同じフィールドに加えて keywords、subjectAreas、openAccess、aggregationType を追加します。get_article_abstract は { scopusId, title, abstract, hasAbstract } を返します。

Scopus が特定のレコードに持っていないフィールドは、省略される代わりに null(リストフィールドの場合は []、または hasAbstract: false)として返されます。バグによる欠落と判断する前に、null/false を確認してください。

Error handling

各ツールはエラーを内部でキャッチし、MCP 接続をクラッシュさせる代わりに、構造化された JSON ボディとともに isError: true を返します:

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

kind は次のいずれかです:unauthorized(API キーが不正/欠落)、rate_limited(HTTP 429)、not_found(不正な Scopus ID / HTTP 404)、bad_request(空のクエリ、不正な入力)、network_error(DNS/接続失敗)、timeout(SCOPUS_REQUEST_TIMEOUT_MS を超過)、または unknown。成功したが一致するものがなかった検索はエラーではありません。totalResults: 0 と、クエリを広げる方法を提案する人間が読める message を返します。

Logging

デバッグ用にすべての API 呼び出しとレスポンスがログに記録されます:

  • 送信前に、各リクエストの URL(API キーは伏せ字)をログに記録します。

  • 各レスポンスのステータスコード、経過時間、500文字のボディプレビューをログに記録します。

  • ログは stderr に単一行の JSON として出力されます(stdout は決して使用しません。stdout は stdio トランスポートでの MCP プロトコル用に予約されています)。また、logs/scopus-mcp.log にも追記されます。

  • 詳細が必要な場合は LOG_LEVEL=debug を、静かにしたい場合は LOG_LEVEL=error を設定してください。

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

stdio トランスポート(src/index.ts)は、ローカルプロセスを起動できる MCP クライアントでのみ機能します。ネットワーク経由では到達できません。このサーバーをリモートでホストするには、代わりに Streamable HTTP エントリポイント(src/httpServer.ts)を使用してください。同じ3つのツールを POST /mcp で提供し、プラットフォームのヘルスチェック用に GET /healthz エンドポイントを追加します。

Render も Railway も真の「サーバーレス」ではありません(リクエスト途中のスケールゼロのコールドスタートはありません)。どちらも通常の永続的な Node プロセスとして実行されます。これは MCP のようなステートフルなプロトコルに必要なものです。ここでの「サーバーレスプラットフォーム」は「マネージド Node ホスティング」とお考えください。

Render

  1. このリポジトリ(または mcp-server/ フォルダのみ)を GitHub にプッシュします。

  2. Render ダッシュボードで:New → Web Service を選択し、リポジトリを接続し、大きなリポジトリのサブフォルダの場合は root directory を mcp-server に設定します。

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

  4. Start command: npm run start:http

  5. Environment で以下を追加します:

    • SCOPUS_API_KEY = あなたのキー(シークレットとしてマーク)

    • MCP_HTTP_AUTH_TOKEN = 生成した長いランダム文字列(例:openssl rand -hex 32)

    • オプションで MCP_ALLOWED_HOSTS = あなたの Render ホスト名(例:scopus-mcp.onrender.com)

  6. Render は PORT を自動設定します。httpServer.ts がそれを読み取るため、操作は不要です。

  7. デプロイします。ヘルスチェックパス:/healthz。

Railway

  1. New Project → Deploy from GitHub repo を選択し、必要に応じてサービスルートを mcp-server に設定します。

  2. Railway は Node を自動検出します。正しいコマンドが実行されない場合は、以下を設定します:

    • Build command: npm install && npm run build

    • Start command: npm run start:http

  3. Variables に、上記の SCOPUS_API_KEY と MCP_HTTP_AUTH_TOKEN を追加します。

  4. Railway は PORT を自動的に注入します。

  5. デプロイ後、MCP エンドポイントは 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

  • 常に MCP_HTTP_AUTH_TOKEN を設定してください。 これがないと、URL を知っている誰でもツールを呼び出して Scopus API クォータを消費できます。未設定の場合、サーバーは起動時に警告をログに記録します。

  • サーバーは localhost/127.0.0.1 に対して DNS リバインディング保護を自動的にバインドします。実際の 0.0.0.0 デプロイでは、MCP_ALLOWED_HOSTS をプラットフォームのホスト名に設定してください。

  • SCOPUS_API_KEY と MCP_HTTP_AUTH_TOKEN は、プラットフォームのシークレットマネージャーを介してローテーションしてください。リポジトリにコミットしてローテーションすることは絶対に避けてください。

  • パブリックデプロイでは、Elsevier のキーごとのレート制限に加えて、プラットフォーム独自のレート制限/リバースプロキシを前面に配置することを検討してください。

Troubleshooting

Symptom

Likely cause

SCOPUS_API_KEY is not set

.env が存在しない/読み込まれていない、またはエクスポートされていないシェルで実行している

kind: "unauthorized", HTTP 401/403

キーが無効、またはキーに Scopus Search の権限がない、またはキャンパス外アクセス用の SCOPUS_INST_TOKEN が不足している

kind: "rate_limited", HTTP 429

Elsevier のキーごとのレート/クォータ制限に達した — バックオフして retryAfterSeconds 後に再試行

kind: "not_found", HTTP 404

scopusId が存在しないか、入力ミス

kind: "network_error" / "timeout"

このマシン/ホストからインターネットにアクセスできない、企業プロキシが api.elsevier.com をブロックしている、または SCOPUS_REQUEST_TIMEOUT_MS が低すぎる

Tool calls silently do nothing in a stdio client

何かが stdout に書き込んだ — 余分な console.log を追加していないか確認してください。代わりに logger(stderr)を使用してください

License

MIT

Available Tools

3 tools
get_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).

NameRequiredDescriptionDefault
scopusIdYesThe Scopus ID of the article, e.g. "85123456789".

TDQS

A4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

NameRequiredDescriptionDefault
scopusIdYesThe Scopus ID of the article, e.g. "85123456789" (the "SCOPUS_ID:" prefix, if present, is stripped automatically).

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

NameRequiredDescriptionDefault
countNoNumber of results to return (default 10, max 25).
queryYesSearch 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

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

  1. 3 tool updatesv1.0.0
    • First observedget_article_abstract
    • First observedget_article_details
    • First observedsearch_scopus

TDQS

A4.2/5.0

Scored across 3 tools

Disambiguation4/5

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.

Naming Consistency5/5

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.

Tool Count4/5

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.

Completeness4/5

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

ActivityStale
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    F
    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
    88 PyPI
    50
    MIT
  • A
    license
    A
    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.
    15
    3
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI agents to search and retrieve academic papers, author profiles, and citation data from the Scopus database via MCP tools.
    7
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables searching Elsevier's Scopus database for scientific literature, retrieving abstracts and metadata, and exporting results in RIS or BibTeX format.
    15 PyPI
    1
    MIT