はじめに — プライベートリポジトリからnpm公開する問題
MCP Serverの実装が完了し、npmに公開する段階になったとき、予想外の壁にぶつかりました。開発環境がクラウドIDEのプライベートリポジトリにあり、そこから直接 npm publish できなかったのです。
ローカル Mac に npm token を設定して publish する方式に変更。
npm config set //registry.npmjs.org/:_authToken=TOKENでグローバル設定し、ビルド→テスト→publish を実行
2月16日の開発日記にはこう書きました。結局、クラウドIDEから直接ではなく、ローカルMacを経由する公開フローを構築することになりました。この記事では、zeronova-lab-mcp をv0.1.0からv0.2.2まで4回公開した中で得た知見を共有します。
公開フローの全体像
最終的に確立した公開フローは6ステップです。
- クラウドIDEで開発・テスト: Claude Codeで実装し、全テストを通す
- GitHubからZIPダウンロード: プライベートリポジトリの該当ブランチからZIPをダウンロード
- 公開リポジトリにコピー: ZIPの
mcp-server/フォルダの中身をパブリックリポジトリに上書きコピー - GitHub Desktopでコミット・プッシュ: 変更をパブリックリポジトリにプッシュ
- ローカルMacでビルド・テスト・公開:
npm ci→npm run build→npm test→npm publish - クリーンアップ: ローカルの認証情報削除 + npmトークン無効化
PM-AI 対話: 直接公開 vs 経由公開
npm publish できないか?プライベートリポジトリだから npm login のインタラクティブ認証ができない。npm config set でトークンを設定すれば認証を回避できますが、npm 2FAが有効な場合はOTPの入力が必要です。Granular Access Tokenを使えば、2FAなしでスコープを絞った公開が可能です。この判断が、セキュリティと運用効率のバランスを取ったフローの出発点でした。
Granular Access Token — スコープを絞ったトークン管理
npm公開で最も重要なのは認証トークンの管理です。npmには3種類のトークンがあります。
Classic Read-only Token: パッケージの読み取りのみ。公開には使えません。
Classic Automation Token: 公開可能ですが、全パッケージに対して権限を持ちます。漏洩した場合のリスクが大きい。
Granular Access Token: 特定のパッケージに対して、期間限定で権限を付与できます。
v0.1.0の初回公開ではClassic Automation Tokenを使いましたが、すぐにGranular Access Tokenに切り替えました。設定は以下の通りです。
- Token name:
publish-v0.x.x(バージョン名を含めると管理しやすい) - Expiration: 7日間(公開作業に十分な期間)
- Permissions: Read and write
- Select packages:
zeronova-lab-mcpのみ
Granular Access Token は特定パッケージ・期間限定で権限を絞れる。万が一漏洩しても影響範囲が限定される
7日間で期限切れになるため、公開作業が終わったら放置しても安全です。さらに、公開後にnpmのダッシュボードからトークンを手動削除し、ローカルの ~/.npmrc からも認証情報を削除します。
v0.1.0: 初回公開の試行錯誤
v0.1.0(Tier 1: 6ツール)の初回公開は、最も学びの多いリリースでした。
node_modules問題
ZIPをダウンロードしてパブリックリポジトリにコピーしたとき、GitHub Desktopに4,000件以上の変更が表示されました。原因は node_modules/ がコピーに含まれていたこと。.gitignore に記載があっても、既にコピーしたファイルは無視されません。Finderで node_modules/ を手動削除し、変更ファイル数が数十件に戻ったことを確認してからコミットしました。
dist/ディレクトリの扱い
逆に dist/ ディレクトリは含める必要がありました。npmパッケージの実行にはビルド済みのJavaScriptファイルが必要で、package.json の main と bin が dist/ 内のファイルを参照しているためです。
dist/はそのまま含める(npm パッケージの実行に必要)。node_modules/は絶対に含めない
このルールをドキュメント化し、以降のリリースで同じ失敗を防ぎました。
v0.2.0〜v0.2.2: リリースの加速
2回目以降のリリースは格段に速くなりました。
| バージョン | 内容 | パッケージサイズ |
|---|---|---|
| v0.1.0 | Tier 1: 6ツール | 14.9 kB |
| v0.2.0 | Tier 2: ワークフロー3つ追加 | 30.9 kB |
| v0.2.1 | 情報パリティ修正 + bot-blocked区別 | — |
| v0.2.2 | site-config-checker + SEO監査全自動化 | — |
v0.2.0とv0.2.1は同じ日(2月16日)に公開しました。v0.2.0のデモ実行で情報パリティ問題を発見し、修正してすぐにv0.2.1をリリースしたためです。v0.2.2ではSEO監査の全項目自動化を実現しています。
バージョン被りの失敗
v0.2.2のリリースで失敗がありました。CHANGELOGにv0.2.1として変更内容を書いていたのですが、npmには既にv0.2.1が公開済み。同じバージョンでの再公開はnpmレジストリが拒否します。
v0.2.2にバンプし、CHANGELOGを分離しました。
- v0.2.2: site-config-checker新設、SEO監査全項目自動化、OGPチェッカーにcanonical/JSON-LD追加
- v0.2.1: 情報パリティ修正、bot-blocked(403)区別(公開済み)
0.2.1は公開済みのため、今回の変更を0.2.2としてリリース。CHANGELOGを0.2.2(今回のFix)と0.2.1(公開済み内容)に正しく分離した
公開前チェックリストの確立
4回のリリースを経て、公開前チェックリストが固まりました。
クラウドIDE側で確認すること:
package.jsonのversionが更新されているCHANGELOG.mdが更新されているREADME.mdが新機能を反映している- テスト全パス(v0.2.2時点で50テスト)
- ビルド成功
ローカルMac側で確認すること:
npm ciで依存関係をクリーンインストールnpm run buildでビルド成功npm testでテスト全パス(クラウドIDEと同じ結果になること)npm publishで公開成功
公開後に確認すること:
- npmjs.comでバージョンが反映されている
npx zeronova-lab-mcpで実行できる- ローカルの認証情報を削除
- npmトークンを無効化
学んだこと
プライベートリポジトリからの公開はフローの設計が重要: クラウドIDEからの直接公開ができない場合、ZIP経由のフローを事前に設計しておくことで、リリース作業が定型化できます。
Granular Access Tokenは個人開発者の味方: パッケージごと・期間限定でスコープを絞れるため、セキュリティリスクを最小化できます。Classic Automation Tokenは漏洩時のリスクが大きすぎます。
CHANGELOGは公開直前に書く: 開発中にCHANGELOGを書き始めると、公開済みバージョンとの衝突が起きます。「開発完了→バージョン決定→CHANGELOG記述→公開」の順序を徹底すべきです。
node_modulesとdistの扱いは逆: node_modules/ は絶対にgitに含めない、dist/ は必ず含める。この判断を間違えると、パッケージが動かないか、リポジトリが肥大化します。
リリース手順のドキュメント化は初回から: 2回目以降のリリースが劇的に速くなったのは、v0.1.0の経験を mcp-npm-publish-guide.md としてドキュメント化したからです。初回の試行錯誤を記録しておくことが、将来の自分への最大の贈り物になります。
Zeronova(ゼロノバ)
Product Manager / AI-Native Builder
Web/IT業界19年以上・20以上のWebサービスを担当したPdM。東証プライム上場企業の子会社代表として事業経営を経験。現在はAIを駆使して企画から実装まで完結させる個人開発を実践中。