Skip to main content
Glama
tschoonj
by tschoonj

list_projects

Retrieve and filter software projects from Repology repositories by maintainer, category, repository presence, or status like outdated or problematic.

Instructions

List projects with optional filtering.

Args: start_from: Project name to start listing from limit: Maximum number of results (default: 10, max: 200) maintainer: Filter by maintainer email category: Filter by category inrepo: Filter by repository presence notinrepo: Filter by repository absence repos: Filter by number of repositories (e.g., "1", "5-", "-5", "2-7") families: Filter by number of repository families newest: Show only newest projects outdated: Show only outdated projects problematic: Show only problematic projects Returns: JSON formatted dictionary of projects and their packages

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
categoryNo
familiesNo
inrepoNo
limitNo
maintainerNo
newestNo
notinrepoNo
outdatedNo
problematicNo
reposNo
start_fromNo

Implementation Reference

  • The @mcp.tool()-decorated handler function implementing the 'list_projects' tool logic. It processes input parameters, builds filters, calls RepologyClient.list_projects, applies additional filtering if needed, and returns formatted JSON.
    @mcp.tool() async def list_projects( start_from: Optional[str] = None, limit: int = 10, maintainer: Optional[str] = None, category: Optional[str] = None, inrepo: Optional[str] = None, notinrepo: Optional[str] = None, repos: Optional[str] = None, families: Optional[str] = None, newest: Optional[bool] = None, outdated: Optional[bool] = None, problematic: Optional[bool] = None, ctx: Context[ServerSession, AppContext] = None, ) -> str: """List projects with optional filtering. Args: start_from: Project name to start listing from limit: Maximum number of results (default: 10, max: 200) maintainer: Filter by maintainer email category: Filter by category inrepo: Filter by repository presence notinrepo: Filter by repository absence repos: Filter by number of repositories (e.g., "1", "5-", "-5", "2-7") families: Filter by number of repository families newest: Show only newest projects outdated: Show only outdated projects problematic: Show only problematic projects Returns: JSON formatted dictionary of projects and their packages """ if limit > 200: limit = 200 try: client = ctx.request_context.lifespan_context.repology_client # Build filters filters = {} if maintainer: filters["maintainer"] = maintainer if category: filters["category"] = category if inrepo: filters["inrepo"] = inrepo if notinrepo: filters["notinrepo"] = notinrepo if repos: filters["repos"] = repos if families: filters["families"] = families if newest: filters["newest"] = "1" if outdated: filters["outdated"] = "1" if problematic: filters["problematic"] = "1" project_packages = await client.list_projects( start_from=start_from, limit=limit, **filters ) # Apply client-side repository filtering if inrepo is specified if inrepo and project_packages: project_packages = _filter_project_packages_by_repo( project_packages, inrepo ) if not project_packages: return json.dumps({"message": "No projects found matching the criteria"}) return _project_packages_to_json(project_packages) 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 listing projects: {e}") return json.dumps({"error": f"Unexpected error: {e}"})
  • RepologyClient.list_projects method: core helper that makes HTTP requests to Repology API /projects/ endpoint, handles pagination and filters, validates and returns ProjectPackages data structure.
    async def list_projects( self, start_from: Optional[str] = None, end_at: Optional[str] = None, limit: int = 200, **filters: Any, ) -> ProjectPackages: """List projects with optional filtering. Args: start_from: Project name to start from (inclusive) end_at: Project name to end at (inclusive) limit: Maximum number of projects (max 200) **filters: Additional filters (maintainer, category, inrepo, etc.) Returns: Dictionary mapping project names to package lists """ # Build endpoint path if start_from and end_at: endpoint = f"projects/{quote(start_from)}/..{quote(end_at)}/" elif start_from: endpoint = f"projects/{quote(start_from)}/" elif end_at: endpoint = f"projects/..{quote(end_at)}/" else: endpoint = "projects/" # Add query parameters for filters params = {} for key, value in filters.items(): if value is not None: params[key] = value try: data = await self._make_request(endpoint, params) if not isinstance(data, dict): raise RepologyAPIError(f"Expected dict, got {type(data)}") result = {} for project_name, packages_data in data.items(): packages = [] for item in packages_data: try: packages.append(Package.model_validate(item)) except ValidationError as e: print(f"Warning: Failed to validate package data: {e}") continue result[project_name] = packages return result except Exception as e: raise RepologyAPIError(f"Failed to list projects: {e}")
  • Utility function to convert ProjectPackages dict to pretty-printed JSON string, used in list_projects handler output.
    def _project_packages_to_json(project_packages: Dict[str, List[Package]]) -> str: """Convert project packages dict to formatted JSON string.""" result = {} for project_name, packages in project_packages.items(): result[project_name] = [pkg.model_dump() for pkg in packages] return json.dumps(result, indent=2)
  • Helper to filter project packages by repository, called conditionally in list_projects handler when 'inrepo' filter is provided.
    def _filter_project_packages_by_repo( project_packages: Dict[str, List[Package]], repo: str ) -> Dict[str, List[Package]]: """Filter project packages to only include those from a specific repository.""" filtered = {} for project_name, packages in project_packages.items(): filtered_packages = _filter_packages_by_repo(packages, repo) if ( filtered_packages ): # Only include projects that have packages in the specified repo filtered[project_name] = filtered_packages return filtered
  • Type definitions including ProjectPackages used throughout the list_projects implementation for return types and data structures.
    ProjectPackages = Dict[str, List[Package]] ProjectData = List[Package] ProblemsData = List[Problem]

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