Skip to main content
Glama
naoto24kawa

Composer Package README MCP Server

by naoto24kawa
search-packages.ts4.29 kB
import { logger } from '../utils/logger.js'; import { packagistApi } from '../services/packagist-api.js'; import { withCache, createSearchCacheKey } from '../utils/cache-helpers.js'; import { CACHE_CONSTANTS } from '../utils/constants.js'; import { SearchPackagesParams, SearchPackagesResponse, PackageSearchResult, } from '../types/index.js'; export async function searchPackages(params: SearchPackagesParams): Promise<SearchPackagesResponse> { const { query, limit = 20, quality, popularity, type } = params; logger.info(`Searching packages: ${query} (limit: ${limit})`); const cacheKey = createSearchCacheKey(query, limit, type); return withCache(cacheKey, async () => { return await performPackageSearch(query, limit, quality, popularity, type); }, CACHE_CONSTANTS.SEARCH_RESULT_TTL_MS); } async function performPackageSearch( query: string, limit: number, quality?: number, popularity?: number, type?: string ): Promise<SearchPackagesResponse> { try { // Search packages on Packagist const searchResult = await packagistApi.searchPackages(query, limit, type); // Transform results to our format and apply quality/popularity filters let packages: PackageSearchResult[] = searchResult.results.map(pkg => { // Calculate scores based on available metrics const qualityScore = calculateQualityScore(pkg); const popularityScore = calculatePopularityScore(pkg); const maintenanceScore = 0.8; // Default maintenance score const finalScore = (qualityScore + popularityScore + maintenanceScore) / 3; return { name: pkg.name, version: 'latest', // Packagist search doesn't provide version info description: pkg.description || 'No description available', keywords: [], // Packagist search API doesn't provide keywords author: extractAuthorFromName(pkg.name), publisher: extractAuthorFromName(pkg.name), maintainers: [extractAuthorFromName(pkg.name)], // Simplified score: { final: finalScore, detail: { quality: qualityScore, popularity: popularityScore, maintenance: maintenanceScore, } }, searchScore: finalScore, // Use same as final score }; }); // Apply quality filter if specified if (quality !== undefined) { packages = packages.filter(pkg => pkg.score.detail.quality >= quality); } // Apply popularity filter if specified if (popularity !== undefined) { packages = packages.filter(pkg => pkg.score.detail.popularity >= popularity); } const response: SearchPackagesResponse = { query, total: packages.length, // Total after filtering packages, }; logger.info(`Successfully searched packages: ${query}, found ${packages.length} results`); return response; } catch (error) { logger.error(`Failed to search packages: ${query}`, { error }); throw error; } } function calculateQualityScore(pkg: any): number { // Calculate quality based on available metrics let score = 0.5; // Base score // Higher score for packages with description if (pkg.description && pkg.description.trim().length > 0) { score += 0.2; } // Higher score for packages with more downloads if (pkg.downloads > 10000) { score += 0.2; } else if (pkg.downloads > 1000) { score += 0.1; } // Cap at 1.0 return Math.min(score, 1.0); } function calculatePopularityScore(pkg: any): number { // Calculate popularity based on downloads and favers let score = 0.1; // Base score // Downloads contribution if (pkg.downloads > 100000) { score += 0.5; } else if (pkg.downloads > 10000) { score += 0.3; } else if (pkg.downloads > 1000) { score += 0.2; } // Favers contribution if (pkg.favers > 100) { score += 0.3; } else if (pkg.favers > 10) { score += 0.2; } else if (pkg.favers > 1) { score += 0.1; } // Cap at 1.0 return Math.min(score, 1.0); } function extractAuthorFromName(packageName: string): string { // Extract vendor/author from package name (vendor/package format) const parts = packageName.split('/'); return parts.length > 0 && parts[0] ? parts[0] : 'Unknown'; }

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/naoto24kawa/composer-package-readme-mcp-server'

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