You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

17 KiB

name description
educoder-skill 提供 Educoder 用户、课堂、作业和考试相关查询能力,当前支持用户基本信息、课堂列表、课堂分班、课堂作业列表、作业学生列表、学生作业完成情况、作业提交及成绩统计、作业成绩分布、课堂考试列表、考试基本信息、考试学生列表、考试统计概览、考试成绩分布、成绩分布区间学生明细查询。

MCP 服务地址

  • 线上地址:http://110.41.32.120:48001/mcp
  • 本地开发:http://localhost:8001/mcp

使用 streamable-http 模式连接,不使用 SSE。

接入方式

  • 客户端应使用 streamable-http MCP 客户端
  • 使用 OpenClaw 安装本 skill 时MCP 服务地址直接填写线上地址:http://110.41.32.120:48001/mcp
  • 不要使用 sse_client
  • 本地开发端口默认是 8001,线上端口使用 48000
  • MCP 路径默认是 /mcp

安装完成提示

安装完成后,面向用户只介绍当前 skill 提供的功能,不展示 MCP 地址、配置文件路径、token 保存方式、headers 规则等接入细节。

推荐展示文案:

Educoder skill 已安装完成。当前支持查询:
- 当前用户基本信息
- 当前用户的课堂列表
- 课堂分班列表
- 课堂中的作业列表
- 某次作业下的学生列表
- 某学生在当前作业下的完成情况
- 作业提交及分数统计
- 作业成绩分布统计
- 课堂中的考试列表
- 考试基本信息
- 某场考试下的学生列表
- 考试统计概览及分班明细
- 考试成绩分布统计
- 成绩分布区间学生明细

前置配置

接入 OpenClaw 时,多个会话使用同一个 Authorization token。第一次安装 skill 时,把 MCP 服务地址和 token 一起写到固定的 OpenClaw MCP 配置文件 ~/.openclaw/educoder-skill/.mcp.json 中;后续调用 MCP 时,也只从 ~/.openclaw/educoder-skill/.mcp.json 读取 token 并放到请求头里。

Authorization 配置

安装 skill 时要求把用户输入 Educoder Authorization token 写入 MCP 配置文件 ~/.openclaw/educoder-skill/.mcp.json

配置文件路径必须固定为:

~/.openclaw/educoder-skill/.mcp.json

不要写入 ~/.openclaw/mcp.json~/.openclaw/config/mcp.json,否则新开会话时可能读取不到配置。

MCP 配置示例:

{
  "educoder-mcp": {
    "url": "http://110.41.32.120:48001/mcp",
    "transport": "streamable-http",
    "headers": {
      "Authorization": "xxxxx"
    }
  }
}

Authorization 的值直接写 token 原文,不要写成 Bearer xxxxx。不要把 token 放到工具参数里。

后续调用 MCP 时,从 MCP 配置读取 headers.Authorization 并注入请求头:

mcp_config = openclaw_mcp_config.get("educoder-mcp")
token = mcp_config["headers"]["Authorization"]

headers = {
    "Authorization": token
}

Authorization 的 header 值直接传 token 原文,不要拼接 Bearer 前缀。例如:

Authorization: xxxxx

不要传成:

Authorization: Bearer xxxxx

创建 MCP 连接时透传:

async with streamable_http_client(self.server_url, headers=headers or None) as (read, write, _):
    yield read, write

Authorization 走 MCP 连接层请求头,不放在工具参数里。

多会话共享 Token

多个会话共用 ~/.openclaw/educoder-skill/.mcp.json 中的同一个 Authorization token。安装后不需要每个会话重复输入 token每次调用 MCP 时读取配置里的 headers.Authorization 即可。

401 Token 过期处理

如果调用 MCP 工具或后端接口时返回 401 Unauthorized,说明当前 token 已过期或无效。

处理流程:

  1. 停止继续使用当前 token 重试
  2. 提示用户重新输入新的 Authorization
  3. 将用户输入的新 token 写入 ~/.openclaw/educoder-skill/.mcp.json
  4. 重新创建 MCP 连接,并从 MCP 配置读取最新 token
  5. 使用新 token 重新发起本次工具调用

