get_project
Retrieve detailed package information for a specific project from multiple repositories, including version data and distribution availability.
Instructions
Get detailed information about a specific project.
Args:
project_name: Exact name of the project to retrieve
repository: Optional repository filter to show only packages from that repository
Returns:
JSON formatted list of packages for the project
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_name | Yes | ||
| repository | No |
Implementation Reference
- src/repology_mcp/server.py:140-183 (handler)The MCP tool handler for 'get_project'. It retrieves packages for the given project using RepologyClient, applies optional repository filtering, handles errors, and returns formatted JSON output.@mcp.tool() async def get_project( project_name: str, repository: Optional[str] = None, ctx: Context[ServerSession, AppContext] = None, ) -> str: """Get detailed information about a specific project. Args: project_name: Exact name of the project to retrieve repository: Optional repository filter to show only packages from that repository Returns: JSON formatted list of packages for the project """ try: client = ctx.request_context.lifespan_context.repology_client packages = await client.get_project(project_name) if not packages: return json.dumps( {"message": f"No packages found for project '{project_name}'"} ) # Apply client-side repository filtering if repository is specified if repository: packages = _filter_packages_by_repo(packages, repository) if not packages: return json.dumps( { "message": f"No packages found for project '{project_name}' in repository '{repository}'" } ) return _packages_to_json(packages) except RepologyNotFoundError: return json.dumps({"error": f"Project '{project_name}' not found"}) except RepologyAPIError as e: await ctx.error(f"Repology API error: {e}") return json.dumps({"error": str(e)}) except Exception as e: await ctx.error(f"Unexpected error getting project: {e}") return json.dumps({"error": f"Unexpected error: {e}"})
- src/repology_mcp/client.py:172-211 (helper)RepologyClient.get_project helper method that makes the HTTP request to Repology API, parses the response, validates packages using Pydantic models, and returns the list of Package objects.async def get_project(self, project_name: str) -> ProjectData: """Get package data for a specific project. Args: project_name: Name of the project Returns: List of packages for the project Raises: RepologyNotFoundError: If project doesn't exist """ endpoint = f"project/{quote(project_name)}" try: data = await self._make_request(endpoint) # API returns a list of package dictionaries if not isinstance(data, list): raise RepologyAPIError(f"Expected list, got {type(data)}") packages = [] for item in data: try: packages.append(Package.model_validate(item)) except ValidationError as e: # Log validation error but continue with other packages print(f"Warning: Failed to validate package data: {e}") continue return packages except RepologyNotFoundError: # Re-raise not found errors raise except RepologyRateLimitError: # Re-raise rate limit errors raise except Exception as e: raise RepologyAPIError(f"Failed to get project {project_name}: {e}")
- src/repology_mcp/models.py:7-34 (schema)Pydantic schema for Package objects used in get_project response parsing and validation.class Package(BaseModel): """A package in a repository.""" repo: str = Field(description="Repository name") subrepo: Optional[str] = Field(None, description="Subrepository name") srcname: Optional[str] = Field(None, description="Source package name") binname: Optional[str] = Field(None, description="Binary package name") binnames: Optional[List[str]] = Field(None, description="All binary package names") visiblename: str = Field(description="Package name as shown by Repology") version: str = Field(description="Package version (sanitized)") origversion: Optional[str] = Field(None, description="Original package version") status: Literal[ "newest", "devel", "unique", "outdated", "legacy", "rolling", "noscheme", "incorrect", "untrusted", "ignored", ] = Field(description="Package status") summary: Optional[str] = Field(None, description="Package description") categories: Optional[List[str]] = Field(None, description="Package categories") licenses: Optional[List[str]] = Field(None, description="Package licenses") maintainers: Optional[List[str]] = Field(None, description="Package maintainers")
- src/repology_mcp/server.py:40-42 (helper)Utility function to convert list of Package objects to pretty-printed JSON string, used in get_project output.def _packages_to_json(packages: List[Package]) -> str: """Convert packages list to formatted JSON string.""" return json.dumps([pkg.model_dump() for pkg in packages], indent=2)
- src/repology_mcp/server.py:50-52 (helper)Utility function to filter packages by repository, used in get_project when repository parameter is provided.def _filter_packages_by_repo(packages: List[Package], repo: str) -> List[Package]: """Filter packages to only include those from a specific repository.""" return [pkg for pkg in packages if pkg.repo == repo]