init
This commit is contained in:
257
docs/development.md
Normal file
257
docs/development.md
Normal file
@@ -0,0 +1,257 @@
|
||||
# 开发指南
|
||||
|
||||
本文档介绍如何开发和扩展 NJUPT MCP Server。
|
||||
|
||||
## 架构概述
|
||||
|
||||
```
|
||||
┌─────────────────┐
|
||||
│ MCP Client │ (Kimi Code CLI, Claude Desktop, etc.)
|
||||
│ (Kimi, Claude) │
|
||||
└────────┬────────┘
|
||||
│ MCP Protocol (stdio / SSE)
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ njupt-mcp │
|
||||
│ (FastMCP) │
|
||||
└────────┬────────┘
|
||||
│
|
||||
┌────┴────┐
|
||||
▼ ▼
|
||||
┌───────┐ ┌───────┐
|
||||
│ Tools │ │Resources│
|
||||
└───┬───┘ └───┬───┘
|
||||
│ │
|
||||
▼ ▼
|
||||
┌───────┐ ┌───────┐
|
||||
│ NJUPT │ │ Static│
|
||||
│ APIs │ │ Data │
|
||||
└───────┘ └───────┘
|
||||
```
|
||||
|
||||
## 添加新功能
|
||||
|
||||
### 1. 添加工具 (Tool)
|
||||
|
||||
工具用于执行操作、调用 API。在 `src/njupt_mcp/server.py` 中添加:
|
||||
|
||||
```python
|
||||
@mcp.tool()
|
||||
async def my_tool(param1: str, param2: int = 10) -> str:
|
||||
"""工具的描述,会显示给 LLM
|
||||
|
||||
详细说明工具的用途、使用场景等。
|
||||
|
||||
Args:
|
||||
param1: 参数1的描述
|
||||
param2: 参数2的描述,默认为 10
|
||||
|
||||
Returns:
|
||||
返回值的描述,通常是 JSON 字符串
|
||||
|
||||
Example:
|
||||
my_tool("test", 20) -> 返回结果
|
||||
"""
|
||||
# 实现逻辑
|
||||
result = {"param1": param1, "param2": param2}
|
||||
return json.dumps(result, ensure_ascii=False)
|
||||
```
|
||||
|
||||
**最佳实践:**
|
||||
|
||||
- 使用 `async def` 定义异步函数
|
||||
- 提供详细的文档字符串(LLM 依赖此信息决定是否调用)
|
||||
- 使用类型注解
|
||||
- 返回 JSON 字符串便于 LLM 解析
|
||||
- 处理异常情况,返回友好的错误信息
|
||||
|
||||
### 2. 添加资源 (Resource)
|
||||
|
||||
资源用于提供数据、文档等只读内容:
|
||||
|
||||
```python
|
||||
@mcp.resource("njupt://resource-name")
|
||||
async def get_resource() -> str:
|
||||
"""资源的描述"""
|
||||
return "资源内容"
|
||||
```
|
||||
|
||||
资源 URI 格式:`scheme://path`,建议使用 `njupt://` 作为 scheme。
|
||||
|
||||
### 3. 添加提示词模板 (Prompt)
|
||||
|
||||
提示词模板用于生成特定场景的提示词:
|
||||
|
||||
```python
|
||||
@mcp.prompt()
|
||||
def my_prompt(context: str, question: str) -> str:
|
||||
"""提示词模板的描述"""
|
||||
return f"""基于以下上下文:
|
||||
{context}
|
||||
|
||||
请回答:{question}
|
||||
"""
|
||||
```
|
||||
|
||||
## 数据获取实现
|
||||
|
||||
目前示例代码使用硬编码数据,实际应用中需要对接 NJUPT 的数据源:
|
||||
|
||||
### 教务系统
|
||||
|
||||
```python
|
||||
import httpx
|
||||
|
||||
async def fetch_course_data(course_code: str) -> dict:
|
||||
"""从教务系统获取课程数据"""
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.get(
|
||||
"https://jw.njupt.edu.cn/api/course",
|
||||
params={"code": course_code},
|
||||
cookies={"session": await get_session()}
|
||||
)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
```
|
||||
|
||||
### 图书馆 OPAC
|
||||
|
||||
```python
|
||||
async def search_library(keyword: str) -> list[dict]:
|
||||
"""搜索图书馆 OPAC 系统"""
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.get(
|
||||
"http://opac.njupt.edu.cn/opac/search",
|
||||
params={"q": keyword}
|
||||
)
|
||||
# 解析 HTML 或 JSON
|
||||
return parse_search_results(response.text)
|
||||
```
|
||||
|
||||
## 测试
|
||||
|
||||
### 运行测试
|
||||
|
||||
```bash
|
||||
# 运行所有测试
|
||||
pytest
|
||||
|
||||
# 运行特定测试文件
|
||||
pytest tests/test_helpers.py -v
|
||||
|
||||
# 运行并生成覆盖率报告
|
||||
pytest --cov=njupt_mcp --cov-report=html
|
||||
```
|
||||
|
||||
### 编写测试
|
||||
|
||||
```python
|
||||
# tests/test_new_feature.py
|
||||
import pytest
|
||||
from njupt_mcp.server import my_new_tool
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_my_tool():
|
||||
result = await my_tool("test", 20)
|
||||
assert "test" in result
|
||||
assert "20" in result
|
||||
```
|
||||
|
||||
## 调试技巧
|
||||
|
||||
### 使用 MCP Inspector
|
||||
|
||||
```bash
|
||||
# 启动服务器
|
||||
uv run njupt-mcp --transport streamable-http
|
||||
|
||||
# 启动 Inspector
|
||||
npx -y @modelcontextprotocol/inspector
|
||||
```
|
||||
|
||||
访问 http://localhost:5173 进行交互式调试。
|
||||
|
||||
### 启用调试日志
|
||||
|
||||
```bash
|
||||
uv run njupt-mcp --debug
|
||||
```
|
||||
|
||||
### 手动测试工具
|
||||
|
||||
```python
|
||||
# test_manual.py
|
||||
import asyncio
|
||||
from njupt_mcp.server import search_course
|
||||
|
||||
async def main():
|
||||
result = await search_course("数据结构")
|
||||
print(result)
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
## 部署
|
||||
|
||||
### 本地部署
|
||||
|
||||
使用 `uv` 运行:
|
||||
|
||||
```bash
|
||||
uv run njupt-mcp
|
||||
```
|
||||
|
||||
### Docker 部署
|
||||
|
||||
```dockerfile
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
|
||||
RUN pip install -e "."
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
CMD ["njupt-mcp", "--transport", "sse", "--host", "0.0.0.0"]
|
||||
```
|
||||
|
||||
### 云服务部署
|
||||
|
||||
适合使用 SSE 或 streamable-http 模式,部署到:
|
||||
|
||||
- [Railway](https://railway.app/)
|
||||
- [Render](https://render.com/)
|
||||
- [Fly.io](https://fly.io/)
|
||||
|
||||
## 性能优化
|
||||
|
||||
### 添加缓存
|
||||
|
||||
```python
|
||||
from functools import lru_cache
|
||||
import asyncio
|
||||
from cachetools import TTLCache
|
||||
|
||||
# 使用 TTLCache 缓存结果
|
||||
course_cache = TTLCache(maxsize=100, ttl=3600)
|
||||
|
||||
@mcp.tool()
|
||||
async def search_course(keyword: str) -> str:
|
||||
if keyword in course_cache:
|
||||
return course_cache[keyword]
|
||||
|
||||
result = await fetch_course_from_api(keyword)
|
||||
course_cache[keyword] = result
|
||||
return result
|
||||
```
|
||||
|
||||
### 并发请求
|
||||
|
||||
```python
|
||||
async def fetch_multiple_courses(course_codes: list[str]) -> list[dict]:
|
||||
async with httpx.AsyncClient() as client:
|
||||
tasks = [fetch_course(client, code) for code in course_codes]
|
||||
return await asyncio.gather(*tasks)
|
||||
```
|
||||
124
docs/kimi-cli-setup.md
Normal file
124
docs/kimi-cli-setup.md
Normal file
@@ -0,0 +1,124 @@
|
||||
# Kimi Code CLI 配置指南
|
||||
|
||||
本文档介绍如何在 Kimi Code CLI 中配置和使用 NJUPT MCP Server。
|
||||
|
||||
## 配置步骤
|
||||
|
||||
### 1. 找到配置文件
|
||||
|
||||
Kimi Code CLI 的配置文件通常位于:
|
||||
|
||||
- Windows: `%APPDATA%\kimi-cli\config.toml`
|
||||
- macOS/Linux: `~/.config/kimi-cli/config.toml`
|
||||
|
||||
### 2. 添加 MCP 服务器配置
|
||||
|
||||
#### stdio 模式(推荐)
|
||||
|
||||
```toml
|
||||
[mcp.servers.njupt-mcp]
|
||||
type = "stdio"
|
||||
command = "uv"
|
||||
args = ["run", "--directory", "E:\\Code\\njupt-mcp", "njupt-mcp"]
|
||||
```
|
||||
|
||||
如果使用 pip 安装:
|
||||
|
||||
```toml
|
||||
[mcp.servers.njupt-mcp]
|
||||
type = "stdio"
|
||||
command = "python"
|
||||
args = ["-m", "njupt_mcp.server"]
|
||||
```
|
||||
|
||||
#### SSE 模式
|
||||
|
||||
首先启动服务器:
|
||||
|
||||
```bash
|
||||
cd /path/to/njupt-mcp
|
||||
uv run njupt-mcp --transport sse --port 8000
|
||||
```
|
||||
|
||||
然后在配置文件中添加:
|
||||
|
||||
```toml
|
||||
[mcp.servers.njupt-mcp]
|
||||
type = "sse"
|
||||
url = "http://localhost:8000/sse"
|
||||
```
|
||||
|
||||
### 3. 验证配置
|
||||
|
||||
在 Kimi Code CLI 中输入:
|
||||
|
||||
```
|
||||
/mcp
|
||||
```
|
||||
|
||||
你应该能看到 `njupt-mcp` 服务器已列出。
|
||||
|
||||
## 使用示例
|
||||
|
||||
配置完成后,你可以在 Kimi Code CLI 中这样使用:
|
||||
|
||||
```
|
||||
> 帮我查一下南京邮电大学数据结构的课程信息
|
||||
```
|
||||
|
||||
Kimi Code CLI 会自动调用 `search_course` 工具。
|
||||
|
||||
```
|
||||
> 帮我查一下学号 B21010101 的课表
|
||||
```
|
||||
|
||||
这会调用 `get_course_schedule` 工具。
|
||||
|
||||
## 故障排查
|
||||
|
||||
### 服务器无法启动
|
||||
|
||||
1. 检查 Python 版本:`python --version` 应 >= 3.11
|
||||
2. 检查依赖是否安装:`uv sync` 或 `pip install -e "."`
|
||||
3. 检查路径是否正确:确保 `--directory` 指向正确位置
|
||||
|
||||
### MCP 命令无响应
|
||||
|
||||
1. 检查 Kimi Code CLI 版本:`kimi --version`
|
||||
2. 查看 Kimi Code CLI 日志,通常在 `%APPDATA%\kimi-cli\logs\`
|
||||
3. 尝试手动运行服务器命令,查看是否有错误输出
|
||||
|
||||
### 工具调用失败
|
||||
|
||||
1. 确保服务器已正确启动
|
||||
2. 检查工具参数是否正确
|
||||
3. 查看服务器日志输出
|
||||
|
||||
## 进阶配置
|
||||
|
||||
### 环境变量
|
||||
|
||||
你可以在配置中设置环境变量:
|
||||
|
||||
```toml
|
||||
[mcp.servers.njupt-mcp]
|
||||
type = "stdio"
|
||||
command = "uv"
|
||||
args = ["run", "--directory", "E:\\Code\\njupt-mcp", "njupt-mcp"]
|
||||
env = { NJUPP_API_KEY = "your-api-key", DEBUG = "1" }
|
||||
```
|
||||
|
||||
### 多个实例
|
||||
|
||||
你可以配置多个服务器实例,分别用于不同环境:
|
||||
|
||||
```toml
|
||||
[mcp.servers.njupt-mcp-dev]
|
||||
type = "stdio"
|
||||
command = "uv"
|
||||
args = ["run", "--directory", "E:\\Code\\njupt-mcp", "njupt-mcp", "--debug"]
|
||||
|
||||
[mcp.servers.njupt-mcp-prod]
|
||||
type = "sse"
|
||||
url = "https://njupt-mcp.your-domain.com/sse"
|
||||
```
|
||||
Reference in New Issue
Block a user