Skip to main content
Glama

ghstars

tests python license version

Your GitHub stars, as a local searchable knowledge base.

中文说明 · 使用指南 · HTML · Changelog

Turns your starred repos into plain Markdown files (Obsidian-friendly) plus a zero-dependency SQLite/FTS5 index — so you (and any AI agent you use) can answer "what did I star that does X?" in milliseconds, in Chinese or English, without a vector database or a 240 MB embedding model.

ghstars sync                 # pull stars → markdown → index
ghstars search "视频制作"      # Chinese scene tags work
ghstars search "rag pipeline" # English project names work too

Why another stars tool

gh / GitHub UI

bookmark managers

ghstars

Find a starred project by what it does (not its name)

✗

partial

✓ Chinese scene tags + weighted fields

Works offline, grep-able, git-diff-able

✗

✗

✓ plain Markdown

Usable by AI agents (CLI / MCP / skill)

✗

✗

✓ three adapters, one core

Install cost

npm/pip

SaaS

stdlib only for pull/search

The Chinese-tag part matters if you write in Chinese: GitHub descriptions are English, so searching "视频剪辑" never hits a repo described as "video editing toolkit". ghstars asks an LLM (optional) for 3–5 Chinese scene tags + a 2–3 sentence Chinese description, and stores them next to the English text — tags and description complement each other, neither alone is enough.

Related MCP server: Stargraph

Install

# try without installing
uvx --from git+https://github.com/zhe97396-tech/ghstars ghstars --help

# or install as a tool
uv tool install git+https://github.com/zhe97396-tech/ghstars

# MCP server support (optional)
uv tool install "ghstars[mcp] @ git+https://github.com/zhe97396-tech/ghstars.git"
# pip 等价写法
pip install "ghstars[mcp] @ git+https://github.com/zhe97396-tech/ghstars.git"

Requires Python ≥ 3.11 (uses tomllib) and nothing else.

Quickstart

ghstars init                 # write config template
$EDITOR "$APPDATA/ghstars/config.toml"   # Windows
# $EDITOR ~/.config/ghstars/config.toml  # macOS / Linux

ghstars doctor               # check token / store / index / LLM
ghstars sync                 # first run: pulls everything
ghstars search "小红书" --json

Token lookup order: --token → the env var named in github.token_env (default GITHUB_TOKEN) → GITHUB_TOKEN / GH_TOKEN → gh auth token (so if gh auth login is already done, nothing to configure).

Config

config.toml (all keys have env-var equivalents; env wins):

[store]
dir = "D:/Notes/github-stars"   # where the Markdown files live
index = ""                      # SQLite index path; empty = config dir/index.db

[github]
username = "your-github-username"
token_env = "GITHUB_TOKEN"
api_base = "https://api.github.com"

[llm]                            # optional — omit to stay offline
base = "https://api.openai.com/v1"
model = "gpt-4o-mini"
api_key_env = "OPENAI_API_KEY"   # recommended over putting the key inline
timeout = 60

[categories]                     # your own buckets; keys = directory names
ai-agents = ["ai-agents", "agent", "agentic-ai"]
mcp-tools = ["mcp"]
rag = ["rag"]
tools-utilities = ["cli", "developer-tools", "tools"]

Env overrides: GHSTARS_STORE, GHSTARS_INDEX, GHSTARS_GITHUB_USERNAME, GHSTARS_LLM_BASE, GHSTARS_LLM_KEY, GHSTARS_LLM_MODEL, GHSTARS_CONFIG.

Commands

Command

What it does

sync

Pull stars → dedupe → classify → Chinese tags → Markdown → archive unstarred → reindex

search "<q>"

Weighted search over name / tags / topics / Chinese desc / English desc. Chinese is split into 2-char bigrams (reordered queries still match); ranking = field weight × idf, tiered by evidence (phrase > full > partial)。结果带 match 字段,全是 partial 说明库里没有完全对口的项目

get <owner/name>

Full record for one repo (--full prints the Markdown)

list

List by stars, filter --category

stats

Counts per category, archived count, index location

export

JSON or CSV

index

Rebuild the SQLite index

doctor

Self-check: Python/SQLite FTS5/token/store/index/LLM

mcp

Run as a stdio MCP server

All commands accept --json. Progress logs go to stderr, structured output to stdout — safe to pipe into jq or parse in an agent.

Useful sync flags: --dry-run (report only, no writes, no LLM), --limit N, --no-llm, --full (ignore resume state).

LLM failure is not silent. If the LLM endpoint is configured but every call fails (renamed model, dead key, network), sync still writes the Markdown but prints a hard warning to stderr and exits 3 — the run is not a success. Partial failures exit 0 with a warning. The report carries the detail:

