Skip to main content
Glama
tschoonj

Repology MCP Server

by tschoonj

get_project

Retrieve detailed package information for a specific project from Repology's database, optionally filtered by repository.

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
NameRequiredDescriptionDefault
project_nameYes
repositoryNo

Implementation Reference

  • The primary MCP tool handler for 'get_project'. It retrieves packages for a project using RepologyClient, applies optional repository filtering, formats as JSON, and handles errors.
    @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}"})
  • Pydantic model defining the structure of individual package objects returned by the get_project tool.
    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")
  • Helper function used by get_project to serialize the list of Package models to a formatted JSON string.
    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)
  • Helper function used by get_project to filter packages by the optional 'repository' parameter.
    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]
  • RepologyClient.get_project method called by the MCP handler to fetch raw project data from the Repology API and validate into Package models.
    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}")

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/tschoonj/repology-mcp-server'

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