Skip to content

Instantly share code, notes, and snippets.

@kuc-arc-f
Last active May 9, 2025 00:44
Show Gist options
  • Save kuc-arc-f/0ab5da6e27c6b3a9d07ad01648d8ce96 to your computer and use it in GitHub Desktop.
Save kuc-arc-f/0ab5da6e27c6b3a9d07ad01648d8ce96 to your computer and use it in GitHub Desktop.
mcp , next.js + Vercel AI example
import { generateText, tool } from "ai";
import { z } from "zod";
// サイコロを振ってください。1から6までの整数を返してください。
export const getNumber = tool({
description: "入力された面数のサイコロを振ります。",
parameters: z.object({
dice: z.number().min(1).describe("サイコロの面数").optional().default(6),
}),
execute: async ({ dice }) => {
return Math.floor(Math.random() * dice) + 1;
},
});
{
"name": "mcp-nextjs",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@ai-sdk/google": "^1.2.11",
"@ai-sdk/react": "^1.2.9",
"ai": "^4.3.9",
"next": "15.3.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"zod": "^3.24.3"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"tailwindcss": "^4",
"typescript": "^5"
}
}
"use client";
import {useState} from 'react';
export default function Chat() {
const [text, setText] = useState<string>("");
const chatStart = async function(){
try{
const elem = document.getElementById("input_text") as HTMLInputElement;
let inText = "";
if(elem){
inText = elem.value;
};
console.log("inText=", inText);
if(!inText){ return; }
const item = {messages: inText};
const body: any = JSON.stringify(item);
const res = await fetch("/api/chat", {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: body
});
const json = await res.json();
console.log(json);
setText(json.text);
} catch(e){
console.error(e);
}
}
return (
<div className="flex flex-col w-full max-w-2xl py-24 mx-auto gap-4">
<h1 className="text-2xl font-bold">MCP-Chat</h1>
<div className="flex flex-col gap-2">
<input
id="input_text"
type="text"
className="w-full p-2 border border-gray-300 rounded dark:disabled:bg-gray-700"
placeholder="Type your message..."
/>
<button
type="button"
className="px-4 py-2 text-white bg-blue-500 rounded hover:bg-blue-600 disabled:bg-gray-700"
onClick={()=>{chatStart()}}
> GO
</button>
<div className="my-2 p-2 bg-gray-100">
{text}
</div>
</div>
</div>
);
}
import { NextResponse } from 'next/server';
import { google } from "@ai-sdk/google";
import { streamText, tool } from "ai";
import { generateText } from 'ai';
import { z } from 'zod';
import { getNumber } from '../../tools/getNumber';
const MODEL_NAME = "gemini-2.0-flash";
export async function POST(req: Request) {
const { messages } = await req.json();
//console.log("msg=", messages);
const result = await generateText({
model: google(MODEL_NAME),
tools: {
getNumber ,
},
maxSteps: 5,
messages: [{ role: "user", content: messages }],
});
console.log("artifact:");
console.log(result.text);
return NextResponse.json({ret: 200, text: result.text});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment