前書き
Streamable HTTP対応のMCPサーバーを気軽にデプロイしたい!
その思いから@vercel/mcp-adapter
と出会いました。使用感も良好で、皆さんに紹介したいと思います。
MCPについてまだご存知でない方は、こちらのスライドをご覧ください。
プロジェクト初期化
まずはNext.jsのプロジェクトを初期化します。
Next.jsを使ってMCPサーバーを作るのは少し不思議な感覚ですが、Next.jsは普通にAPIサーバーとしても使えるので、フルスタック開発が可能です。
npx create-next-app@latest my-mcp-server
初期化完了したら、@vercel/mcp-adapter
と zod
をインストールします。
npm install @vercel/mcp-adapter zod
下記のファイルを追加します。
シンプルなツールで、使用するとランダムに点数が返ってきます。
import { z } from 'zod';
import { createMcpHandler } from '@vercel/mcp-adapter';
const handler = createMcpHandler(
(server) => {
server.tool(
'roll_dice',
'Rolls an N-sided die',
{ sides: z.number().int().min(2) },
async ({ sides }) => {
const value = 1 + Math.floor(Math.random() * sides);
return {
content: [{ type: 'text', text: `🎲 You rolled a ${value}!` }],
};
},
);
},
{},
{ basePath: '/api' },
);
export { handler as GET, handler as POST, handler as DELETE };
実装は以上です!
VScodeからテストします
まずはNext.jsのローカルサーバーを立ち上げます。
npm run dev
VScodeの設定を開き、settings.json
を編集します。
下記の内容を追加してください。
portは実際に立ち上げたサーバーの利用ポートに変更してください。
"local-server": {
"url": "http://localhost:3000/api/mcp"
}
次はCopilotを開き、エージェントモード でツールを利用するようにプロンプトを投げてください。
特に問題がなければ、ダイスの結果が返ってきます。
MCP Inspectorからテストします
VScodeがインストールされてない場合、MCP Inspector
からでも接続テストを行えます。
npx @modelcontextprotocol/inspector
実行後、下記の内容が出力されると思います。
...
Session Tokenに ⚙️ Proxy server listening on 127.0.0.1:6277
🔑 Session token: token_value
...
http://127.0.0.1:6274 にアクセスして MCP Inspector を開きます。
-
Transport Type
で「Streamable HTTP」を選択する -
URL
に http://localhost:3000/api/mcp を入力する -
Proxy Session Token
にtoken_valueを入力する
Connect
ボタンをクリックすれば、MCPサーバーに接続できます。
mcp-adapterの認証
公式のドキュメントには記載されていませんが、mcp-adapter
には認証用の関数が用意されています。
まだ検証段階のようですが、experimental_withMcpAuth
という関数です。
src/app/api/mcp/route.ts
のcodeを下記のように修正してください。
import { z } from 'zod';
import { createMcpHandler,experimental_withMcpAuth } from '@vercel/mcp-adapter';
const handler = createMcpHandler(
(server) => {
server.tool(
'roll_dice',
'Rolls an N-sided die',
{ sides: z.number().int().min(2) },
async ({ sides }, {authInfo}) => {
console.log('authInfo', authInfo);
if (!authInfo?.token) {
return { content: [{ type: "text", text: "Unauthorized" }] };
}
const value = 1 + Math.floor(Math.random() * sides);
return {
content: [{ type: 'text', text: `🎲 You rolled a ${value}!` }],
};
},
);
server.tool(
'story_list',
'Display a list of stories owned by this user',
{},
async ({}, {authInfo}) => {
console.log('authInfo', authInfo);
if (!authInfo?.token) {
return { content: [{ type: "text", text: "Unauthorized" }] };
}
return {
content: [{ type: 'text', text: `黒い馬,天から降りる災難` }],
};
},
)
},
{},
{ basePath: '/api' },
);
const wrappedHandler = async (req: Request) => {
const authHandler = experimental_withMcpAuth(handler, (req) => {
const header = req.headers.get("Authorization");
if (header?.startsWith("Bearer ")) {
const token = header.slice(7).trim();
return Promise.resolve({
token,
clientId: "agent-mcp",
scopes: ["runAgent"],
});
}
return undefined;
});
return authHandler(req);
};
export { wrappedHandler as GET, wrappedHandler as POST, wrappedHandler as DELETE };
VScodeのsettings.json
に、headers
を追加し、Bearer tokenを渡せるようにします。
"local-server": {
"url": "http://localhost:3000/api/mcp",
"headers": {
"Authorization": "Bearer my-api-key",
},
}
修正後、再度VScodeからMCPサーバーのツールを呼び出してみると、
追加したlogの内容が出力されたことが確認できます。
authInfo { token: 'my-api-key', clientId: 'agent-mcp', scopes: [ 'runAgent' ] }
Vercelにデプロイ
作業中にプロジェクトをGitHubにプッシュしてから、Vercelで連携するのが最も簡単な方法ですね。
オプションはデフォルトのままで大丈夫です。
デプロイが完了すると、Vercelから提供されるドメインが付与されます。
それを使って、デプロイされたMCPサーバーに接続してみます。
"vercel-server": {
+ "url": "https://xxxx-xxx.vercel.app/api/mcp",
"headers": {
"Authorization": "Bearer my-api-key",
},
}
VercelにデプロイされたMCP Serverのツールも呼び出しに成功することがわかります。
Vercelのダッシュボードからログの内容を確認することができます。
Next.js製のMCPサーバーを簡単にデプロイできて良いですね。
しかもクライアントとしての機能も残しているため、管理が楽で便利です。
AWS Amplifyでもいけるか
AWS Amplifyは、Webアプリケーションやモバイルアプリケーションを構築、デプロイ、管理するためのフルスタック開発プラットフォームです。
Next.jsのプロジェクトも簡単にデプロイできます。
GitHub
とAmplify
の連携が完了したら、リポジトリとブランチを選択して、「次へ」
アプリケーションの設定はそのままで大丈夫です。
最後に特に問題がなければ、「保存してデプロイ」。
初回デプロイは多少時間がかかりますが、それでも5分以内にロケットの打ち上げが確認できるでしょう。
URLをAmplifyから付与されたURLに変更します。
+ "amplify-server": {
+ "url": "https://main.xxxxx.amplifyapp.com/api/mcp",
"headers": {
"Authorization": "Bearer my-api-key",
},
}
問題なくツールを呼び出せます。
ログも確認してみましょう!
Amplifyのモニタリングからホスティングしているコンピューティングログ
を開き、
CloudWatch ログストリームを確認します
何が嬉しいかというと、AmplifyでMCPサーバーをデプロイすれば、既存のAWSリソースを利用できることです。
簡単にファイアウォールやカスタムドメインを追加することができます。
検証に使用したリポジトリ
参考資料