accoding-mcp-server-test-new 0.1.0

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.
Files changed (56) hide show
  1. package/README.md +86 -0
  2. package/build/accoding/accoding-base-service.d.ts +13 -0
  3. package/build/accoding/accoding-base-service.js +2 -0
  4. package/build/accoding/accoding-base-service.js.map +1 -0
  5. package/build/accoding/accoding-service-factory.d.ts +11 -0
  6. package/build/accoding/accoding-service-factory.js +14 -0
  7. package/build/accoding/accoding-service-factory.js.map +1 -0
  8. package/build/accoding/accoding-service-impl.d.ts +10 -0
  9. package/build/accoding/accoding-service-impl.js +18 -0
  10. package/build/accoding/accoding-service-impl.js.map +1 -0
  11. package/build/accoding/api/contest-api.d.ts +7 -0
  12. package/build/accoding/api/contest-api.js +69 -0
  13. package/build/accoding/api/contest-api.js.map +1 -0
  14. package/build/accoding/api/problem-api.d.ts +5 -0
  15. package/build/accoding/api/problem-api.js +29 -0
  16. package/build/accoding/api/problem-api.js.map +1 -0
  17. package/build/accoding/api/user-api.d.ts +5 -0
  18. package/build/accoding/api/user-api.js +29 -0
  19. package/build/accoding/api/user-api.js.map +1 -0
  20. package/build/common/constants.d.ts +1 -0
  21. package/build/common/constants.js +10 -0
  22. package/build/common/constants.js.map +1 -0
  23. package/build/common/registry-base.d.ts +11 -0
  24. package/build/common/registry-base.js +37 -0
  25. package/build/common/registry-base.js.map +1 -0
  26. package/build/index.d.ts +2 -0
  27. package/build/index.js +80 -0
  28. package/build/index.js.map +1 -0
  29. package/build/mcp/resources/contest-resources.d.ts +15 -0
  30. package/build/mcp/resources/contest-resources.js +21 -0
  31. package/build/mcp/resources/contest-resources.js.map +1 -0
  32. package/build/mcp/resources/problem-resources.d.ts +15 -0
  33. package/build/mcp/resources/problem-resources.js +21 -0
  34. package/build/mcp/resources/problem-resources.js.map +1 -0
  35. package/build/mcp/resources/resource-registry.d.ts +16 -0
  36. package/build/mcp/resources/resource-registry.js +21 -0
  37. package/build/mcp/resources/resource-registry.js.map +1 -0
  38. package/build/mcp/tools/contest-tools.d.ts +19 -0
  39. package/build/mcp/tools/contest-tools.js +62 -0
  40. package/build/mcp/tools/contest-tools.js.map +1 -0
  41. package/build/mcp/tools/problem-tools.d.ts +15 -0
  42. package/build/mcp/tools/problem-tools.js +21 -0
  43. package/build/mcp/tools/problem-tools.js.map +1 -0
  44. package/build/mcp/tools/submission-tools.d.ts +15 -0
  45. package/build/mcp/tools/submission-tools.js +21 -0
  46. package/build/mcp/tools/submission-tools.js.map +1 -0
  47. package/build/mcp/tools/tool-registry.d.ts +16 -0
  48. package/build/mcp/tools/tool-registry.js +21 -0
  49. package/build/mcp/tools/tool-registry.js.map +1 -0
  50. package/build/mcp/tools/user-tools.d.ts +15 -0
  51. package/build/mcp/tools/user-tools.js +21 -0
  52. package/build/mcp/tools/user-tools.js.map +1 -0
  53. package/build/utils/logger.d.ts +2 -0
  54. package/build/utils/logger.js +12 -0
  55. package/build/utils/logger.js.map +1 -0
  56. package/package.json +41 -0
