search-bible
Find Bible verses containing specific keywords in Korean or English across multiple Korean translation versions to support study and reference needs.
Instructions
Search for verses containing specific keywords (searches limited books for demo)
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Search query (Korean or English) | |
| version | No | Bible translation version (default: GAE) | GAE |
Implementation Reference
- src/index.ts:313-331 (registration)Registration of the 'search-bible' tool in the tools array, including name, description, and input schema.name: "search-bible", description: "Search for verses containing specific keywords (searches limited books for demo)", inputSchema: { type: "object", properties: { query: { type: "string", description: "Search query (Korean or English)", }, version: { type: "string", description: "Bible translation version (default: GAE)", enum: ["GAE", "GAE1", "NIR", "KOR", "CEV"], default: "GAE", }, }, required: ["query"], }, },
- src/index.ts:460-490 (handler)Handler implementation for 'search-bible' tool that invokes searchVerses helper, processes results, and returns formatted text content.case "search-bible": { const { query, version = "GAE" } = args as { query: string; version?: string; }; const results = await searchVerses(query, version); if (results.length === 0) { return { content: [ { type: "text", text: `No results found for "${query}" (searched limited books for demo)`, }, ], }; } let result = `# Search Results for "${query}"\n`; result += `Found ${results.length} verses:\n\n`; for (const verse of results) { result += `**${verse.book} ${verse.chapter}:${verse.verse}**\n`; result += `${verse.text}\n\n`; } return { content: [{ type: "text", text: result }], }; }
- src/index.ts:197-239 (helper)Core helper function searchVerses that performs the actual Bible verse search by fetching chapters from limited books and matching query.async function searchVerses( query: string, version: string = "GAE", books?: string[] ): Promise<Array<{ book: string; chapter: number; verse: number; text: string }>> { const results: Array<{ book: string; chapter: number; verse: number; text: string }> = []; const searchLower = query.toLowerCase(); // Determine which books to search const booksToSearch = books || Object.keys(BIBLE_BOOKS); // For demo purposes, we'll search Genesis and Matthew only // In production, you'd want to implement proper search or use the website's search feature const limitedBooks = booksToSearch.slice(0, 2); for (const bookName of limitedBooks) { const bookInfo = BIBLE_BOOKS[bookName]; if (!bookInfo) continue; // Search first few chapters (limit to avoid too many requests) for (let chapter = 1; chapter <= 3; chapter++) { try { const chapterData = await fetchChapter(bookInfo.code, chapter, version); for (const verse of chapterData.verses) { if (verse.text.toLowerCase().includes(searchLower)) { results.push({ book: chapterData.book, chapter: chapterData.chapter, verse: verse.number, text: verse.text, }); } } } catch (error) { // Skip chapters that don't exist break; } } } return results; }
- src/index.ts:143-194 (helper)Supporting helper fetchChapter that scrapes bible website for chapter verses using cheerio, used by searchVerses.async function fetchChapter( bookCode: string, chapter: number, version: string = "GAE" ): Promise<Chapter> { const url = `https://www.bskorea.or.kr/bible/korbibReadpage.php?version=${version}&book=${bookCode}&chap=${chapter}`; const response = await fetch(url); const html = await response.text(); const $ = cheerio.load(html); const verses: Verse[] = []; // Parse verses from span elements // The website uses span elements where verse text starts with verse number $("span").each((i, elem) => { const text = $(elem).text().trim(); // Look for pattern: number followed by spaces and text const match = text.match(/^(\d+)\s+(.+)$/s); if (match) { const verseNum = parseInt(match[1]); let verseText = match[2]; // Remove footnote markers (like 1), 2), etc.) verseText = verseText.replace(/\d+\)/g, "").trim(); // Remove explanatory text that comes after line breaks (like "또는 ...") const lines = verseText.split("\n"); verseText = lines[0].trim(); // Avoid duplicate verses (website has multiple spans per verse) if (!verses.find((v) => v.number === verseNum)) { verses.push({ number: verseNum, text: verseText, }); } } }); const bookInfo = getBookInfo(bookCode); return { book: bookInfo?.name || bookCode, bookKorean: bookInfo?.korean || "", chapter, version, versionName: TRANSLATIONS[version] || version, verses, }; }