@djmima/pubmed-mcp 1.2.2 → 1.2.3

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/CHANGELOG.md CHANGED
@@ -1,77 +1,90 @@
1
- # 変更履歴
1
+ # Changelog
2
2
 
3
- このプロジェクトの主な変更を記録します。
4
- 書式は [Keep a Changelog](https://keepachangelog.com/ja/1.1.0/) に、バージョン番号は [セマンティック バージョニング](https://semver.org/lang/ja/) に従います。
3
+ **English** · [日本語](CHANGELOG_ja.md)
4
+
5
+ All notable changes to this project are recorded in this file.
6
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5
7
 
6
8
  ## [Unreleased]
7
9
 
10
+ ## [1.2.3] - 2026-11-07
11
+
12
+ ### Added
13
+
14
+ - Added an English changelog. `CHANGELOG.md` is now in English and `CHANGELOG_ja.md` in Japanese; both are included in the npm package.
15
+
16
+ ### Fixed
17
+
18
+ - The npm package now includes the Japanese README (`README_ja.md`), which was missing.
19
+
8
20
  ## [1.2.2] - 2026-11-06
9
21
 
10
- ### 変更
22
+ ### Changed
11
23
 
12
- - npm パッケージの説明に CLI を加えました。
24
+ - The npm package description now mentions the CLI.
13
25
 
14
26
  ## [1.2.1] - 2026-11-05
15
27
 
16
- ### 修正
28
+ ### Fixed
17
29
 
18
- - `search_articles`(CLI の `pubmed search`)で、NCBI の検索サーバーの障害時に `Cannot read properties of undefined (reading 'length')` で失敗していたのを、NCBI が返したエラーメッセージ(例: `Search is temporarily unavailable`)を返すようにしました。NCBI は障害時に HTTP 200 で ID の一覧のない応答を返すことがあり、これを検索結果として扱っていました。
30
+ - `search_articles` (`pubmed search` in the CLI) failed with `Cannot read properties of undefined (reading 'length')` when NCBI's search servers had an outage. It now returns the error message NCBI sent (for example, `Search is temporarily unavailable`). During outages NCBI can answer with HTTP 200 and no list of IDs, and this response was treated as a search result.
19
31
 
20
32
  ## [1.2.0] - 2026-11-04
21
33
 
22
- ### 追加
34
+ ### Added
23
35
 
24
- - CLI に `-v` / `--version` を追加しました。インストールされている `pubmed` のバージョンを表示します。
36
+ - Added `-v` / `--version` to the CLI. It prints the version of the installed `pubmed`.
25
37
 
26
- ### 修正
38
+ ### Fixed
27
39
 
28
- - MCP サーバーが `initialize` の応答(`serverInfo.version`)でバージョンを常に `1.0.0` と返していたのを、`package.json` のバージョンを返すようにしました。
40
+ - The MCP server always reported its version as `1.0.0` in the `initialize` response (`serverInfo.version`). It now reports the version in `package.json`.
29
41
 
30
42
  ## [1.1.0] - 2026-11-04
31
43
 
32
- ### 変更
44
+ ### Changed
33
45
 
34
- - **HTTP モードで `ALLOWED_SUBJECTS` を必須にしました。** 未設定または空のときは起動時に終了します。これまでは空のとき、認可サーバー(WorkOS AuthKit)で有効なトークンを取得できるユーザー全員が `/mcp` を使えました。
35
- - HTTP モードで、`/mcp` への GET と DELETE に 405 を返すようにしました。ステートレスなサーバーには GET で開く SSE ストリームに送るものがなく、開いたままのストリームがサーバーインスタンスと Cloud Run のリクエストを占有していました。
46
+ - **`ALLOWED_SUBJECTS` is now required in HTTP mode.** The server exits at startup if it is unset or empty. Previously, when it was empty, anyone who could get a valid token from the authorization server (WorkOS AuthKit) could use `/mcp`.
47
+ - In HTTP mode, GET and DELETE requests to `/mcp` now return 405. A stateless server has nothing to send on an SSE stream opened by GET, and open streams tied up server instances and Cloud Run requests.
36
48
 
37
- ### セキュリティ
49
+ ### Security
38
50
 
39
- - MCP サーバーが `.env` を起動時のカレントディレクトリから読み込んでいたのをやめ、パッケージ自身のルート(ソースからビルドした場合はリポジトリ直下)からだけ読み込むようにしました(CLI はもともとこの動作です)。MCP クライアントは開いているプロジェクトのディレクトリでサーバーを起動するため、そのプロジェクトの `.env` に `PORT` があると HTTP モードで起動し、`HTTPS_PROXY` と `NODE_TLS_REJECT_UNAUTHORIZED=0` があると NCBI への通信(API キーを含む)を第三者のプロキシが読み書きできました。
40
- - ID を受け取るツール(`get_article_metadata`、`find_related_articles`、`get_copyright_status`、`get_full_text_article`、`convert_article_ids`)で、1 つの値に 1 つの ID だけを受け付けるようにしました。NCBI はカンマを ID の区切りとして扱うため、`"1,2,3"` のような値で 1 回あたりの上限を超える件数を取得できました。上限のなかった `find_related_articles` の `pmids` も 200 件までにしました。
41
- - `lookup_article_by_citation` で、引用の各項目に含まれる `|` と改行を空白に置き換えるようにしました。どちらも ECitMatch の区切り文字なので、項目がずれたり別の引用として送られたりして、結果が別の引用に対応づけられるおそれがありました。
42
- - NCBI へのリクエストに 60 秒のタイムアウトを設けました。応答のない接続で、ツールの呼び出し(HTTP モードではクライアントのリクエスト)が止まったままになることがなくなります。
43
- - NCBI へのリクエストがリダイレクトされたときは、HTTPS で `*.ncbi.nlm.nih.gov` に向かうものだけをたどるようにしました。API キーはクエリ文字列に含まれ、リダイレクト先にも引き継がれます。
44
- - エラーメッセージの中の API キーは、NCBI が返した本文のどこに現れても伏せるようにしました。ネットワークエラーには、API キーを含む axios のエラーオブジェクトを付けないようにしました。
45
- - HTTP モードで、`exp` と `sub` のないアクセストークンを拒否するようにしました。
46
- - HTTP モードで、リクエスト本文の JSON をトークンの検証後に解析するようにしました。不正な形式や大きすぎる本文などのエラーには、スタックトレースを含む HTML ではなく JSON を返し、`X-Powered-By` ヘッダーも送らないようにしました。Docker イメージでは `NODE_ENV=production` を設定し、依存パッケージのインストールスクリプトを実行しないようにしました。
47
- - `@modelcontextprotocol/sdk`、`axios`、`express` の最低バージョンを、既知の脆弱性の修正を含むバージョンに上げました。
48
- - GitHub Actions のアクションをコミット SHA で固定し、`actions/checkout` が認証情報を `.git` に残さないようにしました。
51
+ - The MCP server no longer loads `.env` from the current directory at startup. It loads it only from the package's own root (the repository root when built from source), as the CLI already did. MCP clients start the server in the directory of the open project, so a `PORT` in that project's `.env` started the server in HTTP mode, and `HTTPS_PROXY` with `NODE_TLS_REJECT_UNAUTHORIZED=0` let a third-party proxy read and modify traffic to NCBI, including the API key.
52
+ - Tools that take IDs (`get_article_metadata`, `find_related_articles`, `get_copyright_status`, `get_full_text_article`, `convert_article_ids`) now accept only one ID per value. NCBI treats commas as ID separators, so a value such as `"1,2,3"` could fetch more records than the per-call limit allows. `pmids` in `find_related_articles`, which had no limit, is now capped at 200.
53
+ - `lookup_article_by_citation` now replaces `|` and line breaks in each citation field with spaces. Both are ECitMatch delimiters, so they could shift fields or split a citation in two, and results could be matched to a different citation.
54
+ - Requests to NCBI now time out after 60 seconds, so a connection that never answers no longer leaves a tool call (in HTTP mode, the client's request) hanging.
55
+ - When a request to NCBI is redirected, only redirects over HTTPS to `*.ncbi.nlm.nih.gov` are followed. The API key is in the query string and is carried over to the redirect target.
56
+ - The API key is now masked in error messages wherever it appears in the body NCBI returned. Network errors no longer carry the axios error object, which contains the API key.
57
+ - In HTTP mode, access tokens without `exp` or `sub` are rejected.
58
+ - In HTTP mode, the JSON request body is parsed after the token is verified. Errors such as malformed or oversized bodies return JSON instead of HTML with a stack trace, and the `X-Powered-By` header is no longer sent. The Docker image sets `NODE_ENV=production` and does not run install scripts of dependencies.
59
+ - Raised the minimum versions of `@modelcontextprotocol/sdk`, `axios`, and `express` to releases that fix known vulnerabilities.
60
+ - Pinned GitHub Actions to commit SHAs, and `actions/checkout` no longer leaves credentials in `.git`.
49
61
 
50
62
  ## [1.0.2] - 2026-11-03
51
63
 
52
- ### 変更
64
+ ### Changed
53
65
 
54
- - README を英語にしました。日本語版は `README_ja.md` に移し、両方の冒頭に npm のバージョン・パッケージサイズ・ライセンス・Node.js のバージョン・CI のバッジと、言語の切り替えリンクを付けました。
66
+ - The README is now in English. The Japanese version moved to `README_ja.md`. Both start with badges for the npm version, package size, license, Node.js version, and CI, plus links to switch languages.
55
67
 
56
68
  ## [1.0.1] - 2026-11-01
57
69
 
58
- ### 変更
70
+ ### Changed
59
71
 
60
- - NCBI へのリクエストに付ける連絡先(`email` パラメータ)を、ダミーの `pubmed-mcp@example.com` から開発者の転送用アドレスに変更しました。NCBI の E-utilities 利用ガイドラインは、`email` に利用者ではなく開発者のアドレスを使うよう求めています。
61
- - README の「ライセンス」の節で、NCBI の免責事項・著作権表示へのリンクをはっきり示しました。
72
+ - Changed the contact address sent to NCBI (the `email` parameter) from the placeholder `pubmed-mcp@example.com` to the developer's forwarding address. NCBI's E-utilities usage guidelines ask for the developer's address in `email`, not the end user's.
73
+ - The "License" section of the README now links clearly to NCBI's disclaimer and copyright notice.
62
74
 
63
75
  ## [1.0.0] - 2026-10-29
64
76
 
65
- npm パッケージ [`@djmima/pubmed-mcp`](https://www.npmjs.com/package/@djmima/pubmed-mcp) として最初に公開した版です。
77
+ The first release, published to npm as [`@djmima/pubmed-mcp`](https://www.npmjs.com/package/@djmima/pubmed-mcp).
66
78
 
67
- ### 追加
79
+ ### Added
68
80
 
69
- - 7 つの MCP ツール: `search_articles`、`get_article_metadata`、`find_related_articles`、`lookup_article_by_citation`、`convert_article_ids`、`get_full_text_article`、`get_copyright_status`
70
- - stdio と、OAuth で保護した Streamable HTTP の 2 つのトランスポート(`PORT` を設定すると HTTP モード)
71
- - 同じツールをシェルから実行する `pubmed` CLI と、エージェント向けの Skill(`skills/pubmed-cli`)
81
+ - Seven MCP tools: `search_articles`, `get_article_metadata`, `find_related_articles`, `lookup_article_by_citation`, `convert_article_ids`, `get_full_text_article`, `get_copyright_status`
82
+ - Two transports: stdio, and Streamable HTTP protected by OAuth (HTTP mode when `PORT` is set)
83
+ - The `pubmed` CLI, which runs the same tools from the shell, and an agent skill (`skills/pubmed-cli`)
72
84
  - MIT License
73
85
 
74
- [Unreleased]: https://github.com/DJMIMA/PubMed_MCP/compare/v1.2.2...HEAD
86
+ [Unreleased]: https://github.com/DJMIMA/PubMed_MCP/compare/v1.2.3...HEAD
87
+ [1.2.3]: https://github.com/DJMIMA/PubMed_MCP/compare/v1.2.2...v1.2.3
75
88
  [1.2.2]: https://github.com/DJMIMA/PubMed_MCP/compare/v1.2.1...v1.2.2
76
89
  [1.2.1]: https://github.com/DJMIMA/PubMed_MCP/compare/v1.2.0...v1.2.1
77
90
  [1.2.0]: https://github.com/DJMIMA/PubMed_MCP/compare/v1.1.0...v1.2.0
@@ -0,0 +1,94 @@
1
+ # 変更履歴
2
+
3
+ [English](CHANGELOG.md) · **日本語**
4
+
5
+ このプロジェクトの主な変更を記録します。
6
+ 書式は [Keep a Changelog](https://keepachangelog.com/ja/1.1.0/) に、バージョン番号は [セマンティック バージョニング](https://semver.org/lang/ja/) に従います。
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [1.2.3] - 2026-11-07
11
+
12
+ ### 追加
13
+
14
+ - 変更履歴の英語版を追加しました。`CHANGELOG.md` が英語版、`CHANGELOG_ja.md` が日本語版です。どちらも npm パッケージに含めます。
15
+
16
+ ### 修正
17
+
18
+ - npm パッケージに日本語版の README(`README_ja.md`)が含まれていなかったのを、含めるようにしました。
19
+
20
+ ## [1.2.2] - 2026-11-06
21
+
22
+ ### 変更
23
+
24
+ - npm パッケージの説明に CLI を加えました。
25
+
26
+ ## [1.2.1] - 2026-11-05
27
+
28
+ ### 修正
29
+
30
+ - `search_articles`(CLI の `pubmed search`)で、NCBI の検索サーバーの障害時に `Cannot read properties of undefined (reading 'length')` で失敗していたのを、NCBI が返したエラーメッセージ(例: `Search is temporarily unavailable`)を返すようにしました。NCBI は障害時に HTTP 200 で ID の一覧のない応答を返すことがあり、これを検索結果として扱っていました。
31
+
32
+ ## [1.2.0] - 2026-11-04
33
+
34
+ ### 追加
35
+
36
+ - CLI に `-v` / `--version` を追加しました。インストールされている `pubmed` のバージョンを表示します。
37
+
38
+ ### 修正
39
+
40
+ - MCP サーバーが `initialize` の応答(`serverInfo.version`)でバージョンを常に `1.0.0` と返していたのを、`package.json` のバージョンを返すようにしました。
41
+
42
+ ## [1.1.0] - 2026-11-04
43
+
44
+ ### 変更
45
+
46
+ - **HTTP モードで `ALLOWED_SUBJECTS` を必須にしました。** 未設定または空のときは起動時に終了します。これまでは空のとき、認可サーバー(WorkOS AuthKit)で有効なトークンを取得できるユーザー全員が `/mcp` を使えました。
47
+ - HTTP モードで、`/mcp` への GET と DELETE に 405 を返すようにしました。ステートレスなサーバーには GET で開く SSE ストリームに送るものがなく、開いたままのストリームがサーバーインスタンスと Cloud Run のリクエストを占有していました。
48
+
49
+ ### セキュリティ
50
+
51
+ - MCP サーバーが `.env` を起動時のカレントディレクトリから読み込んでいたのをやめ、パッケージ自身のルート(ソースからビルドした場合はリポジトリ直下)からだけ読み込むようにしました(CLI はもともとこの動作です)。MCP クライアントは開いているプロジェクトのディレクトリでサーバーを起動するため、そのプロジェクトの `.env` に `PORT` があると HTTP モードで起動し、`HTTPS_PROXY` と `NODE_TLS_REJECT_UNAUTHORIZED=0` があると NCBI への通信(API キーを含む)を第三者のプロキシが読み書きできました。
52
+ - ID を受け取るツール(`get_article_metadata`、`find_related_articles`、`get_copyright_status`、`get_full_text_article`、`convert_article_ids`)で、1 つの値に 1 つの ID だけを受け付けるようにしました。NCBI はカンマを ID の区切りとして扱うため、`"1,2,3"` のような値で 1 回あたりの上限を超える件数を取得できました。上限のなかった `find_related_articles` の `pmids` も 200 件までにしました。
53
+ - `lookup_article_by_citation` で、引用の各項目に含まれる `|` と改行を空白に置き換えるようにしました。どちらも ECitMatch の区切り文字なので、項目がずれたり別の引用として送られたりして、結果が別の引用に対応づけられるおそれがありました。
54
+ - NCBI へのリクエストに 60 秒のタイムアウトを設けました。応答のない接続で、ツールの呼び出し(HTTP モードではクライアントのリクエスト)が止まったままになることがなくなります。
55
+ - NCBI へのリクエストがリダイレクトされたときは、HTTPS で `*.ncbi.nlm.nih.gov` に向かうものだけをたどるようにしました。API キーはクエリ文字列に含まれ、リダイレクト先にも引き継がれます。
56
+ - エラーメッセージの中の API キーは、NCBI が返した本文のどこに現れても伏せるようにしました。ネットワークエラーには、API キーを含む axios のエラーオブジェクトを付けないようにしました。
57
+ - HTTP モードで、`exp` と `sub` のないアクセストークンを拒否するようにしました。
58
+ - HTTP モードで、リクエスト本文の JSON をトークンの検証後に解析するようにしました。不正な形式や大きすぎる本文などのエラーには、スタックトレースを含む HTML ではなく JSON を返し、`X-Powered-By` ヘッダーも送らないようにしました。Docker イメージでは `NODE_ENV=production` を設定し、依存パッケージのインストールスクリプトを実行しないようにしました。
59
+ - `@modelcontextprotocol/sdk`、`axios`、`express` の最低バージョンを、既知の脆弱性の修正を含むバージョンに上げました。
60
+ - GitHub Actions のアクションをコミット SHA で固定し、`actions/checkout` が認証情報を `.git` に残さないようにしました。
61
+
62
+ ## [1.0.2] - 2026-11-03
63
+
64
+ ### 変更
65
+
66
+ - README を英語にしました。日本語版は `README_ja.md` に移し、両方の冒頭に npm のバージョン・パッケージサイズ・ライセンス・Node.js のバージョン・CI のバッジと、言語の切り替えリンクを付けました。
67
+
68
+ ## [1.0.1] - 2026-11-01
69
+
70
+ ### 変更
71
+
72
+ - NCBI へのリクエストに付ける連絡先(`email` パラメータ)を、ダミーの `pubmed-mcp@example.com` から開発者の転送用アドレスに変更しました。NCBI の E-utilities 利用ガイドラインは、`email` に利用者ではなく開発者のアドレスを使うよう求めています。
73
+ - README の「ライセンス」の節で、NCBI の免責事項・著作権表示へのリンクをはっきり示しました。
74
+
75
+ ## [1.0.0] - 2026-10-29
76
+
77
+ npm パッケージ [`@djmima/pubmed-mcp`](https://www.npmjs.com/package/@djmima/pubmed-mcp) として最初に公開した版です。
78
+
79
+ ### 追加
80
+
81
+ - 7 つの MCP ツール: `search_articles`、`get_article_metadata`、`find_related_articles`、`lookup_article_by_citation`、`convert_article_ids`、`get_full_text_article`、`get_copyright_status`
82
+ - stdio と、OAuth で保護した Streamable HTTP の 2 つのトランスポート(`PORT` を設定すると HTTP モード)
83
+ - 同じツールをシェルから実行する `pubmed` CLI と、エージェント向けの Skill(`skills/pubmed-cli`)
84
+ - MIT License
85
+
86
+ [Unreleased]: https://github.com/DJMIMA/PubMed_MCP/compare/v1.2.3...HEAD
87
+ [1.2.3]: https://github.com/DJMIMA/PubMed_MCP/compare/v1.2.2...v1.2.3
88
+ [1.2.2]: https://github.com/DJMIMA/PubMed_MCP/compare/v1.2.1...v1.2.2
89
+ [1.2.1]: https://github.com/DJMIMA/PubMed_MCP/compare/v1.2.0...v1.2.1
90
+ [1.2.0]: https://github.com/DJMIMA/PubMed_MCP/compare/v1.1.0...v1.2.0
91
+ [1.1.0]: https://github.com/DJMIMA/PubMed_MCP/compare/v1.0.2...v1.1.0
92
+ [1.0.2]: https://github.com/DJMIMA/PubMed_MCP/compare/v1.0.1...v1.0.2
93
+ [1.0.1]: https://github.com/DJMIMA/PubMed_MCP/compare/v1.0.0...v1.0.1
94
+ [1.0.0]: https://github.com/DJMIMA/PubMed_MCP/releases/tag/v1.0.0
package/README.md CHANGED
@@ -766,12 +766,12 @@ Publishing a Release on GitHub makes [`.github/workflows/release.yml`](.github/w
766
766
  The new version is not published until a maintainer approves it on npmjs.com with 2FA. This way, a compromised workflow or dependency cannot publish on its own.
767
767
  Because the workflow uses npm [Trusted Publishing](https://docs.npmjs.com/trusted-publishers/) (OIDC), no npm token is stored in the repository.
768
768
 
769
- PRs that make changes add them to `[Unreleased]` in [`CHANGELOG.md`](CHANGELOG.md). To release:
769
+ PRs that make changes add the same entry to `[Unreleased]` in both [`CHANGELOG.md`](CHANGELOG.md) (English) and [`CHANGELOG_ja.md`](CHANGELOG_ja.md) (Japanese). To release:
770
770
 
771
771
  1. On a release branch, run `npm version patch --no-git-tag-version` (or `minor` / `major`) to bump the version in `package.json`
772
772
  (GitHub adds the tag in step 3, so don't tag here)
773
- 2. Move the contents of `[Unreleased]` in `CHANGELOG.md` under a heading for the new version (for example, `## [1.0.1] - 2026-11-01`), update the comparison links at the end, then open a PR and merge it into main
774
- 3. On GitHub, publish a Release targeting main with the tag `v<version>` (for example, `v1.0.1`). Paste the corresponding part of `CHANGELOG.md` into the release notes
773
+ 2. In both `CHANGELOG.md` and `CHANGELOG_ja.md`, move the contents of `[Unreleased]` under a heading for the new version (for example, `## [1.0.1] - 2026-11-01`), update the comparison links at the end, then open a PR and merge it into main
774
+ 3. On GitHub, publish a Release targeting main with the tag `v<version>` (for example, `v1.0.1`). Paste the corresponding part of `CHANGELOG.md` (English) into the release notes
775
775
  4. The workflow checks that the tag matches the version in `package.json`, runs typecheck, lint, tests, and build, and then stages the publish
776
776
  5. Review it on the **Staged Packages** tab of the package page on npmjs.com and click **Approve** (2FA required). You can also approve from the CLI with `npm stage approve <stage-id>`
777
777
 
package/README_ja.md ADDED
@@ -0,0 +1,827 @@
1
+ <h1 align="center">PubMed MCP/CLI</h1>
2
+
3
+ <p align="center"><strong>AI アシスタントから、医学・生命科学の文献を検索して読む。</strong></p>
4
+
5
+ <p align="center">PubMed と PubMed Central を、Claude・Codex・シェルから。</p>
6
+
7
+ <p align="center">
8
+ <a href="#tools">ツール</a> ·
9
+ <a href="#インストール"><strong>インストール</strong></a> ·
10
+ <a href="#使い方">使い方</a> ·
11
+ <a href="#cli">CLI</a> ·
12
+ <a href="#google-cloud-run-へのデプロイ">デプロイ</a> ·
13
+ <a href="CHANGELOG_ja.md">変更履歴</a>
14
+ </p>
15
+
16
+ <p align="center">
17
+ <a href="https://www.npmjs.com/package/@djmima/pubmed-mcp"><img alt="npm version" src="https://img.shields.io/npm/v/@djmima/pubmed-mcp?label=npm&color=cb3837"></a>
18
+ <a href="https://packagephobia.com/result?p=@djmima/pubmed-mcp"><img alt="npm unpacked size" src="https://img.shields.io/npm/unpacked-size/@djmima/pubmed-mcp"></a>
19
+ <a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-blue"></a>
20
+ <a href="https://nodejs.org/"><img alt="Node.js version" src="https://img.shields.io/node/v/@djmima/pubmed-mcp"></a>
21
+ <a href="https://github.com/DJMIMA/PubMed_MCP/actions/workflows/ci.yml"><img alt="CI status" src="https://github.com/DJMIMA/PubMed_MCP/actions/workflows/ci.yml/badge.svg"></a>
22
+ </p>
23
+
24
+ <p align="center"><a href="README.md">English</a> · <strong>日本語</strong></p>
25
+
26
+ **無料でオープンソース。自分のパソコンで動かせます。** NCBI E-utilities API を通じて、Claude や Codex などの LLM クライアントから [PubMed](https://pubmed.ncbi.nlm.nih.gov/) と [PubMed Central(PMC)](https://www.ncbi.nlm.nih.gov/pmc/) を扱えるようにする [MCP(Model Context Protocol)](https://modelcontextprotocol.io/) サーバーとコマンドラインツールです。アカウントは不要で、NCBI API キーも任意です。
27
+
28
+ ## Tools
29
+
30
+ | Tool | 説明 |
31
+ |------|------|
32
+ | `search_articles` | PubMed構文またはキーワードで文献を検索。ATM診断・フィールド制限・日付フィルタ・ソート・ページネーション対応 |
33
+ | `get_article_metadata` | PMIDを指定してタイトル・抄録・著者・MeSH語・キーワードなどを取得 |
34
+ | `find_related_articles` | ELinkを使って関連文献や他DBへのリンクを検索 |
35
+ | `lookup_article_by_citation` | 雑誌名・年・巻・筆頭著者などの引用情報からPMIDを逆引き |
36
+ | `convert_article_ids` | PMID・PMCID・DOI を相互変換 |
37
+ | `get_full_text_article` | PMC Open Access記事の本文全文をプレーンテキストで取得 |
38
+ | `get_copyright_status` | 全文取得の可否(`has_full_text`)・ライセンス・著作権表示・OAステータスを確認。PMCのEFetchメタデータを使用(旧PMC OA Web Serviceは2026-08-25に廃止) |
39
+
40
+ 同じツールは、シェルから `pubmed` コマンドとしても実行できます(「[CLI](#cli)」を参照)。
41
+
42
+ ---
43
+
44
+ ## `search_articles` の ATM 診断とフィールド制限
45
+
46
+ PubMed はタグのない検索語に Automatic Term Mapping(ATM)を適用します。ATM は MeSH、
47
+ 雑誌名、著者名などへ検索語を展開するため、意図しない変換や、引用句が句インデックスに
48
+ 存在しないことによる検索のフォールバックが起こる場合があります。
49
+
50
+ `search_articles` は次の任意の `field` 値を受け取り、クエリ内のタグなし語をすべてその
51
+ フィールドへ制限します。
52
+
53
+ - `title`
54
+ - `tiab`(Title/Abstract)
55
+ - `mesh`
56
+ - `author`
57
+ - `journal`
58
+ - `affiliation`
59
+
60
+ クエリ内に明示的なフィールドタグがある語では、そのタグが `field` より優先されます。
61
+ `field` を省略した場合の検索動作は従来どおりです。`all` は ATM を無効化しないため、
62
+ 公開パラメータには含めていません。
63
+
64
+ レスポンスには、NCBI ESearch の診断を正規化した次のフィールドが常に含まれます。
65
+
66
+ ```json
67
+ {
68
+ "warnings": {
69
+ "phrases_ignored": [],
70
+ "quoted_phrases_not_found": [],
71
+ "output_messages": []
72
+ },
73
+ "errors": {
74
+ "phrases_not_found": [],
75
+ "fields_not_found": []
76
+ }
77
+ }
78
+ ```
79
+
80
+ この `errors` は NCBI ESearch が返す検索語・フィールドの診断であり、通信エラーや
81
+ MCP ツール自体の実行エラーとは別の情報です。
82
+ これらのキーは診断がない場合も空配列として返ります。低件数や0件を「文献なし」と判断する
83
+ 前に、`query_translation`、`warnings`、`errors` を確認してください。複数語を同一フィールドで
84
+ 確実に検索する場合は各語へタグを付け、引用句が句インデックスにない場合の隣接検索には
85
+ `[ti:~0]` または `[tiab:~0]` を使用できます。
86
+
87
+ ---
88
+
89
+ ## 必要環境
90
+
91
+ - **Node.js** 22 以上(`npx` と `npm` は Node.js に同梱されています)
92
+ - **NCBI API キー**(任意。なくても動作するが、レートリミットが 3 req/s に制限される)
93
+ - **jq**(任意。[CLI](#cli) の出力から必要なフィールドを取り出すのに使う)
94
+
95
+ ---
96
+
97
+ ## インストール
98
+
99
+ npm パッケージ [`@djmima/pubmed-mcp`](https://www.npmjs.com/package/@djmima/pubmed-mcp) として公開しています。
100
+
101
+ - **MCP サーバーとして使う場合**は、インストールは不要です。MCP クライアントの設定に `npx -y @djmima/pubmed-mcp@latest` を書くと、
102
+ 起動時に最新版が自動でダウンロードされます(後述の「[使い方](#使い方)」を参照)。
103
+ - **[CLI](#cli) を使う場合**は、グローバルにインストールします。
104
+
105
+ ```bash
106
+ npm install -g @djmima/pubmed-mcp
107
+ ```
108
+
109
+ `pubmed` と `pubmed-mcp` の 2 つのコマンドが登録されます。更新は `npm update -g @djmima/pubmed-mcp`、
110
+ 削除は `npm rm -g @djmima/pubmed-mcp` です。
111
+
112
+ ソースコードを修正して使いたい場合は「[ソースからビルドする](#ソースからビルドする)」を参照してください。
113
+
114
+ ### NCBI API キーの設定(推奨)
115
+
116
+ APIキーを取得するとレートリミットが 3 → 8 req/s に向上します。
117
+
118
+ 1. [NCBI アカウント](https://www.ncbi.nlm.nih.gov/account/)を作成してAPIキーを発行
119
+ 2. 環境変数 `NCBI_API_KEY` にセット(後述のクライアント別設定を参照)
120
+
121
+ MCP クライアントからローカルで起動する場合は、クライアント設定の `env` でキーを渡してください。
122
+ サーバーが `.env` を読み込むのはパッケージ自身のルート([ソースからビルドした](#ソースからビルドする)場合はリポジトリ直下)だけで、
123
+ 起動時のカレントディレクトリからは読み込みません。そのため、MCP クライアントで開いているプロジェクトの `.env` で設定が変わることはありません。
124
+
125
+ APIキーは、このサーバーを運用する個人または組織が所有・管理するものを設定してください。
126
+ リポジトリにはAPIキーを同梱しません。レスポンス中にNCBI APIの `echo` が含まれる場合も、
127
+ `api_key` 値は `<redacted>` にマスクされます。
128
+
129
+ クライアント側ではプロセスごとに簡易レートリミッターをかけています。APIキーなしでは最大
130
+ 3 req/s、APIキーありではNCBI上限の10 req/sに対して余裕を持たせた8 req/sで送信します(NCBIは到着時刻で数えるため、回線の揺らぎ分の余裕)。HTTP 429 が返った場合は最大2回まで待機して再試行します。
131
+ 同一プロセス内の並列呼び出しは自動的に間隔調整されますが、Cloud Runなどで複数インスタンスを
132
+ 動かす場合は全インスタンス合算でNCBIの上限を超えないようにしてください。目安として、単一
133
+ インスタンスではAPIキーありで8並列程度、APIキーなしで2並列程度までに抑える運用を推奨します。
134
+
135
+ ---
136
+
137
+ ## 使い方
138
+
139
+ ### Claude Desktop(ローカル・stdio)
140
+
141
+ `claude_desktop_config.json` の `mcpServers` にサーバーを追加します。
142
+
143
+ **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
144
+ **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
145
+
146
+ ```json
147
+ {
148
+ "mcpServers": {
149
+ "pubmed-local": {
150
+ "command": "npx",
151
+ "args": ["-y", "@djmima/pubmed-mcp@latest"],
152
+ "env": {
153
+ "NCBI_API_KEY": "your_api_key_here"
154
+ }
155
+ }
156
+ }
157
+ }
158
+ ```
159
+
160
+ - 他のサーバーが登録済みの場合は、`mcpServers` の中に `"pubmed-local": { ... }` を並べて追加します(前の項目との間のカンマを忘れずに)。
161
+ - Windows で起動しない場合は、`"command": "cmd"`、`"args": ["/c", "npx", "-y", "@djmima/pubmed-mcp@latest"]` に変えてください。
162
+ - `@latest` を付けると、起動のたびに npm に最新版があるか確認します。版を固定したい場合は `@djmima/pubmed-mcp@1.0.0` のように書きます。
163
+ - サーバー名を `pubmed-local` にしておくと、リモート版(`pubmed-remote`)や同じツール名を持つ他の PubMed コネクタと区別しやすくなります。
164
+
165
+ 設定後、Claude Desktop を完全に終了してから再起動してください。ウィンドウを閉じただけではアプリが常駐したままになることがあります(Windows ではタスクトレイのアイコンから終了できます)。
166
+ この設定のサーバーは、Claude Desktop の Code タブで開いたセッションにも読み込まれます。
167
+
168
+ 起動しない場合は、ログ(Windows: `%APPDATA%\Claude\logs\mcp-server-pubmed-local.log`、macOS: `~/Library/Logs/Claude/mcp-server-pubmed-local.log`)を確認してください。
169
+
170
+ ---
171
+
172
+ ### Claude Code(ローカル・stdio)
173
+
174
+ `claude mcp add` で登録します。`--scope user` を付けるとすべてのプロジェクトで使えます。
175
+
176
+ ```bash
177
+ claude mcp add --env NCBI_API_KEY=your_api_key_here --transport stdio --scope user pubmed-local -- npx -y @djmima/pubmed-mcp@latest
178
+ ```
179
+
180
+ - `--` より後ろは、サーバーの起動コマンドとしてそのまま渡されます。
181
+ - Windows(WSL ではない環境)では、`--` の後ろを `cmd /c npx -y @djmima/pubmed-mcp@latest` にしてください。
182
+ - `--env` の直後にサーバー名を書くと `KEY=value` の続きとして解釈されてエラーになるため、間に別のオプション(ここでは `--transport stdio`)を挟みます。
183
+ - 登録内容は `~/.claude.json`(user / local スコープ)またはプロジェクト直下の `.mcp.json`(project スコープ)に保存されます。`~/.claude/settings.json` に `mcpServers` を書いても読み込まれません。
184
+ - Claude Desktop の Code タブだけで使う場合は、上記の `claude_desktop_config.json` への登録で読み込まれるため、この手順は不要です。
185
+
186
+ 登録後、`claude mcp list` または Claude Code 内の `/mcp` で接続状態を確認できます。
187
+
188
+ ---
189
+
190
+ ### Codex(ローカル・stdio)
191
+
192
+ Codex のデスクトップアプリ・CLI・IDE 拡張は、同じ設定ファイル `~/.codex/config.toml`(Windows: `%USERPROFILE%\.codex\config.toml`)を共有します。次のブロックを追記してください。
193
+
194
+ ```toml
195
+ [mcp_servers.pubmed-local]
196
+ command = "npx"
197
+ args = ["-y", "@djmima/pubmed-mcp@latest"]
198
+
199
+ [mcp_servers.pubmed-local.env]
200
+ NCBI_API_KEY = "your_api_key_here"
201
+ ```
202
+
203
+ - Windows で起動しない場合は、`command = "cmd"`、`args = ["/c", "npx", "-y", "@djmima/pubmed-mcp@latest"]` に変えてください。
204
+ - Codex は OS の環境変数をそのまま MCP サーバーへ渡しません。API キーは上のように `env` に書くか、`[mcp_servers.pubmed-local]` に `env_vars = ["NCBI_API_KEY"]` を追加して Codex 側の環境変数から転送してください。
205
+
206
+ CLI からは `codex mcp add` でも登録できます。
207
+
208
+ ```bash
209
+ codex mcp add pubmed-local --env NCBI_API_KEY=your_api_key_here -- npx -y @djmima/pubmed-mcp@latest
210
+ ```
211
+
212
+ 設定後は Codex を再起動してください(デスクトップアプリでは **Settings → MCP servers** の **Restart**)。同じ画面の **Add server** から登録することもできます。CLI と IDE 拡張では `/mcp` で接続中のサーバーを確認できます。
213
+
214
+ ---
215
+
216
+ ### Anthropic API(プログラムからの利用)
217
+
218
+ ```python
219
+ import os
220
+
221
+ import anthropic
222
+
223
+ client = anthropic.Anthropic()
224
+ response = client.beta.messages.create(
225
+ model="claude-opus-5",
226
+ max_tokens=16000,
227
+ messages=[{
228
+ "role": "user",
229
+ "content": "Find recent papers on CRISPR gene editing in cancer treatment"
230
+ }],
231
+ mcp_servers=[{
232
+ "type": "url",
233
+ "url": "https://pubmed-mcp-PROJECT_NUMBER.asia-northeast1.run.app/mcp",
234
+ "name": "pubmed",
235
+ # /mcp は OAuth で保護されているため、アクセストークンが必要
236
+ "authorization_token": os.environ["PUBMED_MCP_TOKEN"],
237
+ }],
238
+ tools=[{"type": "mcp_toolset", "mcp_server_name": "pubmed"}],
239
+ betas=["mcp-client-2025-11-20"]
240
+ )
241
+ ```
242
+
243
+ Anthropic API の MCP コネクタは HTTP で公開されたリモートサーバーにしか接続できないため、先に Cloud Run へデプロイしておく必要があります。
244
+ デプロイ方法は後述の「[Google Cloud Run へのデプロイ](#google-cloud-run-へのデプロイ)」、アクセストークンの取得方法は「[クライアント別の接続設定](#クライアント別の接続設定)」を参照してください。
245
+
246
+ ---
247
+
248
+ ### ソースからビルドする
249
+
250
+ ソースコードを修正して使う場合は、リポジトリをクローンしてビルドします。
251
+
252
+ ```bash
253
+ git clone https://github.com/DJMIMA/PubMed_MCP.git
254
+ cd PubMed_MCP
255
+ npm install
256
+ npm run build
257
+ ```
258
+
259
+ MCP クライアントの設定では、`npx -y @djmima/pubmed-mcp@latest` の代わりに `node /absolute/path/to/PubMed_MCP/dist/index.js` を指定します
260
+ (Windows のパスは `C:/path/to/PubMed_MCP/dist/index.js` のようにスラッシュ区切りで書きます)。
261
+ CLI として使う場合は、続けて `npm link` を実行すると `pubmed` と `pubmed-mcp` コマンドが登録されます(解除は `npm rm -g @djmima/pubmed-mcp`)。
262
+
263
+ `dist/` はリポジトリに含まれません。`git pull` でソースを更新したら `npm run build` を再実行し、
264
+ MCP クライアントを再起動してください。起動中のサーバーは再起動するまで古いビルドのまま動きます。
265
+
266
+ ### ローカル開発
267
+
268
+ ```bash
269
+ # .env ファイルを作成してAPIキーを設定
270
+ cp .env.example .env
271
+ # .env を編集して NCBI_API_KEY を記入
272
+
273
+ # stdio モードで起動(デフォルト)
274
+ npm run dev
275
+
276
+ # HTTP モードで起動(PORT を設定すると有効になる。OAuth の環境変数も必須)
277
+ PORT=8080 npm run dev
278
+ # → http://localhost:8080/mcp MCP エンドポイント(Bearer トークン必須)
279
+ # → http://localhost:8080/health ヘルスチェック
280
+ ```
281
+
282
+ HTTP モードは起動時に `OAUTH_ISSUER`・`OAUTH_JWKS_URL`・`MCP_RESOURCE_URL`・`ALLOWED_SUBJECTS` を読み込み、1 つでも未設定だと次のエラーで終了します。
283
+
284
+ ```
285
+ Fatal error: Error: Missing required environment variable: OAUTH_ISSUER
286
+ ```
287
+
288
+ `.env` にこれらの値を設定してから起動してください(各値の意味は「[環境変数](#環境変数)」を参照)。
289
+ `/health` や 401 応答を確かめるだけなら仮の値(URL の変数は URL 形式)でも起動できますが、`/mcp` を実際に呼び出すには
290
+ `MCP_RESOURCE_URL` を `aud` として発行されたアクセストークンが必要です。認証なしでツールを試す場合は stdio モードを使ってください。
291
+
292
+ ---
293
+
294
+ ## CLI
295
+
296
+ MCP サーバーと同じツールを、シェルから `pubmed` コマンドとして実行できます。出力は MCP ツールと同じ JSON で、
297
+ 標準出力またはファイル(`-o`)に書き出されます。結果をファイルに保存して `jq` で必要なフィールドだけを取り出せば、
298
+ Claude Code や Codex などのエージェントが大量のメタデータをコンテキストに読み込まずに済みます。
299
+
300
+ たとえば `TP53 AND myelodysplastic syndromes[mh]` の上位 20 件のメタデータは約 108 KB ありますが、
301
+ PMID・年・タイトルだけを取り出すと 3.2 KB(約 1/34)になります。全文は 1 本で数万文字あります。
302
+
303
+ ### インストール
304
+
305
+ ```bash
306
+ npm install -g @djmima/pubmed-mcp
307
+ ```
308
+
309
+ `pubmed --help` が表示されれば完了です。インストールされているバージョンは `pubmed --version`(または `-v`)で確認できます。
310
+
311
+ NCBI API キーは環境変数 `NCBI_API_KEY` から読み込みます。シェルの設定ファイル(`~/.bashrc`、`~/.zshrc` など)に
312
+ `export NCBI_API_KEY=your_api_key_here` を書くか、Windows では `setx NCBI_API_KEY your_api_key_here` を一度実行してから
313
+ ターミナルを開き直してください。
314
+
315
+ [ソースからビルドして](#ソースからビルドする) `npm link` で登録した場合は、環境変数がなければリポジトリ直下の `.env`
316
+ (`cp .env.example .env` で作成)も読み込むため、どのディレクトリから実行してもキーが使われます。
317
+
318
+ ### コマンド
319
+
320
+ | コマンド | 対応する MCP ツール | 入力 | 1 リクエストの件数 |
321
+ |---|---|---|---|
322
+ | `pubmed search <query>` | `search_articles` | 検索式(`-` で標準入力から) | — |
323
+ | `pubmed metadata <pmid>...` | `get_article_metadata` | PMID | 200 |
324
+ | `pubmed related <pmid>...` | `find_related_articles` | PMID | 200 |
325
+ | `pubmed citation --journal <雑誌> --year <年> ...` | `lookup_article_by_citation` | オプション、または `--input` で JSON 配列か JSON Lines | 100 |
326
+ | `pubmed convert <id>...` | `convert_article_ids` | PMID・PMCID・DOI のいずれか(`--id-type` で指定) | 200 |
327
+ | `pubmed fulltext <pmcid>...` | `get_full_text_article` | PMCID | 20 |
328
+ | `pubmed copyright <pmid>...` | `get_copyright_status` | PMID | 50 |
329
+
330
+ - オプション名は MCP のパラメータ名をケバブケースにしたものです(`max_results` → `--max-results`、`date_from` → `--date-from` など)。詳しくは `pubmed <command> --help` を参照してください。
331
+ - ID は引数(空白またはカンマ区切り)で渡すか、`-` を指定して標準入力から 1 行 1 件で渡します。
332
+ - 1 リクエストの件数を超える ID は自動で分割して順番に送り、結果を 1 つの JSON にまとめます。MCP ツールの件数上限(メタデータなら 200 件)は受けません。
333
+ - `-o <file>` を付けると JSON をファイルに書き出し、件数とファイルサイズを標準エラー出力に表示します。
334
+ - 終了コードは、成功で 0、NCBI やファイル操作のエラーで 1、使い方の誤りで 2 です。エラーの内容は標準エラー出力に出ます。
335
+
336
+ ### 使用例
337
+
338
+ ```bash
339
+ # 検索して、PubMed が検索式をどう解釈したかを確認する
340
+ pubmed search "TP53[tiab] AND myelodysplastic syndromes[mh]" --max-results 200 -o search.json
341
+ jq '{total_count, query_translation, warnings, errors}' search.json
342
+
343
+ # ヒットした全件のメタデータを取得し、PMID・年・雑誌・タイトルの一覧にする
344
+ jq -r '.pmids[]' search.json | pubmed metadata - -o meta.json
345
+ jq -r '.articles[] | [.identifiers.pmid, .publication_date.year, .journal.iso_abbreviation, .title] | @tsv' meta.json
346
+
347
+ # 全文を取得できる論文だけ全文を取得し、必要な箇所だけを検索する
348
+ jq -r '.pmids[]' search.json | pubmed copyright - -o rights.json
349
+ jq -r '.statuses[] | select(.has_full_text) | .pmcid' rights.json | pubmed fulltext - -o full.json
350
+ jq -r '.articles[].full_text' full.json | grep -n -i 'venetoclax'
351
+ ```
352
+
353
+ ### エージェントから使う
354
+
355
+ [`skills/pubmed-cli/SKILL.md`](skills/pubmed-cli/SKILL.md) は、CLI の使い方(結果はファイルに保存して jq で読む、ID はまとめて 1 回で渡す、など)と
356
+ jq のレシピをエージェントに教える Skill です。ユーザー単位のスキルフォルダにコピーすると、どのプロジェクトでも使われます。
357
+ Claude Code(Claude Desktop の Code タブを含む)は `~/.claude/skills/`、Codex は `~/.agents/skills/` から読み込みます
358
+ (Windows では `~` が `%USERPROFILE%` になります)。
359
+
360
+ Skill は npm パッケージにも含まれているので、`npm install -g` でインストールした場合は次のコマンドでコピーできます
361
+ (Windows では Git Bash で実行してください)。
362
+
363
+ ```bash
364
+ SKILL_DIR="$(npm root -g)/@djmima/pubmed-mcp/skills/pubmed-cli"
365
+ mkdir -p ~/.claude/skills ~/.agents/skills
366
+ cp -r "$SKILL_DIR" ~/.claude/skills/
367
+ cp -r "$SKILL_DIR" ~/.agents/skills/
368
+ ```
369
+
370
+ ソースからビルドした場合は、リポジトリ直下で `SKILL_DIR=skills/pubmed-cli` としてから同じコマンドを実行します。
371
+ パッケージや Skill を更新したときは、もう一度コピーしてください。
372
+
373
+ Claude Code でコマンドを実行するたびに許可を求められないようにするには、`~/.claude/settings.json` の `permissions.allow` に
374
+ `pubmed` と `jq` を追加します(既に設定がある場合は配列に追記してください)。
375
+
376
+ ```json
377
+ {
378
+ "permissions": {
379
+ "allow": ["Bash(pubmed:*)", "Bash(jq:*)"]
380
+ }
381
+ }
382
+ ```
383
+
384
+ 注意点:
385
+
386
+ - CLI はシェルを実行できる環境(Claude Code、Codex など)でしか使えません。claude.ai のチャットや、Cloud Run にデプロイしたカスタムコネクタからは、これまでどおり MCP サーバーを使ってください。
387
+ - NCBI のレート制限はプロセスごとにかかります。`pubmed` を並列で複数起動すると合計で上限を超えるため、ID はまとめて 1 回の実行で渡してください。
388
+ - Windows では Git Bash か PowerShell 7 でパイプラインを実行してください。Windows PowerShell 5.1 の `>` はファイルを UTF-16 で保存するため、代わりに `-o` を使ってください。
389
+
390
+ ---
391
+
392
+ ## Google Cloud Run へのデプロイ
393
+
394
+ このサーバーは Docker コンテナとして Google Cloud Run にデプロイできます。
395
+ `PORT` 環境変数が設定されると自動的に HTTP モードで起動し、Streamable HTTP トランスポートで MCP クライアントと通信します。
396
+
397
+ HTTP モードの `/mcp` は **OAuth 2.0 で保護** されています。サーバーは OAuth のリソースサーバーとして動作し、
398
+ リクエストごとに Bearer トークン(JWT)の署名・発行者(`iss`)・対象(`aud`)・有効期限を、認可サーバーの公開鍵(JWKS)で検証します。
399
+ ログイン画面やトークンの発行は外部の認可サーバーが担当します(ここでは WorkOS AuthKit を使います)。
400
+
401
+ Cloud Run 自体は `--allow-unauthenticated` で公開します。Cloud Run の IAM 認証(IAP を含む)は claude.ai からの接続と両立しないため、
402
+ アクセス制御は Cloud Run ではなくアプリ側の OAuth で行います。
403
+
404
+ | パス | 認証 | 内容 |
405
+ |------|------|------|
406
+ | `/mcp` | Bearer トークン必須 | MCP エンドポイント |
407
+ | `/.well-known/oauth-protected-resource` | 不要 | 認可サーバーの場所を示すメタデータ(RFC 9728) |
408
+ | `/health` | 不要 | ヘルスチェック |
409
+
410
+ ```
411
+ Claude(Web / Desktop / モバイル)・Claude Code・Anthropic API
412
+ │ Authorization: Bearer <WorkOS AuthKit が発行したアクセストークン>
413
+ ▼
414
+ Cloud Run(--allow-unauthenticated)
415
+ │ /mcp で JWT を検証し、ALLOWED_SUBJECTS で利用者を限定
416
+ ▼
417
+ MCP ハンドラ
418
+ ```
419
+
420
+ Claude の各アプリと Claude Code は、トークンなしのリクエストに返る 401 応答(`WWW-Authenticate` ヘッダー)から
421
+ メタデータをたどって認可サーバーを見つけ、ブラウザでのログインを経てトークンを取得します。
422
+ Anthropic API から使う場合は、呼び出し側でトークンを用意して渡します。
423
+
424
+ ### 前提条件
425
+
426
+ - Google Cloud プロジェクト(課金が有効なもの)
427
+ - [gcloud CLI](https://cloud.google.com/sdk/docs/install) インストール済み・ログイン済み
428
+ - [WorkOS](https://workos.com/) アカウント(AuthKit を OAuth 認可サーバーとして使用)
429
+
430
+ ### ステップ 1 — プロジェクトと API の準備
431
+
432
+ ```bash
433
+ # デプロイ先プロジェクトをセット
434
+ gcloud config set project MY_PROJECT_ID
435
+
436
+ # 必要な API を有効化(初回のみ)
437
+ gcloud services enable \
438
+ run.googleapis.com \
439
+ artifactregistry.googleapis.com \
440
+ cloudbuild.googleapis.com \
441
+ secretmanager.googleapis.com # NCBI_API_KEY を管理する場合のみ
442
+ ```
443
+
444
+ ### ステップ 2 — Artifact Registry リポジトリを作成(初回のみ)
445
+
446
+ ```bash
447
+ gcloud artifacts repositories create pubmed-mcp \
448
+ --repository-format=docker \
449
+ --location=asia-northeast1 \
450
+ --description="PubMed MCP Server"
451
+ ```
452
+
453
+ ### ステップ 3 — シークレットを Secret Manager に登録
454
+
455
+ NCBI API キーをコマンド履歴やログに残さないために Secret Manager を使います。
456
+
457
+ ```bash
458
+ # NCBI API キーを登録
459
+ echo -n "your_ncbi_api_key" | \
460
+ gcloud secrets create ncbi-api-key \
461
+ --data-file=- \
462
+ --replication-policy=automatic
463
+ ```
464
+
465
+ ### ステップ 4 — コンテナイメージをビルドしてプッシュ
466
+
467
+ Cloud Build を使うとローカルに Docker をインストールせずにビルドできます。
468
+ `gcloud builds submit` はカレントディレクトリのファイルを Cloud Build に送信するため、
469
+ **事前にリポジトリをクローンしておく必要があります。**
470
+
471
+ ```bash
472
+ # リポジトリをクローンしてディレクトリに移動
473
+ git clone https://github.com/DJMIMA/PubMed_MCP.git
474
+ cd PubMed_MCP
475
+
476
+ # Cloud Build でビルド(ローカルに Docker 不要)
477
+ gcloud builds submit \
478
+ --region=asia-northeast1 \
479
+ --tag asia-northeast1-docker.pkg.dev/MY_PROJECT_ID/pubmed-mcp/server:latest
480
+ ```
481
+
482
+ ローカルの Docker でビルドする場合:
483
+
484
+ ```bash
485
+ gcloud auth configure-docker asia-northeast1-docker.pkg.dev
486
+
487
+ docker build -t asia-northeast1-docker.pkg.dev/MY_PROJECT_ID/pubmed-mcp/server:latest .
488
+ docker push asia-northeast1-docker.pkg.dev/MY_PROJECT_ID/pubmed-mcp/server:latest
489
+ ```
490
+
491
+ ### ステップ 5 — OAuth 認可サーバー(WorkOS AuthKit)を設定
492
+
493
+ まず MCP エンドポイントの公開 URL を決めます。Cloud Run のサービスには
494
+ `https://サービス名-プロジェクト番号.リージョン.run.app` 形式の URL が割り当てられるため、デプロイ前に確定できます。
495
+
496
+ ```bash
497
+ PROJECT_NUMBER=$(gcloud projects describe MY_PROJECT_ID --format='value(projectNumber)')
498
+ MCP_RESOURCE_URL="https://pubmed-mcp-${PROJECT_NUMBER}.asia-northeast1.run.app/mcp"
499
+ echo "$MCP_RESOURCE_URL"
500
+ ```
501
+
502
+ この URL が `MCP_RESOURCE_URL` です。WorkOS の Resource Indicator や各クライアントに登録する URL とは**完全に同じ文字列**にしてください
503
+ (クライアントは接続先の URL とメタデータの `resource` が一致するかを確認し、サーバーはトークンの `aud` をこの値と照合します)。
504
+ Cloud Run には `https://pubmed-mcp-xxxx-an.a.run.app` 形式の URL も割り当てられ、どちらでもアクセスできますが、OAuth で使う URL はどちらか一方に統一します。
505
+
506
+ 次に WorkOS ダッシュボードで AuthKit を設定します。
507
+
508
+ 1. **Connect → Configuration** で **Dynamic Client Registration** を有効にする(claude.ai などの MCP クライアントが、自分自身を OAuth クライアントとして登録できるようにするため)
509
+ 2. `MCP_RESOURCE_URL` を **Resource Indicator** として登録する(アクセストークンの `aud` がこの URL になる)
510
+ 3. AuthKit ドメインの認可サーバーメタデータを開き、`issuer` と `jwks_uri` の値を控える
511
+
512
+ ```bash
513
+ curl https://YOUR_AUTHKIT_DOMAIN/.well-known/oauth-authorization-server
514
+ # → {"issuer":"https://YOUR_AUTHKIT_DOMAIN", ..., "jwks_uri":"https://YOUR_AUTHKIT_DOMAIN/oauth2/jwks", ...}
515
+ ```
516
+
517
+ WorkOS の Staging 環境と Production 環境は、設定も AuthKit ドメインも別々です。環境を切り替えるときは上の設定をやり直し、
518
+ `OAUTH_ISSUER`・`OAUTH_JWKS_URL` も差し替えてください。
519
+
520
+ ### ステップ 6 — Cloud Run にデプロイ
521
+
522
+ ステップ 5 で控えた値を使ってデプロイします。`ALLOWED_SUBJECTS` には最初は仮の値(ここでは `placeholder`)を入れておきます(理由はステップ 8 を参照)。
523
+
524
+ ```bash
525
+ # ステップ 5 で控えた issuer と jwks_uri の値に置き換える
526
+ OAUTH_ISSUER="https://YOUR_AUTHKIT_DOMAIN"
527
+ OAUTH_JWKS_URL="https://YOUR_AUTHKIT_DOMAIN/oauth2/jwks"
528
+
529
+ gcloud run deploy pubmed-mcp \
530
+ --image asia-northeast1-docker.pkg.dev/MY_PROJECT_ID/pubmed-mcp/server:latest \
531
+ --region asia-northeast1 \
532
+ --port 8080 \
533
+ --memory 512Mi \
534
+ --cpu 1 \
535
+ --timeout 300 \
536
+ --allow-unauthenticated \
537
+ --set-secrets NCBI_API_KEY=ncbi-api-key:latest \
538
+ --set-env-vars "OAUTH_ISSUER=${OAUTH_ISSUER},OAUTH_JWKS_URL=${OAUTH_JWKS_URL},MCP_RESOURCE_URL=${MCP_RESOURCE_URL},ALLOWED_SUBJECTS=placeholder"
539
+ ```
540
+
541
+ | 変数 | 設定する値 |
542
+ |------|-----------|
543
+ | `OAUTH_ISSUER` | 認可サーバーメタデータの `issuer`。トークンの `iss` と完全一致で照合されるので、末尾の `/` の有無も含めてそのままコピーする |
544
+ | `OAUTH_JWKS_URL` | 同じメタデータの `jwks_uri`。トークンの署名検証に使う公開鍵の URL |
545
+ | `MCP_RESOURCE_URL` | ステップ 5 で決めた MCP エンドポイントの URL。トークンの `aud` と照合し、`/.well-known/oauth-protected-resource` の `resource` としても公開される |
546
+ | `ALLOWED_SUBJECTS` | 接続を許可するユーザー ID(トークンの `sub`)のカンマ区切りリスト。必須(ないと、AuthKit で有効なトークンを取得できるユーザー全員が接続できてしまう) |
547
+
548
+ `OAUTH_ISSUER`・`OAUTH_JWKS_URL`・`MCP_RESOURCE_URL`・`ALLOWED_SUBJECTS` のどれかが欠けていると、サーバーは起動時に
549
+ `Missing required environment variable: ...` で終了し、デプロイは失敗します。失敗した場合は Cloud Run のログでこのメッセージを確認してください
550
+ (Cloud Console で設定した場合は、変数名の前後に空白が入っていないかも確認してください)。
551
+
552
+ > **`--set-env-vars` と `--update-env-vars` の違い**: `--set-env-vars` は既存の環境変数をすべて削除してから、指定した値を設定します(指定しなかった変数は消えます)。
553
+ > デプロイ後に一部の値だけを追加・変更するときは、既存の値とマージされる `--update-env-vars` を使ってください(`gcloud run services update` でも使えます)。
554
+
555
+ ### ステップ 7 — 動作確認
556
+
557
+ `/health` と `/.well-known/oauth-protected-resource` は認証なしで応答します。`/mcp` はトークンなしでは **401 が返れば正常** です。
558
+
559
+ **Linux / macOS (bash)**
560
+
561
+ ```bash
562
+ PROJECT_NUMBER=$(gcloud projects describe MY_PROJECT_ID --format='value(projectNumber)')
563
+ CLOUD_RUN_URL="https://pubmed-mcp-${PROJECT_NUMBER}.asia-northeast1.run.app"
564
+
565
+ # ヘルスチェック
566
+ curl "$CLOUD_RUN_URL/health"
567
+ # → ok
568
+
569
+ # Protected Resource Metadata(resource が MCP_RESOURCE_URL、authorization_servers が OAUTH_ISSUER になっていることを確認)
570
+ curl "$CLOUD_RUN_URL/.well-known/oauth-protected-resource"
571
+ # → {"resource":"https://pubmed-mcp-PROJECT_NUMBER.asia-northeast1.run.app/mcp","authorization_servers":["https://YOUR_AUTHKIT_DOMAIN"],"bearer_methods_supported":["header"]}
572
+
573
+ # MCP エンドポイント(トークンなしなので 401。-i でヘッダーも表示。ヒアドキュメントでクォート問題を回避)
574
+ curl -i "$CLOUD_RUN_URL/mcp" \
575
+ -X POST \
576
+ -H "Content-Type: application/json" \
577
+ -d @- <<'EOF'
578
+ {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"0.0.1"}}}
579
+ EOF
580
+ ```
581
+
582
+ `/mcp` の応答は次のようになります(抜粋。HTTP のバージョンやヘッダー名の大文字・小文字は環境によって異なります)。
583
+
584
+ ```
585
+ HTTP/2 401
586
+ www-authenticate: Bearer resource_metadata="https://pubmed-mcp-PROJECT_NUMBER.asia-northeast1.run.app/.well-known/oauth-protected-resource", error="missing_token"
587
+ content-type: application/json; charset=utf-8
588
+
589
+ {"error":"missing_token"}
590
+ ```
591
+
592
+ MCP クライアントは `WWW-Authenticate` ヘッダーの `resource_metadata` をたどって認可サーバーを見つけます。
593
+ トークンの検証に失敗した場合は `error="invalid_token"` の 401、トークンは有効でも `sub` が `ALLOWED_SUBJECTS` にない場合は 403(`{"error":"forbidden"}`)が返ります。
594
+
595
+ **Windows(コマンドプロンプト)**
596
+
597
+ ```cmd
598
+ :: %CLOUD_RUN_URL% に URL を設定してから実行(PROJECT_NUMBER は自分のプロジェクト番号に置き換える)
599
+ set CLOUD_RUN_URL=https://pubmed-mcp-PROJECT_NUMBER.asia-northeast1.run.app
600
+
601
+ curl "%CLOUD_RUN_URL%/health"
602
+
603
+ curl "%CLOUD_RUN_URL%/.well-known/oauth-protected-resource"
604
+
605
+ curl -i "%CLOUD_RUN_URL%/mcp" -X POST -H "Content-Type: application/json" -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2025-03-26\",\"capabilities\":{},\"clientInfo\":{\"name\":\"test\",\"version\":\"0.0.1\"}}}"
606
+ ```
607
+
608
+ **Windows(PowerShell)**
609
+
610
+ ```powershell
611
+ $CLOUD_RUN_URL = "https://pubmed-mcp-PROJECT_NUMBER.asia-northeast1.run.app"
612
+
613
+ curl.exe "$CLOUD_RUN_URL/health"
614
+
615
+ curl.exe "$CLOUD_RUN_URL/.well-known/oauth-protected-resource"
616
+
617
+ curl.exe -i "$CLOUD_RUN_URL/mcp" -X POST -H "Content-Type: application/json" `
618
+ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"0.0.1"}}}'
619
+ ```
620
+
621
+ ### ステップ 8 — 自分のユーザー ID を ALLOWED_SUBJECTS に登録
622
+
623
+ Dynamic Client Registration では誰でも OAuth クライアントを登録できるため、`ALLOWED_SUBJECTS` で接続できるユーザーを限定します
624
+ (ないと AuthKit にログインできるユーザー全員が `/mcp` を使えてしまい、AuthKit でサインアップを許可している場合は第三者も含まれるため、未設定ではサーバーが起動しません)。
625
+ 設定する値はアクセストークンの `sub`(WorkOS のユーザー ID。`user_` で始まる値)です。
626
+
627
+ サーバーは拒否したユーザーの `sub` をログに記録します。そのため、仮の値を入れた状態で一度接続し、拒否されたときのログから確認します。
628
+
629
+ 1. 後述の「[クライアント別の接続設定](#クライアント別の接続設定)」の手順で claude.ai などから接続し、WorkOS AuthKit でログインします。
630
+ `sub` が `ALLOWED_SUBJECTS` に含まれていないため接続は 403 で失敗し、サーバーのログに `[auth] forbidden subject: ...` が記録されます。
631
+ 2. ログから自分の `sub` を確認します(WorkOS ダッシュボードの **Users** で確認できるユーザー ID と同じ値です)。
632
+
633
+ ```bash
634
+ gcloud run services logs read pubmed-mcp \
635
+ --region asia-northeast1 \
636
+ --log-filter='textPayload:"forbidden subject"' \
637
+ --limit 5
638
+ # → ... [auth] forbidden subject: user_01XXXXXXXXXXXXXXXXXXXXXXXX
639
+ ```
640
+
641
+ 3. その値を設定します。`--update-env-vars` なので、ほかの環境変数はそのまま残ります。
642
+
643
+ ```bash
644
+ gcloud run services update pubmed-mcp \
645
+ --region asia-northeast1 \
646
+ --update-env-vars ALLOWED_SUBJECTS=user_01XXXXXXXXXXXXXXXXXXXXXXXX
647
+ ```
648
+
649
+ 複数のユーザーを許可する場合は、値にカンマが含まれるため `^@^` で区切り文字を変えて指定します
650
+ (例: `--update-env-vars '^@^ALLOWED_SUBJECTS=user_01AAAA,user_01BBBB'`。Windows の cmd / PowerShell では `^` を `^^^^` と書きます。詳しくは `gcloud topic escaping` を参照)。
651
+ 4. クライアントから接続し直します。
652
+
653
+ ---
654
+
655
+ ### クライアント別の接続設定
656
+
657
+ デプロイ後、各クライアントに MCP エンドポイントの URL を登録します。URL は `MCP_RESOURCE_URL` と**完全に同じ文字列**
658
+ (例: `https://pubmed-mcp-PROJECT_NUMBER.asia-northeast1.run.app/mcp`)にしてください。
659
+ 初回接続時に WorkOS AuthKit のログイン画面が開きます。ログインしたアカウントの `sub` が `ALLOWED_SUBJECTS` に含まれていれば接続できます
660
+ (自分の `sub` を登録する手順はステップ 8 を参照)。
661
+
662
+ **Claude(Web 版・Claude Desktop)— カスタムコネクタ**
663
+
664
+ リモートサーバーは「カスタムコネクタ」として追加します([Claude ヘルプセンター](https://support.claude.com/en/articles/11175166-get-started-with-custom-connectors-using-remote-mcp))。
665
+ カスタムコネクタは Free プランでも 1 つまで利用できます。
666
+
667
+ - Pro / Max プラン
668
+ 1. [claude.ai](https://claude.ai) または Claude Desktop で **Customize > Connectors** を開く
669
+ 2. **+** → **Add custom connector** をクリック
670
+ 3. URL(`MCP_RESOURCE_URL`)を入力して **Add** をクリック
671
+ 4. 追加したコネクタの **Connect** から認証する(WorkOS AuthKit のログイン画面が開く)
672
+ - Team / Enterprise プラン
673
+ 1. オーナーが **Organization settings > Connectors** を開き、**Add** → **Custom** にカーソルを合わせて **Web** を選ぶ
674
+ 2. URL(`MCP_RESOURCE_URL`)を入力して **Add** をクリック
675
+ 3. 各メンバーが **Customize > Connectors** でこのコネクタを探し、**Connect** から認証する
676
+
677
+ **Advanced settings** の OAuth Client ID / OAuth Client Secret は空欄のままで構いません(Dynamic Client Registration でクライアントが自動登録されます)。
678
+ チャットで使うときは、入力欄左下の **+** → **Connectors** から会話ごとに有効にします。
679
+
680
+ Claude Desktop の `claude_desktop_config.json` はローカル(stdio)サーバー用の設定で、`"type"` や `"url"` を書いてもリモートサーバーには接続されません。
681
+ Desktop でもリモートサーバーは上記のカスタムコネクタとして追加してください(Web 版で追加したコネクタは Desktop でもそのまま使えます)。
682
+
683
+ **Claude モバイルアプリ(Android / iOS)**
684
+
685
+ Web 版または Claude Desktop で追加したカスタムコネクタは、同じアカウントのモバイルアプリでもそのまま使えます。
686
+ モバイルアプリからのコネクタ追加はベータ機能のため、追加は Web 版か Desktop で行ってください。
687
+
688
+ **Claude Code**
689
+
690
+ ```bash
691
+ claude mcp add --transport http --scope user pubmed-remote https://pubmed-mcp-PROJECT_NUMBER.asia-northeast1.run.app/mcp
692
+ ```
693
+
694
+ Claude Code は `~/.claude/settings.json` の `mcpServers` を読み込まないため、`claude mcp add` で登録します。
695
+ 登録後、Claude Code で `/mcp` を開いて `pubmed-remote` を選び、ブラウザで WorkOS AuthKit にログインして認証します。
696
+
697
+ **Anthropic API(Python)**
698
+
699
+ ```python
700
+ import os
701
+
702
+ import anthropic
703
+
704
+ client = anthropic.Anthropic()
705
+ response = client.beta.messages.create(
706
+ model="claude-opus-5",
707
+ max_tokens=16000,
708
+ messages=[{"role": "user", "content": "..."}],
709
+ mcp_servers=[{
710
+ "type": "url",
711
+ "url": "https://pubmed-mcp-PROJECT_NUMBER.asia-northeast1.run.app/mcp",
712
+ "name": "pubmed",
713
+ "authorization_token": os.environ["PUBMED_MCP_TOKEN"],
714
+ }],
715
+ tools=[{"type": "mcp_toolset", "mcp_server_name": "pubmed"}],
716
+ betas=["mcp-client-2025-11-20"]
717
+ )
718
+ ```
719
+
720
+ MCP コネクタは OAuth のログインもトークンの更新も行いません。WorkOS AuthKit がこのサーバー向けに発行したアクセストークン
721
+ (`aud` が `MCP_RESOURCE_URL` で、`sub` が `ALLOWED_SUBJECTS` に含まれるもの)を呼び出し側で取得して `authorization_token` に渡し、
722
+ 有効期限が切れたら取得し直してください。
723
+
724
+ テスト用のトークンは MCP Inspector で取得できます([MCP connector ドキュメント](https://platform.claude.com/docs/en/agents-and-tools/mcp-connector#authentication))。
725
+
726
+ 1. `npx @modelcontextprotocol/inspector` を実行
727
+ 2. **Transport type** で **Streamable HTTP** を選び、URL に `MCP_RESOURCE_URL` を入力
728
+ 3. **Open Auth Settings** → **Quick OAuth Flow** をクリックし、WorkOS AuthKit でログイン
729
+ 4. **Authentication complete** まで進めたら、表示された `access_token` の値をコピー
730
+
731
+ ---
732
+
733
+ ### イメージを更新する(再デプロイ)
734
+
735
+ ```bash
736
+ cd PubMed_MCP
737
+ git pull
738
+
739
+ gcloud builds submit \
740
+ --region=asia-northeast1 \
741
+ --tag asia-northeast1-docker.pkg.dev/MY_PROJECT_ID/pubmed-mcp/server:latest
742
+
743
+ gcloud run services update pubmed-mcp \
744
+ --region asia-northeast1 \
745
+ --image asia-northeast1-docker.pkg.dev/MY_PROJECT_ID/pubmed-mcp/server:latest
746
+ ```
747
+
748
+ `--image` だけを指定した更新では、環境変数とシークレットの設定はそのまま引き継がれます。
749
+
750
+ ---
751
+
752
+ ## 開発コマンド
753
+
754
+ ```bash
755
+ npm run build # TypeScript をコンパイル → dist/
756
+ npm run dev # tsx で直接実行(開発用)
757
+ npm run cli -- search "CRISPR" --max-results 5 # CLI を tsx で直接実行(開発用)
758
+ npm test # テストスイートを実行
759
+ npm run typecheck # 型チェックのみ(コンパイルなし)
760
+ npm run lint # ESLint を実行
761
+ ```
762
+
763
+ ### npm へのリリース(メンテナー向け)
764
+
765
+ GitHub で Release を公開すると、[`.github/workflows/release.yml`](.github/workflows/release.yml) が npm に公開を申請します([staged publishing](https://docs.npmjs.com/staged-publishing/))。
766
+ メンテナーが npmjs.com で 2FA を使って承認するまで、新しいバージョンは公開されません。ワークフローや依存パッケージが乗っ取られても、それだけでは公開できないようにするためです。
767
+ npm の [Trusted Publishing](https://docs.npmjs.com/trusted-publishers/)(OIDC)を使うため、npm のトークンはリポジトリに保存しません。
768
+
769
+ 変更を加える PR では、[`CHANGELOG.md`](CHANGELOG.md)(英語)と [`CHANGELOG_ja.md`](CHANGELOG_ja.md)(日本語)の両方の `[Unreleased]` に同じ内容を追記しておきます。リリースの手順は次のとおりです。
770
+
771
+ 1. リリース用のブランチで `npm version patch --no-git-tag-version`(または `minor` / `major`)を実行し、`package.json` のバージョンを上げる
772
+ (タグは手順 3 で GitHub が付けるため、ここでは付けません)
773
+ 2. `CHANGELOG.md` と `CHANGELOG_ja.md` のそれぞれで、`[Unreleased]` の内容を新しいバージョンの見出し(例: `## [1.0.1] - 2026-11-01`)の下に移し、末尾の比較リンクを更新して、PR を作って main にマージする
774
+ 3. GitHub で、main を対象に `v<バージョン>`(例: `v1.0.1`)のタグを付けた Release を公開する。リリースノートには `CHANGELOG.md`(英語)の該当部分を貼る
775
+ 4. ワークフローがタグと `package.json` のバージョンが一致するか確かめ、型チェック・lint・テスト・ビルドを通してから公開を申請する
776
+ 5. npmjs.com のパッケージページの **Staged Packages** タブで内容を確認し、**Approve** を押す(2FA が必要)。CLI では `npm stage approve <stage-id>` でも承認できる
777
+
778
+ バージョンの上げ方の目安は、不具合の修正やドキュメントの変更が `patch`、ツールやオプションの追加が `minor`、
779
+ ツール名・引数・出力の形を変えて既存の使い方が動かなくなる変更が `major` です。
780
+
781
+ 初回だけは手動で公開します。Trusted Publishing はパッケージが npm に存在しないと設定できないためです。
782
+
783
+ 1. 2FA を有効にした npm アカウントで `npm login` し、main の最新を `npm publish` で公開する(保留になった場合は上記の手順 5 のとおり承認する)
784
+ 2. npmjs.com のパッケージ設定 → **Trusted Publisher** で GitHub Actions を選び、リポジトリ `DJMIMA/PubMed_MCP`、ワークフロー `release.yml` を登録する。
785
+ **Allowed actions** は `npm stage publish`(常に許可)だけにし、`npm publish` と `npm dist-tag` は許可しない
786
+ 3. 同じ設定画面の **Publishing access** で **Require two-factor authentication and disallow tokens** を選ぶ
787
+
788
+ ---
789
+
790
+ ## 環境変数
791
+
792
+ | 変数 | 必須 | 説明 |
793
+ |------|------|------|
794
+ | `NCBI_API_KEY` | 任意 | NCBIのAPIキー。設定するとレートリミットが 3 → 8 req/s になる |
795
+ | `PORT` | 任意 | 設定するとHTTPモードで起動。Cloud Run はこの変数を自動で注入する |
796
+ | `OAUTH_ISSUER` | HTTPモードでは必須 | 認可サーバーの issuer(認可サーバーメタデータの `issuer`)。トークンの `iss` と照合する |
797
+ | `OAUTH_JWKS_URL` | HTTPモードでは必須 | 認可サーバーの JWKS の URL(同じメタデータの `jwks_uri`)。トークンの署名検証に使う |
798
+ | `MCP_RESOURCE_URL` | HTTPモードでは必須 | MCP エンドポイントの公開 URL。トークンの `aud` と照合し、Protected Resource Metadata の `resource` として公開する |
799
+ | `ALLOWED_SUBJECTS` | HTTPモードでは必須 | 接続を許可するトークン `sub` のカンマ区切りリスト |
800
+
801
+ `OAUTH_ISSUER`・`OAUTH_JWKS_URL`・`MCP_RESOURCE_URL`・`ALLOWED_SUBJECTS` は HTTP モードでのみ使われ、stdio モードでは不要です。
802
+ 値の決め方は「[Google Cloud Run へのデプロイ](#google-cloud-run-へのデプロイ)」のステップ 5〜8 を参照してください。
803
+
804
+ `.env` ファイルを使う場合は `.env.example` をコピーして編集してください。
805
+ 本番環境では、`NCBI_API_KEY` は Cloud Run の `--set-secrets` で Secret Manager から渡し、OAuth 関連の値は `--set-env-vars` / `--update-env-vars` で設定してください。
806
+
807
+ ---
808
+
809
+ ## 参考リンク
810
+
811
+ - [MCP ドキュメント](https://modelcontextprotocol.io/docs)
812
+ - [NCBI E-utilities ドキュメント](https://www.ncbi.nlm.nih.gov/books/NBK25499/)
813
+ - [NCBI APIキー登録](https://www.ncbi.nlm.nih.gov/account/)
814
+ - [PubMed 検索ヘルプ](https://pubmed.ncbi.nlm.nih.gov/help/)
815
+ - [Cloud Run ドキュメント](https://cloud.google.com/run/docs)
816
+ - [Secret Manager ドキュメント](https://cloud.google.com/secret-manager/docs)
817
+
818
+ ---
819
+
820
+ ## ライセンス
821
+
822
+ このリポジトリのソースコードは [MIT License](LICENSE) で公開しています。
823
+
824
+ - このプロジェクトは NCBI / NLM(米国国立医学図書館)とは関係のない非公式のツールです。
825
+ - PubMed / PMC へのアクセスには NCBI の E-utilities を使います。利用時は [NCBI の免責事項・著作権表示を含む利用ポリシー](https://www.ncbi.nlm.nih.gov/home/about/policies/)(NCBI Disclaimer and Copyright notice)と [E-utilities の利用ガイドライン](https://www.ncbi.nlm.nih.gov/books/NBK25497/) に従ってください。
826
+ - ガイドラインに従い、NCBI へのリクエストにはこのソフトウェアの名前(`tool=pubmed-mcp`)と開発者の連絡先(`email`)を付けています。このコードを改変して別のソフトウェアとして配布する場合は、`src/pubmed/client.ts` の `TOOL_NAME` と `TOOL_EMAIL` を自分の値に変えてください。
827
+ - MIT License が適用されるのはこのソフトウェアのコードだけです。取得した抄録や全文の著作権は各著者・出版社に帰属します。論文ごとのライセンスは `get_copyright_status` で確認できます。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djmima/pubmed-mcp",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "MCP server and CLI for searching and reading PubMed and PubMed Central literature",
5
5
  "license": "MIT",
6
6
  "author": "DJ MIMA",
@@ -31,7 +31,9 @@
31
31
  "files": [
32
32
  "dist",
33
33
  "skills",
34
- "CHANGELOG.md"
34
+ "README_ja.md",
35
+ "CHANGELOG.md",
36
+ "CHANGELOG_ja.md"
35
37
  ],
36
38
  "scripts": {
37
39
  "build": "tsc",