nob@lit-forge

自家製 MCP サーバーで lit-forge.com の 10 ツールを Claude から直接呼べるようにした完全レシピ

lit-forge.com の開発者向けユーティリティ 10 種を Model Context Protocol サーバーとして実装し、npm・公式 MCP Registry・awesome-mcp-servers に公開するまでの完全な記録。ツール選定の基準、200 行規模の TypeScript 実装、npm 2FA + OTP の罠、GitHub username rename と Contributors widget の永続キャッシュ問題、公式 Registry の namespace 仕様(io.github.org 形式)など、Claude Code と二人三脚で踏んだ落とし穴を全部公開します。

#MCP#Model Context Protocol#Claude Code#個人開発#npm#TypeScript

やったこと(要約)

lit-forge.com の開発者向けユーティリティ 10 種を MCP(Model Context Protocol) サーバー化し、Claude Desktop / Claude Code / Cursor から直接呼び出せるようにした。npm にも、公式 MCP Registry にも、awesome-mcp-servers にも公開済み。

以下、ツール選定の基準・実装・公開で踏んだ落とし穴を全部公開します。 これから自分の Web ツール集を MCP 化する人の参考になれば。

なぜ MCP 化したか(集客戦略の話)

lit-forge.com は 38 個の Web ツールを抱える個人開発サイト で、収益源は AdSense + アフィリエイト。問題は「人を呼ぶ手段」です。 Google 検索流入は SEO の積み上げに数ヶ月かかるし、SNS は 1 投稿の射程が短い。

そこで「Google 検索以外の発見経路」を開きたくて選んだのが MCP 化です。狙いは 3 つ:

  1. awesome-mcp-servers / 公式 MCP Registry に掲載される。 数万スターのリストの読者・MCP クライアントの推奨候補に乗る
  2. Claude / Cursor のユーザーが普段使いするうちに lit-forge ブランドに触れる
  3. AI クライアント上で実際にツールを使ったユーザーが、「Web 版もある」と知って lit-forge.com を訪問する

Web ツールという土俵で「もう 39 個目のサイト」を作るより、 AI クライアントという別土俵に同じ機能で出る方が、 少ない労力でニッチ独占できる可能性が高いと踏みました。

ツール選定: 「Claude が苦手な領域」を狙う

lit-forge.com の 38 ツールから、MCP 化して意味があるものだけを選びました。 判定基準は「Claude が単体でやろうとすると不正確になる処理か?」

優先度ツール理由
★★★ 必須generate_hashClaude はハッシュ計算できない。架空の hex 文字列を返してしまう
★★★ 必須generate_uuidv4 はそれっぽく書けるが乱数性なし。v7 は時刻部の精度が出ない
★★★ 必須describe_cron「次回実行時刻」の計算でしばしば誤る。タイムゾーン込みなら確実
★★ 有利test_regex脳内シミュで誤ることがある。実 RegExp 実行で安心
★★ 有利decode_jwtexp の今時刻判定が不正確。Date.now() で確実
★★ 有利convert_timestampタイムゾーン誤りが頻発する
★★ 有利convert_yaml_json単純なら可、エッジケースで誤る
★ 互角format_json小規模なら自力 OK、巨大 JSON では省略・改変リスク
★ 互角convert_url単純な文字列なら正確
★ 互角convert_base64ASCII OK、UTF-8 で誤りやすい

10 中 3 つだけが「絶対 MCP 必須」、残りは「有利」「互角」。機能的差別化だけ見たら 30% しか勝ち目がないけど、 それでも 10 個セットにしたのはブランド露出が本来の目的だから。 登録時に「ツール 10 個」と言える方がリスト掲載で目立つ。

逆に MVP から外したのは:

  • BMI 計算機・割り勘・年齢計算 → Claude が暗算できる
  • テキスト読み上げ・画像リサイズ → ブラウザ API 必須で stdio MCP では実装困難
  • QR コード生成・PDF 生成 → バイナリ返却が面倒(後の v0.2.0 候補)
  • 診断系(エンジニアタイプ等)→ 対話 UI が本質

実装: 200 行規模の TypeScript で完結

MCP TypeScript SDK は v1.29.0 を採用(v2 は alpha のため見送り)。 stdio transport を使い、McpServerregisterTool でツールを登録するだけ。

// src/index.ts (簡略版)
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { tools } from "./tools/index.js";

const server = new McpServer({ name: "lit-forge", version: "0.1.2" });
for (const tool of tools) {
  server.registerTool(tool.name, {
    title: tool.title,
    description: tool.description,
    inputSchema: tool.inputSchema,  // zod schema
  }, tool.handler);
}
const transport = new StdioServerTransport();
await server.connect(transport);

