CannJudge Local OJ MCP Server
by mojohugo
README.md
# CannJudge Local OJ
面向 Ascend C 算子开发的自托管评测服务。提交 `kernel.asc`,通过 SSH 在自己的昇腾服务器编译、校验、计时和采集 profiler;提供网页、HTTP API 和带认证的 MCP。
本项目是独立工具,与 CANNJudge、华为或 OpenAI 无隶属关系。适用于可信开发者共用的评测环境,**不是面向任意不可信代码的安全沙箱**。
## 功能
- 独立题目包:CumSum、Cosine Similarity、LogSigmoid,各带十组默认测试规格;可扩展其他题目和测试数量。
- 自定义 C++17 数据生成器;C++ 独立参考实现和答案检查,不接受用户提供的参考答案。
- 源码预检、运行时单 kernel launch 检查、输入修改检测、输出覆盖检查及详细错误报告。
- ACL Event 计时、设备耗时、PipeUtilization、L2Cache、MemoryUB、workspace 和设备内存信息;不支持的指标明确标为不可用。
- 异步队列、并行 CPU 准备、NPU 设备锁、编译缓存、SSH 重连、每题排行榜、逐点最佳源码和手动基线。
- MCP 支持题目信息、优化提示、源码修订、自定义数据、提交与查询;OAuth / PKCE / DCR 或 API bearer token。
- 可选官方集成:独立官方提交队列、历史同步、官方分数/逐点时间和最佳源码。默认关闭,需部署者自己的账号登录。
## 快速启动网页
需要 Python 3.11+。网页/API 可以在 Windows 或 Linux 运行;真正的 NPU 评测需要 Linux Ascend 服务器。当前 harness 面向 Ascend 910B / `dav-2201`,曾在 CANN 9.0.0 验证;其他硬件和 SDK 版本需自行验证。
```bash
python -m venv .venv
# Linux/macOS: source .venv/bin/activate
# Windows PowerShell: .\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
python -c "from oj.config import load_settings; load_settings()"
python -m uvicorn oj.app:create_app --factory --host 127.0.0.1 --port 8765 --workers 1 --no-proxy-headers
```
打开 [本机网页](http://127.0.0.1:8765)。首次启动生成 `var/config.json` 和 `var/admin-access.txt`,后者包含随机登录密码和 API key。不要将这两个文件上传到 GitHub。
新安装默认关闭评测 worker、官方提交和自动同步;可以先查看页面、题目和静态检查。启用 worker 后才会执行排队任务。Windows 也可在激活环境后运行 `start.cmd`。
参考 [config.example.json](config.example.json) 修改**已生成**的配置项,保留随机生成的密码盐与摘要。示例不包含凭据,不能直接覆盖运行配置。`OJ_STATE_DIR` 可指定另一个状态目录。
## 接入 NPU 服务器
1. 配置自己的 OpenSSH 别名 `npu-worker`,验证主机指纹及免交互登录。
2. 将 `config/backends.example.json` 复制为 `config/backends.json`,设置远端路径、执行用户、CANN 环境脚本、设备与核心数。
3. 按 [部署说明](docs/DEPLOYMENT.md) 准备服务器依赖与权限,执行 `python scripts/deploy.py --backend npu-worker`。
4. 将 `var/config.json` 的 `ssh_host`、`remote_root` 与后端对应,并设 `worker_enabled: true`。在队列空闲时启动或重启服务。
网页一次只运行一个 Uvicorn worker。`evaluation_workers` 控制 1–4 个任务的 CPU 准备并行度;默认 2。共用设备上的正确性检查、计时和 profiler 保持独占。
## 数据与分数
默认规格见各题的 `problem.json`。输入在安装时由 C++ 用固定种子生成;这些是**合成测试数据**,不包含官方隐藏输入、随机种子或用户提交源码。历史验证摘要保留来源类别,个人提交链接与原始归档不随仓库发布。
| 题目 | ID | 默认点数 | 自定义生成器 |
| --- | --- | ---: | --- |
| CumSum | `cum_sum` | 10 | [示例](problems/cum_sum/examples/generate.cpp) |
| Cosine Similarity | `cosine_similarity` | 10 | [示例](problems/cosine_similarity/examples/generate.cpp) |
| LogSigmoid | `log_sigmoid` | 10 | [示例](problems/log_sigmoid/examples/generate.cpp) |
生成器只写输入及 manifest,C++ reference 独立生成 golden。各题的数值语义、容差、限制和优化注意事项可通过 `get_problem` / `get_problem_guide` 查询;CumSum 的 half 参考按每一步加法舍入,不能直接替换成 FP32 累加再转 half。
本地排名采用 `100 / (1 + log(time / TBest) / log(1.5))` 逐点计分后取平均,失败点处理由题目规则决定。`TBest` 来自相同本地数据、环境和计时协议的历史最优;这不是官方实得分。官方记录单独展示,服务端返回的官方分数优先,公式重算结果有单独标记。规则快照见 [contest_scoring.json](config/contest_scoring.json)。
基线由部署者从已通过的提交中选择,仓库不捆绑私人校准源码或计时。Event、profiler 设备时间、估算时间分别展示;没有足够同版本校准资料时不提供线上估时。硬件相同也不保证与官方耗时一致。
## API / MCP / 官方集成
- API:`/api`;FastAPI 接口说明:`/docs`。
- MCP:`/mcp`,Streamable HTTP,支持 `Authorization: Bearer <API_KEY>`。
- 公网 MCP:通过 HTTPS 反向代理或隧道访问;OAuth 使用动态客户端注册和 `oj:access` scope。
- 官方页面:`/official`;需要 Node.js 22+、Playwright 和部署者自己的专用登录状态。
完整配置与「只使用官方数据」提示词见 [MCP 和官方集成](docs/MCP.md)。生产配置、SQLite、源码、浏览器登录状态和日志均属于私有运行数据。
## 开发与验证
```bash
python -m pip install -r requirements-dev.txt
python -m pytest -q
node --test tests/official-data.test.mjs tests/test_polling.cjs
```
测试使用临时状态和模拟队列,不连接 SSH、不发起官方提交。安装了 `g++` 时,还会验证 C++ 默认数据生成与参考结果;GitHub CI 在 Linux 和 Windows 上执行服务测试。真实 NPU 集成需要明确运行 `scripts/integration.py`,见部署说明。
```text
oj/ 网页、API、MCP、认证、队列与排名
remote/ SSH worker、执行限制、设备锁与 profiler 管理
problems/ 每题独立的契约、C++ generator/reference 和 harness
knowledge/ MCP 题目信息与带证据类别的优化提示
web/ 当前前端资源
config/ 公开规则快照与后端配置示例
scripts/ 部署、检查、官方浏览器集成与发布审计
tests/ 无 NPU 测试及可选 C++ 测试
var/ 私有运行数据(Git 忽略)
```
添加题目见 [PROBLEM_PACKS.md](PROBLEM_PACKS.md),贡献方式见 [CONTRIBUTING.md](CONTRIBUTING.md),部署边界见 [SECURITY.md](SECURITY.md)。
## 许可证
项目自有代码采用 [MIT](LICENSE)。CANN SDK、驱动、第三方 Python/Node 依赖和外部站点内容遵循各自条款,见 [第三方说明](THIRD_PARTY_NOTICES.md)。
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues