dep-rank

io.github.j7an由 GitHub 账号 j7an 发布v0.10.2更新于 Nov 3, 2026

Rank a GitHub repo's dependents by stars or trust heuristic, and search their code

发布方自己的服务:Rank Fast

概览

AI 生成的概览

按星标数或信任启发式对依赖某个 GitHub 仓库的项目进行排名,并可在这些依赖方中搜索代码。

可以做什么
  • 按星标数对某仓库的依赖方排名,可限制行数、最低星标、包名和抓取页数
  • 用综合星标、fork、issue 与 PR、活跃时间的启发式信任分重新排序,并可附带提示信号
  • 在排名靠前的依赖方中搜索代码,了解真实项目如何使用某个 API
  • 可选附带包的下载量统计和仓库描述
适用场景
适合想了解某个库到底被谁使用、评估其真实采用度,或在采用、撰写文档前查找下游项目中的实际用法示例时使用。
运行要求
以 stdio 方式在本地运行,通常通过带 mcp 扩展的 uvx 或 Docker 镜像启动。需要在 DEP_RANK_TOKEN 环境变量中提供 GitHub 个人访问令牌,缺少时两个工具都会失败。需要访问 GitHub 网络,请求下载量统计时还需访问包注册表。
安装前请注意
GitHub 令牌只从服务器环境读取,可访问你的 GitHub 账号,应尽量缩小权限范围。结果可能不完整,把计数当作总数前请检查 complete 标志和 reason。信任分与提示信号是相对于候选池的启发式指标,并非质量或造假判定。工具返回内容包含第三方仓库的文本,仍存在提示注入风险。下载量查询会把展示的仓库地址发送给第三方服务。

安装

在 SourceWeft 中

  1. 打开 控制台中的 dep-rank,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

dep-rank

Rank GitHub dependents by stars or trust.

[PyPI] [License: MIT] [Python 3.11+] [GHCR]

dep-rank finds the most popular repositories that depend on a given GitHub project. It scrapes GitHub's dependents page, enriches results via the GraphQL API, and works as a command-line tool and as an MCP server for AI agents (see MCP server).

Also: JSON output, package download stats, choosing among multiple packages, local cache, Docker image, Python API.

Quick Start

bash
pip install dep-rankexport DEP_RANK_TOKEN=ghp_your_token_here   # see Authentication belowdep-rank deps https://github.com/django/django --rows 5

A token is effectively required; see Authentication. Example output (numbers change over time). dep-rank also prints a scrape summary on stderr; this run stopped early, so the count is a lower bound, not a total (see Partial results):

       Top dependents ofhttps://github.com/django/django┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓┃ Repository           ┃ Stars ┃┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩│ makeplane/plane      │   61K ││ scalar/scalar        │   16K ││ jetify-com/devbox    │   12K ││ shiaho777/web-to-app │  7.1K ││ WeblateOrg/weblate   │  6.1K │└──────────────────────┴───────┘
178 dependents at or above the star threshold

CLI Reference

dep-rank deps — List top dependents

bash
dep-rank deps https://github.com/django/djangodep-rank deps https://github.com/django/django --rows 20 --min-stars 100dep-rank deps https://github.com/django/django --descriptions --format jsondep-rank deps https://github.com/django/django --packages
OptionDefaultDescription
--rows10Number of results
--min-stars5Minimum star count filter
--formattableOutput format: table or json
--descriptionsoffFetch descriptions via GitHub API (requires token)
--packagesoffSearch packages instead of repositories
--tokenDEP_RANK_TOKENGitHub token
--max-pages200Maximum pages to scrape (ceiling 1000)
--no-adaptive-stopoffDisable adaptive early-stop; scrape continues until exhaustion or --max-pages
--rank-bystarsRanking strategy: stars or trust (heuristic, requires token)
--trust-checkoffCheck sampled star history for up to 25 top results (requires --rank-by trust and token)
--downloadsoffShow each dependent's most-downloaded registry package (ecosyste.ms / deps.dev / npm; display only)
--package-nameGitHub's defaultScrape only this package (exact name from the dependents page dropdown). Without it, GitHub's default package is scraped and any other listed packages are named in a hint

