Skip to main content
Glama
naoto24kawa

Composer Package README MCP Server

by naoto24kawa
get-package-readme.ts3.57 kB
import { logger } from '../utils/logger.js'; import { packagistApi } from '../services/packagist-api.js'; import { githubApi } from '../services/github-api.js'; import { readmeParser } from '../services/readme-parser.js'; import { withCache, createPackageReadmeCacheKey } from '../utils/cache-helpers.js'; import { ResponseBuilder } from '../utils/response-builder.js'; import { GetPackageReadmeParams, PackageReadmeResponse, RepositoryInfo, } from '../types/index.js'; export async function getPackageReadme(params: GetPackageReadmeParams): Promise<PackageReadmeResponse> { const { package_name, version = 'latest', include_examples = true } = params; logger.info(`Fetching package README: ${package_name}@${version}`); const cacheKey = createPackageReadmeCacheKey(package_name, version); return withCache(cacheKey, async () => { return await fetchPackageReadme(package_name, version, include_examples); }); } async function fetchPackageReadme( packageName: string, version: string, includeExamples: boolean ): Promise<PackageReadmeResponse> { try { const versionInfo = await getVersionInfo(packageName, version); const readmeContent = await getReadmeContent(versionInfo, packageName); return buildSuccessResponse(packageName, versionInfo, readmeContent, includeExamples); } catch (error) { if ((error as Error).message.includes('not found')) { return ResponseBuilder.createNotFoundResponse(packageName, version); } logger.error(`Failed to fetch package README: ${packageName}@${version}`, { error }); throw error; } } async function getVersionInfo(packageName: string, version: string) { try { logger.debug(`Getting package info for: ${packageName}@${version}`); return await packagistApi.getVersionInfo(packageName, version); } catch (error) { logger.debug(`Package not found: ${packageName}`); throw new Error(`Package ${packageName} not found`); } } async function getReadmeContent(versionInfo: any, packageName: string): Promise<string> { if (!versionInfo.source?.url) { return ''; } const repository: RepositoryInfo = { type: versionInfo.source.type, url: versionInfo.source.url, reference: versionInfo.source.reference, }; const githubReadme = await githubApi.getReadmeFromRepository(repository); if (githubReadme) { logger.debug(`Got README from GitHub: ${packageName}`); return githubReadme; } return ''; } async function buildSuccessResponse( packageName: string, versionInfo: any, readmeContent: string, includeExamples: boolean ): Promise<PackageReadmeResponse> { const actualVersion = versionInfo.version; const cleanedReadme = readmeParser.cleanMarkdown(readmeContent); const usageExamples = readmeParser.parseUsageExamples(readmeContent, includeExamples); const downloadStats = await packagistApi.getDownloadStats(packageName); const response: PackageReadmeResponse = { package_name: packageName, version: actualVersion, description: ResponseBuilder.createBasicInfo(versionInfo, actualVersion).description, readme_content: cleanedReadme, usage_examples: usageExamples, installation: ResponseBuilder.createInstallationInfo(packageName, actualVersion), basic_info: ResponseBuilder.createBasicInfo(versionInfo, actualVersion), repository: ResponseBuilder.createRepositoryInfo(versionInfo), download_stats: downloadStats, exists: true, }; logger.info(`Successfully fetched package README: ${packageName}@${actualVersion}`); return response; }

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