内容
# CSES MCP 服务器
*您的人工智能助手的 CSES(代码提交评估系统)网关*
## 🤔 这是什么?
`cses-mcp` 是一个基于 Python 的 MCP(模型上下文协议)服务器,允许与 MCP 兼容的客户端(如 Claude Desktop 或 Claude Code)代表您在 CSES 上执行操作:浏览问题、阅读问题陈述、提交解决方案和查看提交历史/结果。
据我所知,CSES 没有公开的 API,因此所有数据访问都是通过抓取身份验证的 HTML 页面并使用您的会话 cookie 发布到现有的 Web 表单来实现的。
### 为什么?
CSES 是学习竞争性编程的最佳免费问题集之一,但通常需要手动切换标签页:阅读陈述,在其他地方编写代码,返回提交,然后深入结果页面以找出问题所在。该项目将整个循环转化为对话 - 请求人工智能助手为您找到问题,解释陈述,帮助您思考解决方案,提交您的解决方案,并诊断错误的结果,而无需离开聊天。目标不是为您解决问题(尽管它可以做到),而是使反馈循环足够紧密,以便您能更快地学习:在需要时获取提示而不是完整的解决方案,了解为什么提交结果错误或超时,并使用过去的尝试历史查看自己的进度。
---
## 🚀 快速开始
选择适合您的方式 - 选项 A 如果您只需要使用它,选项 B 如果您正在编辑代码。
### 选项 A - 复制粘贴(无需本地克隆)
将此内容直接粘贴到您的 MCP 客户端配置中 - `uvx` 获取并运行已发布的软件包,无需克隆,无需 `uv sync`,无需 `.env` 文件管理:
```json
{
"mcpServers": {
"cses-mcp": {
"command": "uvx",
"args": ["qhung-cses-mcp@latest"],
"env": {
"PHPSESSID": "<您的 CSES 会话 cookie>"
}
}
}
}
```
要求:
- 安装 [`uv`](https://docs.astral.sh/uv/)(`uvx` 随它一起提供):
```bash
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
```
- 将您的 `PHPSESSID` 粘贴到上面的 `env` 块中 - 请参阅 [获取您的 CSES 会话 cookie](#获取您的-cses-会话-cookie)。
重启您的 MCP 客户端,工具即可使用 - 就是这样。
<details>
<summary>尚未在 PyPI 上或希望直接跟踪存储库?</summary>
指向存储库的纯 HTTPS 存档,而不是发布的软件包 - 仍然无需 `git clone`,无需 `uv sync`,且(与 `git+` URL 不同)无需可执行的本地 `git`,这在某些环境中很重要(例如 Claude Desktop 的 Windows 软件包无法执行 `git` 甚至当它安装并在 `PATH` 上时):
```json
{
"mcpServers": {
"cses-mcp": {
"command": "uvx",
"args": ["--from", "https://github.com/qhung23125005/CSES-MCP/archive/refs/heads/master.tar.gz", "qhung-cses-mcp"],
"env": {
"PHPSESSID": "<您的 CSES 会话 cookie>"
}
}
}
}
```
如果您希望它始终通过 git 解析,也可以使用 `--from git+https://github.com/qhung23125005/CSES-MCP` URL,但这需要一个可用的本地 `git`,您的 MCP 客户端进程可以实际执行 - 请参阅 [选项 B - 手动克隆进行本地开发/编辑代码](#选项-b-手动克隆进行本地开发编辑代码),如果这两种方式在您的环境中都不可靠。
</details>
### 选项 B - 手动克隆(用于本地开发/编辑代码)
1. **前提条件** - Python 3.12+ 和 `uv`(请参阅上面的安装命令)。
2. **克隆和安装:**
```bash
git clone https://github.com/qhung23125005/CSES-MCP.git
cd CSES-MCP
uv sync --all-extras
cp .env.example .env
```
3. **将您的 `PHPSESSID` 添加到 `.env`** - 请参阅 [获取您的 CSES 会话 cookie](#获取您的-cses-会话-cookie)。
4. **独立运行**(用于手动测试/MCP 检查器):
```bash
make run # STDIO 传输(默认)
make run-debug # STDIO 和调试日志
make run-sse # SSE 传输,端口 8000
make run-inspector # 运行 MCP 检查器(浏览器 UI 手动调用工具)
```
5. **或连接 MCP 客户端** 到克隆的副本:
```json
{
"mcpServers": {
"cses-mcp": {
"command": "uv",
"args": ["run", "--project", "/path/to/CSES-MCP", "python", "-m", "cses_mcp.main"]
}
}
}
```
`--project` 将 `uv` 固定到此项目的环境中,与工作目录无关 - 比 `cwd` 设置更可靠。`.env` 相对于项目根目录自动解析(请参阅 `src/cses_mcp/config/settings.py`),因此客户端配置中不需要 `env` 块 - 虽然您仍然可以使用它而不是 `.env`,就像选项 A 一样。
### 获取您的 CSES 会话 cookie
服务器使用您的 CSES 会话 cookie(`PHPSESSID`)为您进行身份验证 - 工具从不接受密码或 cookie 作为参数,因此调用这些工具的人工智能助手永远不会看到或处理凭证本身。
1. 在浏览器中登录 [cses.fi](https://cses.fi)。
2. 打开 DevTools(`F12`)→ **应用程序**(Chrome/Edge)或 **存储**(Firefox)→ **Cookie** → `https://cses.fi`。
3. 复制 `PHPSESSID` 值 - 到客户端配置的 `env` 块(选项 A)或 `.env`(选项 B)。
CSES 会话可能过期;如果工具开始返回 `CSES_NOT_AUTHENTICATED`,请重新复制一个新鲜的 cookie。
您已准备就绪!通过您的 MCP 客户端开始发出提示 - 请参阅 [Claude 的示例提示](#-claude-示例提示)。
---
## 🛠️ 可用工具
*(输入参数为字符串,除非另有说明)*
- **`fetch_categories`** *(无需身份验证)*:列出每个 CSES 问题类别名称(例如“入门问题”,“排序和搜索”)。
- _返回:_ 类别名称字符串列表。
- **`fetch_problems`** *(需要身份验证)*:列出问题,可选按类别/状态过滤,并显示每个问题的解决状态。
- `category`(可选字符串):精确的类别名称,不区分大小写和空格(使用 `fetch_categories`查找)。
- `status`(可选字符串):`"completed"`、`"not accepted"`或`"not completed"`之一。
- _返回:_ `{name, link, status, category}` 列表。
- **`fetch_problem_statement`** *(无需身份验证)*:获取单个问题的陈述。
- `url`(字符串):绝对问题页面 URL,例如 `https://cses.fi/problemset/task/1068`。
- _返回:_ `{Title, Limit: {time_limit, memory_limit}, description, sections: {input, output, constraints, example}}`。
- **`submit_code`** *(需要身份验证)*:将解决方案提交给任务进行评判。
- `task_id`(字符串):CSES 任务 ID,例如 `"1068"`。
- `filename`(字符串):仅用于从扩展名推断语言,例如 `"solution.py"`。支持:`.asm .c .cpp/.cc .hs .java .js .pas .py .rb .rs .scala`。
- `code`(字符串):完整的源代码,内存中 - 无需文件系统访问。
- _返回:_ `{task_id, submission_id, redirect}`。
- **`fetch_submission`** *(需要身份验证)*:获取单个提交的详细信息,每个测试的结果和提交的代码。
- `submission_id`(字符串):从 `submit_code` 的响应或结果 URL。
- _返回:_ `{task, sender, submission_time, language, status, result, tests: [{test, verdict, time}], code}`。
- **`fetch_submission_list`** *(需要身份验证)*:列出您过去提交的任务,最近的优先。
- `task_id`(字符串):CSES 任务 ID,例如 `"2134"`。
- _返回:_ `{submission_id, time, lang, code_time, code_size, result}` 列表。
每个工具在失败时返回单个错误字典 (`{"error": true, "error_code": ..., "message": ..., ...}`) 而不是引发异常 - 在将结果视为成功之前,请检查 `"error": true`。`"auth required"` 工具需要设置 `PHPSESSID`(请参阅 [获取您的 CSES 会话 cookie](#获取您的-cses-会话-cookie));其他工具抓取公共页面,无需设置。
---
## 💬 Claude 示例提示
连接后,尝试以下提示:
- “CSES 有哪些问题类别?”
- “列出所有我尚未解决的排序和搜索问题。”
- “给我 Weird Algorithm 的陈述。”
- “将此 Python 解决方案提交到任务 1068:`<code>`。”
- “我的上一次 Path Queries II 提交是否被接受?如果未被接受,获得了什么结果?”
- “显示我提交的编号为 17833364 的代码。”
- “我向任务 2134 提交了多少次,结果是什么?”
- “在动态规划中找到一个我尚未解决的简单问题,给我陈述并帮助我编写解决方案。”
- “在我的最新提交中,Path Queries II 提交结果为 WA 和 TLE。请找出原因。”
- “完成 Tree Algorithms 类别中剩余的未解决的问题,供我参考。”
- “您可以给我一个关于如何解决 \<problem name\> 的提示吗?”
### 实际操作
**“在我的 CSES 账户中,我有多少问题尚未完成?”**

**“您可以为我选择一个计数问题类别中的随机简单问题吗?”**

**“在我的最新提交(2024 年)中,我获得了 TLE。找出代码为什么运行这么慢的原因”**

**“您可以为我完成前 3 个问题吗?”**

---
## 🧪 测试
```bash
make test # 运行测试(模拟 HTTP,无网络,无凭证)
make test-cov # 运行测试并覆盖
make lint # Ruff lint
make format # Ruff 格式/修复
```
每个工具的测试还包括一个可选的 **实时烟雾测试**,使用您的 `.env` cookie 访问真实的 cses.fi 网站 - 默认跳过,运行:
```bash
RUN_LIVE_TESTS=1 uv run pytest -k live
```
---
## 📁 项目结构
```
src/cses_mcp/
├── __init__.py
├── main.py # CLI 入口点
├── server.py # 核心服务器实现
├── client.py # 用于本地锻炼服务器的临时脚本
├── config/
│ └── settings.py # 配置管理(pydantic-settings)
├── tools/ # MCP 工具
│ ├── fetch_categories_tools.py
│ ├── fetch_problems_tools.py
│ └── submission_tools.py
├── resources/ # MCP 资源(脚手架,空)
├── prompts/ # MCP 提示(脚手架,空)
├── handlers/
│ └── error_handler.py # 集中式工具错误处理
└── utils/
├── logger.py
└── validation.py
tests/
├── fixtures/ # 保存的用于单元测试的 CSES HTML 页面样本
├── unit/ # 模拟 HTTP 测试 + 可选的实时烟雾测试
└── integration/ # 进程内 MCP 服务器/工具注册测试
```
### 添加工具、资源和提示
1. 在 `src/cses_mcp/tools/`(或 `resources/`、`prompts/`)下创建新文件,使用 `from ..server import mcp` 和相关的 `@mcp.tool` / `@mcp.resource` / `@mcp.prompt` 装饰器。
2. 在该包的 `__init__.py` 中导入模块进行注册。
---
## ⚙️ 配置
复制 `.env.example` 到 `.env` 并自定义。有关所有可用设置(服务器名称、日志级别/文件、调试模式、CSES 基本 URL、请求超时、`PHPSESSID`)请参阅 [src/cses_mcp/config/settings.py](src/cses_mcp/config/settings.py)。设置优先顺序为:实时环境变量、`.env` 第二 - 因此 MCP 客户端也可以通过其自己的 `"env"` 配置块注入 `PHPSESSID` 而不是提交的 `.env` 文件。
---
## 🔒 安全
- `PHPSESSID` 仅存在于服务器端配置(`.env` 或进程环境)中,从未作为工具参数 - 没有工具调用可以将其暴露在对话历史中,错误响应会从记录的工具参数中删除它。
- 会话 cookie/凭证绝不能被记录,在工具输出中打印,或传输到 `cses.fi` 以外的任何地方。
- 对 CSES 的请求应该是顺序的、限速的,而不是并行化的。
---
## 📄 许可证
该项目根据 MIT 许可证许可 - 有关详细信息,请参阅 [LICENSE](LICENSE)。