Skip to main content
Glama
elad12390
by elad12390

package_info

Retrieve package details from npm, PyPI, crates.io, or Go modules to evaluate libraries before project integration, including version, dependencies, license, and security status.

Instructions

Look up package information from npm, PyPI, crates.io, or Go modules. Returns version, downloads, license, dependencies, security status, and repository links. Use this to quickly evaluate libraries before adding them to your project. Examples: - package_info("express", reasoning="Need web framework", registry="npm") - package_info("requests", reasoning="HTTP client for API", registry="pypi") - package_info("serde", reasoning="JSON serialization", registry="crates")

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nameYes
reasoningYes
registryNonpm

Implementation Reference

  • The primary handler function for the 'package_info' tool, decorated with @mcp.tool(). It dispatches to the appropriate registry_client.search_* method based on the registry parameter, formats the PackageInfo result using _format_package_info, handles errors, and tracks usage.
    @mcp.tool() async def package_info( name: Annotated[str, "Package or module name to look up"], reasoning: Annotated[str, "Why you're looking up this package (required for analytics)"], registry: Annotated[ Literal["npm", "pypi", "crates", "go"], "Package registry to search (npm, pypi, crates, go)", ] = "npm", ) -> str: """ Look up package information from npm, PyPI, crates.io, or Go modules. Returns version, downloads, license, dependencies, security status, and repository links. Use this to quickly evaluate libraries before adding them to your project. Examples: - package_info("express", reasoning="Need web framework", registry="npm") - package_info("requests", reasoning="HTTP client for API", registry="pypi") - package_info("serde", reasoning="JSON serialization", registry="crates") """ start_time = time.time() success = False error_msg = None result = "" try: if registry == "npm": info = await registry_client.search_npm(name) elif registry == "pypi": info = await registry_client.search_pypi(name) elif registry == "crates": info = await registry_client.search_crates(name) else: # go info = await registry_client.search_go(name) result = clamp_text(_format_package_info(info), MAX_RESPONSE_CHARS) success = True except httpx.HTTPStatusError as exc: error_msg = f"HTTP {exc.response.status_code}" if exc.response.status_code == 404: result = f"Package '{name}' not found on {registry}.\n\nDouble-check the package name and try again." else: result = f"Failed to fetch {registry} package '{name}': HTTP {exc.response.status_code}" except Exception as exc: # noqa: BLE001 error_msg = str(exc) result = f"Failed to fetch {registry} package '{name}': {exc}" finally: # Track usage response_time = (time.time() - start_time) * 1000 tracker.track_usage( tool_name="package_info", reasoning=reasoning, parameters={"name": name, "registry": registry}, response_time_ms=response_time, success=success, error_message=error_msg, response_size=len(result.encode("utf-8")), ) return result
  • Helper function to format the PackageInfo object into a human-readable string response for the package_info tool.
    def _format_package_info(info: PackageInfo) -> str: """Format PackageInfo into readable text response.""" lines = [ f"Package: {info.name} ({info.registry})", "─" * 50, f"Version: {info.version}", ] if info.license: lines.append(f"License: {info.license}") if info.downloads: lines.append(f"Downloads: {info.downloads}") lines.append(f"Last Updated: {info.last_updated}") if info.dependencies_count is not None: lines.append(f"Dependencies: {info.dependencies_count}") if info.security_issues > 0: lines.append(f"⚠️ Security Issues: {info.security_issues}") else: lines.append("Security: ✅ No known vulnerabilities") lines.append("") # blank line if info.repository: lines.append(f"Repository: {info.repository}") if info.homepage and info.homepage != info.repository: lines.append(f"Homepage: {info.homepage}") if info.description: lines.append(f"\nDescription: {info.description}") return "\n".join(lines)
  • Dataclass defining the schema/structure for package metadata returned by the registry client methods used by package_info.
    class PackageInfo: """Structured package metadata from various registries.""" name: str registry: str version: str description: str license: str | None downloads: str | None last_updated: str repository: str | None homepage: str | None dependencies_count: int | None security_issues: int
  • Example backend implementation for npm registry lookup (search_npm method), called by package_info handler when registry='npm'. Similar methods exist for other registries.
    async def search_npm(self, name: str) -> PackageInfo: """Fetch package information from npm registry.""" url = f"https://registry.npmjs.org/{name}" async with httpx.AsyncClient(timeout=self.timeout, headers=self._headers) as client: response = await client.get(url) response.raise_for_status() data = response.json() latest_version = data.get("dist-tags", {}).get("latest", "unknown") version_data = data.get("versions", {}).get(latest_version, {}) # Get weekly downloads from npm API downloads = await self._get_npm_downloads(name) # Parse last update time time_data = data.get("time", {}) last_updated = time_data.get(latest_version) or time_data.get("modified", "unknown") if last_updated != "unknown": last_updated = self._format_time_ago(last_updated) repository = ( version_data.get("repository", {}).get("url") if isinstance(version_data.get("repository"), dict) else version_data.get("repository") ) if repository and repository.startswith("git+"): repository = repository[4:] dependencies = version_data.get("dependencies", {}) return PackageInfo( name=name, registry="npm", version=latest_version, description=version_data.get("description", "No description available"), license=version_data.get("license", "Unknown"), downloads=downloads, last_updated=last_updated, repository=repository, homepage=version_data.get("homepage"), dependencies_count=len(dependencies) if dependencies else 0, security_issues=0, # Would need separate npm audit API call )
  • The @mcp.tool() decorator registers the package_info function as an MCP tool.
    @mcp.tool()

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/elad12390/web-research-assistant'

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