search_database
Search RPG Maker MZ game databases to find actors, enemies, skills, and items using filters for name, ID range, and specific data types.
Instructions
Search game database (actors, enemies, skills, items, etc.) with filters
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id_max | No | Maximum ID | |
| id_min | No | Minimum ID | |
| name_contains | No | Filter by name containing text | |
| project_path | Yes | Project path | |
| types | No | Database types to search |
Implementation Reference
- src/database-index.ts:135-244 (handler)Main handler function that implements the search logic: builds database index from JSON files, applies filters (type, name, ID range, properties), and returns matching results.export async function searchDatabase( projectPath: string, options: SearchOptions ): Promise<{ success: boolean; results?: SearchResult[]; error?: string }> { try { await Logger.info("Searching database", { projectPath, options }); const index = await buildDatabaseIndex(projectPath); const results: SearchResult[] = []; // 検索対象のタイプを決定 const types = options.type || [ "actor", "class", "skill", "item", "weapon", "armor", "enemy", "troop", "state", "animation", "tileset", "commonEvent" ]; for (const type of types) { let dataMap: Map<number, any>; switch (type) { case "actor": dataMap = index.actors; break; case "class": dataMap = index.classes; break; case "skill": dataMap = index.skills; break; case "item": dataMap = index.items; break; case "weapon": dataMap = index.weapons; break; case "armor": dataMap = index.armors; break; case "enemy": dataMap = index.enemies; break; case "troop": dataMap = index.troops; break; case "state": dataMap = index.states; break; case "animation": dataMap = index.animations; break; case "tileset": dataMap = index.tilesets; break; case "commonEvent": dataMap = index.commonEvents; break; default: continue; } for (const [id, data] of dataMap.entries()) { // ID範囲フィルター if (options.idRange) { if (options.idRange.min !== undefined && id < options.idRange.min) continue; if (options.idRange.max !== undefined && id > options.idRange.max) continue; } // 名前検索フィルター if (options.nameContains) { const name = (data.name || "").toLowerCase(); if (!name.includes(options.nameContains.toLowerCase())) continue; } // プロパティ存在フィルター if (options.hasProperty) { if (!(options.hasProperty in data)) continue; } results.push({ type, id, name: data.name || `${type} ${id}`, data }); } } await Logger.info("Database search complete", { resultsCount: results.length }); return { success: true, results }; } catch (error) { await Logger.error("Failed to search database", { projectPath, error }); return { success: false, error: error instanceof Error ? error.message : String(error) }; } }
- src/index.ts:794-807 (schema)Input schema for the search_database tool, defining parameters: project_path (required), types (array), name_contains, id_min, id_max.{ name: "search_database", description: "Search game database (actors, enemies, skills, items, etc.) with filters", inputSchema: { type: "object", properties: { project_path: { type: "string", description: "Project path" }, types: { type: "array", items: { type: "string" }, description: "Database types to search" }, name_contains: { type: "string", description: "Filter by name containing text" }, id_min: { type: "number", description: "Minimum ID" }, id_max: { type: "number", description: "Maximum ID" }, }, required: ["project_path"], },
- src/index.ts:1447-1459 (registration)MCP tool dispatch handler that maps incoming tool arguments to the searchDatabase function and formats the response.case "search_database": { const result = await searchDatabase(args.project_path as string, { type: args.types as string[], nameContains: args.name_contains as string, idRange: { min: args.id_min as number, max: args.id_max as number } }); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }], }; }
- src/database-index.ts:45-130 (helper)Helper function that builds the in-memory DatabaseIndex from project data files, used by searchDatabase.export async function buildDatabaseIndex(projectPath: string): Promise<DatabaseIndex> { await validateProjectPath(projectPath); await Logger.info("Building database index", { projectPath }); const dataDir = path.join(projectPath, "data"); const index: DatabaseIndex = { projectPath, lastUpdated: new Date().toISOString(), actors: new Map(), classes: new Map(), skills: new Map(), items: new Map(), weapons: new Map(), armors: new Map(), enemies: new Map(), troops: new Map(), states: new Map(), animations: new Map(), tilesets: new Map(), commonEvents: new Map(), nameIndex: new Map() }; // 各データベースファイルを読み込み const databases = [ { file: "Actors.json", map: index.actors, type: "actor" }, { file: "Classes.json", map: index.classes, type: "class" }, { file: "Skills.json", map: index.skills, type: "skill" }, { file: "Items.json", map: index.items, type: "item" }, { file: "Weapons.json", map: index.weapons, type: "weapon" }, { file: "Armors.json", map: index.armors, type: "armor" }, { file: "Enemies.json", map: index.enemies, type: "enemy" }, { file: "Troops.json", map: index.troops, type: "troop" }, { file: "States.json", map: index.states, type: "state" }, { file: "Animations.json", map: index.animations, type: "animation" }, { file: "Tilesets.json", map: index.tilesets, type: "tileset" }, { file: "CommonEvents.json", map: index.commonEvents, type: "commonEvent" } ]; for (const { file, map, type } of databases) { try { const data = await FileHelper.readJSON(path.join(dataDir, file)); if (Array.isArray(data)) { for (let i = 0; i < data.length; i++) { const item = data[i]; if (item && item.id !== undefined) { map.set(item.id, item); // 名前インデックスに追加 if (item.name) { const key = item.name.toLowerCase(); if (!index.nameIndex.has(key)) { index.nameIndex.set(key, []); } index.nameIndex.get(key)!.push({ type, id: item.id }); } } } } } catch (error) { await Logger.warn(`Failed to load ${file}`, { error }); } } const totalEntries = index.actors.size + index.classes.size + index.skills.size + index.items.size + index.weapons.size + index.armors.size + index.enemies.size + index.troops.size + index.states.size + index.animations.size + index.tilesets.size + index.commonEvents.size; await Logger.info("Database index built", { totalEntries, uniqueNames: index.nameIndex.size }); return index; }