"llm": {
  "enabled": true, "calls": 10, "ok": 0, "failed": 10,
  "tag_failed": 10, "failed_all": true,
  "last_error": "model=... HTTP 400: Upstream request failed: Model is unavailable",
  "note": "LLM 全部失败(10 次调用无一次成功)..."
}

Exit codes: 0 ok (or nothing to do) · 1 doctor found problems · 2 config / GitHub error · 3 LLM all-failed (files written without Chinese tags).

Use it from AI agents

1. MCP (Claude Code / Codex / Hermes / Cursor …) — ghstars mcp exposes read-only tools: stars_search, stars_get, stars_stats. Writing (sync / index rebuild) is CLI-only on purpose: one write path, one place for the exit-3 guardrail, and MCP has no exit-code semantics for "every tag failed". MCP servers are long-lived child processes: after upgrading ghstars, restart the host for the new code to load.

// Claude Code: ~/.claude.json  →  "mcpServers"
// Cursor / generic clients: same shape
{
  "mcpServers": {
    "ghstars": { "command": "ghstars", "args": ["mcp"] }
  }
}
# Hermes: ~/.hermes/config.yaml
mcp_servers:
  ghstars:
    command: "ghstars"
    args: ["mcp"]
    timeout: 120

MCP hosts often run servers with a filtered environment (Hermes passes only PATH/HOME and friends). That is fine here: the token comes from gh auth token or from whatever [github] token_env names — pass secrets explicitly via the host's env: block if you use an env-only token.

2. Skill — copy skills/ghstars/ into your agent's skills dir (~/.claude/skills/, ~/.codex/skills/, Hermes profile skills/). The skill only teaches when to call the CLI; the CLI owns all behavior.

3. Plain shell — anything that can run a command can use it:

ghstars search "剪视频" --json | jq -r '.results[].repo'

How it works

GitHub API (stars + README)
  → dedupe by repo name, case-insensitive
  → classify: topics map → description keywords → LLM picking from *existing* dirs → other
  → LLM: 3–5 Chinese scene tags + 2–3 sentence Chinese description
  → Markdown file per repo  (frontmatter carries every searchable field)
  → SQLite index (derived cache, rebuildable)

Markdown is the single source of truth. The index is a cache: delete it, run ghstars index, nothing is lost. Files are byte-stable, so git diff shows only real changes and Obsidian shows a clean graph.

Design notes (the non-obvious decisions)

  • Ranking is not bm25. Measured on a 268-repo library: bm25 returns -0.0 for high-frequency terms (agent), so every hit ties and ranking collapses; adding a LIKE fallback then lets fallback hits outrank real ones. ghstars scores fields explicitly — repo 6 > title/tags 4 > topics/chinese 2 > english desc 1.5 — with an exact-match bonus. Predictable, explainable, and it keeps "tag hit > description hit".

  • Short CJK queries (简历, 剪辑) are below trigram's 3-char minimum, so they bypass FTS and go through LIKE. No Chinese tokenizer dependency (no jieba).

  • Classification never invents new categories. The LLM picks from directories that already exist, which stops taxonomy drift.

  • Compatibility topics are ignored. Bare claude-code / anthropic topics mean "compatible with", not "is a Claude skill" — using them for classification was the single biggest source of misfiled projects.

  • Archiving is idempotent. type: github-star-archived is matched as a whole value and rewritten exactly once; substring replacement produced -archived-archived-... and broke type-based weighting.

Privacy

  • No telemetry, no cloud. The only network calls are to the GitHub API (to read your star list) and, if you configure one, your own LLM endpoint.

  • No data in this repo. Your stars, index, sync state and config live only where you point store.dir; .gitignore excludes index.db, config.toml, .sync_state.json and .local/.

  • Docs contain no personal data. Examples use placeholders (acme/video-kit, <your notes dir>).

  • Secrets stay out of files when you choose so. Prefer llm.api_key_env over inlining a key; GitHub tokens are read from env or gh auth token.

Platforms

Platform

Status

Windows

✅ tested (console forced to UTF-8; cmd/PowerShell safe)

macOS

✅ by design — stdlib only, config in ~/.config (honors XDG_CONFIG_HOME)

Linux

✅ by design — same; gh auth token needs gh on PATH

The only platform branch is the config directory (%APPDATA% vs $XDG_CONFIG_HOME).

Maintenance

Change

Where

How it takes effect

Search / sync / classification behaviour

src/ghstars/

uv tool install --reinstall git+… (or -e . while developing)

MCP tools

TOOLS in mcp_server.py

same, then restart the host

Skill wording

skills/ghstars/SKILL.md

python scripts/sync_skill.py

Version

version in pyproject.toml only

__version__ follows automatically; then git tag

Index schema

index.py

users run ghstars index (the index is a cache — no migrations)

