#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import { v0 } from "v0-sdk";
import * as dotenv from "dotenv";
dotenv.config();
// 型定義
interface GeneratePrototypeArgs {
requirements: string;
model?: "v0-1" | "v0-2";
}
// V0レスポンス用の型定義(将来の拡張用)
// interface V0Response {
// success: boolean;
// chatId?: string;
// demoUrl?: string;
// files?: Array<{
// name: string;
// path: string;
// type: string;
// }>;
// error?: string;
// createdAt?: string;
// timestamp?: string;
// }
class V0MCPServer {
private server: Server;
constructor() {
this.server = new Server(
{
name: "v0-mcp-server",
version: "0.1.0",
},
{
capabilities: {
tools: {},
},
}
);
this.setupHandlers();
}
private setupHandlers(): void {
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "generate_prototype",
description: "v0 Platform APIを使って要件からプロトタイプを生成し、デモURLを返します",
inputSchema: {
type: "object",
properties: {
requirements: {
type: "string",
description: "プロトタイプの要件を自然言語で記述",
},
model: {
type: "string",
description: "使用するモデル(オプション)",
enum: ["v0-1", "v0-2"],
default: "v0-2",
},
},
required: ["requirements"],
},
},
],
};
});
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === "generate_prototype") {
const args = request.params.arguments as unknown as GeneratePrototypeArgs;
return await this.generatePrototype(args);
}
throw new Error(`Unknown tool: ${request.params.name}`);
});
}
private async generatePrototype(args: GeneratePrototypeArgs): Promise<any> {
const { requirements } = args;
if (!requirements || typeof requirements !== "string") {
throw new Error("requirements parameter is required and must be a string");
}
const apiKey = process.env.V0_API_KEY;
if (!apiKey) {
throw new Error(
"V0_API_KEY environment variable is required. Please set it in your MCP client configuration."
);
}
try {
const chat = await v0.chats.create({
message: requirements,
});
return {
content: [
{
type: "text",
text: JSON.stringify({
success: true,
chatId: chat.id,
demoUrl: chat.demo,
files: chat.files?.map((file: any) => ({
name: file.name,
path: file.path,
type: file.type,
})) || [],
createdAt: new Date().toISOString(),
}, null, 2),
},
],
};
} catch (error) {
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
return {
content: [
{
type: "text",
text: JSON.stringify({
success: false,
error: errorMessage,
timestamp: new Date().toISOString(),
}, null, 2),
},
],
isError: true,
};
}
}
async run(): Promise<void> {
const transport = new StdioServerTransport();
await this.server.connect(transport);
console.error("V0 MCP Server running on stdio");
}
}
const server = new V0MCPServer();
server.run().catch((error) => {
console.error("Failed to run server:", error);
process.exit(1);
});