Skip to main content
Glama
elad12390

Web Research Assistant

by elad12390

get_changelog

Retrieve changelog and release notes for software packages to track updates and changes across different package registries.

Instructions

Get changelog and release notes for a package.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
packageYes
reasoningYes
registryNoauto
max_releasesNo

Implementation Reference

  • Core handler function in ChangelogFetcher class that implements the get_changelog logic: finds repo, fetches releases from GitHub, parses for breaking changes, returns structured data.
    async def get_changelog(self, package: str, registry: str, max_releases: int = 5) -> dict:
        """Get changelog for a package."""
        # Find repository
        repo_url = await self._find_repository(package, registry)
        if not repo_url:
            return {"error": "Could not find repository", "package": package}
    
        # Extract owner/repo
        owner, repo = self._parse_repo_url(repo_url)
        if not owner or not repo:
            return {"error": "Invalid repository URL", "package": package}
    
        # Fetch releases
        try:
            releases_data = await self.github.get_releases(owner, repo, max_releases)
            releases = [self.parser.parse_release(r) for r in releases_data]
    
            breaking_count = sum(len(r.breaking_changes) for r in releases)
    
            return {
                "package": package,
                "registry": registry,
                "repository": repo_url,
                "releases": [
                    {
                        "version": r.version,
                        "date": r.date,
                        "notes": r.notes,
                        "breaking_changes": r.breaking_changes,
                    }
                    for r in releases
                ],
                "summary": {
                    "total_releases": len(releases),
                    "breaking_changes_count": breaking_count,
                    "recommendation": "Safe to upgrade"
                    if breaking_count == 0
                    else f"{breaking_count} breaking change(s) - review carefully",
                },
            }
        except Exception as e:
            return {"error": f"Failed to fetch releases: {e}", "package": package}
  • MCP tool registration (@mcp.tool()) for get_changelog, including schema via Annotated params, calls ChangelogFetcher.get_changelog, handles JSON output, tracking, and errors.
    @mcp.tool()
    async def get_changelog(
        package: Annotated[str, "Package name (e.g., react, fastapi)"],
        reasoning: Annotated[str, "Why you're checking the changelog"],
        registry: Annotated[Literal["npm", "pypi", "auto"], "Package registry"] = "auto",
        max_releases: Annotated[int, "Maximum releases to fetch"] = 5,
    ) -> str:
        """Get changelog and release notes for a package."""
        import json
    
        start_time = time.time()
        success = False
        error_msg = None
        result = ""
        detected_registry = registry
    
        try:
            # Auto-detect registry
            if registry == "auto":
                detected_registry = "npm"  # Default to npm
    
            # Fetch changelog
            changelog = await changelog_fetcher.get_changelog(package, detected_registry, max_releases)
    
            result = json.dumps(changelog, indent=2, ensure_ascii=False)
            result = clamp_text(result, MAX_RESPONSE_CHARS)
            success = "error" not in changelog
            if not success:
                error_msg = changelog.get("error")
    
        except Exception as exc:
            error_msg = str(exc)
            result = f"Changelog fetch failed for {package}: {exc}"
    
        finally:
            response_time = (time.time() - start_time) * 1000
            tracker.track_usage(
                tool_name="get_changelog",
                reasoning=reasoning,
                parameters={
                    "package": package,
                    "registry": detected_registry,
                    "max_releases": max_releases,
                },
                response_time_ms=response_time,
                success=success,
                error_message=error_msg,
                response_size=len(result.encode("utf-8")),
            )
    
        return result
  • Instantiation of ChangelogFetcher instance used by the get_changelog tool.
    changelog_fetcher = ChangelogFetcher(github_client, registry_client)
  • Dataclass schema for Release information parsed from changelogs.
    @dataclass
    class Release:
        """Information about a package release."""
    
        version: str
        date: str | None = None
        notes: str | None = None
        breaking_changes: list[str] = field(default_factory=list)
  • ChangelogParser helper class for parsing release notes and detecting breaking changes.
    class ChangelogParser:
        """Parse and analyze package changelogs."""
    
        BREAKING_KEYWORDS = [
            "breaking",
            "removed",
            "deprecated",
            "incompatible",
            "migration",
            "⚠",
            "🚨",
        ]
    
        def parse_release(self, release_data: dict) -> Release:
            """Parse GitHub release data."""
            body = release_data.get("body", "")
            release = Release(
                version=release_data.get("tag_name", "unknown"),
                date=release_data.get("published_at"),
                notes=body[:500] if body else None,
            )
    
            # Extract breaking changes
            lines = body.split("\n") if body else []
            for line in lines:
                if any(kw in line.lower() for kw in self.BREAKING_KEYWORDS):
                    clean = re.sub(r"^[-*•]\s*", "", line).strip()
                    if clean:
                        release.breaking_changes.append(clean[:200])
    
            return release

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