In table output (deps, search, and the live progress table), repository names are clickable links to their GitHub pages in terminals that support OSC 8 hyperlinks; piped or redirected output stays plain text.

dep-rank search — Search code in dependents

bash
dep-rank search https://github.com/django/django "from django.db import"dep-rank search https://github.com/django/django "middleware" --max-repos 20
OptionDefaultDescription
--max-repos10Maximum repos to search
--min-stars50Only search repos with this many stars
--tokenDEP_RANK_TOKENGitHub token (required)
--max-pages200Maximum pages to scrape (ceiling 1000)
--package-nameGitHub's defaultScrape only this package (exact name from the dependents page dropdown). Without it, GitHub's default package is scraped and any other listed packages are named in a hint

search always runs a bounded non-adaptive top-K scrape (--no-adaptive-stop is not exposed; adaptive early-stop is permanently disabled for this command).

Rate-limited code searches are retried up to twice, honoring GitHub's wait headers; if GitHub keeps limiting, the remaining repositories are reported as not searched (rate limited).

Partial results

A scrape result (deps, and the search pre-pass) reports whether it finished: results include a complete flag and a reason. complete: false means the scrape stopped early — max_pages_reached (raise --max-pages), trend_converged (the adaptive heuristic judged the top-K stable; use --no-adaptive-stop to scrape until exhaustion or --max-pages), network_failure, or rate_limited. total_count/filtered_count are then lower bounds across the pages actually scraped, not population totals.

Repositories with several packages

Some repositories publish several packages, and GitHub's dependents page lists them in a dropdown (at most 100). Without --package-name, GitHub picks the package, and dep-rank names it and the others in a hint. JSON output then also carries package (the one scraped) and packages (every listed name).

dep-rank cache — Manage cache

bash
dep-rank cache stats    # Show cache sizedep-rank cache clear    # Clear all cached data

MCP server

dep-rank mcp runs an MCP server over stdio so AI agents can call dep-rank directly. It needs the optional mcp extra:

bash
pip install "dep-rank[mcp]"

Client configuration (the command works with any MCP client that launches stdio servers):

json
{  "mcpServers": {    "dep-rank": {      "command": "uvx",      "args": ["--with", "dep-rank[mcp]", "dep-rank", "mcp"],      "env": { "DEP_RANK_TOKEN": "ghp_your_token_here" }    }  }}

DEP_RANK_TOKEN is required: both tools fail without it. The token is read from the server's environment only, never from a tool argument.

Tools:

  • get_dependents — rank a repository's dependents by stars or trust (the dep-rank deps pipeline). Parameters mirror the CLI: url, rows, min_stars, dependent_type, descriptions, rank_by, trust_check, downloads, max_pages, adaptive_stop, package_name.
  • search_dependents — search code across the top dependents (the dep-rank search pipeline): url, query, max_repos, min_stars, max_pages, package_name.