package/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # Accoding MCP Server
2
+
3
+ MCP Server for Accoding API - Model Context Protocol server for Accoding platform.
4
+
5
+ ## 项目结构
6
+
7
+ ```
8
+ accoding-mcp-server/
9
+ ├── src/
10
+ │ ├── common/ # 通用基础层
11
+ │ │ ├── constants.ts # 常量定义(语言、分类、标签等)
12
+ │ │ └── registry-base.ts # 注册基类(简化版,无需区分站点)
13
+ │ ├── accoding/ # Accoding 服务层
14
+ │ │ ├── api/ # RESTful API 调用(替代 GraphQL)
15
+ │ │ │ ├── problem-api.ts # 题目相关 API
16
+ │ │ │ ├── user-api.ts # 用户相关 API
17
+ │ │ │ └── contest-api.ts # 比赛相关 API
18
+ │ │ ├── accoding-base-service.ts # 服务接口定义
19
+ │ │ ├── accoding-service-factory.ts # 工厂类
20
+ │ │ └── accoding-service-impl.ts # 服务实现
21
+ │ ├── mcp/ # MCP 工具和资源层
22
+ │ │ ├── tools/ # MCP 工具注册
23
+ │ │ │ ├── tool-registry.ts # 工具注册基类
24
+ │ │ │ ├── problem-tools.ts # 题目工具
25
+ │ │ │ ├── user-tools.ts # 用户工具
26
+ │ │ │ ├── contest-tools.ts # 比赛工具
27
+ │ │ │ └── submission-tools.ts # 提交工具
28
+ │ │ └── resources/ # MCP 资源注册
29
+ │ │ ├── resource-registry.ts # 资源注册基类
30
+ │ │ ├── problem-resources.ts # 题目资源
31
+ │ │ └── contest-resources.ts # 比赛资源
32
+ │ ├── utils/
33
+ │ │ └── logger.ts # 日志工具
34
+ │ └── index.ts # 程序入口
35
+ ├── package.json
36
+ ├── tsconfig.json
37
+ └── README.md
38
+ ```
39
+
40
+ ## 设计特点
41
+
42
+ 1. **工厂模式**:使用 `AccodingServiceFactory` 创建服务实例
43
+ 2. **注册模式**:使用 `RegistryBase` 统一管理工具和资源的注册
44
+ 3. **分层架构**:
45
+ - 入口层 (`index.ts`) - 解析参数、创建服务器、注册组件
46
+ - 服务层 (`accoding/`) - 定义接口、实现业务逻辑
47
+ - API 层 (`accoding/api/`) - RESTful API 调用封装
48
+ - 工具/资源层 (`mcp/`) - MCP 工具和资源的注册
49
+
50
+ ## 安装和运行
51
+
52
+ ```bash
53
+ # 安装依赖
54
+ npm install
55
+
56
+ # 编译
57
+ npm run build
58
+
59
+ # 运行
60
+ node build/index.js
61
+
62
+ # 使用认证运行
63
+ node build/index.js --token <your-token>
64
+ ```
65
+
66
+ ## 环境变量
67
+
68
+ - `ACCODING_SESSION_TOKEN`: Accoding 会话令牌(用于认证请求)
69
+ - `ACCODING_API_BASE_URL`: Accoding API 基础 URL(默认为 `https://api.accoding.com`)
70
+
71
+ ## 待实现功能
72
+
73
+ 当前框架已搭建完成,但 API 调用部分标记为 `TODO`,需要根据实际的 Accoding API 文档实现:
74
+
75
+ - [ ] `problem-api.ts` - 实现题目相关的 RESTful API 调用
76
+ - [ ] `user-api.ts` - 实现用户相关的 RESTful API 调用
77
+ - [ ] `contest-api.ts` - 实现比赛相关的 RESTful API 调用
78
+ - [ ] `submission-tools.ts` - 实现提交统计功能
79
+
80
+ ## 与 LeetCode MCP Server 的主要区别
81
+
82
+ 1. **无站点区分**:不需要区分 Global/CN,只有一个实现
83
+ 2. **RESTful API**:使用 RESTful API 替代 GraphQL
84
+ 3. **简化注册**:`RegistryBase` 只区分认证/非认证,不需要区分站点
85
+ 4. **API 目录**:使用 `api/` 目录替代 `graphql/` 目录
86
+
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Accoding服务接口 - 基于实际需求
3
+ */
4
+ export interface AccodingBaseService {
5
+ /**
6
+ * 根据比赛ID获取比赛题目详情
7
+ */
8
+ getContestProblems(contestId: string): Promise<any>;
9
+ /**
10
+ * 检查当前服务是否有有效的认证凭证
11
+ */
12
+ isAuthenticated(): boolean;
13
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=accoding-base-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accoding-base-service.js","sourceRoot":"","sources":["../../src/accoding/accoding-base-service.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ import { AccodingBaseService } from "./accoding-base-service.js";
2
+ /**
3
+ * Accoding服务工厂类
4
+ * 负责创建Accoding服务实例并管理认证凭证
5
+ */
6
+ export declare class AccodingServiceFactory {
7
+ /**
8
+ * 创建并配置Accoding服务实例
9
+ */
10
+ static createService(session?: string): AccodingBaseService;
11
+ }
@@ -0,0 +1,14 @@
1
+ import { AccodingServiceImpl } from "./accoding-service-impl.js";
2
+ /**
3
+ * Accoding服务工厂类
4
+ * 负责创建Accoding服务实例并管理认证凭证
5
+ */
6
+ export class AccodingServiceFactory {
7
+ /**
8
+ * 创建并配置Accoding服务实例
9
+ */
10
+ static createService(session) {
11
+ return new AccodingServiceImpl(session);
12
+ }
13
+ }
14
+ //# sourceMappingURL=accoding-service-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accoding-service-factory.js","sourceRoot":"","sources":["../../src/accoding/accoding-service-factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE;;;GAGG;AACH,MAAM,OAAO,sBAAsB;IAC/B;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,OAAgB;QACjC,OAAO,IAAI,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;CACJ"}
@@ -0,0 +1,10 @@
1
+ import { AccodingBaseService } from "./accoding-base-service.js";
2
+ /**
3
+ * Accoding服务实现
4
+ */
5
+ export declare class AccodingServiceImpl implements AccodingBaseService {
6
+ private session?;
7
+ constructor(session?: string);
8
+ getContestProblems(contestId: string): Promise<any>;
9
+ isAuthenticated(): boolean;
10
+ }
@@ -0,0 +1,18 @@
1
+ import * as contestApi from "./api/contest-api.js";
2
+ /**
3
+ * Accoding服务实现
4
+ */
5
+ export class AccodingServiceImpl {
6
+ session;
7
+ constructor(session) {
8
+ this.session = session;
9
+ }
10
+ async getContestProblems(contestId) {
11
+ // 调用真实的contestApi获取比赛题目
12
+ return await contestApi.getContestProblems(contestId, this.session);
13
+ }
14
+ isAuthenticated() {
15
+ return !!this.session;
16
+ }
17
+ }
18
+ //# sourceMappingURL=accoding-service-impl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accoding-service-impl.js","sourceRoot":"","sources":["../../src/accoding/accoding-service-impl.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,UAAU,MAAM,sBAAsB,CAAC;AAGnD;;GAEG;AACH,MAAM,OAAO,mBAAmB;IACpB,OAAO,CAAU;IAEzB,YAAY,OAAgB;QACxB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,SAAiB;QACtC,wBAAwB;QACxB,OAAO,MAAM,UAAU,CAAC,kBAAkB,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACxE,CAAC;IAGD,eAAe;QACX,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;IAC1B,CAAC;CACJ"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Accoding平台比赛相关API调用
3
+ */
4
+ /**
5
+ * 根据比赛ID获取比赛题目详情
6
+ */
7
+ export declare function getContestProblems(contestId: string, session?: string): Promise<any>;
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Accoding平台比赛相关API调用
3
+ */
4
+ const API_BASE_URL = "https://accoding.buaa.edu.cn";
5
+ /**
6
+ * 向Accoding API发起HTTP请求
7
+ */
8
+ async function apiRequest(endpoint, options = {}, session) {
9
+ const url = `${API_BASE_URL}${endpoint}`;
10
+ const headers = {
11
+ "Content-Type": "application/json",
12
+ ...options.headers
13
+ };
14
+ if (session) {
15
+ headers["Cookie"] = session;
16
+ }
17
+ const response = await fetch(url, {
18
+ ...options,
19
+ headers
20
+ });
21
+ if (!response.ok) {
22
+ const errorText = await response.text().catch(() => response.statusText);
23
+ throw new Error(`API request failed: ${response.status} ${errorText}`);
24
+ }
25
+ const contentType = response.headers.get("content-type");
26
+ if (contentType && contentType.includes("application/json")) {
27
+ return await response.json();
28
+ }
29
+ else {
30
+ const text = await response.text();
31
+ throw new Error(`API returned non-JSON content: ${contentType}`);
32
+ }
33
+ }
34
+ /**
35
+ * 根据比赛ID获取比赛题目详情
36
+ */
37
+ export async function getContestProblems(contestId, session) {
38
+ const contestData = await apiRequest(`/api/contests/${contestId}`, { method: "GET" }, session);
39
+ // 检查是否有题目数据
40
+ if (!contestData.problems || !Array.isArray(contestData.problems)) {
41
+ return [];
42
+ }
43
+ // 提取并格式化题目信息
44
+ return contestData.problems.map((problem) => {
45
+ let supportedLanguages = [];
46
+ try {
47
+ if (problem.test_setting) {
48
+ const testSetting = typeof problem.test_setting === 'string'
49
+ ? JSON.parse(problem.test_setting)
50
+ : problem.test_setting;
51
+ supportedLanguages = testSetting.supported_languages || [];
52
+ }
53
+ }
54
+ catch (e) {
55
+ // 如果解析失败,使用空数组
56
+ supportedLanguages = [];
57
+ }
58
+ return {
59
+ id: problem.id,
60
+ title: problem.title,
61
+ description: problem.description,
62
+ difficulty: problem.difficulty,
63
+ score: problem.contest_problem_list?.score || 100,
64
+ order: problem.contest_problem_list?.order || 0,
65
+ supportedLanguages: supportedLanguages
66
+ };
67
+ });
68
+ }
69
+ //# sourceMappingURL=contest-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contest-api.js","sourceRoot":"","sources":["../../../src/accoding/api/contest-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,YAAY,GAAG,8BAA8B,CAAC;AAEpD;;GAEG;AACH,KAAK,UAAU,UAAU,CACrB,QAAgB,EAChB,UAAuB,EAAE,EACzB,OAAgB;IAEhB,MAAM,GAAG,GAAG,GAAG,YAAY,GAAG,QAAQ,EAAE,CAAC;IACzC,MAAM,OAAO,GAA2B;QACpC,cAAc,EAAE,kBAAkB;QAClC,GAAI,OAAO,CAAC,OAAkC;KACjD,CAAC;IAEF,IAAI,OAAO,EAAE,CAAC;QACV,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC;IAChC,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC9B,GAAG,OAAO;QACV,OAAO;KACV,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACzE,MAAM,IAAI,KAAK,CAAC,uBAAuB,QAAQ,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACzD,IAAI,WAAW,IAAI,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC1D,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACjC,CAAC;SAAM,CAAC;QACJ,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,kCAAkC,WAAW,EAAE,CAAC,CAAC;IACrE,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,SAAiB,EAAE,OAAgB;IACxE,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,iBAAiB,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;IAE/F,YAAY;IACZ,IAAI,CAAC,WAAW,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChE,OAAO,EAAE,CAAC;IACd,CAAC;IAED,aAAa;IACb,OAAO,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAY,EAAE,EAAE;QAC7C,IAAI,kBAAkB,GAAa,EAAE,CAAC;QACtC,IAAI,CAAC;YACD,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACvB,MAAM,WAAW,GAAG,OAAO,OAAO,CAAC,YAAY,KAAK,QAAQ;oBACxD,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC;oBAClC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC;gBAC3B,kBAAkB,GAAG,WAAW,CAAC,mBAAmB,IAAI,EAAE,CAAC;YAC/D,CAAC;QACL,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,eAAe;YACf,kBAAkB,GAAG,EAAE,CAAC;QAC5B,CAAC;QAED,OAAO;YACH,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,KAAK,EAAE,OAAO,CAAC,oBAAoB,EAAE,KAAK,IAAI,GAAG;YACjD,KAAK,EAAE,OAAO,CAAC,oBAAoB,EAAE,KAAK,IAAI,CAAC;YAC/C,kBAAkB,EAAE,kBAAkB;SACzC,CAAC;IACN,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Accoding平台题目相关API调用
3
+ * 预留文件,当前无需实现具体功能
4
+ */
5
+ export {};
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Accoding平台题目相关API调用
3
+ * 预留文件,当前无需实现具体功能
4
+ */
5
+ const API_BASE_URL = "https://accoding.buaa.edu.cn";
6
+ /**
7
+ * 向Accoding API发起HTTP请求
8
+ */
9
+ async function apiRequest(endpoint, options = {}, session) {
10
+ const url = `${API_BASE_URL}${endpoint}`;
11
+ const headers = {
12
+ "Content-Type": "application/json",
13
+ ...options.headers
14
+ };
15
+ if (session) {
16
+ headers["Cookie"] = session;
17
+ }
18
+ const response = await fetch(url, {
19
+ ...options,
20
+ headers
21
+ });
22
+ if (!response.ok) {
23
+ throw new Error(`API请求失败: ${response.status} ${response.statusText}`);
24
+ }
25
+ return await response.json();
26
+ }
27
+ export {};
28
+ // 此文件暂时没有导出的API函数,后续需要题目相关功能时再实现
29
+ //# sourceMappingURL=problem-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"problem-api.js","sourceRoot":"","sources":["../../../src/accoding/api/problem-api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,YAAY,GAAG,8BAA8B,CAAC;AAEpD;;GAEG;AACH,KAAK,UAAU,UAAU,CACrB,QAAgB,EAChB,UAAuB,EAAE,EACzB,OAAgB;IAEhB,MAAM,GAAG,GAAG,GAAG,YAAY,GAAG,QAAQ,EAAE,CAAC;IACzC,MAAM,OAAO,GAA2B;QACpC,cAAc,EAAE,kBAAkB;QAClC,GAAI,OAAO,CAAC,OAAkC;KACjD,CAAC;IAEF,IAAI,OAAO,EAAE,CAAC;QACV,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC;IAChC,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC9B,GAAG,OAAO;QACV,OAAO;KACV,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,YAAY,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;AACjC,CAAC;;AAED,iCAAiC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Accoding平台用户相关API调用
3
+ * 预留文件,当前无需实现具体功能
4
+ */
5
+ export {};
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Accoding平台用户相关API调用
3
+ * 预留文件,当前无需实现具体功能
4
+ */
5
+ const API_BASE_URL = "https://accoding.buaa.edu.cn";
6
+ /**
7
+ * 向Accoding API发起HTTP请求
8
+ */
9
+ async function apiRequest(endpoint, options = {}, session) {
10
+ const url = `${API_BASE_URL}${endpoint}`;
11
+ const headers = {
12
+ "Content-Type": "application/json",
13
+ ...options.headers
14
+ };
15
+ if (session) {
16
+ headers["Cookie"] = session;
17
+ }
18
+ const response = await fetch(url, {
19
+ ...options,
20
+ headers
21
+ });
22
+ if (!response.ok) {
23
+ throw new Error(`API请求失败: ${response.status} ${response.statusText}`);
24
+ }
25
+ return await response.json();
26
+ }
27
+ export {};
28
+ // 此文件暂时没有导出的API函数,后续需要用户相关功能时再实现
29
+ //# sourceMappingURL=user-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-api.js","sourceRoot":"","sources":["../../../src/accoding/api/user-api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,YAAY,GAAG,8BAA8B,CAAC;AAEpD;;GAEG;AACH,KAAK,UAAU,UAAU,CACrB,QAAgB,EAChB,UAAuB,EAAE,EACzB,OAAgB;IAEhB,MAAM,GAAG,GAAG,GAAG,YAAY,GAAG,QAAQ,EAAE,CAAC;IACzC,MAAM,OAAO,GAA2B;QACpC,cAAc,EAAE,kBAAkB;QAClC,GAAI,OAAO,CAAC,OAAkC;KACjD,CAAC;IAEF,IAAI,OAAO,EAAE,CAAC;QACV,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC;IAChC,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC9B,GAAG,OAAO;QACV,OAAO;KACV,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,YAAY,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;AACjC,CAAC;;AAED,iCAAiC"}
@@ -0,0 +1 @@
1
+ export declare const PROGRAMMING_LANGS: string[];
@@ -0,0 +1,10 @@
1
+ //编程语言
2
+ export const PROGRAMMING_LANGS = [
3
+ "cpp",
4
+ "java",
5
+ "python",
6
+ "c",
7
+ "javascript",
8
+ "typescript"
9
+ ];
10
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/common/constants.ts"],"names":[],"mappings":"AAAA,MAAM;AACN,MAAM,CAAC,MAAM,iBAAiB,GAAa;IACvC,KAAK;IACL,MAAM;IACN,QAAQ;IACR,GAAG;IACH,YAAY;IACZ,YAAY;CACf,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { AccodingBaseService } from "../accoding/accoding-base-service.js";
3
+ export declare abstract class RegistryBase {
4
+ protected server: McpServer;
5
+ protected accodingService: AccodingBaseService;
6
+ constructor(server: McpServer, accodingService: AccodingBaseService);
7
+ protected isAuthenticated(): boolean;
8
+ register(): void;
9
+ protected registerCommon(): void;
10
+ protected registerAuthenticated(): void;
11
+ }
@@ -0,0 +1,37 @@
1
+ /*
2
+ * 注册器基类,根据认证状态动态注册组件
3
+ * 子类实现注册通用组件和需要认证的组件
4
+ */
5
+ export class RegistryBase {
6
+ server;
7
+ accodingService;
8
+ constructor(server, accodingService) {
9
+ this.server = server;
10
+ this.accodingService = accodingService;
11
+ }
12
+ /*
13
+ * 检查当前服务是否已认证
14
+ */
15
+ isAuthenticated() {
16
+ return this.accodingService.isAuthenticated();
17
+ }
18
+ /*
19
+ * 注册所有适用的组件
20
+ * 先注册通用组件,如果已认证再注册需要登录的组件
21
+ */
22
+ register() {
23
+ this.registerCommon();
24
+ if (this.isAuthenticated()) {
25
+ this.registerAuthenticated();
26
+ }
27
+ }
28
+ /*
29
+ * 注册不需要认证的通用组件
30
+ */
31
+ registerCommon() { }
32
+ /*
33
+ * 注册需要认证的组件
34
+ */
35
+ registerAuthenticated() { }
36
+ }
37
+ //# sourceMappingURL=registry-base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-base.js","sourceRoot":"","sources":["../../src/common/registry-base.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,OAAgB,YAAY;IAEhB;IACA;IAFd,YACc,MAAiB,EACjB,eAAoC;QADpC,WAAM,GAAN,MAAM,CAAW;QACjB,oBAAe,GAAf,eAAe,CAAqB;IAC/C,CAAC;IAEJ;;OAEG;IACO,eAAe;QACrB,OAAO,IAAI,CAAC,eAAe,CAAC,eAAe,EAAE,CAAC;IAClD,CAAC;IAED;;;OAGG;IACI,QAAQ;QACX,IAAI,CAAC,cAAc,EAAE,CAAC;QAEtB,IAAI,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YACzB,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACjC,CAAC;IACL,CAAC;IAED;;OAEG;IACO,cAAc,KAAU,CAAC;IAEnC;;OAEG;IACO,qBAAqB,KAAU,CAAC;CAC7C"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/build/index.js ADDED
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import minimist from "minimist";
5
+ import { readFileSync } from "node:fs";
6
+ import { dirname, join } from "node:path";
7
+ import { fileURLToPath } from "node:url";
8
+ import { AccodingServiceFactory } from "./accoding/accoding-service-factory.js";
9
+ import { registerProblemResources } from "./mcp/resources/problem-resources.js";
10
+ import { registerContestResources } from "./mcp/resources/contest-resources.js";
11
+ import { registerContestTools } from "./mcp/tools/contest-tools.js";
12
+ import { registerProblemTools } from "./mcp/tools/problem-tools.js";
13
+ import { registerSubmissionTools } from "./mcp/tools/submission-tools.js";
14
+ import { registerUserTools } from "./mcp/tools/user-tools.js";
15
+ import logger from "./utils/logger.js";
16
+ /**
17
+ * 解析并验证命令行参数
18
+ */
19
+ function parseArgs() {
20
+ const args = minimist(process.argv.slice(2), {
21
+ string: ["session"],
22
+ boolean: ["help"],
23
+ alias: {
24
+ s: "session",
25
+ h: "help"
26
+ }
27
+ });
28
+ if (args.help) {
29
+ console.log(`
30
+ Accoding MCP Server - 北航Accoding平台MCP服务
31
+
32
+ 用法: accoding-mcp-server [选项]
33
+
34
+ 选项:
35
+ --session, -s <cookie> Accoding平台会话Cookie
36
+ --help, -h 显示帮助信息
37
+ `);
38
+ process.exit(0);
39
+ }
40
+ return {
41
+ session: args.session || process.env.ACCODING_SESSION
42
+ };
43
+ }
44
+ /**
45
+ * 获取package.json中的项目元数据
46
+ */
47
+ function getPackageJson() {
48
+ const __filename = fileURLToPath(import.meta.url);
49
+ const __dirname = dirname(__filename);
50
+ const packageJSONPath = join(__dirname, "..", "package.json");
51
+ const packageJSON = JSON.parse(readFileSync(packageJSONPath, "utf-8"));
52
+ return packageJSON;
53
+ }
54
+ /**
55
+ * 主函数:初始化并启动Accoding MCP服务器
56
+ */
57
+ async function main() {
58
+ const options = parseArgs();
59
+ const packageJSON = getPackageJson();
60
+ const server = new McpServer({
61
+ name: "Accoding MCP Server",
62
+ version: packageJSON.version
63
+ });
64
+ const accodingService = AccodingServiceFactory.createService(options.session);
65
+ // 注册所有工具和资源(为后续扩展预留)
66
+ registerProblemTools(server, accodingService);
67
+ registerUserTools(server, accodingService);
68
+ registerContestTools(server, accodingService);
69
+ registerSubmissionTools(server, accodingService);
70
+ registerProblemResources(server, accodingService);
71
+ registerContestResources(server, accodingService);
72
+ const transport = new StdioServerTransport();
73
+ await server.connect(transport);
74
+ logger.info("Accoding MCP Server 已启动");
75
+ }
76
+ main().catch((error) => {
77
+ logger.error("启动Accoding MCP Server失败: %s", error);
78
+ process.exit(1);
79
+ });
80
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { AccodingBaseService } from "../../accoding/accoding-base-service.js";
3
+ import { ResourceRegistry } from "./resource-registry.js";
4
+ /**
5
+ * 比赛资源注册器
6
+ * 处理Accoding平台比赛相关资源的注册
7
+ */
8
+ export declare class ContestResourceRegistry extends ResourceRegistry {
9
+ protected registerCommon(): void;
10
+ protected registerAuthenticated(): void;
11
+ }
12
+ /**
13
+ * 注册所有比赛相关资源
14
+ */
15
+ export declare function registerContestResources(server: McpServer, accodingService: AccodingBaseService): void;
@@ -0,0 +1,21 @@
1
+ import { ResourceRegistry } from "./resource-registry.js";
2
+ /**
3
+ * 比赛资源注册器
4
+ * 处理Accoding平台比赛相关资源的注册
5
+ */
6
+ export class ContestResourceRegistry extends ResourceRegistry {
7
+ registerCommon() {
8
+ // 当前没有需要实现的比赛资源
9
+ }
10
+ registerAuthenticated() {
11
+ // 需要认证的比赛资源可以在这里注册
12
+ }
13
+ }
14
+ /**
15
+ * 注册所有比赛相关资源
16
+ */
17
+ export function registerContestResources(server, accodingService) {
18
+ const registry = new ContestResourceRegistry(server, accodingService);
19
+ registry.registerResources();
20
+ }
21
+ //# sourceMappingURL=contest-resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contest-resources.js","sourceRoot":"","sources":["../../../src/mcp/resources/contest-resources.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D;;;GAGG;AACH,MAAM,OAAO,uBAAwB,SAAQ,gBAAgB;IAC/C,cAAc;QACpB,gBAAgB;IACpB,CAAC;IAES,qBAAqB;QAC3B,mBAAmB;IACvB,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CACpC,MAAiB,EACjB,eAAoC;IAEpC,MAAM,QAAQ,GAAG,IAAI,uBAAuB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACtE,QAAQ,CAAC,iBAAiB,EAAE,CAAC;AACjC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { AccodingBaseService } from "../../accoding/accoding-base-service.js";
3
+ import { ResourceRegistry } from "./resource-registry.js";
4
+ /**
5
+ * 题目资源注册器
6
+ * 处理Accoding平台题目相关资源的注册
7
+ */
8
+ export declare class ProblemResourceRegistry extends ResourceRegistry {
9
+ protected registerCommon(): void;
10
+ protected registerAuthenticated(): void;
11
+ }
12
+ /**
13
+ * 注册所有题目相关资源
14
+ */
15
+ export declare function registerProblemResources(server: McpServer, accodingService: AccodingBaseService): void;
@@ -0,0 +1,21 @@
1
+ import { ResourceRegistry } from "./resource-registry.js";
2
+ /**
3
+ * 题目资源注册器
4
+ * 处理Accoding平台题目相关资源的注册
5
+ */
6
+ export class ProblemResourceRegistry extends ResourceRegistry {
7
+ registerCommon() {
8
+ // 当前没有需要实现的题目资源
9
+ }
10
+ registerAuthenticated() {
11
+ // 需要认证的题目资源可以在这里注册
12
+ }
13
+ }
14
+ /**
15
+ * 注册所有题目相关资源
16
+ */
17
+ export function registerProblemResources(server, accodingService) {
18
+ const registry = new ProblemResourceRegistry(server, accodingService);
19
+ registry.registerResources();
20
+ }
21
+ //# sourceMappingURL=problem-resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"problem-resources.js","sourceRoot":"","sources":["../../../src/mcp/resources/problem-resources.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D;;;GAGG;AACH,MAAM,OAAO,uBAAwB,SAAQ,gBAAgB;IAC/C,cAAc;QACpB,gBAAgB;IACpB,CAAC;IAES,qBAAqB;QAC3B,mBAAmB;IACvB,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CACpC,MAAiB,EACjB,eAAoC;IAEpC,MAAM,QAAQ,GAAG,IAAI,uBAAuB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACtE,QAAQ,CAAC,iBAAiB,EAAE,CAAC;AACjC,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { RegistryBase } from "../../common/registry-base.js";
3
+ import { AccodingBaseService } from "../../accoding/accoding-base-service.js";
4
+ /**
5
+ * 资源注册器基类
6
+ * 为不同类型的资源提供统一的注册框架
7
+ */
8
+ export declare abstract class ResourceRegistry extends RegistryBase {
9
+ protected server: McpServer;
10
+ protected accodingService: AccodingBaseService;
11
+ constructor(server: McpServer, accodingService: AccodingBaseService);
12
+ /**
13
+ * 注册所有适用的资源
14
+ */
15
+ registerResources(): void;
16
+ }
@@ -0,0 +1,21 @@
1
+ import { RegistryBase } from "../../common/registry-base.js";
2
+ /**
3
+ * 资源注册器基类
4
+ * 为不同类型的资源提供统一的注册框架
5
+ */
6
+ export class ResourceRegistry extends RegistryBase {
7
+ server;
8
+ accodingService;
9
+ constructor(server, accodingService) {
10
+ super(server, accodingService);
11
+ this.server = server;
12
+ this.accodingService = accodingService;
13
+ }
14
+ /**
15
+ * 注册所有适用的资源
16
+ */
17
+ registerResources() {
18
+ this.register();
19
+ }
20
+ }
21
+ //# sourceMappingURL=resource-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-registry.js","sourceRoot":"","sources":["../../../src/mcp/resources/resource-registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAG7D;;;GAGG;AACH,MAAM,OAAgB,gBAAiB,SAAQ,YAAY;IAEzC;IACA;IAFd,YACc,MAAiB,EACjB,eAAoC;QAE9C,KAAK,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;QAHrB,WAAM,GAAN,MAAM,CAAW;QACjB,oBAAe,GAAf,eAAe,CAAqB;IAGlD,CAAC;IAED;;OAEG;IACI,iBAAiB;QACpB,IAAI,CAAC,QAAQ,EAAE,CAAC;IACpB,CAAC;CACJ"}
@@ -0,0 +1,19 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { AccodingBaseService } from "../../accoding/accoding-base-service.js";
3
+ import { ToolRegistry } from "./tool-registry.js";
4
+ /**
5
+ * 比赛工具注册器
6
+ * 处理Accoding平台比赛相关工具的注册
7
+ */
8
+ export declare class ContestToolRegistry extends ToolRegistry {
9
+ protected registerCommon(): void;
10
+ protected registerAuthenticated(): void;
11
+ /**
12
+ * 注册获取比赛题目的工具
13
+ */
14
+ private registerGetContestProblems;
15
+ }
16
+ /**
17
+ * 注册所有比赛相关工具
18
+ */
19
+ export declare function registerContestTools(server: McpServer, accodingService: AccodingBaseService): void;
@@ -0,0 +1,62 @@
1
+ import { z } from "zod";
2
+ import { ToolRegistry } from "./tool-registry.js";
3
+ /**
4
+ * 比赛工具注册器
5
+ * 处理Accoding平台比赛相关工具的注册
6
+ */
7
+ export class ContestToolRegistry extends ToolRegistry {
8
+ registerCommon() {
9
+ this.registerGetContestProblems();
10
+ }
11
+ registerAuthenticated() {
12
+ // 需要认证的比赛工具可以在这里注册
13
+ }
14
+ /**
15
+ * 注册获取比赛题目的工具
16
+ */
17
+ registerGetContestProblems() {
18
+ this.server.tool("get_contest_problems", "根据比赛ID获取比赛中的所有题目详情", {
19
+ contestId: z.string().describe("比赛的唯一标识ID")
20
+ }, async ({ contestId }) => {
21
+ try {
22
+ const problems = await this.accodingService.getContestProblems(contestId);
23
+ return {
24
+ content: [
25
+ {
26
+ type: "text",
27
+ text: JSON.stringify({
28
+ contestId: contestId,
29
+ problems: problems,
30
+ count: problems.length
31
+ }, null, 2)
32
+ }
33
+ ]
34
+ };
35
+ }
36
+ catch (error) {
37
+ const errorMessage = error.message || String(error);
38
+ return {
39
+ content: [
40
+ {
41
+ type: "text",
42
+ text: JSON.stringify({
43
+ error: "Failed to get contest problems",
44
+ message: errorMessage,
45
+ contestId: contestId
46
+ })
47
+ }
48
+ ],
49
+ isError: true
50
+ };
51
+ }
52
+ });
53
+ }
54
+ }
55
+ /**
56
+ * 注册所有比赛相关工具
57
+ */
58
+ export function registerContestTools(server, accodingService) {
59
+ const registry = new ContestToolRegistry(server, accodingService);
60
+ registry.registerTools();
61
+ }
62
+ //# sourceMappingURL=contest-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contest-tools.js","sourceRoot":"","sources":["../../../src/mcp/tools/contest-tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD;;;GAGG;AACH,MAAM,OAAO,mBAAoB,SAAQ,YAAY;IACvC,cAAc;QACpB,IAAI,CAAC,0BAA0B,EAAE,CAAC;IACtC,CAAC;IAES,qBAAqB;QAC3B,mBAAmB;IACvB,CAAC;IAED;;OAEG;IACK,0BAA0B;QAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,CACZ,sBAAsB,EACtB,oBAAoB,EACpB;YACI,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;SAC9C,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;YACpB,IAAI,CAAC;gBACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;gBAE1E,OAAO;oBACH,OAAO,EAAE;wBACL;4BACI,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACjB,SAAS,EAAE,SAAS;gCACpB,QAAQ,EAAE,QAAQ;gCAClB,KAAK,EAAE,QAAQ,CAAC,MAAM;6BACzB,EAAE,IAAI,EAAE,CAAC,CAAC;yBACd;qBACJ;iBACJ,CAAC;YACN,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBAClB,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;gBACpD,OAAO;oBACH,OAAO,EAAE;wBACL;4BACI,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACjB,KAAK,EAAE,gCAAgC;gCACvC,OAAO,EAAE,YAAY;gCACrB,SAAS,EAAE,SAAS;6BACvB,CAAC;yBACL;qBACJ;oBACD,OAAO,EAAE,IAAI;iBAChB,CAAC;YACN,CAAC;QACL,CAAC,CACJ,CAAC;IACN,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAChC,MAAiB,EACjB,eAAoC;IAEpC,MAAM,QAAQ,GAAG,IAAI,mBAAmB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAClE,QAAQ,CAAC,aAAa,EAAE,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { AccodingBaseService } from "../../accoding/accoding-base-service.js";
3
+ import { ToolRegistry } from "./tool-registry.js";
4
+ /**
5
+ * 题目工具注册器
6
+ * 处理Accoding平台题目相关工具的注册
7
+ */
8
+ export declare class ProblemToolRegistry extends ToolRegistry {
9
+ protected registerCommon(): void;
10
+ protected registerAuthenticated(): void;
11
+ }
12
+ /**
13
+ * 注册所有题目相关工具
14
+ */
15
+ export declare function registerProblemTools(server: McpServer, accodingService: AccodingBaseService): void;
@@ -0,0 +1,21 @@
1
+ import { ToolRegistry } from "./tool-registry.js";
2
+ /**
3
+ * 题目工具注册器
4
+ * 处理Accoding平台题目相关工具的注册
5
+ */
6
+ export class ProblemToolRegistry extends ToolRegistry {
7
+ registerCommon() {
8
+ // 当前没有需要实现的题目工具
9
+ }
10
+ registerAuthenticated() {
11
+ // 需要认证的题目工具可以在这里注册
12
+ }
13
+ }
14
+ /**
15
+ * 注册所有题目相关工具
16
+ */
17
+ export function registerProblemTools(server, accodingService) {
18
+ const registry = new ProblemToolRegistry(server, accodingService);
19
+ registry.registerTools();
20
+ }
21
+ //# sourceMappingURL=problem-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"problem-tools.js","sourceRoot":"","sources":["../../../src/mcp/tools/problem-tools.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD;;;GAGG;AACH,MAAM,OAAO,mBAAoB,SAAQ,YAAY;IACvC,cAAc;QACpB,gBAAgB;IACpB,CAAC;IAES,qBAAqB;QAC3B,mBAAmB;IACvB,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAChC,MAAiB,EACjB,eAAoC;IAEpC,MAAM,QAAQ,GAAG,IAAI,mBAAmB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAClE,QAAQ,CAAC,aAAa,EAAE,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { AccodingBaseService } from "../../accoding/accoding-base-service.js";
3
+ import { ToolRegistry } from "./tool-registry.js";
4
+ /**
5
+ * 提交工具注册器
6
+ * 处理Accoding平台提交相关工具的注册
7
+ */
8
+ export declare class SubmissionToolRegistry extends ToolRegistry {
9
+ protected registerCommon(): void;
10
+ protected registerAuthenticated(): void;
11
+ }
12
+ /**
13
+ * 注册所有提交相关工具
14
+ */
15
+ export declare function registerSubmissionTools(server: McpServer, accodingService: AccodingBaseService): void;
@@ -0,0 +1,21 @@
1
+ import { ToolRegistry } from "./tool-registry.js";
2
+ /**
3
+ * 提交工具注册器
4
+ * 处理Accoding平台提交相关工具的注册
5
+ */
6
+ export class SubmissionToolRegistry extends ToolRegistry {
7
+ registerCommon() {
8
+ // 不需要认证的提交工具可以在这里注册
9
+ }
10
+ registerAuthenticated() {
11
+ // 需要认证的提交工具可以在这里注册
12
+ }
13
+ }
14
+ /**
15
+ * 注册所有提交相关工具
16
+ */
17
+ export function registerSubmissionTools(server, accodingService) {
18
+ const registry = new SubmissionToolRegistry(server, accodingService);
19
+ registry.registerTools();
20
+ }
21
+ //# sourceMappingURL=submission-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submission-tools.js","sourceRoot":"","sources":["../../../src/mcp/tools/submission-tools.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD;;;GAGG;AACH,MAAM,OAAO,sBAAuB,SAAQ,YAAY;IAC1C,cAAc;QACpB,oBAAoB;IACxB,CAAC;IAES,qBAAqB;QAC3B,mBAAmB;IACvB,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CACnC,MAAiB,EACjB,eAAoC;IAEpC,MAAM,QAAQ,GAAG,IAAI,sBAAsB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACrE,QAAQ,CAAC,aAAa,EAAE,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { RegistryBase } from "../../common/registry-base.js";
3
+ import { AccodingBaseService } from "../../accoding/accoding-base-service.js";
4
+ /**
5
+ * 工具注册器基类
6
+ * 为不同类型的工具提供统一的注册框架
7
+ */
8
+ export declare abstract class ToolRegistry extends RegistryBase {
9
+ protected server: McpServer;
10
+ protected accodingService: AccodingBaseService;
11
+ constructor(server: McpServer, accodingService: AccodingBaseService);
12
+ /**
13
+ * 注册所有适用的工具
14
+ */
15
+ registerTools(): void;
16
+ }
@@ -0,0 +1,21 @@
1
+ import { RegistryBase } from "../../common/registry-base.js";
2
+ /**
3
+ * 工具注册器基类
4
+ * 为不同类型的工具提供统一的注册框架
5
+ */
6
+ export class ToolRegistry extends RegistryBase {
7
+ server;
8
+ accodingService;
9
+ constructor(server, accodingService) {
10
+ super(server, accodingService);
11
+ this.server = server;
12
+ this.accodingService = accodingService;
13
+ }
14
+ /**
15
+ * 注册所有适用的工具
16
+ */
17
+ registerTools() {
18
+ this.register();
19
+ }
20
+ }
21
+ //# sourceMappingURL=tool-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-registry.js","sourceRoot":"","sources":["../../../src/mcp/tools/tool-registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAG7D;;;GAGG;AACH,MAAM,OAAgB,YAAa,SAAQ,YAAY;IAErC;IACA;IAFd,YACc,MAAiB,EACjB,eAAoC;QAE9C,KAAK,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;QAHrB,WAAM,GAAN,MAAM,CAAW;QACjB,oBAAe,GAAf,eAAe,CAAqB;IAGlD,CAAC;IAED;;OAEG;IACI,aAAa;QAChB,IAAI,CAAC,QAAQ,EAAE,CAAC;IACpB,CAAC;CACJ"}
@@ -0,0 +1,15 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { AccodingBaseService } from "../../accoding/accoding-base-service.js";
3
+ import { ToolRegistry } from "./tool-registry.js";
4
+ /**
5
+ * 用户工具注册器
6
+ * 处理Accoding平台用户相关工具的注册
7
+ */
8
+ export declare class UserToolRegistry extends ToolRegistry {
9
+ protected registerCommon(): void;
10
+ protected registerAuthenticated(): void;
11
+ }
12
+ /**
13
+ * 注册所有用户相关工具
14
+ */
15
+ export declare function registerUserTools(server: McpServer, accodingService: AccodingBaseService): void;
@@ -0,0 +1,21 @@
1
+ import { ToolRegistry } from "./tool-registry.js";
2
+ /**
3
+ * 用户工具注册器
4
+ * 处理Accoding平台用户相关工具的注册
5
+ */
6
+ export class UserToolRegistry extends ToolRegistry {
7
+ registerCommon() {
8
+ // 不需要认证的用户工具可以在这里注册
9
+ }
10
+ registerAuthenticated() {
11
+ // 需要认证的用户工具可以在这里注册
12
+ }
13
+ }
14
+ /**
15
+ * 注册所有用户相关工具
16
+ */
17
+ export function registerUserTools(server, accodingService) {
18
+ const registry = new UserToolRegistry(server, accodingService);
19
+ registry.registerTools();
20
+ }
21
+ //# sourceMappingURL=user-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-tools.js","sourceRoot":"","sources":["../../../src/mcp/tools/user-tools.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD;;;GAGG;AACH,MAAM,OAAO,gBAAiB,SAAQ,YAAY;IACpC,cAAc;QACpB,oBAAoB;IACxB,CAAC;IAES,qBAAqB;QAC3B,mBAAmB;IACvB,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC7B,MAAiB,EACjB,eAAoC;IAEpC,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC/D,QAAQ,CAAC,aAAa,EAAE,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,2 @@
1
+ declare const logger: import("pino").Logger<never, boolean>;
2
+ export default logger;
@@ -0,0 +1,12 @@
1
+ import { pino } from "pino";
2
+ const logger = pino({
3
+ level: "info",
4
+ formatters: {
5
+ level: (label) => ({ level: label.toUpperCase() })
6
+ },
7
+ timestamp: () => `,"timestamp":"${new Date().toISOString()}"`,
8
+ messageKey: "message",
9
+ nestedKey: "payload"
10
+ });
11
+ export default logger;
12
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,MAAM,MAAM,GAAG,IAAI,CAAC;IAChB,KAAK,EAAE,MAAM;IACb,UAAU,EAAE;QACR,KAAK,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;KAC7D;IACD,SAAS,EAAE,GAAG,EAAE,CAAC,iBAAiB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,GAAG;IAC7D,UAAU,EAAE,SAAS;IACrB,SAAS,EAAE,SAAS;CACvB,CAAC,CAAC;AAEH,eAAe,MAAM,CAAC"}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "accoding-mcp-server-test-new",
3
+ "description": "MCP Server for Accoding API-test",
4
+ "version": "0.1.0",
5
+ "author": "",
6
+ "main": "./build/index.js",
7
+ "keywords": [
8
+ "accoding",
9
+ "mcp",
10
+ "programming",
11
+ "algorithm"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "start": "node build/index.js",
16
+ "dev": "tsc-watch --onSuccess \"node build/index.js\"",
17
+ "format": "prettier --write ."
18
+ },
19
+ "bin": {
20
+ "accoding-mcp-server": "build/index.js"
21
+ },
22
+ "type": "module",
23
+ "files": [
24
+ "build"
25
+ ],
26
+ "license": "MIT",
27
+ "dependencies": {
28
+ "@modelcontextprotocol/sdk": "^1.8.0",
29
+ "minimist": "^1.2.8",
30
+ "pino": "^9.6.0",
31
+ "zod": "^3.24.2"
32
+ },
33
+ "devDependencies": {
34
+ "@types/minimist": "^1.2.5",
35
+ "@types/node": "^22.14.0",
36
+ "prettier": "^3.5.3",
37
+ "tsc-watch": "6.2.1",
38
+ "typescript": "^5.8.3"
39
+ }
40
+ }
41
+