ghstars
This server manages and queries a local searchable knowledge base of your GitHub-starred repositories.
Search starred projects by Chinese/English scene terms, project names, or tech tags, with limit, category filtering, and optional archived items.
Retrieve full details for a single repo by
owner/name(case-insensitive, partial match accepted).View library stats: total count, archived count, per-category counts, and index location.
Sync latest GitHub stars into the local store, with dry-run, LLM tag/description toggle, and processing limit.
Rebuild the search index after manually editing or deleting Markdown files.
Pulls the user's starred repositories (stars list and READMEs) from the GitHub API and turns them into a local, searchable knowledge base — plain Markdown files plus a rebuildable SQLite/FTS5 index. Enables searching starred projects by what they do (name, topics, tags, Chinese/English descriptions), retrieving a full repo record, listing and filtering by category, sync/archiving of star changes, stats, and export to JSON/CSV.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ghstarsfind a repo I starred that does video editing"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ghstars
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 tooWhy another stars tool
| 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 "小红书" --jsonToken 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 |
| Pull stars → dedupe → classify → Chinese tags → Markdown → archive unstarred → reindex |
| 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 ( |
| Full record for one repo ( |
| List by stars, filter |
| Counts per category, archived count, index location |
| JSON or CSV |
| Rebuild the SQLite index |
| Self-check: Python/SQLite FTS5/token/store/index/LLM |
| 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: 120MCP 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 tokenor from whatever[github] token_envnames — pass secrets explicitly via the host'senv: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.0for 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/anthropictopics 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-archivedis 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;.gitignoreexcludesindex.db,config.toml,.sync_state.jsonand.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_envover inlining a key; GitHub tokens are read from env orgh auth token.
Platforms
Platform | Status |
Windows | ✅ tested (console forced to UTF-8; cmd/PowerShell safe) |
macOS | ✅ by design — stdlib only, config in |
Linux | ✅ by design — same; |
The only platform branch is the config directory (%APPDATA% vs $XDG_CONFIG_HOME).
Maintenance
Change | Where | How it takes effect |
Search / sync / classification behaviour |
|
|
MCP tools |
| same, then restart the host |
Skill wording |
|
|
Version |
|
|
Index schema |
| users run |
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 -vWindows/Hermes users: run with
PYTHONPATH=""when a host injects its own site-packages, otherwise the wrongmcp/pydanticgets imported.
MIT licensed.
Available Tools
3 toolsstars_getA
按仓库名查看单个已收藏项目的完整信息(owner/name,大小写不敏感)。
Args:
repo: 仓库全名,如 owner/name;也接受部分匹配。
| Name | Required | Description | Default |
|---|---|---|---|
| repo | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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.
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.
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.
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.
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.
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_searchA
检索本地已收藏的 GitHub 星标项目。
这是查「我 star 过什么」的首选工具:支持中文场景词(如「视频制作」「简历」)、 项目名、技术标签。返回项目名、分类、中文标签、描述、star 数、本地文件路径。
Args: query: 检索词,中英文均可。 limit: 返回条数上限。 category: 只在该分类内检索(如 ai-agents)。 include_archived: 是否包含已取消 star 的历史项目。
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes | ||
| category | No | ||
| include_archived | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so the description carries the full burden. It clarifies that include_archived reaches projects the user has un-starred, which is genuine behavioral context, but it never says the search is read-only, whether it is keyword or semantic, how results are ranked, or whether a synced index is required — notable given stars_sync/stars_reindex exist as siblings.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded purpose sentence, then a positioning line, then a compact Args block. The return-field list is partly wasteful because an output schema exists, but overall the text is tight and every parameter line adds meaning over the bare schema titles.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema is present so return values need not be described, and parameter meaning is well covered. What is missing is the operational context an agent needs to decide when this tool is not usable — e.g. index freshness, sync prerequisites, or result ordering.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the Args block does the work: query accepts Chinese or English, limit caps result count, category restricts to one category with an example, and include_archived is explained as including historically un-starred projects. This is solid compensation, with only minor gaps (no limit range or default restated).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: searching locally stored GitHub starred projects, and adds that it is the primary tool for the question 'what have I starred'. That implicitly separates it from stars_get/stars_stats, but the siblings are never named, so the differentiation is inferred rather than explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clear guidance on query style (Chinese scenario words like '视频制作', project names, tech tags) and a positioning statement that this is the first-choice tool for 'what have I starred'. No explicit when-not conditions or named alternatives, but the intended use case is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stars_statsA
查看星标库概况:总数、已归档数、各分类计数、索引位置。
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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.
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.
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.
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.
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.
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.
2 tool updates
v0.2.0- Removed
stars_reindex - Removed
stars_sync
5 tool updates
v0.1.0- First observed
stars_get - First observed
stars_reindex - First observed
stars_search - First observed
stars_stats - First observed
stars_sync
TDQS
Scored across 3 tools
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.
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.
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.
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
Related MCP Connectors
Search GitHub, npm, PyPI, StackOverflow, ArXiv from one MCP — built for coding agents.
Search and fetch AI agent skills, rules files and MCP servers indexed from GitHub.
An MCP server that gives your AI access to the source code and docs of all public github repos
Search 386+ AI tools with China-access data, live GitHub stats, 4-language metadata. No key needed
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables 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-
- AlicenseNot gradedqualityDmaintenanceEnables evidence-first analytics over GitHub starred repositories, including search, similarity comparison, explanation, and clustering via MCP tools.MIT
- AlicenseAqualityDmaintenanceAn 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.51MIT
- AlicenseAqualityBmaintenanceOrganizes, categorizes, and syncs GitHub starred repositories with AI agents, enabling offline conceptual search, health auditing, and tech-stack recommendations.17MIT