Caveats:

  • Results can be partial. Check complete and reason before treating counts as totals; see Partial results.
  • Trust scores are pool-relative heuristics, not quality or fraud verdicts; see Trust Ranking.
  • Calls run one at a time; a call that arrives while another is running waits for it.
  • Long calls report progress, including GitHub rate-limit waits. Claude Code moves MCP calls that run longer than two minutes into the background.
  • The server honors HTTP_PROXY, HTTPS_PROXY, and NO_PROXY from its environment. A SOCKS proxy (for example ALL_PROXY=socks5://...) is not supported: tool calls fail with an error until it is removed from the server's environment.

Run the MCP server in Docker (MCP Toolkit)

The ghcr.io/j7an/dep-rank image runs the MCP server under Docker MCP Toolkit. You get:

  • container isolation, with no host filesystem access;
  • network access limited to GitHub when the gateway runs with --block-network;
  • one profile shared by every agent harness you connect.

It does not change prompt-injection risk: tool results still contain text from third-party repositories, and your agent reads it.

Prerequisites: Docker Desktop with MCP Toolkit, and profiles enabled (the MCPWorkingSets feature flag in Docker Desktop, or docker mcp feature enable profiles).

  1. Save this server definition as ~/.docker/mcp/catalogs/dep-rank.yaml. The gateway only reads file:// definitions from that directory.

    yaml
    name: dep-ranktitle: dep-ranktype: serverimage: ghcr.io/j7an/dep-rank:latestdescription: Rank a GitHub repo's dependents by stars or trust heuristic, and search their codesecrets:  - name: dep-rank.token    env: DEP_RANK_TOKEN    example: ghp_your_token_herevolumes:  - dep-rank-cache:/cacheallowHosts:  - github.com:443  - api.github.com:443

    get_dependents with downloads also needs packages.ecosyste.ms:443, api.npmjs.org:443, and api.deps.dev:443 in allowHosts; without them, download stats are reported as unavailable.

  2. Create the profile. Keep --id dep-rank: without it the ID becomes dep_rank, which won't match the harness config below.

    bash
    docker mcp profile create --name dep-rank --id dep-rank \  --server "file://$HOME/.docker/mcp/catalogs/dep-rank.yaml"
  3. Store your GitHub token:

    bash
    gh auth token | docker mcp secret set dep-rank.token

    If the secret is missing, the gateway passes the literal value <UNKNOWN> as DEP_RANK_TOKEN, so calls fail with GitHub errors rather than a "token missing" message.

  4. Point each harness at the gateway. Write the entry by hand so it includes --block-network, which is what enforces allowHosts:

    json
    {  "mcpServers": {    "dep-rank": {      "command": "docker",      "args": ["mcp", "gateway", "run", "--profile", "dep-rank", "--block-network"]    }  }}

    docker mcp client connect <client> -p dep-rank also works, but the entry it writes omits --block-network; add it yourself.

Notes:

  • For reproducible installs, pin image to a release tag (ghcr.io/j7an/dep-rank:<version>) or an @sha256: digest. Verify an image's build provenance with gh attestation verify oci://ghcr.io/j7an/dep-rank:<version> --repo j7an/dep-rank.
  • Each tool call starts a fresh container. The dep-rank-cache volume keeps the cache warm between calls.
  • The gateway can leave its proxy containers behind. Remove them with docker rm -f $(docker ps -aq --filter label=docker-mcp-proxy=true).

Python API (provisional)

Use dep_rank.core.dependents.get_dependents for the deps pipeline in Python. It returns dep_rank.core.models.DependentsResult; select repository or package dependents with dep_rank.core.models.DependentType. The API may change during 0.x.

python
import asyncio
import httpx2
from dep_rank.core.cache import SqliteCachefrom dep_rank.core.dependents import get_dependentsfrom dep_rank.core.models import DependentsResult, DependentType

async def main(cache_dir: str | None = None) -> None:    cache = SqliteCache(cache_dir) if cache_dir is not None else None    try:        if cache is not None:            await cache.initialize()        async with httpx2.AsyncClient() as session:            result: DependentsResult = await get_dependents(                session,                "https://github.com/django/django",                dependent_type=DependentType.REPOSITORY,                cache=cache,            )            for repo in result.repos:                print(repo.url, repo.stars)            if not result.complete:                print("Partial results:", result.reason)    finally:        if cache is not None:            await cache.close()

asyncio.run(main(cache_dir=".dep-rank-cache"))

dep_rank.core.cache.SqliteCache(path) takes a cache directory. Caching is optional: call main() in this example to omit it. The caller opens and closes the session and initializes and closes the cache; get_dependents closes neither. The defaults return up to 10 dependents with at least 5 stars, ranked by stars. Pass a GitHub token explicitly as token=... for descriptions or trust ranking; the library entry point does not read DEP_RANK_TOKEN. Pass downloads=True for optional package download statistics; no token is required for this lookup. Check result.downloads_check.complete and .unavailable to distinguish lookup failures from repositories with no matching package.

get_dependents raises ValueError for an invalid GitHub repository URL, rank_by other than "stars" or "trust", descriptions=True without a token, rank_by="trust" without a token, or trust_check=True without rank_by="trust". It raises NotFoundError (a ValueError subclass, from dep_rank.core.scraper) when GitHub returns 404 for the repository's dependents page — the repository does not exist or is private — and when package_name names no listed package. Trust scores are pool-relative heuristics, not quality or fraud verdicts.

Check result.complete and result.reason for partial results; counts are lower bounds when incomplete. result.stale_pages counts pages served from expired cache entries, and result.trust_metadata_complete is false when trust scores used partial metadata. result.trust_pool_size is the number of dependents scored together, which trust scores are relative to (0 when not trust-ranked). These fields exist on the result but are excluded from model_dump() and JSON serialization (model_dump_json()). If trust metadata cannot be fetched, results fall back to stars; check result.ranked_by == "trust" to confirm trust ranking, since trust_metadata_complete describes only metadata used for successful trust ranking.

Authentication

Set the DEP_RANK_TOKEN environment variable with a GitHub personal access token:

bash
export DEP_RANK_TOKEN=ghp_your_token_here

A token is effectively required for non-trivial use: unauthenticated GitHub HTML scraping is limited to ~60 requests/hour per IP, so unauthenticated runs are suitable only for small one-off scrapes. Set DEP_RANK_TOKEN to raise the limit.

What works without a token:

  • dep-rank deps — core scraping and star ranking

What requires a token:

  • --descriptions flag — fetches repo descriptions via GitHub GraphQL API
  • --rank-by trust — fetches engagement/recency metadata via GitHub GraphQL API
  • --trust-check — adds authenticated REST star-history requests to trust ranking
  • dep-rank search — code search across dependents
  • dep-rank mcp — both MCP tools require DEP_RANK_TOKEN in the server environment

Create a token at github.com/settings/tokens with public_repo scope.

How It Works

dep-rank uses a three-stage pipeline:

  1. Scrape — fetches GitHub's /network/dependents HTML pages to discover the dependents GitHub lists and their approximate star counts
  2. Enrich (optional) — one GraphQL batch query fetches accurate star counts and descriptions for the top N results (replaces 100 individual REST API calls)
  3. Present — returns structured results as a Rich table

With --downloads, the displayed rows receive optional package download statistics after ranking.

GitHub only lists repositories whose dependency graph is enabled. Since June 2025 the graph defaults to off for new public repositories and is disabled on long-inactive ones, so counts can miss real dependents.

Responses are cached in a local SQLite database (~/Library/Caches/dep-rank on macOS, $XDG_CACHE_HOME/dep-rank or ~/.cache/dep-rank on Linux, and %LOCALAPPDATA%\dep-rank\dep-rank\Cache on Windows) with ETag support for conditional requests. Expired pages are served immediately and refreshed in the background (stale-while-revalidate) on authenticated runs. Unauthenticated runs serve expired pages as-is and never refresh them; deps prints a notice on stderr when that happens. Set a token or run dep-rank cache clear for current results.

Package downloads

bash
dep-rank deps https://github.com/django/django --downloads

--downloads works with both --repositories and --packages, with no token requirement. For each displayed dependent, ecosyste.ms provides package candidates and non-npm counts, and deps.dev provides attestation evidence. npm counts come from npm's download API (api.npmjs.org, last 30 days); non-npm counts are ecosyste.ms snapshots that can lag. The package with the highest download count among accepted candidates is shown; counts never affect star or trust ranking.

A package is accepted when any of these rules holds:

  • deps.dev links the package to the repository through a publish or SLSA attestation with at least one attestation marked verified: true.
  • A package name without a namespace matches the repository name after lowercasing, removing -, _, and ., and optionally stripping one recognized language affix.
  • A namespaced package (@scope/name, vendor/name, publisher/name) matches only when its namespace matches the repository owner under the same normalization; matching only the name after the namespace is insufficient.

Packages marked removed are rejected even when attested. A ✓ means a verified attested repository-to-package link; it does not prove how the package was built. Unmarked packages matched by name alone are unverified: check before installing. A squatter may register the matching name or an unclaimed owner scope or vendor namespace. Still-listed malware has no structured flag in these lookup results, and legitimate packages can later be compromised. dep-rank is not a vulnerability scanner; use tools such as pip-audit, npm audit, or OSV to check for known vulnerabilities.

Counts may be inflated or stale, and periods differ: /mo means last month, total means all time, and other periods are shown explicitly. Raw counts across these periods are not directly comparable. Name matching can also miss legitimate packages (for example, a repository whose package has a different name). A — means no accepted package was found; unavailable means lookup failed. Lookup failures leave the deps run usable and print a warning to stderr, including in JSON mode.

Third-party egress: opting in sends the repository URLs of displayed rows to ecosyste.ms and deps.dev. Displayed npm package names are also sent to api.npmjs.org. Lookup requests omit caller credentials.

JSON adds a per-repository downloads object (or null) and a top-level downloads_check; without the flag these fields are omitted. This example is illustrative: selected packages and counts can change.

json
{  "repos": [{    "owner": "facebook",    "name": "react",    "downloads": {      "ecosystem": "npm",      "name": "react-is",      "downloads": 1524448794,      "period": "last-month",      "verified": true    }  }],  "downloads_check": {    "complete": true,    "unavailable": []  }}

A null download value means no accepted package unless the repository's owner/name appears in downloads_check.unavailable; in that case the lookup failed and downloads_check.complete is false.

Trust Ranking

dep-rank deps --rank-by trust re-ranks dependents by a lightweight composite score instead of raw stars. Stars are useful but gameable; trust ranking blends stars with non-star signals — forks, total issues and pull requests, and recency of activity — fetched via low-cost GitHub GraphQL queries (batched at 25 repositories per request, so a larger pool issues more than one).

bash
dep-rank deps https://github.com/django/django --rank-by trust --token ghp_...

Important caveats:

  • The score is a pool-relative ranking signal, not an absolute quality score — it min-max normalizes signals across the scraped candidate set.
  • It re-ranks only the scraped candidate pool (the star-top-N dependents), not every dependent.
  • It is heuristic and does not detect fake stars. By default it does not fetch star history; --trust-check optionally samples it. Neither mode fetches GHArchive data or external fraud datasets.
  • Trust ranking scrapes a larger candidate pool and is therefore deeper and slower than star ranking.
  • --rank-by trust requires a GitHub token; trust scores appear in --format json output under each repo's trust field.

How the score is computed

Trust mode scores the most-starred dependents together, then shows the top --rows of that ranking. The number scored (the pool) is min(100, rows × 10), never fewer than --rows, and fewer if fewer dependents match. The default --rows 10 scores 100 and shows 10; --rows 50 scores 100 and shows 50. With --rows ≥ 100, or when at most --rows dependents match, every scored dependent is shown.

Each of the four signals is log-scaled (except recency) and min-max normalized across the pool: the pool's lowest value maps to 0, its highest to 1, and values in between proportionally. When every repo in the pool has the same value for a signal (including a pool of one), that signal is 0.5 for all of them. The score is the weighted sum × 100:

SignalWeight
Stars35%
Forks25%
Issues + pull requests (all-time)20%
Recency of last push20%
  • 100 means highest in the pool on every signal. 50 means the weighted normalized signals average 0.5. It is not a median rank: normalization is linear between the pool's extremes, so one outlier can leave most of the pool far below 50. A score of 50 is not "half as trustworthy" as 100.
  • Scores are only comparable within one run. A different target, --rows, or --min-stars changes the pool and therefore every score.
  • Because the table shows the top of the pool, scores usually cluster high: the defaults show only the top tenth. --rows 100 shows the full range.
  • The table footer states how many dependents were scored and how many rows are shown. JSON includes the per-signal 0–1 values under trust.components.

Star-history check

bash
dep-rank deps https://github.com/django/django --rank-by trust --trust-check

This optional check samples the last 30 weeks of daily star counts for up to 25 top returned repositories, using GitHub's authenticated repository star-history API. It adds a concentrated_starring caution when the window contains at least 200 stars and at least 15% arrived on one day. It does not change trust scores or ranking. This is not proof of fake stars: launches and Hacker News spikes can match the same pattern. See StarScout and the research references below for the motivation and limits of star-based signals.

The table footer reports checked versus returned repositories, concentrated patterns, insufficient_history (fewer than 200 stars in the window), and unavailable (history could not be obtained). JSON adds top-level trust_check status only when the check is requested; for example (excerpt):

json
{  "trust_check": {    "complete": true,    "window_weeks": 30,    "repos_checked": 1,    "insufficient_history": [],    "unavailable": []  },  "repos": [{    "trust": {      "cautions": [{        "code": "concentrated_starring",        "description": "300 of 1,000 stars in the last 30 weeks arrived on 2026-09-01"      }]    }  }]}

trust_check.complete describes availability for the sampled repositories, not coverage of all results or all historical stars. Unavailable history makes it false and leaves the ranking usable. If trust ranking is unavailable, the check is skipped and the status reports the returned repositories as unavailable. The check uses no account-level signals: GitHub limited stargazer listings to repository admins and collaborators in July 2026; aggregate star history remains the basis of this check.

Caution signals

Trust-ranked results may carry informational caution signals, built from the same metadata fetch without extra requests by default. The optional --trust-check adds a star-history caution using separate requests. Signals appear in JSON under each repo's trust.cautions (a list of code + description, possibly empty) and, in the table, as a Cautions column of short tags, shown only when at least one result has a signal. A legend below the table defines each tag that appears.

CodeTable tagShown when
low_non_star_activitylow-activity≥ 500 stars, and both forks and issues + pull requests are below 1% of stars
stale_activitystale≥ 500 stars and no push for more than 365 days
archived_or_disabledarchivedThe repository is archived or disabled
new_with_high_starsyoung≥ 1,000 stars and created within the last 180 days
concentrated_starringspikeOnly with --trust-check: ≥ 200 stars in the sampled window and ≥ 15% arriving on one day

Thresholds are fixed heuristics. Star floors stand in for a minimum sample size, and the low-activity signal requires forks and issues/PRs to be low together, because popular list and documentation repositories routinely have few issues. Missing metadata never produces a signal. Age-based signals are measured against the run's scraped_at time.

Caution signals are not proof of fake stars or malicious behavior. They flag patterns worth a closer look, and legitimate repositories — finished libraries, archived projects, a new tool that went viral — can match them. They do not change the trust score.

Motivation that stars are gameable comes from StarScout (repo, preprint, ICSE 2026). The low-resource API basis is the GitHub GraphQL rate-limit docs.

Development

Development needs Python 3.11+ and uv. The setup, test, lint, and type-check commands CI runs are listed in AGENTS.md; test layout and coverage commands are in tests/README.md.

Acknowledgments

dep-rank is a full rewrite of ghtopdep by Andriy Orehov. The original project is licensed under MIT.

License

MIT — see LICENSE for details.

来源:README.md,提交 e0033b2

工具

0
SourceWeft 尚未在沙箱中启动过该软件包,因此其工具未知。

版本历史

5
  1. v0.10.2最新Nov 3, 2026
  2. v0.10.1Oct 30, 2026
  3. v0.10.0Oct 29, 2026
  4. v0.9.2Oct 26, 2026
  5. v0.9.1Oct 25, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分

其他 Rank 集成