各ツールは src/tools/<name>.ts に zod スキーマと handler 関数を一緒に書いて、tools/index.ts で集約。 新ツール追加は 1 ファイル足して 1 行 import するだけ。

「lit-forge.com の既存 app/lib/ を再利用すればよかった」と 思いたいところですが、ブラウザ依存(btoa/atob/unescape/Web Crypto の一部) があるので結局 Node native(Buffer/node:crypto)で書き直し。 同じロジックを 2 箇所に持つのは美しくないけど、サーバー側の純粋性を優先しました。

npm 公開でハマった: 2FA + OTP の罠

npm publish --access public 1 発で終わると思ったら、 3 つの段差がありました。

段差 1: WSL2 では npm login のブラウザフローが落ちる

WSL2 は OS 標準ブラウザがないので、npm login が web 認証 URL を 出した直後に stdin の Username プロンプトに落ちて EOF で死ぬ。回避策:

sleep infinity | npm login --auth-type=web </dev/null

sleep infinity で stdin を活かしつつ Web 認証の polling を待つ。 URL を wslview で Windows 側ブラウザに渡せば device flow が完走します。

段差 2: 新規 npm アカウントは即 2FA 強制

npm は新規アカウントの publish に対して2FA を実質強制します。 2FA 未設定なら EOTP (One-Time Password) エラーで弾かれる。 認証アプリ(Google Authenticator 等)で TOTP を設定し、毎回 publish 時に:

npm publish --access public --otp=847291

30 秒で OTP が変わるので、認証アプリの数字を確認したら即実行。

段差 3: スコープ取得は意外と難しい

ブランド名で scope を取りたかったけど、@nob-labs は 既にユーザーが取得済み、@nobs も既存。3 文字の短い scope は ほぼ全滅。結局 unscoped で lit-forge-mcp として公開

npm の package 名と user/scope 名は別 namespace ですが、人気の単語は ほぼ取られているので、初めて公開する時は「scope なしで動詞 + 機能名」が一番スッと取れて分かりやすいです。

ブランド統一でやらかした: GitHub username rename と Contributors 永続キャッシュ

ここから本当の地獄。npm のユーザー名を実名要素含む形で取ってしまったので、 途中で「ブランド統一のため別アカウントに移管したい」と判断。 ところが GitHub と npm では rename の仕様が真逆でした。

npm: rename 不可、新規作成 + 所有権移管 + 旧アカ削除

# 旧アカで(OTP 必要)
npm owner add nob-labs lit-forge-mcp --otp=...
# 新アカで(招待を承認、OTP 必要)
npm owner rm 旧アカ lit-forge-mcp --otp=...
# Web UI から旧アカウント完全削除

所有権移管には新アカ側で招待を承認するステップが必要 (npm owner ls ですぐ反映されない)。30 日後に旧 username が 他人取得可能になるので、squat リスクは残ります。

GitHub: rename は公式サポート、ただし profile URL は redirect されない

GitHub は Settings → Account → Change username で 1 クリック改名。 既存のリポジトリ・PR・Issue・Contribution graph が全部新名前に追従して redirect も効きます。ただし profile URL(github.com/旧名)は 404 になるので、profile への直リンクは生き残らない。これは privacy 観点ではむしろ好都合でした(旧 profile 経由で過去活動を辿られない)。

Contributors widget の永続キャッシュ問題

ここが一番ハマった。GitHub のリポジトリ右サイドに出る「Contributors」ウィジェット は、force-push で commit author を rewrite しても古いキャッシュを 数日〜数週間返し続ける

git filter-branch で全 commit の author を新名前に書き換え、 force-push しても、Contributors widget には旧名前のままが表示される。 GitHub API の /contributors エンドポイントも同じ。 stats endpoint は {} を返してきて再集計中であることを示すが、 widget は更新されない。

解決策はリポジトリを一度削除して同じ名前で作り直す。 これで完全にゼロから集計され、新 author だけが表示される。 既に PR や issue が付いていなければダメージなし(私の場合は公開直後だったので 0 件)。

# delete_repo スコープが必要
gh auth refresh -h github.com -s delete_repo
gh repo delete noblabs/lit-forge-mcp --yes
gh repo create noblabs/lit-forge-mcp --public --description "..."
git push -u origin main

公開済みの awesome-mcp-servers PR や npm の repository.url は 同じ URL なので無傷。リポジトリ削除は怖いですが、commit 履歴が 数件しかない初期段階なら最速の解決でした。

公式 MCP Registry の罠: 公開ドメインの選び方

公式 MCP Registrymcp-publisher CLI で publish します。package.jsonmcpName を追加し、server.json をリポジトリ直下に置いて、CLI で GitHub device flow 認証 → publish。

ハマったのはnamespace 仕様。GitHub auth で publish する場合、mcpNameio.github.<owner>/<name> 形式必須で、ownerOAuth 認証したユーザー本人 or 公開メンバーである orgでなければ 403 が返ります。

