How to Summarise GitHub with CrewAI

Summarise GitHub content inside a CrewAI agent using EnConvert Distill, returning a clean summary from repos, issues, and PRs in one call without parsing logic

Get API key

A CrewAI agent that reads GitHub content needs a summary, not a page dump. Fetching a repository, issue, or pull request directly returns sidebar navigation, contributor panels, reaction counts, and rendering markup that bury the content the agent actually needs. The GitHub REST API avoids the HTML but returns raw markdown or JSON, and you still have to write the parsing and summarisation logic before any of it is usable. EnConvert’s Distill endpoint takes a GitHub URL and returns a clean summary of the repository, README, issue thread, or pull request in one API call, ready to pass into a CrewAI tool.

Example

python
import os

import requests
from crewai import Agent, Crew, Task
from crewai.tools import BaseTool
from pydantic import BaseModel, Field

ENCONVERT_API_KEY = os.environ["ENCONVERT_API_KEY"]
GITHUB_URL = os.environ["GITHUB_URL"]  # a public GitHub repo, issue, or pull request URL
# CrewAI's default LLM reads OPENAI_API_KEY from the environment


class GitHubUrlInput(BaseModel):
    url: str = Field(description="The GitHub repository, issue, or pull request URL")


class GitHubDistillTool(BaseTool):
    name: str = "GitHub content summariser"
    description: str = (
        "Summarises a GitHub repository, issue, or pull request URL "
        "into clean prose using EnConvert Distill."
    )
    args_schema: type[BaseModel] = GitHubUrlInput

    def _run(self, url: str) -> str:
        # Step 1: Distill the GitHub page into a summary
        response = requests.post(
            "https://api.enconvert.com/v2/distill",
            headers={
                "X-API-Key": ENCONVERT_API_KEY,
                "Content-Type": "application/json",
            },
            json={
                "urls": [url],
                "schema": {
                    "summary": (
                        "a clear summary of the page. For a repository: its "
                        "purpose and README. For an issue: what is raised, its "
                        "status, and any proposed fix. For a pull request: "
                        "what it changes and its review status"
                    ),
                },
            },
            timeout=120,
        )
        response.raise_for_status()

        # Distill reports failures per URL, so check the item, not just the HTTP status
        item = response.json()["results"][0]
        summary = (item.get("data") or {}).get("summary")
        if item.get("error") or not summary:
            raise RuntimeError(
                f"Distill failed for {url}: {item.get('error') or item.get('warnings')}"
            )
        return summary


github_tool = GitHubDistillTool()

# Step 2: Give the tool to a CrewAI agent
analyst = Agent(
    role="GitHub content analyst",
    goal="Summarise GitHub repositories, issues, and pull requests into usable context",
    backstory="You read GitHub content and produce clean summaries for downstream tasks.",
    tools=[github_tool],
    verbose=True,
)

task = Task(
    description=(
        f"Summarise the GitHub page at {GITHUB_URL} "
        "and report what it covers and whether a fix has been proposed."
    ),
    expected_output="A short summary of the page, its current status, and any proposed fix.",
    agent=analyst,
)

# Step 3: Run the crew
crew = Crew(agents=[analyst], tasks=[task])
result = crew.kickoff()
print(result.raw)

What you get back

Distill returns the repository description, README content, or issue thread as clean prose, with contributor metadata, labels, and navigation chrome stripped before the response comes back. Fetching raw GitHub HTML produces bloated output with sidebar and header markup embedded in the text. The GitHub REST API avoids the HTML but returns unformatted markdown or JSON that still requires a separate summarisation step before an agent can use it.

Get free API key — 500 ops per month, no card required.