Skip to main content
Glama
djalal

quran-mcp-server

by djalal

list-chapters

Retrieve Quran chapters in a specified language using the 'list-chapters' tool from the quran-mcp-server. Simplify Quran navigation by accessing chapter details in your preferred language.

Instructions

List Chapters

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
languageYesParameter language (e.g., 'en', 'ar', 'fr-CA')

Implementation Reference

  • MCP tool handler for 'list-chapters': validates input args using Zod schema, delegates to chaptersService.listChapters, formats JSON response as text content, handles errors with verbose logging.
    export async function handleListChapters(args: any) {
      try {
        // Validate arguments
        const validatedArgs = listChaptersSchema.parse(args);
        
        // Call the service
        const result = await chaptersService.listChapters(validatedArgs);
        
        // Log the response in verbose mode
        verboseLog('response', {
          tool: 'list-chapters',
          result
        });
        
        return {
          content: [
            {
              type: "text",
              text: JSON.stringify(result, null, 2)
            }
          ]
        };
      } catch (error) {
        verboseLog('error', {
          tool: 'list-chapters',
          error: error instanceof Error ? error.message : String(error)
        });
        
        if (error instanceof z.ZodError) {
          return {
            content: [{ 
              type: "text", 
              text: `Validation error: ${error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ')}`
            }],
            isError: true,
          };
        }
        
        return {
          content: [{ 
            type: "text", 
            text: `Error: ${error instanceof Error ? error.message : "Unknown error"}`
          }],
          isError: true,
        };
      }
    }
  • Zod input validation schema for 'list-chapters' tool defining the required 'language' parameter with constraints and description.
    export const listChaptersSchema = z.object({
      language: z.string()
        .trim()
        .min(2, "Language code must be at least 2 characters")
        .max(10, "Language code must not exceed 10 characters")
        .regex(/^[a-zA-Z-]+$/, "Language code must contain only letters and hyphens")
        .describe("Parameter language (e.g., 'en', 'ar', 'fr-CA')"),
    });
  • src/server.ts:124-128 (registration)
    Registration of 'list-chapters' tool in the MCP server's listTools handler: specifies name, description, input schema (converted from Zod), and usage examples.
      name: ApiTools.list_chapters,
      description: "List Chapters",
      inputSchema: zodToJsonSchema(chaptersSchemas.listChapters),
      examples: toolExamples['list-chapters'],
    },
  • src/server.ts:257-258 (registration)
    Dispatch registration in MCP server's callTool handler: routes 'list-chapters' tool calls to the handleListChapters function.
    case ApiTools.list_chapters:
      return await handleListChapters(request.params.arguments);
  • Helper service method implementing core 'list-chapters' logic: parameter validation, caching, API call to Quran.com /chapters endpoint, data reduction, verbose logging, fallback to mock data on API failure or errors.
    async listChapters(params: z.infer<typeof listChaptersSchema>): Promise<ListChaptersResponse> {
      try {
        // Validate parameters
        const validatedParams = listChaptersSchema.parse(params);
        
        // Generate cache key based on parameters
        const cacheKey = `chapters_${validatedParams.language || 'en'}`;
        
        // Check cache first
        const cachedData = this.chaptersCache.get(cacheKey);
        if (cachedData) {
          verboseLog('response', {
            method: 'listChapters',
            source: 'cache',
            cacheSize: this.chaptersCache.size()
          });
          
          return {
            success: true,
            message: "list-chapters executed successfully (from cache)",
            data: cachedData
          };
        }
        
        try {
          // Make request to Quran.com API
          const url = `${API_BASE_URL}/chapters`;
          const response = await makeApiRequest(url, {
            language: validatedParams.language
          });
          
          // Process and reduce the data to only essential fields
          const reducedData = {
            chapters: response.chapters.map((chapter: any) => ({
              id: chapter.id,
              name_arabic: chapter.name_arabic,
              name_simple: chapter.name_simple,
              translated_name: { 
                name: chapter.translated_name?.name || "" 
              }
              // Only include essential fields
            }))
          };
          
          verboseLog('response', {
            method: 'listChapters',
            source: 'api',
            dataSize: JSON.stringify(reducedData).length
          });
          
          // Update cache with the new data
          this.chaptersCache.set(cacheKey, reducedData);
          
          return {
            success: true,
            message: "list-chapters executed successfully",
            data: reducedData
          };
        } catch (axiosError) {
          verboseLog('error', {
            method: 'listChapters',
            error: axiosError instanceof Error ? axiosError.message : String(axiosError)
          });
          
          // If the API call fails, return mock data
          verboseLog('response', {
            method: 'listChapters',
            source: 'mock',
            reason: 'API unavailable'
          });
          
          const mockData = this.getChaptersMockData();
          
          return {
            success: true,
            message: "list-chapters executed with mock data (API unavailable)",
            data: mockData
          };
        }
      } catch (error) {
        verboseLog('error', {
          method: 'listChapters',
          error: error instanceof Error ? error.message : String(error)
        });
        
        if (error instanceof z.ZodError) {
          throw new ApiError(`Validation error: ${error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ')}`, 400);
        }
        
        // Return mock data as a fallback for any error
        verboseLog('response', {
          method: 'listChapters',
          source: 'mock',
          reason: 'error occurred'
        });
        
        const mockData = this.getChaptersMockData();
        
        return {
          success: true,
          message: "list-chapters executed with mock data (error occurred)",
          data: mockData
        };
      }
    }

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/djalal/quran-mcp-server'

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