示例提示:

当前 Educoder 授权已过期,请重新输入 Authorization token。

更新 token 后必须重新建立 MCP 连接,不能复用已经携带旧 headers 的连接。

OpenClaw 接入建议

如果使用 OpenClaw推荐按下面的方式接入

  1. 安装 skill 时MCP 服务地址填写:http://110.41.32.120:48001/mcp
  2. 安装 skill 时,要求用户输入 Educoder Authorization token
  3. OpenClaw 将 MCP 地址和 token 写入 ~/.openclaw/educoder-skill/.mcp.json,其中 token 放到 headers.Authorization
  4. 当前用户发起工具调用时,后端创建 MCPClient
  5. MCPClient 建连时从 MCP 配置读取 token
  6. MCPClient 把读取到的 token 原文放进 MCP headers不要添加 Bearer 前缀
  7. 如果调用返回 401 Unauthorized,提示用户重新输入 token更新 MCP 配置后重新建连并重试

参考流程:

tool_server_url = "http://110.41.32.120:48001/mcp"

mcp_config = openclaw_mcp_config.get("educoder-mcp")

client = MCPClient(mcp_config=mcp_config)

tool_result = await client.call_tool(tool_name, tool_arguments)

MCPClient 示例:

class MCPClient:
    def __init__(self, mcp_config: dict):
        self.server_url = mcp_config["url"]
        self.mcp_config = mcp_config

    def _build_headers(self) -> dict[str, str]:
        headers = {}
        authorization = self.mcp_config.get("headers", {}).get("Authorization", "").strip()
        if authorization:
            headers["Authorization"] = authorization
        return headers

不推荐的做法:

  • 让用户在每个会话里重复输入 Authorization
  • Authorization 放到工具参数里
  • Authorization 自动拼接 Bearer 前缀
  • 把 token 写入 OpenClaw .env 后要求用户重启才能生效
  • 每个会话都重复要求用户输入 token

触发场景

意图 → 工具 速查表

用户意图 调用工具
查询当前用户基本信息 educoder_user_info
查询当前用户的课堂列表 educoder_user_course_list
查询课堂分班列表 educoder_course_groups
查询某个课堂中的作业列表 educoder_course_homeworks
查询某次作业下的学生列表 educoder_homework_student_works
查询某学生在当前作业下的完成情况 educoder_homework_student_completion
查询作业提交及分数统计 educoder_homework_submission_summary
查询作业成绩分布统计 educoder_homework_score_distribution
查询某个课堂中的考试列表 educoder_course_exercises
查看考试基本信息 educoder_exercise_info
查询某场考试下的学生列表 educoder_exercise_users
查询考试统计概览及分班明细 educoder_exercise_overview
查询考试成绩分布统计 educoder_exercise_score_distribution
查询成绩分布区间学生明细 educoder_exercise_score_distribution_students

不要触发的情况

  • 与课堂、作业、考试数据查询无关的问题
  • 需要新增、修改、删除数据的写操作
  • 纯闲聊场景

组合调用示例

用户说:“帮我查一下我有哪些课堂,再看看某个课堂里的作业和考试”

交互逻辑:

  1. 回复用户:“好的,我先为您获取当前用户信息和课堂列表,然后再查看具体课堂内的作业和考试安排。”
  2. 依次调用
    • educoder_user_info
    • educoder_user_course_list
    • educoder_course_groups
    • educoder_course_homeworks
    • educoder_course_exercises

用户说:“帮我看看这次作业的提交情况、成绩分布,以及某个学生完成得怎么样”

交互逻辑:

  1. 回复用户:“没问题,我将为您分析作业的提交统计和成绩分布,并查询指定学生的完成细节。”
  2. 依次调用
    • educoder_homework_submission_summary
    • educoder_homework_score_distribution
    • educoder_homework_student_completion

用户说:“帮我看一下这次作业和这场考试的学生列表”

