Skip to main content
Glama

get_package_details

Retrieve detailed information about Typst packages including description, authors, categories, repository links, import code, and version history.

Instructions

Get detailed information about a specific Typst package, including its description, authors, categories, repository link, import code, and version history.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
packageNameYesThe exact name of the package (e.g., "cetz", "polylux", "fletcher")

Implementation Reference

  • Core handler function that scrapes the Typst Universe package page using Cheerio to extract details like version, description, authors, categories, repository, import code, and version history.
    export async function getPackageDetails(packageName: string): Promise<PackageDetails | null> { const packageUrl = `${UNIVERSE_URL}/package/${packageName}`; try { const html = await fetchPage(packageUrl); const $ = cheerio.load(html); // Extract package name and version from the header const headerText = $('h1').first().text().trim(); // Get the description from meta tag or first paragraph const metaDescription = $('meta[name="description"]').attr('content') || $('meta[property="og:description"]').attr('content') || ''; // Extract the full description from the main content const mainContent = $('main').text().trim(); // Find version in the page const versionMatch = mainContent.match(/(\d+\.\d+\.\d+)/); const version = versionMatch ? versionMatch[1] : 'unknown'; // Extract authors const authors: string[] = []; $('a[href*="author"]').each((_, el) => { const authorName = $(el).text().trim(); if (authorName && !authors.includes(authorName)) { authors.push(authorName); } }); // Extract categories const categories: string[] = []; $('a[href*="category="]').each((_, el) => { const category = $(el).text().trim(); if (category && !categories.includes(category)) { categories.push(category); } }); // Extract repository link let repository: string | undefined; const githubLink = $('a[href*="github.com"]').first().attr('href'); if (githubLink && !githubLink.includes('typst/packages')) { repository = githubLink; } // Extract homepage let homepage: string | undefined; $('a').each((_, el) => { const href = $(el).attr('href'); const text = $(el).text().toLowerCase(); if (href && (text.includes('.io') || text.includes('.com') || text.includes('homepage')) && !href.includes('github.com') && !href.includes('typst.app')) { homepage = href; } }); // Build import code const importCode = `#import "@preview/${packageName}:${version}"`; // Extract version history const versionHistory: string[] = []; $(`a[href^="/universe/package/${packageName}/"]`).each((_, el) => { const versionText = $(el).text().trim(); if (versionText.match(/^\d+\.\d+\.\d+$/)) { versionHistory.push(versionText); } }); return { name: packageName, version, description: metaDescription, fullDescription: mainContent.substring(0, 2000), // Limit full description length authors, categories, repository, homepage, importCode, versionHistory, url: packageUrl, }; } catch (error) { console.error(`Failed to fetch package details for ${packageName}:`, error); return null; } }
  • Zod schema used to validate the input arguments (packageName) for the get_package_details tool.
    const GetPackageDetailsSchema = z.object({ packageName: z.string().min(1, 'Package name is required'), });
  • src/index.ts:50-63 (registration)
    Tool registration in the MCP server's TOOLS array, defining name, description, and JSON input schema.
    { name: 'get_package_details', description: 'Get detailed information about a specific Typst package, including its description, authors, categories, repository link, import code, and version history.', inputSchema: { type: 'object', properties: { packageName: { type: 'string', description: 'The exact name of the package (e.g., "cetz", "polylux", "fletcher")', }, }, required: ['packageName'], }, },
  • Dispatch handler in the main CallToolRequestSchema handler that validates arguments, calls getPackageDetails, handles errors, and formats the response using formatPackageDetails.
    case 'get_package_details': { const validatedArgs = GetPackageDetailsSchema.parse(args); const details = await getPackageDetails(validatedArgs.packageName); if (!details) { return { content: [ { type: 'text', text: `Package "${validatedArgs.packageName}" not found. Please check the package name and try again.`, }, ], isError: true, }; } return { content: [ { type: 'text', text: formatPackageDetails(details), }, ], }; }
  • TypeScript interface defining the structure of the PackageDetails return type from getPackageDetails.
    export interface PackageDetails { name: string; version: string; description: string; fullDescription: string; authors: string[]; categories: string[]; repository?: string; homepage?: string; importCode: string; versionHistory: string[]; url: string; }

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/W1seGit/Typst-Universe-MCP'

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