ClaudeにUUIDを生成させると、それっぽい文字列は返ってくるが乱数性がない。ハッシュ計算を頼めば架空のhex文字列が出てくる。これはLLMの構造上の限界で、今後も変わらない。

この問題を解決するアプローチとして注目されているのがMCPサーバーの自作だ。個人開発者のnob193氏がQiitaで公開した実践レポートが、その具体的な手順と落とし穴を余さず記録している。

この記事でわかること:

  • どのWebツールをMCP化すべきかの判断基準
  • TypeScript 200行規模での実装方法
  • npm公開で躓く3つのポイント
  • 公式MCPレジストリへの登録手順
  • MCP化で集客・ブランド露出を狙う考え方

Claudeが苦手な処理を狙う

nob193氏が運営するlit-forge.comには38個の開発者向けWebツールがある。そのうちMCP化したのは10個だ。選定基準はシンプルで、「Claude単体でやろうとすると不正確になる処理か」で判断した。

優先度ごとに整理すると以下のようになる。

必須(★★★)
generate_hash ── Claudeはハッシュ計算ができず架空のhex文字列を返す
generate_uuid ── v4はそれっぽく書けるが乱数性なし。v7は時刻部の精度が出ない
describe_cron ── 次回実行時刻の計算でしばしば誤る。タイムゾーン込みなら確実

有利(★★)
test_regex ── 脳内シミュレーションで誤ることがある
decode_jwt ── exp の今時刻判定が不正確
convert_timestamp ── タイムゾーン誤りが頻発する
convert_yaml_json ── 単純なら可。エッジケースで誤る

互角(★)
format_json / convert_url / convert_base64

10ツール中「絶対必須」は3つだけで、機能面だけ見れば勝ち目は30%しかない。それでも10個セットで公開したのは、ブランド露出が本来の目的だからだ。リスト掲載時に「ツール10個」と言える方が目立つ。

逆にMVPから外したのは、BMI計算機や割り勘のように「Claudeが暗算できる」もの、テキスト読み上げのように「ブラウザAPI必須でstdio MCPでは実装困難」なもの、QRコード生成のように「バイナリ返却が面倒」なものだ。

実装はTypeScript 200行で完結

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するだけで済む。

注意点として、Webサイト側の既存ロジック(app/lib/)を再利用しようとすると、btoa/atobなどブラウザ依存APIが含まれていて使えないケースが出てくる。Node native(Buffer/node:crypto)で書き直す前提で設計した方がスムーズだ。

npm公開で躓く3つの段差

npm publish --access public一発で終わると思いきや、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: 新規アカウントは2FA強制

npmは新規アカウントのpublishに対して2FAを実質強制する。2FA未設定ならEOTPエラーで弾かれる。認証アプリでTOTPを設定した上で、毎回publishのたびにOTPを付与する必要がある。

npm publish --access public --otp=847291

OTPは30秒で変わるため、認証アプリの数字を確認したら即実行することが肝心だ。

段差3: スコープ取得は想像より難しい

ブランド名でscopeを取ろうとすると、短い文字列はほぼ取得済みで空きがない。今回は@nob-labs@nobsも既存ユーザーに取られていたため、unscopedでlit-forge-mcpとして公開した。初めて公開する場合は「動詞+機能名」の形が取れやすく分かりやすい。

公式MCPレジストリへの登録

公式MCP Registryへの掲載はmcp-publisher CLIで行う。package.jsonmcpNameを追加し、server.jsonをリポジトリ直下に置いた上でCLIからpublishする。

namespaceの仕様として、GitHub認証でpublishする場合mcpNameio.github.<owner>/<name>形式が必須だ。ownerはOAuth認証したユーザー本人か、公開メンバーであるorgでなければ403が返る。

orgを使いたい場合、orgのmember visibilityがPublicでないと401/403で弾かれる。プライバシー目的でPrivateにしていると詰まるポイントだ。

発見されるための4つのリスト

MCPサーバーを「見つけてもらう」主要な露出先は以下の4つだ。

リスト 規模 投稿方法
punkpeye/awesome-mcp-servers 85kスター PR(README1行追加)
公式MCP Registry 公式 mcp-publisher publish
mcpservers.org 独立サイト フォーム送信
tolkonepiu/best-of-mcp-servers 小規模 Issueテンプレ

punkpeyeのawesome-mcp-serversはDeveloper Toolsジャンルだけで類似のMCPが既に複数存在する。差別化ポイントを明確にした上で登録するとレビューが通りやすい。

なお、lit-forge-mcp自体はその後v0.2.0でツール構成をNISA/iDeCoなどの個人資産形成プランニングに全面刷新している。開発ユーティリティ10種から金融計算4種へのピボットだ。MCPサーバーを作った後に用途を変えることも十分できる、という意味での参考事例になっている。

Claudeに補完させるより正確に処理する

MCPサーバーの自作は「Claudeができないことをツールで補う」という発想の具体化だ。ハッシュ・UUID・cron計算など、LLMの確率的な動作では信頼できない処理は、正確な実装をMCPツールとして渡すことで解決できる。実装規模は200行程度で、公開まで含めても週末の作業量に収まる。

自分のWebツール集がある開発者なら、「Claudeが苦手な処理かどうか」を軸に選び直すだけで、すぐ試せる規模感の取り組みだ。