交互逻辑:

  1. 回复用户:“好的,正在为您提取作业和考试对应的学生名单。”
  2. 依次调用
    • educoder_homework_student_works
    • educoder_exercise_users

用户说:“帮我看一下某场考试的信息和参与学生”

交互逻辑:

  1. 回复用户:“这就为您查询该场考试的基础信息以及参与考试的学生列表。”
  2. 依次调用
    • educoder_exercise_info
    • educoder_exercise_users

用户说:“帮我分析一下这场考试的整体情况、成绩分布,再看看优秀区间有哪些学生”

交互逻辑:

  1. 回复用户:“好的,我将为您获取考试概览、成绩分布数据,并列出优秀分数段的学生明细。”
  2. 依次调用
    • educoder_exercise_overview
    • educoder_exercise_score_distribution
    • educoder_exercise_score_distribution_students

交互行为规范

为了提供更好的用户体验,在调用工具之前,模型应先向用户简要说明操作意图。这种“先解释后执行”的方式可以模拟更自然的人机交互。

解释原则

  • 简明扼要:解释应直接说明为什么要调用该工具,不要冗长。
  • 关联上下文:结合用户的具体问题进行解释,增强互动感。
  • 组合调用时的处理:如果需要连续调用多个工具,建议在开始第一步操作之前,一次性告知用户接下来的处理流程。
  • 模拟对话感:语气应自然、友好,让用户感觉到是在与一个助手交流,而不仅仅是执行指令。

示例话术

  • “好的,我先为您查询一下当前的课堂列表,以便找到对应的课堂标识。”
  • “为了深入分析这场考试的成绩分布,我需要先获取考试的整体统计信息。”
  • “这就为您查询该学生的作业完成情况,请稍等。”

工具详细说明

全局规则

  • 交互要求:在执行任何工具调用前,必须先向用户解释接下来的操作意图,模拟真实的对话交互体验。
  • 当前工具都是查询类工具,没有写操作
  • 调用时必须传入完整的结构化 JSON 参数对象
  • 参数名必须严格匹配工具定义
  • 课堂相关接口优先使用课堂标识 identifier
  • 作业相关接口优先使用 homework_id
  • 考试相关接口优先使用 exercise_id
  • 客户端每次连接 MCP 服务时,请从 OpenClaw MCP 配置读取 token 原文,并在 transport headers 中传 Authorization,不要添加 Bearer 前缀

1. educoder_user_info

获取当前用户基本信息。

参数:

参数 必填 说明
school 可选的 school 查询参数

典型问法:

  • “查询当前用户信息”
  • “我是谁”
  • “获取我的基本资料”

2. educoder_user_course_list

获取当前用户课堂列表。

参数:

典型问法:

  • “查询我有哪些课堂”
  • “我的课堂列表”
  • “获取当前用户的课堂信息”

返回字段:

  • status
  • message
  • data
  • meta

3. educoder_course_homeworks

获取课堂中的作业列表。

参数:

参数 必填 说明
identifier 课堂标识 identifier

典型问法:

  • “查询课堂中的作业列表”
  • “这个课堂有哪些作业”
  • “帮我看一下课堂作业”

4. educoder_course_groups

获取课堂分班列表。

参数:

参数 必填 说明
identifier 课堂标识 identifier

典型问法:

  • “查询课堂分班列表”
  • “这个课堂有哪些班级”
  • “帮我看一下课堂分组情况”

5. educoder_homework_student_works

获取某次作业下的学生列表。

参数:

参数 必填 说明
homework_id 作业 ID

典型问法:

  • “查询某次作业下的学生列表”
  • “这次作业有哪些学生提交了”
  • “帮我看一下作业学生情况”

6. educoder_homework_student_completion

获取某学生在当前作业下的完成情况。

参数:

参数 必填 说明
homework_id 作业 ID
user_id 用户 ID

典型问法:

  • “查询某个学生这次作业完成情况”
  • “这个学生在当前作业下做得怎么样”
  • “帮我看一下学生的实训作业通关情况”

7. educoder_homework_submission_summary

获取作业提交及分数统计。

参数:

参数 必填 说明
homework_id 作业 ID

