最近の開発ではClaudeCode, Cursor, CodexなどのAIエージェントを使って自然言語で開発するケースが多くなってきました。
それに加えて大きな変化だと感じているのがCodexのiOSアプリを使ってスマホからエージェントを起動して開発するスタイルです。私もプライベートの個人開発では行っています。
これによって生活の中に開発が自然と溶け込むようになっていって、開発スタイルの変化を感じています。
それに加えて私は個人ブログで日記をほぼ毎日書くという習慣があります。以前はスマホからmicroCMSの管理画面を開いて入稿をしていましたが、開発と同様にCodexなどのエージェントのサポートも得ながらできないか?考えました。
その解決策として、個人用のリモートMCPサーバーを作成しました。
CodexのスマホアプリなどからもmicroCMSに投稿できる仕組みを作りましたので、紹介したいと思います。
リモートMCPサーバーとは?
MCP(Model Context Protocol)は、AIエージェントを外部システムに接続するためのオープンな標準プロトコルです。これによって、microCMSや他のデータソースをAIエージェントが操作できるようになります。
https://modelcontextprotocol.io/docs/getting-started/intro
microCMSでは現在公式のOSSとしてmicrocms-mcp-serverを公開しています。
https://document.microcms.io/mcp-server/microcms-mcp-server
これは主に、Claude DesktopやCursorなどのMCPクライアントがローカルで npx 経由でサーバーを起動するstdio方式で使う想定です。APIキーはクライアント側の設定に置く形になります。
一方で今回作ったリモートMCPサーバーは、MCPサーバー自体をWebエンドポイントとして公開し、CodexなどのMCPクライアントからStreamable HTTP(HTTP POSTベースのMCPトランスポート)で呼び出せるようにしたものです。
- クライアント側でサーバーを起動しなくてよいこと
- microCMSのAPIキーをサーバー側に閉じられること
- 認証・レート制限・ログをサーバー側に集約できること
が大きな違いです。スマホのCodexアプリのようにローカルプロセスを起動できないクライアントからも使えるため、今回の要件に合っていました。
なお microcms-mcp-server 自体もHTTPモードでリモート運用は可能です。
今回はブログ執筆用の専用ツールを自作してみたかったこと(下書き作成、画像アップロード、カテゴリー整理など)とよりセキュアな要件としてOAuth認証を試してみたかったため、Vercel上に独自のリモートMCPサーバーを構築しました。
今回作成した仕組み
実際に作ったものを紹介します。実際に個人ブログで活用しているものです。
Codexなどのアプリのターミナルで codex mcp login [mcp名] のようなコマンドを叩くとOAuth対応のリモートMCPサーバーが立ち上がります(mcp名は公開しても問題ないのですが、個人用なため不要なアクセスを避けるため隠しています)。
![ChatGPT Desktopを開き、ターミナルで codex mcp login [mcp ツール名] を実行してMCPサーバーへのログインを開始する様子。](https://images.blog.microcms.io/assets/f5d83e38f9374219900ef1b0cc4d85cd/fd42a131da6342b0a0c5d7a16389966b/CleanShot%202026-07-03%20at%2015.47.03%402x.png?w=3840)
発行されたURLに遷移すると、ログイン画面に遷移します。

ログイン成功するとCodexとの接続許可を確認できます。

これらのアクセスを許可すると、Codex上で独自に作ったmicroCMSのMCPツールを叩けます。
以下はブログの下書きを作成するシンプルなツールです。下書きプレビューも見ながら執筆できるのが便利です。スクリーンショットの関係でデスクトップで紹介していますが、スマホのiOSアプリからでも同様の操作が可能です。

カテゴリーを自動生成して紐づけたり、AIの補助を得ながらブログを執筆できます。

このようなOAuth対応の認証と、リモートMCPサーバーと便利なツールを作ったのでその作り方を解説します。
今回作成した仕組みの裏側
今回のリモートMCPサーバーは、大きく3つの要素で構成されています。
- Codex(MCPクライアント) — スマホからMCPサーバーに接続し、ツールを呼び出す側
- Hono(リソースサーバー) — 「ブログと同一ドメイン」の
/mcpパスとして公開するMCP本体。トークン検証・レート制限・ツール実行を担う。Honoで作成したサーバーは今回はVercelにデプロイしています。 - WorkOS AuthKit(認可サーバー) — ログイン画面とOAuthトークンの発行・検証基盤を担う
microCMSのAPIキーはHono/Vercel側の環境変数にだけ置き、Codexには渡しません。
代わりにCodexはOAuthで操作をしているのは「自分であること」を証明し、証明できたリクエストだけがMCPツールを実行できます。
個人ブログ向けに「自分以外は使えない」状態を保ちつつ、AIクライアントから安全にアクセスできるようにするというのが今回の設計の核です。
またHonoは Vercel のAPI Routeとしてデプロイしています。
ブログ本体と同一ドメインで /mcp や /api/mcp として公開できるため、環境変数・デプロイ・ログ確認を既存のWebサイト運用に寄せられます。ディレクトリ構成は以下のようなイメージです。
api/mcp.ts # VercelのAPIルートとして呼び出す
mcp-server/src/transport/vercel.ts # Honoアプリ(認証・transportなど)
mcp-server/src/auth/ # トークン検証・401応答
mcp-server/src/server.ts # MCPサーバー本体(登録したtoolsを呼び出す)
mcp-server/src/tools/microcms/ # microCMS汎用ツール
mcp-server/src/tools/ryusou/ # ブログ執筆用に独自にカスタマイズしたツール(命名はハンドルネームで適当です)
mcp-server/src/security.ts # レート制限・エンドポイント制限など
src/ # ルートにAstroのブログ側の実装OAuthとは何か、3者はどう関わるか
OAuthは、ざっくり言うと「パスワードやAPIキーを直接渡さずに、第三者サービスへのアクセス権を安全に許可する認可の仕組み」です。
詳しくは以下の記事などがわかりやすいです。
https://qiita.com/TakahikoKawasaki/items/e37caf50776e00e733be
今回の文脈では、Codexが「このMCPリソースを操作していいですよ」という許可(access token)をWorkOS経由で受け取り、Honoがその許可を検証してからMCPツールを実行する、という流れになります。
Codexで codex mcp login [mcpツール名] を実行すると、おおむね次の流れになります。

このフローについて大まかではありますが、実装方法の解説をします。
401とProtected Resource Metadata(図の1~4)
OAuthフローの起点となるのが、Protected Resource Metadata(RFC 9728の規格)です。
トークンなしで MCPサーバーに直接アクセスすると、Honoは401を返し、WWW-Authenticate ヘッダーに resource_metadata のURLを載せます。Codexはそこから「どの認可サーバーにログインすればよいか」を自動で知ります。
Honoでは以下のように実装します。
// 一部抜粋
app.route(
"/",
simpleMcpAuthRouter({
issuer: config.workosAuthkitDomain,
resourceServerUrl: new URL(config.mcpResourceUrl),
scopesSupported: ["openid", "profile", "email"],
}),
);simpleMcpAuthRouter を使って認証なしで公開し、Codexが「どの認可サーバー(WorkOS)にログインすればよいか」を自動で知れるようにします。
トークンなしで /mcp にPOSTすると401が返ります。このとき WWW-Authenticate ヘッダーにRFC 9728に沿ったメタデータURLを載せて返却するようにします。以下のようなヘッダーをオリジンを元に生成する関数を用意します。
export function buildChallengeHeader(): string {
const config = getConfig();
const rsUrl = new URL(config.mcpResourceUrl);
const rsPath = rsUrl.pathname === "/" ? "" : rsUrl.pathname;
const prmUrl = `${rsUrl.origin}/.well-known/oauth-protected-resource${rsPath}`;
return `Bearer error="Unauthorized", ..., resource_metadata="${prmUrl}"`;
}@hono/mcpのbearerAuth ミドルウェアを使って、トークンがない場合・無効な場合の両方でこのヘッダーを返すよう設定しています。
const challengeHeader = buildChallengeHeader()
app.use(path, bearerAuth({
verifyToken: async (token) => (await verifyAccessToken(token)) !== null,
noAuthenticationHeader: { wwwAuthenticateHeader: challengeHeader },
invalidToken: { wwwAuthenticateHeader: challengeHeader },
}));HonoはMCPの認証を作るクライアントが整備されていてとても使い勝手が良いです。
OAuth2.1認可~accessTokenを受け取るところまで(図の5~8)
前のステップでクライアントはどのような方法・URLに認可を受ければ良いのかを知ることができました。次に実際に認可サーバーにリクエストを送り、MCPツールを操作するのに必要なaccessTokenを得る必要があります。
この認可サーバーはWorkOSというSaaSを使い、自身でサーバー運用しない構成としました。
今回はWorkOSは自分自身以外の認証を弾く(第三者が利用できない状態)ために以下の設定を行なっています。
- Sign upをOFFにして新規登録を禁止とする(WorkOSから直接inviteしたユーザーのみ認証)。
- Radar allowlistで自分のメールアドレスだけホワイトリスト形式で許可する。
- Resource Indicatorで該当のMCPのURLのみを許可する。
ちなみに二重防御としてHonoのサーバー側でもこれらの権限などをチェックしています。
Resource IndicatorでURLを許可することによって、ログイン成功時にCodexなどにaccessTokenが付与されます。
MCPのツールにリクエストする。JWTの検証(図の9~11)
accessTokenが付与されたので、これでCodexはMCPを経由してリクエストをする準備ができました。
このリクエストに対してもJWTの署名検証を行うのがこのフェーズです。 issuer (WorkOSのAuthkitのドメインと一致しているか)や sub ユーザーが正しいのか検証するフェーズです。
jose の jwtVerify を使って検証します。
export async function verifyAccessToken(token: string): Promise<JWTPayload | null> {
const config = getConfig();
try {
const { payload } = await jwtVerify(token, getJwks(), {
issuer: config.workosAuthkitDomain,
audience: config.mcpResourceUrl,
});
const sub = payload.sub
if (!sub || !config.allowedUserIds.includes(sub)) return null;
return payload;
} catch {
return null;
}
}認証を通過したPOSTだけがMCPのツール群を呼び出せるという仕組みです。
サーバーの起動の仕方や、ツールの登録方法などは microcms-mcp-server を参考にすると良いと思います(この記事では省略します)。
https://github.com/microcmsio/microcms-mcp-server/blob/main/src/server.ts
Vercelのサーバーレス環境でリモートMCPサーバーを建てる時のポイントは StreamableHTTPTransport を使うことです。
サーバーレス環境ではプロセスを常時起動できないため、リクエストごとにMCPサーバーとtransportを生成して呼び出す構成にしています。
async function handleMcpRequest(c: Context) {
const server = createMcpServer();
const transport = new StreamableHTTPTransport({
sessionIdGenerator: undefined,
enableJsonResponse: true,
});
await server.connect(transport);
const parsedBody = await c.req.json().catch(() => undefined);
const response = await transport.handleRequest(c, parsedBody);
await transport.close();
await server.close();
return response ?? c.text("Internal Server Error", 500);
}これで基本的なOAuthフローの仕組みと処理のフローの解説は以上です。これらの流れを理解してプロンプトにすれば大まかに実装できるかと思います。
これらのOAuthワークフローを守ればセキュアに認証できますが、追加で以下のような対策も検討すると良いと思います。
- レート制限を入れる。
- 監査ログを入れる。
- APIキーはVercelの環境変数のみに置く(基本的に上記の手順でやれば問題ないかと思います)
- APIキーは分離して、MCPキー用のキーを発行する。不必要な書き込み権限を付与しない。
独自実装のブログ執筆ツールの例
最後に私がどのようなツールを登録しているのか一例を紹介します。
便利なのが下書きを作成するツールです。
export async function handleCreateBlogDraft(params: CreateBlogDraftParams) {
const htmlBody = bodyFormat === "html" ? body : markdownToHtml(body);
const created = await createBlogDraft(client, { title, body: htmlBody });
const draftKey = await getManagementContentDraftKey("blogs", created.id);
return {
id: created.id,
draftKey,
previewUrl: buildPreviewUrl(config.siteOrigin, created.id, draftKey),
};
}レスポンスにpreview用のURLを含めることで、CodexなどのAIクライアント上で下書きプレビューを確認できます。
その他にも画像をアップロードするツールを少しカスタマイズして、画像データのまま投稿したり圧縮するツールなどを登録しています。
またAIクライアントを活用したツールとしてはカテゴリーを付与するツールもあります。
自分のブログでは、microCMSで
{
"id": "18q267gniw",
"createdAt": "2026-05-27T14:19:25.602Z",
"updatedAt": "2026-05-27T14:19:25.602Z",
"publishedAt": "2026-05-27T14:19:25.602Z",
"revisedAt": "2026-05-27T14:19:25.602Z",
"name": "読書",
"bg": "#F5F1E8",
"border": "#8D6E63"
}のようにカラーコードを付与したデータを持っているのですが、これを自動で既存のカテゴリーのカラーを見て自動作成して記事に付与するツールなどを作成しています。
このように通常のAPIだけでは組めないようなワークフローをAIクライアント上で組めるのもリモートMCPサーバーのメリットなのかなと思います。
ただし、公開まではMCPで自動化していません。下書き作成と更新まではAIに任せ、最終的な公開はmicroCMSの管理画面で人間が確認して行う方針にしています。ここは自分のブログでも、公式ブログに載せる記事でも大事な線引きだと思っています。
まとめ
今回のリモートMCPサーバーは、microCMSをAIエージェントから操作するための入口です。ただ、作ってみると単なるAPIラッパーではなく、ブログを書く、画像を入れる、カテゴリーを整える、プレビューで確認する、という運用そのものをツール化する感覚に近いと感じました。
Hono、WorkOS、Vercelを組み合わせることで、個人ブログでも現実的に運用できるリモートMCPサーバーになりました。
AIに何でも任せるというより、人間が確認すべき場所を残したまま、繰り返しの作業をツールに寄せる。
そのためのインターフェースとして、リモートMCPサーバーはかなり使いやすい選択肢だと思います。
参考
- What is the Model Context Protocol (MCP)?: https://modelcontextprotocol.io/docs/getting-started/intro
- Hono: https://hono.dev/
- WorkOS: https://workos.com/
- 一番わかりやすいOAuthの説明: https://qiita.com/TakahikoKawasaki/items/e37caf50776e00e733be