mcp-github-learning-assistant 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcp_github_learning_assistant-0.1.0/.env.example +4 -0
- mcp_github_learning_assistant-0.1.0/.github/workflows/ci.yml +30 -0
- mcp_github_learning_assistant-0.1.0/.gitignore +39 -0
- mcp_github_learning_assistant-0.1.0/LICENSE +21 -0
- mcp_github_learning_assistant-0.1.0/PKG-INFO +100 -0
- mcp_github_learning_assistant-0.1.0/README.md +75 -0
- mcp_github_learning_assistant-0.1.0/docs/decisions.md +156 -0
- mcp_github_learning_assistant-0.1.0/docs/plan.md +61 -0
- mcp_github_learning_assistant-0.1.0/docs/screenshots/inspector-analyze.jpg +0 -0
- mcp_github_learning_assistant-0.1.0/docs/screenshots/inspector-tools.jpg +0 -0
- mcp_github_learning_assistant-0.1.0/pyproject.toml +48 -0
- mcp_github_learning_assistant-0.1.0/scripts/debug_issues.py +47 -0
- mcp_github_learning_assistant-0.1.0/scripts/test_analyze.py +15 -0
- mcp_github_learning_assistant-0.1.0/scripts/test_client.py +32 -0
- mcp_github_learning_assistant-0.1.0/scripts/test_compare.py +17 -0
- mcp_github_learning_assistant-0.1.0/scripts/test_issues.py +14 -0
- mcp_github_learning_assistant-0.1.0/scripts/test_recommend.py +21 -0
- mcp_github_learning_assistant-0.1.0/scripts/test_roadmap.py +10 -0
- mcp_github_learning_assistant-0.1.0/scripts/test_similar.py +10 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/__init__.py +3 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/__main__.py +8 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/analyzer.py +125 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/comparer.py +71 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/github_client.py +24 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/issuefind.py +54 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/models/__init__.py +1 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/models/outputs.py +130 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/recommender.py +119 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/roadmap.py +77 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/server.py +155 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/similar.py +86 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/tools/__init__.py +1 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/tools/analyze.py +25 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/tools/compare.py +22 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/tools/info.py +16 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/tools/issues.py +21 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/tools/recommend.py +33 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/tools/roadmap.py +22 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/tools/similar.py +22 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/tools/trending.py +35 -0
- mcp_github_learning_assistant-0.1.0/src/mcp_github_learning_assistant/trending.py +82 -0
- mcp_github_learning_assistant-0.1.0/tests/__init__.py +1 -0
- mcp_github_learning_assistant-0.1.0/tests/test_analyzer.py +73 -0
- mcp_github_learning_assistant-0.1.0/tests/test_info.py +10 -0
- mcp_github_learning_assistant-0.1.0/tests/test_roadmap.py +59 -0
- mcp_github_learning_assistant-0.1.0/tests/test_trending.py +80 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Set up Python
|
|
19
|
+
uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: ${{ matrix.python-version }}
|
|
22
|
+
|
|
23
|
+
- name: Install project and dev dependencies
|
|
24
|
+
run: pip install -e .[dev]
|
|
25
|
+
|
|
26
|
+
- name: Lint
|
|
27
|
+
run: ruff check src tests scripts
|
|
28
|
+
|
|
29
|
+
- name: Test
|
|
30
|
+
run: pytest -q
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
|
|
23
|
+
# Virtual environments
|
|
24
|
+
venv/
|
|
25
|
+
ENV/
|
|
26
|
+
env/
|
|
27
|
+
.venv
|
|
28
|
+
|
|
29
|
+
# IDE
|
|
30
|
+
.vscode/
|
|
31
|
+
.idea/
|
|
32
|
+
*.swp
|
|
33
|
+
*.swo
|
|
34
|
+
|
|
35
|
+
# Environment
|
|
36
|
+
.env
|
|
37
|
+
|
|
38
|
+
# pytest
|
|
39
|
+
.pytest_cache/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 iyiook333
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the Software), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: mcp-github-learning-assistant
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: An MCP server that helps developers discover and learn from GitHub open-source projects
|
|
5
|
+
Author: iyiook333
|
|
6
|
+
License: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Requires-Dist: httpx>=0.27.0
|
|
17
|
+
Requires-Dist: mcp>=1.0.0
|
|
18
|
+
Requires-Dist: pydantic>=2.0.0
|
|
19
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
20
|
+
Provides-Extra: dev
|
|
21
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
22
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
23
|
+
Requires-Dist: ruff>=0.6.0; extra == 'dev'
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# MCP GitHub Learning Assistant
|
|
27
|
+
|
|
28
|
+
An MCP (Model Context Protocol) server that helps developers discover and learn from open-source projects on GitHub, based on their skill level and goals.
|
|
29
|
+
|
|
30
|
+
## Features
|
|
31
|
+
|
|
32
|
+
8 tools to support every stage of open-source learning:
|
|
33
|
+
|
|
34
|
+
| Tool | Description |
|
|
35
|
+
|------|-------------|
|
|
36
|
+
| `analyze_repo_for_learning` | Score a repo: stars, doc quality, difficulty, prerequisites, suggested learning path |
|
|
37
|
+
| `recommend_learning_repos` | Curated recommendations per tech stack (Spring Boot, FastAPI, Vue, React, Electron, HarmonyOS) |
|
|
38
|
+
| `get_repo_roadmap` | Generate a step-by-step learning roadmap from a repo's directory structure |
|
|
39
|
+
| `find_similar_repos` | Find thematically similar repos (same language/topic) for comparison |
|
|
40
|
+
| `find_good_first_issues` | Find beginner-friendly open issues (good first issue / help wanted) |
|
|
41
|
+
| `compare_learning_repos` | Compare 2+ candidate repos and suggest which to learn first |
|
|
42
|
+
| `get_trending_repos_for_learning` | Find breakout repos created recently by language/topic |
|
|
43
|
+
| `get_server_info` | Verify the MCP server connection |
|
|
44
|
+
|
|
45
|
+
## Screenshots
|
|
46
|
+
|
|
47
|
+
| MCP Inspector - Tools list | MCP Inspector - analyze_repo_for_learning result |
|
|
48
|
+
|:---:|:---:|
|
|
49
|
+
|  |  |
|
|
50
|
+
|
|
51
|
+
Screenshots use dark-mode crops under 500KB each.
|
|
52
|
+
|
|
53
|
+
## Installation
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install mcp-github-learning-assistant
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Configuration
|
|
60
|
+
|
|
61
|
+
Set your GitHub Personal Access Token:
|
|
62
|
+
|
|
63
|
+
```powershell
|
|
64
|
+
# Windows PowerShell
|
|
65
|
+
$env:GITHUB_TOKEN = "your_github_token"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# Linux / macOS
|
|
70
|
+
export GITHUB_TOKEN=your_github_token
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Token scope: fine-grained PAT with no special permissions (public repo read-only) is enough.
|
|
74
|
+
|
|
75
|
+
## Usage in MCP Clients
|
|
76
|
+
|
|
77
|
+
### MCP Inspector (development)
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npx @modelcontextprotocol/inspector python -m mcp_github_learning_assistant
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Cherry Studio
|
|
84
|
+
|
|
85
|
+
1. Open Cherry Studio, go to Settings -> MCP
|
|
86
|
+
2. Add an MCP server with the command `python -m mcp_github_learning_assistant`
|
|
87
|
+
3. Set the environment variable `GITHUB_TOKEN`
|
|
88
|
+
|
|
89
|
+
## Development
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
git clone https://github.com/iyiook333/mcp-github-learning-assistant.git
|
|
93
|
+
cd mcp-github-learning-assistant
|
|
94
|
+
pip install -e .[dev]
|
|
95
|
+
pytest
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
|
|
100
|
+
MIT
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# MCP GitHub Learning Assistant
|
|
2
|
+
|
|
3
|
+
An MCP (Model Context Protocol) server that helps developers discover and learn from open-source projects on GitHub, based on their skill level and goals.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
8 tools to support every stage of open-source learning:
|
|
8
|
+
|
|
9
|
+
| Tool | Description |
|
|
10
|
+
|------|-------------|
|
|
11
|
+
| `analyze_repo_for_learning` | Score a repo: stars, doc quality, difficulty, prerequisites, suggested learning path |
|
|
12
|
+
| `recommend_learning_repos` | Curated recommendations per tech stack (Spring Boot, FastAPI, Vue, React, Electron, HarmonyOS) |
|
|
13
|
+
| `get_repo_roadmap` | Generate a step-by-step learning roadmap from a repo's directory structure |
|
|
14
|
+
| `find_similar_repos` | Find thematically similar repos (same language/topic) for comparison |
|
|
15
|
+
| `find_good_first_issues` | Find beginner-friendly open issues (good first issue / help wanted) |
|
|
16
|
+
| `compare_learning_repos` | Compare 2+ candidate repos and suggest which to learn first |
|
|
17
|
+
| `get_trending_repos_for_learning` | Find breakout repos created recently by language/topic |
|
|
18
|
+
| `get_server_info` | Verify the MCP server connection |
|
|
19
|
+
|
|
20
|
+
## Screenshots
|
|
21
|
+
|
|
22
|
+
| MCP Inspector - Tools list | MCP Inspector - analyze_repo_for_learning result |
|
|
23
|
+
|:---:|:---:|
|
|
24
|
+
|  |  |
|
|
25
|
+
|
|
26
|
+
Screenshots use dark-mode crops under 500KB each.
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install mcp-github-learning-assistant
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Configuration
|
|
35
|
+
|
|
36
|
+
Set your GitHub Personal Access Token:
|
|
37
|
+
|
|
38
|
+
```powershell
|
|
39
|
+
# Windows PowerShell
|
|
40
|
+
$env:GITHUB_TOKEN = "your_github_token"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Linux / macOS
|
|
45
|
+
export GITHUB_TOKEN=your_github_token
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Token scope: fine-grained PAT with no special permissions (public repo read-only) is enough.
|
|
49
|
+
|
|
50
|
+
## Usage in MCP Clients
|
|
51
|
+
|
|
52
|
+
### MCP Inspector (development)
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npx @modelcontextprotocol/inspector python -m mcp_github_learning_assistant
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Cherry Studio
|
|
59
|
+
|
|
60
|
+
1. Open Cherry Studio, go to Settings -> MCP
|
|
61
|
+
2. Add an MCP server with the command `python -m mcp_github_learning_assistant`
|
|
62
|
+
3. Set the environment variable `GITHUB_TOKEN`
|
|
63
|
+
|
|
64
|
+
## Development
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
git clone https://github.com/iyiook333/mcp-github-learning-assistant.git
|
|
68
|
+
cd mcp-github-learning-assistant
|
|
69
|
+
pip install -e .[dev]
|
|
70
|
+
pytest
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
|
|
75
|
+
MIT
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# 决策记录
|
|
2
|
+
|
|
3
|
+
## 2026-10-10:项目方向
|
|
4
|
+
|
|
5
|
+
决定不做通用 GitHub MCP Server,因为 GitHub 官方已经做了很全的版本。
|
|
6
|
+
我们选择「开源学习助手」这一细分方向,聚焦学习决策。
|
|
7
|
+
|
|
8
|
+
## 2026-10-10:技术选型
|
|
9
|
+
|
|
10
|
+
- 语言:Python 3.10+
|
|
11
|
+
- 原因:MCP 官方 Python SDK 最成熟,上手快,适合快速验证
|
|
12
|
+
- 分发方式:pip install(主要),Docker 后续可选
|
|
13
|
+
- 依赖管理:pyproject.toml + pip
|
|
14
|
+
- 用户实际环境:Python 3.12.10(Windows)
|
|
15
|
+
- 测试客户端:Cherry Studio(国产开源,MCP 支持好)
|
|
16
|
+
- 备选客户端:Cline(VS Code 插件)、LobeHub
|
|
17
|
+
|
|
18
|
+
## 2026-10-10:GitHub API 选择
|
|
19
|
+
|
|
20
|
+
使用 GitHub REST API v3,因为:
|
|
21
|
+
- 文档完善
|
|
22
|
+
- 无需复杂 GraphQL 查询
|
|
23
|
+
- 覆盖我们需要的所有功能
|
|
24
|
+
|
|
25
|
+
## 2026-10-10:部署策略
|
|
26
|
+
|
|
27
|
+
优先 pip install,原因:
|
|
28
|
+
- Python 项目安装最自然
|
|
29
|
+
- 用户已有 Python 环境
|
|
30
|
+
- 比 Docker 轻量
|
|
31
|
+
- 开发和调试更方便
|
|
32
|
+
|
|
33
|
+
Docker 作为第二阶段的可选方案。
|
|
34
|
+
|
|
35
|
+
## 2026-10-10:测试客户端
|
|
36
|
+
|
|
37
|
+
没有 Claude Desktop,选择国产客户端 Cherry Studio 进行测试。
|
|
38
|
+
Cherry Studio 开源、支持 MCP、中文界面友好。
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 2026-10-11:MCP SDK API 版本适配
|
|
43
|
+
|
|
44
|
+
mcp 2.3.0 的 Server 类没有 list_tools / call_tool 装饰器。
|
|
45
|
+
改用高层 MCPServer,使用 @app.tool() 装饰器注册工具。
|
|
46
|
+
决策:跟随已安装的 mcp 2.3.0 API,不回退旧版本。
|
|
47
|
+
|
|
48
|
+
## 2026-10-11:添加 python -m 运行入口
|
|
49
|
+
|
|
50
|
+
为了支持 `python -m mcp_github_learning_assistant`,
|
|
51
|
+
新增 src/mcp_github_learning_assistant/__main__.py 作为包执行入口。
|
|
52
|
+
|
|
53
|
+
## 2026-10-11:项目分层
|
|
54
|
+
|
|
55
|
+
参考 Spring Boot 分层结构:
|
|
56
|
+
- models/outputs.py → DTO(数据结构)
|
|
57
|
+
- analyzer.py → Service(核心业务逻辑)
|
|
58
|
+
- tools/analyze.py → Controller(MCP 工具接入口)
|
|
59
|
+
- server.py → 启动类
|
|
60
|
+
|
|
61
|
+
好处:逻辑独立、便于测试、面试讲得清楚。
|
|
62
|
+
|
|
63
|
+
## 2026-10-11:GitHub Token 策略
|
|
64
|
+
|
|
65
|
+
申请 fine-grained PAT:
|
|
66
|
+
- Repository access: Public Repositories (read-only)
|
|
67
|
+
- Permissions: 无
|
|
68
|
+
- 目的:只提高 60 -> 5000 次每小时的请求额度
|
|
69
|
+
- 传递方式:环境变量 GITHUB_TOKEN,不入库(.gitignore 排除 .env)
|
|
70
|
+
|
|
71
|
+
## 2026-10-11:评分算法调整
|
|
72
|
+
|
|
73
|
+
发现 learning_score 可能超过 10(stars 加分后再 + 文档分)。
|
|
74
|
+
修复:min(10.0, ...) 挪到所有加减法之后统一封顶。
|
|
75
|
+
评分函数是纯启发式,后续可以替换成更复杂的启发式或模型打分。
|
|
76
|
+
|
|
77
|
+
## 2026-10-11:首次 Git 提交
|
|
78
|
+
|
|
79
|
+
commit: d2ab733
|
|
80
|
+
提交内容:项目骨架 + 2 个工具(get_server_info、analyze_repo_for_learning)+ 文档。
|
|
81
|
+
其中 analyze_repo_for_learning 已实测成功(spring-projects/spring-boot)。
|
|
82
|
+
|
|
83
|
+
## 2026-10-11:确认项目不含 FastAPI
|
|
84
|
+
|
|
85
|
+
MCP 走 stdio 时不需要 HTTP 服务。
|
|
86
|
+
后续若支持远程部署(SSE / streamable HTTP)再考虑引入 FastAPI。
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## 2026-10-11:MCP Inspector 调试通过
|
|
92
|
+
|
|
93
|
+
使用 MCP 官方 Inspector(npx @modelcontextprotocol/inspector)验证:
|
|
94
|
+
- Server 进程启动正常(stdio 待命)
|
|
95
|
+
- Connect 握手成功
|
|
96
|
+
- Tools 标签列出 get_server_info 和 analyze_repo_for_learning
|
|
97
|
+
- get_server_info Run 后正确返回
|
|
98
|
+
|
|
99
|
+
结论:MCP 协议层、工具注册层全链路可用,可以进入新工具开发和真实客户端(Cherry Studio)集成阶段。
|
|
100
|
+
|
|
101
|
+
## 2026-10-11:README 乱码修复
|
|
102
|
+
|
|
103
|
+
原因:PowerShell 5.1 Set-Content -Encoding UTF8 带 BOM,且代码块语言标注被写入坏字节。
|
|
104
|
+
修复:用 .NET [System.IO.File]::WriteAllText 配合 UTF8Encoding($false) 重写为 UTF-8 无 BOM。
|
|
105
|
+
README 改为英文为主,后续考虑增加 README.zh-CN.md 双语版。
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## 2026-10-11:MVP 全部工具实数据验证通过
|
|
111
|
+
|
|
112
|
+
所有 7 个工具在真实 GitHub 数据下验证成功:
|
|
113
|
+
- spring-boot analysis 评分/难度/路径
|
|
114
|
+
- Spring Boot 仓库推荐(3 条)
|
|
115
|
+
- vscode good-first-issues(10 条)
|
|
116
|
+
- fastapi similar repos(aiohttp/starlette,语义正确)
|
|
117
|
+
- spring-boot vs quarkus vs micronaut 排序
|
|
118
|
+
- spring-boot roadmap(documentation → core → tests 顺序合理)
|
|
119
|
+
|
|
120
|
+
### Issues 空列表诊断(spring-boot)
|
|
121
|
+
|
|
122
|
+
连续三次为空,通过 debug_issues.py 三路交叉验证:
|
|
123
|
+
- 无 label 基线 → 有数据(排除连通性)
|
|
124
|
+
- labels=good first issue → []
|
|
125
|
+
- Search API 同条件 → total_count: 0
|
|
126
|
+
|
|
127
|
+
结论:spring-boot 确实当前 0 条 open good-first-issue(大数据项目常见),
|
|
128
|
+
不是 bug。测试目标切到 microsoft/vscode 后正常返回 10 条。
|
|
129
|
+
产品改进点(下一步):空结果时返回引导文案而非空 JSON。
|
|
130
|
+
|
|
131
|
+
### Roadmap 优化史
|
|
132
|
+
|
|
133
|
+
第一版:按 API 返回顺序取前 10 个目录,充斥 .idea/antora/buildSrc 等噪音。
|
|
134
|
+
第二版:加 _SKIP_PATTERNS 跳过工程目录,按关键词赋学习优先级。
|
|
135
|
+
第三版:修复 "src in buildSrc" 子串误匹配(buildSrc 加入黑名单),
|
|
136
|
+
documentation 通过 "doc" 关键词正确识别为高优先级。
|
|
137
|
+
经验:目录名关键词匹配必须用词边界或黑名单双保险。
|
|
138
|
+
|
|
139
|
+
### Similar 优化史
|
|
140
|
+
|
|
141
|
+
第一版按 topic/language 搜索,fastapi 混入 public-apis(只是同为 Python)。
|
|
142
|
+
第二版增加策略:优先非通用 topic,其次从 repo 名/描述提关键词,
|
|
143
|
+
兜底 language-only + stars:>10000。fastapi 现在返回 aiohttp/starlette,语义正确。
|
|
144
|
+
|
|
145
|
+
## 2026-10-11:整理截图文档
|
|
146
|
+
|
|
147
|
+
docs/screenshots/README.md 是给开发者看的临时截图指引,对仓库访客没有价值。
|
|
148
|
+
删除该子文档,截图使用说明并入主 README 的 Screenshots 部分。
|
|
149
|
+
仓库内只保留主 README 一个入口,避免访客在截图目录看到重复说明。
|
|
150
|
+
|
|
151
|
+
## 2026-10-11:新增 trending 工具
|
|
152
|
+
|
|
153
|
+
GitHub API 没有官方 trending 接口,工具不再假装能直接取到榜单。
|
|
154
|
+
改用 Search API 近似实现:按 language/topic、最低星数、创建时间和是否 fork/archived 过滤,
|
|
155
|
+
再用 stars / age_days 作为趋势分排序。
|
|
156
|
+
决策:输出明确的 stars_per_day 计算依据,让调用方知道这是可解释的近似,而非官方榜单。
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# 项目规划
|
|
2
|
+
|
|
3
|
+
## 产品定位
|
|
4
|
+
|
|
5
|
+
帮助开发者(尤其是初学者和转行者)根据自身水平和目标,发现适合学习的 GitHub 开源项目。
|
|
6
|
+
|
|
7
|
+
区别于 GitHub 官方 MCP Server(侧重仓库操作),我们聚焦「学习决策」。
|
|
8
|
+
|
|
9
|
+
## 目标用户
|
|
10
|
+
|
|
11
|
+
- 编程初学者
|
|
12
|
+
- 转行开发者
|
|
13
|
+
- 面试准备者
|
|
14
|
+
- 想参与开源的人
|
|
15
|
+
- 进阶学习者
|
|
16
|
+
|
|
17
|
+
## 核心功能
|
|
18
|
+
|
|
19
|
+
### Tools
|
|
20
|
+
1. recommend_learning_repos:根据定位推荐项目
|
|
21
|
+
2. analyze_repo_for_learning:深度分析项目学习价值
|
|
22
|
+
3. get_repo_roadmap:生成学习路线
|
|
23
|
+
4. find_similar_repos:查找相似项目
|
|
24
|
+
5. compare_learning_repos:对比多个项目
|
|
25
|
+
6. find_good_first_issues:找适合新手的 issue
|
|
26
|
+
7. get_trending_repos_for_learning:发现热门学习项目
|
|
27
|
+
|
|
28
|
+
## 技术栈
|
|
29
|
+
|
|
30
|
+
- Python 3.10+
|
|
31
|
+
- MCP 官方 SDK
|
|
32
|
+
- httpx
|
|
33
|
+
- pydantic
|
|
34
|
+
- pytest
|
|
35
|
+
- ruff
|
|
36
|
+
- pip / uv
|
|
37
|
+
|
|
38
|
+
## 开发阶段
|
|
39
|
+
|
|
40
|
+
### Week 1:项目骨架 + recommend tool
|
|
41
|
+
- 搭建项目结构
|
|
42
|
+
- 封装 GitHub API 客户端
|
|
43
|
+
- 实现第一个 Tool:recommend_learning_repos
|
|
44
|
+
- 在 Cherry Studio 中测试
|
|
45
|
+
|
|
46
|
+
### Week 2:核心分析工具
|
|
47
|
+
- analyze_repo_for_learning
|
|
48
|
+
- get_repo_roadmap
|
|
49
|
+
- find_similar_repos
|
|
50
|
+
|
|
51
|
+
### Week 3:高级工具 + Prompts
|
|
52
|
+
- compare_learning_repos
|
|
53
|
+
- find_good_first_issues
|
|
54
|
+
- get_trending_repos_for_learning
|
|
55
|
+
- 添加 MCP Prompts
|
|
56
|
+
|
|
57
|
+
### Week 4:测试 + 发布 + 文档
|
|
58
|
+
- 补充 pytest 测试
|
|
59
|
+
- GitHub Actions CI
|
|
60
|
+
- 发布到 PyPI
|
|
61
|
+
- 完善 README 和使用教程
|
|
Binary file
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "mcp-github-learning-assistant"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "An MCP server that helps developers discover and learn from GitHub open-source projects"
|
|
5
|
+
authors = [{name = "iyiook333"}]
|
|
6
|
+
license = {text = "MIT"}
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
requires-python = ">=3.10"
|
|
9
|
+
classifiers = [
|
|
10
|
+
"Development Status :: 3 - Alpha",
|
|
11
|
+
"Intended Audience :: Developers",
|
|
12
|
+
"License :: OSI Approved :: MIT License",
|
|
13
|
+
"Programming Language :: Python :: 3",
|
|
14
|
+
"Programming Language :: Python :: 3.10",
|
|
15
|
+
"Programming Language :: Python :: 3.11",
|
|
16
|
+
"Programming Language :: Python :: 3.12",
|
|
17
|
+
]
|
|
18
|
+
dependencies = [
|
|
19
|
+
"mcp>=1.0.0",
|
|
20
|
+
"httpx>=0.27.0",
|
|
21
|
+
"pydantic>=2.0.0",
|
|
22
|
+
"python-dotenv>=1.0.0",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[project.optional-dependencies]
|
|
26
|
+
dev = [
|
|
27
|
+
"pytest>=8.0.0",
|
|
28
|
+
"pytest-asyncio>=0.23.0",
|
|
29
|
+
"ruff>=0.6.0",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.scripts]
|
|
33
|
+
mcp-github-learning-assistant = "mcp_github_learning_assistant.server:run"
|
|
34
|
+
|
|
35
|
+
[build-system]
|
|
36
|
+
requires = ["hatchling"]
|
|
37
|
+
build-backend = "hatchling.build"
|
|
38
|
+
|
|
39
|
+
[tool.ruff]
|
|
40
|
+
line-length = 100
|
|
41
|
+
target-version = "py310"
|
|
42
|
+
|
|
43
|
+
[tool.ruff.lint]
|
|
44
|
+
select = ["E", "F", "I", "N", "W", "UP"]
|
|
45
|
+
|
|
46
|
+
[tool.pytest.ini_options]
|
|
47
|
+
asyncio_mode = "auto"
|
|
48
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Debug why issue queries return empty."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
|
|
5
|
+
from dotenv import load_dotenv
|
|
6
|
+
|
|
7
|
+
from mcp_github_learning_assistant.github_client import github_client
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
async def main():
|
|
11
|
+
"""Print raw responses for label queries."""
|
|
12
|
+
load_dotenv()
|
|
13
|
+
owner, repo = "spring-projects", "spring-boot"
|
|
14
|
+
|
|
15
|
+
async with await github_client() as client:
|
|
16
|
+
# No-label baseline
|
|
17
|
+
r0 = await client.get(
|
|
18
|
+
f"/repos/{owner}/{repo}/issues",
|
|
19
|
+
params={"state": "open", "per_page": 3},
|
|
20
|
+
)
|
|
21
|
+
print("no-label status:", r0.status_code)
|
|
22
|
+
if r0.status_code == 200:
|
|
23
|
+
items = r0.json()
|
|
24
|
+
print(" got", len(items), "issues (any labels)")
|
|
25
|
+
for it in items:
|
|
26
|
+
print(" -", it.get("number"), it.get("title"))
|
|
27
|
+
|
|
28
|
+
# Label query
|
|
29
|
+
r1 = await client.get(
|
|
30
|
+
f"/repos/{owner}/{repo}/issues",
|
|
31
|
+
params={"labels": "good first issue", "state": "open", "per_page": 3},
|
|
32
|
+
)
|
|
33
|
+
print("good-first-issue status:", r1.status_code)
|
|
34
|
+
print(" body[:300]:", r1.text[:300])
|
|
35
|
+
|
|
36
|
+
# Search API alternative (OR across labels)
|
|
37
|
+
q = f"repo:{owner}/{repo} is:issue is:open label:'good first issue',label:'help wanted'"
|
|
38
|
+
r2 = await client.get("/search/issues", params={"q": q, "per_page": 5})
|
|
39
|
+
print("search-api status:", r2.status_code)
|
|
40
|
+
if r2.status_code == 200:
|
|
41
|
+
data = r2.json()
|
|
42
|
+
print(" total_count:", data.get("total_count"))
|
|
43
|
+
for it in data.get("items", [])[:5]:
|
|
44
|
+
print(" -", it.get("number"), it.get("title"))
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Direct test for the analyzer logic (no MCP involved)."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
|
|
5
|
+
from mcp_github_learning_assistant.analyzer import analyze_repo
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
async def main():
|
|
9
|
+
"""Analyze spring-projects/spring-boot and print JSON."""
|
|
10
|
+
result = await analyze_repo("spring-projects", "spring-boot")
|
|
11
|
+
print(result.model_dump_json(indent=2))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
if __name__ == "__main__":
|
|
15
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Simple MCP client to test the server locally."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
from mcp import ClientSession, StdioServerParameters
|
|
7
|
+
from mcp.client.stdio import stdio_client
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
async def main():
|
|
11
|
+
"""Connect to the MCP server and call get_server_info."""
|
|
12
|
+
server_params = StdioServerParameters(
|
|
13
|
+
command=sys.executable,
|
|
14
|
+
args=["-m", "mcp_github_learning_assistant"],
|
|
15
|
+
env=None,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
async with stdio_client(server_params) as (read, write):
|
|
19
|
+
async with ClientSession(read, write) as session:
|
|
20
|
+
await session.initialize()
|
|
21
|
+
|
|
22
|
+
tools = await session.list_tools()
|
|
23
|
+
print("Available tools:", [tool.name for tool in tools.tools])
|
|
24
|
+
|
|
25
|
+
result = await session.call_tool("get_server_info", {})
|
|
26
|
+
print("Tool result:")
|
|
27
|
+
for content in result.content:
|
|
28
|
+
print(content.text)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
if __name__ == "__main__":
|
|
32
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
|
|
3
|
+
from mcp_github_learning_assistant.comparer import compare_repos
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
async def main():
|
|
7
|
+
r = await compare_repos(
|
|
8
|
+
repos=[
|
|
9
|
+
"spring-projects/spring-boot",
|
|
10
|
+
"quarkusio/quarkus",
|
|
11
|
+
"micronaut-projects/micronaut-core",
|
|
12
|
+
],
|
|
13
|
+
user_level="beginner",
|
|
14
|
+
)
|
|
15
|
+
print(r.model_dump_json(indent=2))
|
|
16
|
+
|
|
17
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Direct test for find_first_issues (no MCP involved)."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
|
|
5
|
+
from mcp_github_learning_assistant.issuefind import find_first_issues
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
async def main():
|
|
9
|
+
"""vscode reliably has many good first issues."""
|
|
10
|
+
r = await find_first_issues("microsoft", "vscode", ["good first issue"])
|
|
11
|
+
print(r.model_dump_json(indent=2))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
asyncio.run(main())
|