典型问法:

  • “查询这次作业提交统计”
  • “这次作业平均分、最高分、最低分是多少”
  • “帮我看一下作业提交和分数概览”

8. educoder_homework_score_distribution

获取作业成绩分布统计。

参数:

参数 必填 说明
homework_id 作业 ID

典型问法:

  • “查询这次作业成绩分布”
  • “这次作业各分数段有多少人”
  • “帮我分析一下作业成绩分布”

9. educoder_course_exercises

获取课堂中的考试列表。

参数:

参数 必填 说明
identifier 课堂标识 identifier

典型问法:

  • “查询课堂中的考试列表”
  • “这个课堂有哪些考试”
  • “帮我看一下课堂考试”

10. educoder_exercise_info

查看考试基本信息。

参数:

参数 必填 说明
exercise_id 考试 ID

典型问法:

  • “查看考试基本信息”
  • “这场考试的基本情况是什么”
  • “帮我看一下考试信息”

11. educoder_exercise_users

获取某场考试下的学生列表。

参数:

参数 必填 说明
exercise_id 考试 ID

典型问法:

  • “查询某场考试下的学生列表”
  • “这场考试有哪些学生”
  • “帮我看一下考试参与学生”

12. educoder_exercise_overview

获取考试统计概览及分班明细。

参数:

参数 必填 说明
exercise_id 考试 ID
course_group_id 分班班级 ID

典型问法:

  • “查询这场考试的统计概览”
  • “这场考试应考、实考、平均分是多少”
  • “帮我看一下考试概览和分班信息”

13. educoder_exercise_score_distribution

获取考试成绩分布统计。

参数:

参数 必填 说明
exercise_id 考试 ID
course_group_id 分班班级 ID

典型问法:

  • “查询这场考试成绩分布”
  • “这场考试优秀、良好、及格、不及格各有多少人”
  • “帮我看一下某个分班的考试成绩分布”

14. educoder_exercise_score_distribution_students

获取成绩分布区间学生明细。

参数:

参数 必填 说明
exercise_id 考试 ID
level_key 成绩等级标识,如 excellentgoodpassfail
min_score 分数区间下限
max_score 分数区间上限
page 页码
per_page 每页数量
course_group_id 分班班级 ID

典型问法:

  • “查询优秀区间有哪些学生”
  • “这场考试 60 分以下的学生名单”
  • “分页查看某个成绩区间的学生明细”

客户端调用示例

import httpx
from mcp import ClientSession
from mcp.client.streamable_http import streamable_http_client


async def main(openclaw_mcp_config):
    mcp_config = openclaw_mcp_config.get("educoder-mcp")
    token = mcp_config.get("headers", {}).get("Authorization", "").strip()

    headers = {
        "Authorization": token
    }

    async with httpx.AsyncClient(headers=headers) as http_client:
        async with streamable_http_client("http://110.41.32.120:48001/mcp", http_client=http_client) as (read, write, _):
            async with ClientSession(read, write) as session:
                await session.initialize()

                tools = await session.list_tools()
                print([tool.name for tool in tools.tools])

                result = await session.call_tool("educoder_user_info", {})
                print(result)

注意事项

  • 当前服务使用 streamable-http,不是 SSE
  • 如果客户端使用了 sse_client,将无法正常调用当前服务
  • Authorization 应从 OpenClaw MCP 配置读取 token 原文,通过 MCP 连接层 headers 传入,不放在工具参数里,也不要添加 Bearer 前缀
  • 调用接口返回 401 Unauthorized 时,视为 token 过期或无效,应要求用户重新输入 token并更新 ~/.openclaw/educoder-skill/.mcp.json 中的 headers.Authorization
  • 新开会话直接从 ~/.openclaw/educoder-skill/.mcp.json 读取 headers.Authorization
  • MCP 配置文件路径固定为 ~/.openclaw/educoder-skill/.mcp.json,不要写入或读取 ~/.openclaw/mcp.json~/.openclaw/config/mcp.json
  • 后续新增或调整工具时,需要同步更新本文件