Compatibility contract: the Markdown frontmatter fields (repo, type, category, tags, topics, starred_at) are public API. Renaming one is a major version and needs a migration script. The index can change freely — it is rebuildable.

Known limits

  • Renames aren't tracked. A repo transferred/renamed gets a new owner/name, so it is treated as a new star and produces a second file. (Archive the old one by hand.)

  • Deleting a Markdown file leaves the index stale until ghstars index.

  • LLM calls are reasoning, not translation. Machine translation can't produce useful scene tags. Without an LLM you still get English descriptions + keyword classification.

Development

git clone https://github.com/zhe97396-tech/ghstars
cd ghstars
uv venv .venv && uv pip install -e ".[mcp]" --python .venv/Scripts/python.exe
.venv/Scripts/python.exe -m unittest discover -s tests -v

Windows/Hermes users: run with PYTHONPATH="" when a host injects its own site-packages, otherwise the wrong mcp/pydantic gets imported.

MIT licensed.

Available Tools

3 tools
stars_getA

按仓库名查看单个已收藏项目的完整信息(owner/name,大小写不敏感)。

Args: repo: 仓库全名,如 owner/name;也接受部分匹配。

NameRequiredDescriptionDefault
repoYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It usefully discloses case-insensitive lookup and partial matching, but it does not explain what happens if no repository matches or if partial matching returns multiple results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is short and front-loaded, with the core purpose stated first and parameter guidance following immediately. Every sentence contributes useful information without repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given one parameter and an existing output schema, the description need not explain return values. It covers purpose and parameter matching semantics well, but it leaves a small gap around ambiguous or missing repository matches.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for the single required parameter. It does so by explaining the expected 'owner/name' format, noting case-insensitivity, and stating that partial matching is accepted.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: viewing the full information of a single favorited project by repository name. The phrase '单个' and '按仓库名' distinguishes it from a broad search, though it does not explicitly name the sibling stars_search.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied: use this when you know or partially know the repository name and want one favorite's details. It does not explicitly say when to use stars_search instead, nor does it describe exclusions or handling of ambiguous matches.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stars_statsA

查看星标库概况:总数、已归档数、各分类计数、索引位置。

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. '查看' implies a read-only operation and the enumerated fields tell the agent what data surfaces, but it does not state whether the call is cheap/cached, whether it triggers a sync, or whether it can be slow on large libraries — the traits that would matter for a stats endpoint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence naming the resource first and then its contents. No filler, no redundancy with the schema or annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description need not explain return shapes, and enumerating the headline metrics is enough for a zero-parameter aggregate tool. The one missing piece is whether the statistics reflect stored state or require a fresh sync, which affects result freshness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters and the schema has no properties, so there is no parameter meaning to add; the description correctly adds no param text. Baseline 4 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('查看' / view) and resource (星标库概况 / starred library overview), then enumerates the exact contents: totals, archived count, category counts, index position. It is clearly distinct from the siblings (get/sync/reindex/search) by being an aggregated statistics read, though it does not name those siblings explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: an agent can infer this is the overview/summary call to make before drilling into a specific star or running a search, but the description never states when to prefer it over stars_search or stars_get, nor any preconditions (e.g., whether a sync must run first for the index position to be meaningful).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv0.2.0
    • Removedstars_reindex
    • Removedstars_sync
  2. 5 tool updatesv0.1.0
    • First observedstars_get
    • First observedstars_reindex
    • First observedstars_search
    • First observedstars_stats
    • First observedstars_sync

TDQS

A4/5.0

Scored across 3 tools

Disambiguation5/5

The three tools target clearly distinct operations: fetch one starred repo's details, search the local star index, and show library statistics. Search returns summaries while get returns full per-repo information, so overlap is minimal and the roles are easy to distinguish.

Naming Consistency5/5

All tool names use the same stars_ prefix with snake_case suffixes, giving a predictable resource/action pattern. Although stats is a noun rather than a verb, it is still consistent with the namespaced convention.

Tool Count5/5

Three tools is a focused, well-scoped read-only surface for browsing a local starred-project index. Each tool earns its place: one for lookup, one for search, and one for overview statistics.

Completeness4/5

The core read operations are covered: search, single-repo detail, and aggregate stats. Minor gaps remain, such as explicitly listing all stars or categories and refreshing the local index from GitHub, but agents can work around most of these via search and stats.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to search and retrieve information from your GitHub starred repositories via semantic matching, turning your stars into a searchable personal code toolbox.
    1
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables evidence-first analytics over GitHub starred repositories, including search, similarity comparison, explanation, and clustering via MCP tools.
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    An MCP server that caches your GitHub starred repositories in a local SQLite database and lets you search, list, and retrieve details about them through any MCP client (Claude Desktop, Cursor, VS Code, etc.), with automatic freshness checks via GitHub's ETag mechanism.
    5
    1
    MIT