Skip to main content
Glama
kokushin

exia-scenario-generator MCP Server

by kokushin

generateScenario

Create Kotonoha Sisters Explainer style scenarios for the exia novel game engine based on your specified topic and display them in a separate window.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
topicYes

Implementation Reference

  • Handler function for the 'generateScenario' tool. Registers the tool, defines input schema {topic: z.string()}, generates scenario using OpenAI helper, parses it, but returns only a confirmation message without the scenario content.
    server.tool("generateScenario", { topic: z.string() }, async ({ topic }) => { try { // シナリオの生成 const rawScenario = await generateVoiceroidScenario({ topic, minLength: 2000 }); // シナリオのパースとexia形式への変換 const scenario = parseVoiceroidScenario(rawScenario); return { content: [ { type: "text", text: `「${topic}」についての琴葉姉妹解説シナリオを生成しました。`, }, ], }; } catch (error) { console.error("Error generating scenario:", error); return { content: [ { type: "text", text: `シナリオの生成に失敗しました: ${error}`, }, ], isError: true, }; } });
  • Core helper function that generates the raw Voiceroid scenario text using OpenAI API with a detailed prompt for Kotoha sisters commentary.
    export async function generateVoiceroidScenario(params: ScenarioGenerationParams): Promise<string> { const { topic, minLength = 2000 } = params; const prompt = ` あなたは「琴葉姉妹解説」形式のシナリオを作成するライターです。 「${topic}」について、琴葉茜と琴葉葵が解説するシナリオを作成してください。 以下の条件を満たすシナリオを作成してください: 1. 琴葉茜と琴葉葵の姉妹が会話形式で解説する 2. 琴葉茜は関西弁でちょっと天然の姉。語尾に「〜やで」「〜やろ」などを使い、積極的に解説を進める。一人称は「うち」。葵のことは「葵」と呼ぶ 3. 琴葉葵は標準語でしっかり者の妹。語尾に「〜だね」「〜だよ」などを使い、茜の暴走を時々制御する。一人称は「わたし」。茜のことは「おねぇちゃん」と呼ぶ 4. 「${topic}」について分かりやすく、かつ詳細に解説する 5. 冒頭で簡単な挨拶と今回のテーマ紹介をする 6. 本編では「${topic}」の基本概念、歴史、重要ポイント、応用例などを解説する 7. 最後に簡単なまとめと締めの挨拶をする 8. 全体の文字数は${minLength}文字以上にする 9. 専門用語がある場合は、初心者にも分かるように噛み砕いて説明する 10. 説明だけでなく、キャラクターの反応や感想も挟めると良い 11. 茜と葵の掛け合いを活かし、時には茜が熱くなりすぎて葵がツッコミを入れるような場面も入れる 12. ナレーションは必要最低限にする。基本的にはキャラクターの会話が中心になるようにする 出力形式: シナリオ全体を出力してください。キャラクターのセリフは「キャラクター名: セリフ内容」の形式で記述してください。 例:「琴葉 茜: いくで!」「琴葉 葵: いくよ!」 短く「茜: 」「葵: 」と書いても構いません。 ナレーションや場面転換は「(ナレーション内容)」の形式で記述してください。「ナレーション:」といった表記や琴葉姉妹の情景描写は不要です。 `; try { const response = await openai.chat.completions.create({ model: "o4-mini-2025-04-16", messages: [ { role: "system", content: "あなたはシナリオライターです。" }, { role: "user", content: prompt }, ], }); return response.choices[0].message.content || ""; } catch (error) { console.error("Error generating scenario with OpenAI:", error); throw new Error(`シナリオ生成に失敗しました: ${error}`); } }
  • Helper function that parses the raw scenario text into structured Exia scenario format with characters and lines.
    export function parseVoiceroidScenario(rawScenario: string): Scenario { const lines: Line[] = []; const characters: Character[] = [ { index: 0, name: "琴葉 茜", imageFile: "chara_01.png", isShow: true, speakerId: 3, }, { index: 1, name: "琴葉 葵", imageFile: "chara_02.png", isShow: true, speakerId: 2, }, ]; // シナリオのパース処理 // 正規表現を使って「キャラクター名: セリフ」の形式を抽出 const scenarioLines = rawScenario.split("\n").filter((line) => line.trim() !== ""); scenarioLines.forEach((line) => { // ナレーション(括弧で囲まれたテキスト)の処理 if (line.trim().startsWith("(") && line.trim().endsWith(")")) { lines.push({ type: 0, // ナレーション text: line.trim().substring(1, line.trim().length - 1), }); return; } // キャラクターのセリフの処理 const match = line.match(/^(琴葉 茜|茜|琴葉 葵|葵)[::](.*)/); if (match) { const characterName = match[1]; const text = match[2].trim(); const characterIndex = characterName === "琴葉 茜" || characterName === "茜" ? 0 : 1; lines.push({ character: { index: characterIndex, }, type: 1, // セリフ text: text, }); return; } // その他のテキストはナレーションとして扱う if (line.trim() !== "") { lines.push({ type: 0, // ナレーション text: line.trim(), }); } }); // 最初のナレーションで挨拶を入れる lines.unshift({ type: 0, text: "琴葉姉妹の解説へようこそ!今回のテーマについて、琴葉茜と琴葉葵が解説します。", }); return { id: "S_000", backgroundFile: "bg_01.webp", currentLineIndex: 0, characters, lines, }; }
  • TypeScript type definitions for ScenarioGenerationParams used in generation, and Scenario/Line/Character structures for Exia format.
    // exiaのシナリオ型定義 export interface Character { index: number; name: string; imageFile: string; isShow: boolean; speakerId?: number; } export interface Line { id?: string; character?: { index?: number; name?: string; imageFile?: string; }; cutIn?: { imageFile?: string; isFullScreen?: boolean; }; type: number; // 0=ナレーション, 1=セリフ, 2=選択肢 text: string; choices?: Array<{ text: string; jumpTo: string; }>; jumpTo?: string; } export interface Scenario { id: string; backgroundFile: string; currentLineIndex: number; characters: Character[]; lines: Line[]; } // シナリオ生成のパラメータ export interface ScenarioGenerationParams { topic: string; minLength?: number; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kokushin/exia-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server