Skip to main content
Glama
oksure

Bible Korean MCP Server

by oksure

compare-translations

Compare Korean Bible translations side-by-side to analyze verse differences across multiple versions. Enter book, chapter, and verse to view parallel translations.

Instructions

Compare a verse across different Korean translations

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
bookYesBook name (English or Korean) or code
chapterYesChapter number
verseYesVerse number
versionsNoArray of version codes to compare (default: all versions)

Implementation Reference

  • The main handler logic for the 'compare-translations' tool within the CallToolRequestSchema switch statement. It parses arguments, finds the book code, fetches the verse from multiple Bible translations using fetchChapter, handles errors, and returns a markdown comparison.
    case "compare-translations": {
      const { book, chapter, verse, versions } = args as {
        book: string;
        chapter: number;
        verse: number;
        versions?: string[];
      };
    
      const bookCode = findBookCode(book);
      if (!bookCode) {
        return {
          content: [
            {
              type: "text",
              text: `Error: Book '${book}' not found.`,
            },
          ],
        };
      }
    
      const versionsToCompare = versions || Object.keys(TRANSLATIONS);
    
      let result = `# ${book} ${chapter}:${verse} - Translation Comparison\n\n`;
    
      for (const versionCode of versionsToCompare) {
        try {
          const chapterData = await fetchChapter(bookCode, chapter, versionCode);
          const verseData = chapterData.verses.find((v) => v.number === verse);
    
          if (verseData) {
            result += `## ${TRANSLATIONS[versionCode] || versionCode}\n`;
            result += `${verseData.text}\n\n`;
          }
        } catch (error) {
          result += `## ${TRANSLATIONS[versionCode] || versionCode}\n`;
          result += `(Error loading this version)\n\n`;
        }
      }
    
      return {
        content: [{ type: "text", text: result }],
      };
    }
  • Input schema definition for the compare-translations tool, defining the expected arguments: book (string), chapter (number), verse (number), and optional versions (array of strings).
    inputSchema: {
      type: "object",
      properties: {
        book: {
          type: "string",
          description: "Book name (English or Korean) or code",
        },
        chapter: {
          type: "number",
          description: "Chapter number",
        },
        verse: {
          type: "number",
          description: "Verse number",
        },
        versions: {
          type: "array",
          items: { type: "string" },
          description: "Array of version codes to compare (default: all versions)",
        },
      },
      required: ["book", "chapter", "verse"],
    },
  • src/index.ts:346-372 (registration)
    The tool registration object included in the 'tools' array used by ListToolsRequestSchema handler. This exposes the tool's name, description, and schema to MCP clients.
    {
      name: "compare-translations",
      description: "Compare a verse across different Korean translations",
      inputSchema: {
        type: "object",
        properties: {
          book: {
            type: "string",
            description: "Book name (English or Korean) or code",
          },
          chapter: {
            type: "number",
            description: "Chapter number",
          },
          verse: {
            type: "number",
            description: "Verse number",
          },
          versions: {
            type: "array",
            items: { type: "string" },
            description: "Array of version codes to compare (default: all versions)",
          },
        },
        required: ["book", "chapter", "verse"],
      },
    },
  • Key helper function used by the handler to fetch and parse a Bible chapter's HTML from the website, extract verses using cheerio, and return structured Chapter data.
    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,
      };
    }
  • Helper function to resolve book name (English, Korean, or code) to the internal book code used in URLs.
    function findBookCode(bookName: string): string | null {
      const normalized = bookName.toLowerCase().trim();
    
      // Try direct match
      for (const [name, info] of Object.entries(BIBLE_BOOKS)) {
        if (name.toLowerCase() === normalized ||
            info.korean === bookName ||
            info.code === normalized) {
          return info.code;
        }
      }
    
      // Try partial match
      for (const [name, info] of Object.entries(BIBLE_BOOKS)) {
        if (name.toLowerCase().includes(normalized) ||
            info.korean.includes(bookName)) {
          return info.code;
        }
      }
    
      return null;
    }

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/oksure/bible-ko-mcp'

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