個人 namespace(io.github.nob-owner/...)で publish するのが 一番楽ですが、ブランド統一を考えると org(io.github.noblabs/...) を使いたい。すると条件としてorg member visibility が Publicでなければならない。私は最初 privacy 目的で Private にしていたので、 401 / 403 でハマりました。

結論: org publish したいなら member visibility は Public 必須。 privacy と公開ブランドのトレードオフがここに発生します。私は noblabs の Public 化を選びました(ハンドル nob-owner 自体に実名要素がないので exposure コストは限定的)。

露出経路: 4 リストへの登録

MCP サーバーを「見つけてもらう」ための主要露出先と、各々の特徴:

リストスター投稿方法結果
punkpeye/awesome-mcp-servers85kPR (README 1 行追加)提出済み・レビュー待ち
公式 MCP Registry公式mcp-publisher publish即時 active
mcpservers.org独立サイトフォーム送信送信済み・レビュー待ち
tolkonepiu/best-of-mcp-servers小規模Issue テンプレIssue 提出済み
appcypher/awesome-mcp-servers5.5kPR/Issue 共に無効投稿不可(メンテ停止)

punkpeye の awesome-mcp-servers はジャンル「Developer Tools」だけで既に 類似ユーティリティ系 MCP が 4 つ登録されていて、差別化が苦しい。 自分の lit-forge-mcp の場合は「lit-forge.com の Web UI 版と並走」を差別化文言に据えました。 Web UI ↔ MCP の選択肢があるのは他社にない強みです。

lit-forge.com 内の導線整備

外部から流入してきたユーザーが「lit-forge.com 本体も Web 版あるんだ」と 気づく導線が必要。3 段構えで配置しました:

  • TOPページのヒーロー直下にバナー: 紫グラデの 1 行カード 「🤖 AI 連携 - lit-forge MCP サーバー」。全訪問者が必ず通る位置
  • MCP 対応 10 ツールのフッターに案内:JSON 整形UUID 生成等の MCP 化済みツールにはusePathname() でパス判定して「Claude から直接呼ぶには」のリンクを自動表示
  • 専用ページ /mcp: Claude Desktop / Code / Cursor のインストール手順、10 ツール一覧、自然言語での使い方例、 公式 Registry へのリンクを集約

逆に「lit-forge.com の Web ツールを使ってた人が AI でも使う」流れも狙えます。 双方向の導線で、ユーザーがどの土俵で接触してきても lit-forge ブランドに繋ぎ留める設計。

結果と学び

数字(公開直後の状態)

  • npm: lit-forge-mcp v0.1.2 公開、ダウンロード数は集計中
  • 公式 MCP Registry: 即時 active
  • awesome-mcp-servers PR: 提出 1 日目、レビュー待ち
  • lit-forge.com /mcp ページ: 公開済み、流入計測はこれから

学び 5 つ

  1. MCP 化は機能差別化より露出が本命。10 ツール中 3 つしか 「絶対 MCP じゃないとできない」処理はなかった。それでもやる価値があるのは、 awesome リスト・公式 Registry・AI クライアント経由のブランド接触が増えるから
  2. ブランド名取得は最初に全部やる。npm / GitHub / Vercel / X / ドメインで同じ名前を全部押さえてから始めるべき。途中で rename すると Contributors キャッシュ問題のような副作用が出る
  3. privacy と publish 権限のトレードオフ。公式 Registry に org namespace で publish したいなら member visibility は Public 必須。 privacy 重視なら個人 namespace で妥協する
  4. WSL2 開発者は wslview + sleep infinity パイプを覚えると CLI ベースの Web 認証フロー全般で詰まらなくなる
  5. 類似 MCP が既にあっても出す価値はある。Web UI と並走、 Japanese-first ドキュメント、無料・no-telemetry など独自性で勝負できる

試してみる

一番楽な試し方は Claude Code 経由:

claude mcp add lit-forge -- npx -y lit-forge-mcp

セッションを開き直して /mcp でリストに lit-forge が出れば成功。 あとは「この JWT デコードして」「UUID v7 を 5 個」「0 9 * * 1-5 を Asia/Tokyo で次の3回」 のように自然言語で頼むだけで Claude が自動的にツールを呼びます。

Claude Desktop / Cursor の設定方法は /mcp ページに集約してあります。バグ報告・機能要望は GitHub Issuesまでどうぞ。

X

記事の更新通知を受け取りませんか?

新しいブログ記事・ツール追加・不具合修正などは X アカウントlit_forge_jpで先行告知しています。フォローで最新情報をお受け取りいただけます。

フォロー

コメント(投稿は運営者の承認後に公開されます)

読み込み中...