# Github Repository Analyzer (`constant_quadruped/github-repository-analyzer`) Actor

Analyze any GitHub repo: quality scores, bus factor, tech stack, dependencies, activity metrics & AI insights. Perfect for due diligence, hiring, and OSS evaluation. Supports Node, Python, Go, Rust, Java.

- **URL**: https://apify.com/constant\_quadruped/github-repository-analyzer.md
- **Developed by:** [CQ](https://apify.com/constant_quadruped) (community)
- **Categories:** Developer tools, AI, Automation
- **Stats:** 119 total users, 6 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## GitHub Repository Analyzer

Comprehensive GitHub repository analysis with security scanning, code quality metrics, contributor bus factor, dependency audit, license compatibility, trends analysis, and optional AI-powered insights.

**Useful for technical due diligence, dependency selection, and open source evaluation.**

> 💡 **First run? Add a free GitHub token** to the `githubToken` input for the best experience.
> Without one you're on GitHub's unauthenticated **60 requests/hour** limit, which even a single deep
> analysis can exhaust — a token (no scopes needed for public repos) gives **5,000/hour** and unlocks
> security data. Create one in 30 seconds: https://github.com/settings/tokens
> *(Token-less runs still work — they use lighter defaults and stop early with guidance instead of hanging.)*

### Continuous Monitoring Setup

Track repos over time with automatic alerts:

1. **Enable `trackHistory: true`** (default) — each run's scores are persisted for trend comparison.
2. **Add a `webhookUrl`** — the actor POSTs alerts when quality/security thresholds are breached. Supports Slack (`webhookFormat: "slack"`), Discord, or generic JSON.
3. **Set up a schedule** (Apify Console → Schedules → weekly/daily) — get notified when a tracked repo's quality drops, new vulnerabilities appear, or bus factor changes.
4. **Customize `alertThresholds`** — e.g. `{"qualityScore": {"warning": 80, "critical": 60}}` to match your standards.

**Result:** Automatic repo health monitoring with Slack/Discord pings on degradation. No manual re-runs.

### ✨ Features

#### Core Analysis

- **Basic Info**: Stars, forks, license, topics, archive status
- **Tech Stack**: Languages, frameworks, build tools, package managers
- **Contributors**: Bus factor, contribution distribution (Gini coefficient), top contributors
- **Dependencies**: Package count, lock file detection, transitive dependencies
- **Activity**: Commit frequency, staleness score, release history
- **Quality**: Tests, CI/CD, linting, documentation scores

#### Extended Analysis

- **Security**: Dependabot alerts, code scanning, secret scanning, security advisories
- **Code Quality**: Coverage integration (Codecov, Coveralls), complexity estimates
- **Issues & PRs**: Resolution time, merge velocity, stale issue count
- **Trends**: Star history, fork patterns, commit activity, momentum score
- **Branches**: Protection rules, branching strategy detection
- **Monorepo**: Lerna, Turborepo, Nx, workspaces detection
- **License Compatibility**: GPL/MIT/Apache/LGPL conflict detection
- **AI Insights**: Executive summary, strengths, concerns, risk assessment

#### 🆕 New Features

##### 📊 Repository Comparison

Compare multiple repositories side-by-side with automated winner detection:

```json
{
  "repositories": ["facebook/react", "vuejs/vue", "sveltejs/svelte"],
  "compareMode": true
}
```

##### 🏷️ Badge Generation

Get embeddable shields.io-style badges (with inline SVG) for your README:

- Quality Score badge
- Bus Factor badge
- Security Score badge
- Activity/Staleness badge
- Momentum badge
- Coverage badge (when the repo publishes a Codecov/Coveralls percentage)
- Overall Health Grade (A+ to F)

##### 📈 Historical Tracking

Track metrics over time with automatic trend detection:

- Quality score trends
- Security score changes
- Bus factor evolution
- Activity patterns
- Degradation alerts

##### 🔔 Webhook Monitoring

Get notified when metrics cross thresholds:

- Slack integration
- Discord integration
- Generic JSON webhooks
- Customizable alert thresholds

#### 🤖 MCP Server (local / self-hosted only)

The repo also ships a standalone Model Context Protocol (stdio) server for AI assistants
(Claude Desktop, Cursor, etc.). It is a **separate entry point** (`node src/mcp-server.js` /
`npm run mcp`) and is **not** invoked by the Apify Actor run — running the Actor on the
platform produces the dataset described below, not MCP tools. The server exposes 11 tools:

- `analyze_repository` - Full repository analysis
- `compare_repositories` - Side-by-side comparison of two repositories
- `get_security_report` - Security vulnerability scan (needs a token)
- `get_issue_analytics` - Issue/PR metrics
- `get_trends` - Historical trend data
- `get_branch_analysis` - Branch and protection rules
- `get_code_quality` - Quality metrics
- `check_monorepo` - Monorepo structure detection
- `check_license_compatibility` - License conflict detection
- `generate_badges` - Generate embeddable badges
- `check_alerts` - Evaluate quality/security threshold alerts

### 🚀 Quick Start

#### Basic Analysis

```json
{
  "repositories": ["facebook/react"],
  "analysisDepth": "deep"
}
```

#### Compare Frameworks

```json
{
  "repositories": [
    "vercel/next.js",
    "facebook/react",
    "vuejs/vue",
    "sveltejs/svelte"
  ],
  "compareMode": true,
  "analysisDepth": "standard"
}
```

#### Security Audit with Alerts

```json
{
  "repositories": ["your-org/main-app"],
  "analysisDepth": "deep",
  "githubToken": "ghp_xxxxxxxxxxxx",
  "webhookUrl": "https://hooks.slack.com/services/xxx",
  "webhookFormat": "slack",
  "alertThresholds": {
    "securityScore": { "warning": 80, "critical": 60 },
    "criticalVulns": { "warning": 0, "critical": 1 }
  }
}
```

#### Scheduled Monitoring

Set up a scheduled run to monitor your dependencies:

```json
{
  "repositories": [
    "your-org/frontend",
    "your-org/backend",
    "your-org/shared-lib"
  ],
  "trackHistory": true,
  "webhookUrl": "https://discord.com/api/webhooks/xxx",
  "webhookFormat": "discord"
}
```

### 📋 Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `repositories` | array | Yes | Repository URLs or owner/repo format |
| `analysisDepth` | string | No | `quick`, `standard`, or `deep` (default: `standard`) |
| `compareMode` | boolean | No | Generate comparison for multiple repos |
| `generateBadgesOutput` | boolean | No | Create embeddable badges (default: `true`) |
| `trackHistory` | boolean | No | Save results for trend tracking (default: `true`) |
| `webhookUrl` | string | No | URL for alert notifications |
| `webhookFormat` | string | No | `json`, `slack`, or `discord` |
| `alertThresholds` | object | No | Custom thresholds for alerts |
| `alwaysNotify` | boolean | No | Send webhook on every run |
| `includeAiSummary` | boolean | No | Generate AI insights (default: `true`) |
| `openaiApiKey` | string | No | Required for AI summaries |
| `githubToken` | string | No | For higher rate limits and security data |
| `maxConcurrency` | integer | No | Parallel repos (default: 3, max: 10) |

> **Which analysis modules run is controlled by `analysisDepth`**, not by individual toggles:
> `quick` = basic info + languages; `standard` adds contributors, dependencies, activity, branches,
> and issues/PRs; `deep` adds security, code quality, trends, monorepo detection, and license
> compatibility. (The input form may show additional `include*` switches; coverage is determined by
> depth.)

### 📤 Output

#### Dataset (per repository)

Full analysis results with all metrics, badges, and alerts.

#### Key-Value Store

| Key | Description |
|-----|-------------|
| `SUMMARY` | Run summary with all repo scores |
| `COMPARISON` | Side-by-side comparison (if compareMode=true) |
| `BADGES` | All generated badges for easy access |
| `HISTORY_owner_repo` | Historical data for each repository |

#### Example Output (abbreviated)

Each dataset record contains these top-level fields (sections are `null` when a sub-source is
skipped for the chosen depth, unavailable, or rate-limited): `repositoryUrl`, `owner`, `name`,
`analysisDepth`, `analyzedAt`, `basicInfo`, `techStack`, `contributors`, `dependencies`,
`activity`, `quality`, `security`, `codeQuality`, `issuesPRs`, `trends`, `monorepo`, `branches`,
`licenseCompatibility`, `aiInsights`, plus `badges` + `badgeMarkdown` (when badge output is on),
`trendReport` (when 2+ history points exist), and either `alerts` or `monitoring`. A repository
that fails outright is written as a compact record: `{ repositoryUrl, owner, name, error, analyzedAt }`.

```json
{
  "repositoryUrl": "https://github.com/facebook/react",
  "owner": "facebook",
  "name": "react",
  "analysisDepth": "deep",
  "analyzedAt": "2026-07-11T00:00:00.000Z",
  "basicInfo": {
    "stars": 220000,
    "forks": 45000,
    "license": "MIT",
    "topics": ["javascript", "ui"],
    "isArchived": false
  },
  "techStack": { "primaryLanguage": "JavaScript", "frameworks": [], "buildTools": [] },
  "contributors": { "total": 1600, "busFactor": 12, "giniCoefficient": 0.87 },
  "quality": { "overallScore": 95, "hasTests": true, "hasCI": true },
  "security": {
    "securityScore": 85,
    "vulnerabilityAlerts": { "enabled": true, "critical": 0, "high": 1, "total": 1 },
    "dependabotEnabled": true
  },
  "activity": { "stalenessScore": 0, "daysSinceLastCommit": 1 },
  "badges": {
    "qualityScore": {
      "markdown": "![Quality Score](https://img.shields.io/badge/quality-95%2F100-brightgreen)",
      "svg": "<svg ...>",
      "alt": "Quality Score: 95/100"
    },
    "health": { "markdown": "![Health](https://img.shields.io/badge/health-A-brightgreen)" }
  },
  "alerts": [],
  "aiInsights": {
    "summary": "React is a mature, actively maintained UI library...",
    "strengths": ["Large contributor base", "Strong CI"],
    "concerns": ["High issue volume"],
    "maintenanceRisk": "low",
    "recommendation": "Safe to depend on."
  }
}
```

> Note: `aiInsights` is populated only when `includeAiSummary` is on **and** a valid `openaiApiKey`
> is supplied; otherwise it stays `null`. The `vulnerabilityAlerts`, `codeScanning`, and
> `secretScanning` sections under `security` are only populated when a GitHub token with the
> relevant access is provided.

### 📊 Key Metrics Explained

#### Bus Factor

Minimum contributors responsible for 50% of commits. Low values (1-2) indicate risk.

#### Staleness Score (0-100)

- 0-10: Active (< 30 days)
- 10-50: Moderate (30-180 days)
- 50-80: Stale (6-12 months)
- 80-100: Abandoned (> 1 year)

#### Quality Score (0-100)

Composite of: README (30%), Tests (20%), CI/CD (15%), Linting (10%), TypeScript (10%), Docs (15%)

#### Security Score (0-100)

Based on: No critical vulns (+40), Security policy (+15), Dependabot (+15), Code scanning (+15), Secret scanning (+15)

### 🔧 MCP Server Setup

The MCP server is a **local** stdio server (not the Apify platform run). From a checkout of this
project, point your Claude Desktop / Cursor configuration at `src/mcp-server.js`:

```json
{
  "mcpServers": {
    "github-analyzer": {
      "command": "node",
      "args": ["/absolute/path/to/github-repository-analyzer/src/mcp-server.js"],
      "env": {
        "OPENAI_API_KEY": "sk-xxx"
      }
    }
  }
}
```

Or run it directly:

```bash
npm run mcp          # node src/mcp-server.js
```

Notes:

- A GitHub token is passed **per tool call** via the `githubToken` argument, not through an
  environment variable.
- `OPENAI_API_KEY` is read from the environment and is only used by `analyze_repository` when its
  `includeAI` argument is `true`.

### 💰 Pricing

Runs on Apify's standard usage-based pricing — you pay for the platform compute/usage the run
consumes, which scales with the number of repositories and the chosen `analysisDepth` (deeper
analysis issues more GitHub API calls). See the actor's Apify page for current pricing.

*If you enable the AI summary, OpenAI API usage is billed separately by OpenAI against your own key.*

### ⚡ Rate Limits

| Token | Rate | Repos/hour |
|-------|------|------------|
| None | 60/hour | ~5-7 |
| GitHub PAT | 5000/hour | ~400+ |

Get a token: https://github.com/settings/tokens

Required scopes: `repo` (private repos), `security_events` (security data)

### ⚠️ Limitations

- **Data source:** All data comes from the public GitHub REST API (`api.github.com`). No web
  scraping of github.com pages and no GraphQL — only documented REST endpoints.
- **Rate limits are the main constraint.** Without a `githubToken` you are on GitHub's
  unauthenticated **60 requests/hour** limit, and a single `deep` analysis issues many requests
  (each analysis module plus per-branch commit lookups), so one deep run can exhaust it. A free
  token raises this to **5,000/hour**. If a call is rate-limited, that section is left empty
  rather than crashing the run.
- **Private repositories** require a token with the `repo` scope. Public repos work with or
  without a token.
- **Security sections need a token.** Dependabot alerts, code scanning, and secret scanning
  (`security.vulnerabilityAlerts`, `codeScanning`, `secretScanning`) are only queried when a token
  is present and require the relevant access (e.g. `security_events`); otherwise they stay
  disabled/zero. Traffic data (views/clones/referrers under `trends`) and branch protection details
  require a token with push/admin access.
- **AI insights are optional and gated.** `aiInsights` is only produced when `includeAiSummary` is
  on **and** a valid `openaiApiKey` is provided (model: `gpt-4o-mini`); OpenAI usage is billed to
  your key. Without a key this field is `null` and the rest of the analysis still runs.
- **Dependency analysis reads the first matching root manifest only** (package.json → pyproject.toml
  → requirements.txt → Gemfile → composer.json → go.mod → Cargo.toml → pom.xml → build.gradle) using
  heuristic parsing. Transitive dependency counts are only computed for `package-lock.json`. License
  compatibility only checks npm licenses for package.json projects (top ~20 dependencies).
- **Detection is signature-based.** Frameworks, build tools, test frameworks, monorepo type,
  branching strategy, and coverage % (scraped from README badges) are inferred from well-known files
  and patterns, so they can be missed or misclassified. Contributors are read from the first 100
  returned by the API; `activeLastMonth` is not computed.
- **Historical trends require ≥2 runs.** Trend data, `trendReport`, and degradation alerts only
  appear after the same repository has been analyzed at least twice (history is stored in the actor's
  key-value store under `HISTORY_<owner>_<repo>`).
- **Partial results by design.** If a sub-source fails, its section is `null` and the record is still
  pushed. If an entire repository fails (e.g. it doesn't exist or the API is unreachable), a compact
  error record is pushed for it instead — the overall run does not fail and the dataset is never
  empty for a valid input.

### 📝 Changelog

#### v1.2.0

- Added repository comparison mode with winner detection
- Added embeddable badge generation (shields.io style)
- Added historical tracking with trend analysis
- Added webhook notifications (Slack, Discord, JSON)
- Added customizable alert thresholds
- Added degradation detection

#### v1.1.0

- Added security vulnerability scanning
- Added code quality metrics with coverage
- Added issue/PR analytics
- Added license compatibility analysis
- Added monorepo detection
- Added MCP server for AI assistants

### 🆘 Support

For issues or feature requests, please open an issue on the actor's GitHub repository or contact us through Apify.

***

*Built for developers who need to make informed decisions about open source dependencies.*

# Actor input Schema

## `repositories` (type: `array`):

List of repositories to analyze. Use owner/repo format (e.g., 'facebook/react') or full URLs

## `analysisDepth` (type: `string`):

How deep to analyze each repository

## `compareMode` (type: `boolean`):

Generate side-by-side comparison when analyzing multiple repositories

## `generateBadgesOutput` (type: `boolean`):

Generate embeddable SVG badges (shields) for README files

## `trackHistory` (type: `boolean`):

Save analysis results for trend tracking over time

## `includeSecurity` (type: `boolean`):

Scan for security vulnerabilities via Dependabot alerts (requires GitHub token with security read access)

## `includeTrends` (type: `boolean`):

Analyze historical star/fork trends and momentum

## `includeMonorepo` (type: `boolean`):

Detect Lerna, Turborepo, Nx, and workspace configurations

## `includeLicenseCheck` (type: `boolean`):

Analyze compatibility between project license and dependencies

## `includeAiSummary` (type: `boolean`):

Generate AI-powered insights and recommendations (requires OpenAI API key)

## `webhookUrl` (type: `string`):

URL to send alerts when quality/security thresholds are breached. Supports Slack, Discord, or generic JSON webhooks.

## `webhookFormat` (type: `string`):

Format for webhook payloads

## `alwaysNotify` (type: `boolean`):

Send webhook on every run (not just when alerts are triggered)

## `alertThresholds` (type: `object`):

Override default thresholds for alerts (e.g., {"qualityScore": {"warning": 80, "critical": 60}})

## `openaiApiKey` (type: `string`):

Required for AI summaries. Get one at platform.openai.com

## `githubToken` (type: `string`):

RECOMMENDED. A free GitHub token raises the limit from 60 to 5,000 requests/hour (a single deep analysis can exhaust 60), and unlocks security data. No scopes needed for public repos; add 'repo' for private and 'security\_events' for security alerts. Create one at github.com/settings/tokens

## `maxConcurrency` (type: `integer`):

Maximum repositories to analyze in parallel

## `proxyConfiguration` (type: `object`):

Proxy settings for requests

## Actor input object example

```json
{
  "repositories": [
    "apify/crawlee"
  ],
  "analysisDepth": "standard",
  "compareMode": false,
  "generateBadgesOutput": true,
  "trackHistory": true,
  "includeSecurity": true,
  "includeTrends": true,
  "includeMonorepo": true,
  "includeLicenseCheck": true,
  "includeAiSummary": true,
  "webhookFormat": "json",
  "alwaysNotify": false,
  "maxConcurrency": 3
}
```

# Actor output Schema

## `repositoryAnalysis` (type: `string`):

Full analysis results including basic info, tech stack, contributors, dependencies, activity metrics, quality scores, and AI insights

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "repositories": [
        "apify/crawlee"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("constant_quadruped/github-repository-analyzer").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "repositories": ["apify/crawlee"] }

# Run the Actor and wait for it to finish
run = client.actor("constant_quadruped/github-repository-analyzer").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "repositories": [
    "apify/crawlee"
  ]
}' |
apify call constant_quadruped/github-repository-analyzer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,constant_quadruped/github-repository-analyzer"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/rhben6z9tVb0X0pqS/builds/YV6XaZYXVxkZXiv9c/openapi.json
