Skip to main content
Glama
manfye

Data.gov.my MCP Server

by manfye

search_catalogues

Find Malaysian government datasets by searching catalogue names and descriptions with keywords. Use this tool to discover relevant open data from Data.gov.my.

Instructions

Search for catalogues by keyword in their names or descriptions.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
keywordYesKeyword to search for in catalogue names/descriptions

Implementation Reference

  • src/index.ts:105-115 (registration)
    Registration of the 'search_catalogues' tool in the ListTools response, including its name, description, and input schema definition.
    { name: 'search_catalogues', description: 'Search for catalogues by keyword in their names or descriptions.', inputSchema: { type: 'object', properties: { keyword: { type: 'string', description: 'Keyword to search for in catalogue names/descriptions' } }, required: ['keyword'], }, },
  • Core handler implementation for the 'search_catalogues' tool. Validates input, fetches catalogue list from GitHub, retrieves metadata for up to 20 catalogues, searches for keyword matches in title, description, or ID, and returns matching results.
    } else if (name === 'search_catalogues') { if (!isSearchArgs(args)) { throw new McpError(ErrorCode.InvalidParams, 'Missing required parameter: keyword'); } console.error(`[GitHub] Searching catalogues for keyword: ${args.keyword}`); // First get the list of all catalogues const listResponse = await this.githubAxios.get('/repos/data-gov-my/datagovmy-meta/contents/data-catalogue'); const catalogueFiles = (listResponse.data as GitHubFile[]) .filter((item: GitHubFile) => item.type === 'file' && item.name.endsWith('.json')) .map((item: GitHubFile) => ({ id: item.name.replace('.json', ''), download_url: item.download_url })); // Search through metadata for matching catalogues const matchingCatalogues = []; const keyword = args.keyword.toLowerCase(); for (const catalogue of catalogueFiles.slice(0, 20)) { // Limit to first 20 to avoid rate limits try { const metadataResponse = await axios.get(catalogue.download_url); const metadata = metadataResponse.data; const titleMatch = metadata.title && metadata.title.toLowerCase().includes(keyword); const descMatch = metadata.description && metadata.description.toLowerCase().includes(keyword); const idMatch = catalogue.id.toLowerCase().includes(keyword); if (titleMatch || descMatch || idMatch) { matchingCatalogues.push({ id: catalogue.id, title: metadata.title || catalogue.id, description: metadata.description || 'No description available', match_reason: titleMatch ? 'title' : descMatch ? 'description' : 'id' }); } } catch (error) { console.error(`[Warning] Failed to fetch metadata for ${catalogue.id}:`, (error as Error).message); } } return { content: [ { type: 'text', text: JSON.stringify({ keyword: args.keyword, matches: matchingCatalogues, count: matchingCatalogues.length, message: `Found ${matchingCatalogues.length} catalogues matching "${args.keyword}".` }, null, 2), }, ], };
  • TypeScript type definition (SearchArgs) and type guard (isSearchArgs) used for input validation in the search_catalogues handler.
    interface SearchArgs { keyword: string; } // Type guards function isCatalogueArgs(args: any): args is CatalogueArgs { return args && typeof args.id === 'string'; } function isSearchArgs(args: any): args is SearchArgs { return args && typeof args.keyword === 'string'; }
  • JSON input schema defined for the search_catalogues tool in the tool registration.
    inputSchema: { type: 'object', properties: { keyword: { type: 'string', description: 'Keyword to search for in catalogue names/descriptions' } }, required: ['keyword'],

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/manfye/data-dosm-mcp-nodejs'

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