mcpField
U
umd-mcp

umd-mcp

本地服务
github.com/Open-Sourcery-UMD科研与教育02 周前更新

关于 umd-mcp

umd-mcp 将马里兰大学的信息与服务提供给 MCP 客户端,覆盖校园生活、学业、体育和活动,也包括仅限会员访问的 RecWell 数据;需要登录的服务可通过登录工具访问。

主要功能

  1. 01课程、成绩与学业信息
  2. 02校园餐饮、新闻和目录
  3. 03班车路线与时刻表
  4. 04体育赛程、名单与新闻
  5. 05校园活动与学术日历
  6. 06RecWell 项目与会员记录

适用场景

  1. 01查询课程和校园服务
  2. 02查看球队赛程与球员名单
  3. 03查找校园活动和演出
  4. 04查看 RecWell 项目或账户记录

MCP 相关

向 MCP 客户端提供马里兰大学数据和服务工具。部分工具需要先用 `login` 登录;ELMS 也可选用 Canvas 令牌访问。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"avivkeller-umd": {
"command": "npx",
"args": [
"-y",
"umd-mcp"
]
}
}
}
启动命令npx -y umd-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmumd-mcp0.0.1

工具

100

收录的工具列表 · 更新于 2 周前

此工具无需参数。

详细介绍

umd-mcp

一个 MCP 服务,提供马里兰大学的数据:课程和成绩(PlanetTerp、Jupiterp、课程表、Testudo 学生门户、ELMS)、餐饮菜单和新闻、Shuttle-UM 路线和时刻表、体育、校园日历、TerpLink 组织和活动、RecWell 设施和 ActiveTerp 校园休闲门户、大学评议会以及校园通讯录。

开发

pnpm install
pnpm dev        # run the server on stdio with hot reload
pnpm inspect    # open the MCP Inspector against the dev server
pnpm test       # run tests
pnpm check      # typecheck + lint + format check + knip (dead code) + tests
pnpm build      # emit dist/

与客户端搭配使用

添加到 MCP 客户端配置中(例如 Claude Desktop、Claude Code):

{
  "mcpServers": {
    "umd": {
      "command": "node",
      "args": ["/path/to/umd-mcp/dist/index.js"]
    }
  }
}

登录

部分 UMD 服务需要用户登录。login 工具会在 UMD Shibboleth IdP 打开一个由 umd-mcp 控制的浏览器窗口(Chrome 或 Edge,使用其独立配置文件 ~/.umd-mcp/browser-profile),并使用 CAS service URL 指向 127.0.0.1 上的一次性监听器。用户完成登录(包括 Duo)后,IdP 会携带服务票据重定向回来,服务端会通过 serviceValidate 验证票据,以确认登录用户的身份。

在单点登录会话仍有效期间,login 会在同一窗口中访问所有已连接的服务(见下文),让每个应用设置自己的会话 Cookie,并将这些 Cookie 复制到各服务对应的 Session 中。窗口会自动关闭。配置文件会保留,因此之后登录通常无需交互。logout 会清除所有信息和配置文件中的 Cookie。

为什么要使用浏览器:CAS 只会针对登录 URL 中指定的服务发放票据,而每个应用都会将自己的票据兑换为其来源域的 Cookie。服务端要获取这些 Cookie,唯一的方法就是充当接收它们的浏览器。

回调主机名为 localtest.dev.umd.edu,这是 UMD IT 发布的公共 DNS 名称,解析到 127.0.0.1。使用它而不是 localhost,是因为 IdP 位于 AWS WAF 后面,任何包含 localhost 的 service URL 都会被拒绝并返回 403。

环境变量:

  • UMD_MCP_BROWSER:Chromium 可执行文件的路径;适用于未安装 Chrome 或 Edge 的情况。
  • UMD_MCP_PROFILE_DIR:浏览器配置文件的存放位置。
  • CANVAS_TOKEN:Canvas 个人访问令牌(在 ELMS 个人资料设置中获取)。设置后,ELMS 工具会将其用作 bearer token,无需通过浏览器登录。

工具

除登录工具外,工具名称均为 <integration>_<method>。标注为“(需登录)”的集成需要先使用 login 工具;标注为“(可选登录)”的集成在登录后会返回更多内容;其余集成可匿名使用。

shibboleth
工具描述
login使用 UMD Directory ID 登录。
logout忘记已登录用户及所有服务会话,并清除登录浏览器,以便下次登录时重新提示。
whoami报告当前已登录的 UMD 用户;如果无人登录,则说明无人登录,并列出哪些服务存在有效会话。
activeterp
工具描述
activeterp_list_program_filtersactiveterp.umd.edu 项目所属的分类(例如,Fitness、Aquatics、Esports)和标签(例如,Adventure Trips)。
activeterp_list_programsactiveterp.umd.edu 上的项目(团体健身课程、游泳课程、冒险旅行、诊所、营地、电竞预约)及其价格,可按分类或标签筛选。
activeterp_search_programs按名称搜索 activeterp.umd.edu 项目,方式与网站搜索栏相同。
activeterp_get_programactiveterp.umd.edu 上的一个项目:描述、分类、价格、是否需要签署免责书,以及安排方式。
activeterp_list_program_offeringsactiveterp.umd.edu 某个项目在一个学期内的开设安排:每个有日期的场次或系列,以及其价格、剩余名额、上课模式和取消日期。
activeterp_list_program_instancesactiveterp.umd.edu 某个项目未来几天内可预约的时段:开始和结束时间、地点、教练、班级人数和剩余名额。
activeterp_list_facilitiesactiveterp.umd.edu 上可预约的设施(目前为 Terps Esports Center 的站点),以及其所属的上级设施和简介。
activeterp_get_facilityactiveterp.umd.edu 上的一个设施:描述、类型、面积、最大容纳人数和每周各工作日的常规开放时间。
activeterp_get_facility_schedule指定日期范围内 activeterp.umd.edu 设施日历上的预约,可查询一个或所有设施,并包含重复规则。
activeterp_list_calendarsactiveterp.umd.edu 主页可显示的日历(例如,Group Fitness Classes、Adventure Program)。
activeterp_list_calendar_eventsactiveterp.umd.edu 主页日历:未来几天内安排的所有课程、预约时段和活动。
activeterp-member(登录)
工具描述
activeterp_member_get_profile已登录成员在 activeterp.umd.edu 上的个人资料:姓名、大学 ID 号、资格、出生日期、性别以及存档的联系方式。
activeterp_member_list_my_memberships已登录成员当前和过往的 RecWell 会员资格:类型、开始和到期日期、续费条款以及退款或取消状态。
activeterp_member_get_access_history已登录成员的设施签到记录:设施、签到站点、入口和出口设备、时间,以及是否获准进入。
activeterp_member_list_my_orders已登录成员的订单:订单号、日期、下单地点、总额以及订单是否已作废。
activeterp_member_list_my_invoices已登录成员的全部发票或仅未付款发票:编号、日期、总额、已付金额和欠款金额,以及 PDF 链接。
activeterp_member_get_invoice已登录成员的一张发票:账单详情、小计、税额、总额、已付金额、未结余额以及明细项目。
activeterp_member_list_membershipsRecWell 在 activeterp.umd.edu 上销售的会员资格(日票、免费的 Group Fitness 和 Bouldering Zone 会员资格)及其简介。
activeterp_member_get_membershipRecWell 销售的一种会员资格及其每种可购买期限:名称、计费方式、预付价格,以及适用于已登录成员的起止日期。
activeterp_member_list_towel_servicesRecWell 在 activeterp.umd.edu 上销售的毛巾服务(学期和年度)。
activeterp_member_get_towel_service一种毛巾服务及其每种可购买期限:名称、计费方式、预付价格,以及适用于已登录成员的起止日期。
activeterp_member_list_multi_visit_passesRecWell 销售的多次访问通行证(私人训练课程套餐、会员访问通行证),包括类别列表、价格和任何购买要求。
activeterp_member_get_multi_visit_pass一种多次访问通行证:类别、价格、完整描述以及任何购买要求。
athletics
工具描述
athletics_list_sportsMaryland 的所有校队运动项目(Terps,umterps.com),以及其他 athletics 工具所需的 ID。
athletics_list_seasons某项运动有赛程的往届和当前赛季;对于往届赛季,还会提供传递给 athletics_get_schedule 的赛程 ID。
athletics_get_scheduleMaryland 某支队伍的赛程和比赛结果:每场比赛的日期、时间、对手、场地、电视/流媒体信息,以及比赛结束后的比分,还有该队的战绩。
athletics_get_game根据 ID(来自 athletics_get_schedule 或 athletics_get_calendar)获取一场 Maryland 比赛:对手、场地、媒体链接和比赛结果。
athletics_get_rosterMaryland 某支队伍当前的球员名单:球员的球衣号码、位置、年级、身高、体重、家乡和专业,以及教练组成员。
athletics_search_players按姓氏查找 Maryland 现役和退役运动员,涵盖 umterps.com 上的所有赛季;也可限定为某项运动。
athletics_get_coachesMaryland 某支队伍的教练组成员,包括职务、电子邮件、电话和个人简介页面链接。
athletics_get_newsMaryland Athletics 的最新新闻,按时间从新到旧排列;也可限定为某项运动。
athletics_get_article根据新闻 ID 获取 Maryland Athletics 新闻的全文(比赛回顾、预告、公告)。
athletics_get_calendar指定日期范围内所有运动项目(或某项运动)的 Maryland 比赛或活动,按日期分组,并提供对手、场地、媒体链接和比赛结果。
athletics_get_upcoming_eventsMaryland 某支队伍接下来的几场比赛,包括日期、时间、对手、场地和观看方式。
calendar
工具描述
calendar_search_events指定日期范围内 UMD 校园日历(calendar.umd.edu)上的活动;也可按全文查询、活动类型、受众或精选状态缩小范围。
calendar_get_event根据 ID 或 slug 获取 UMD 校园日历中的一项活动,包括完整描述、地点、联系人和重复规则。
calendar_list_categoriesUMD 校园日历用于归类活动的活动类型、受众和状态类别,以及 calendar_search_events 接受的 slug。
calendar_get_academic_calendar教务长办公室批准的 UMD 学期日历:涵盖未来数年的每个学年,包括课程首日和末日、假期、阅读日、期末考试、毕业典礼和暑期课程。
clarice
工具描述
clarice_search_eventsThe Clarice Smith 表演艺术中心(theclarice.umd.edu)的即将上演演出,可按标题、类型、类别或主办方进一步筛选。
clarice_get_event按 slug 查询一场 Clarice 活动:简介、每场演出的场馆、价格、地点和座位信息、内容提示,以及票务 ID。
clarice-tickets
工具描述
clarice_tickets_list_events有演出安排且可售票的 Clarice 活动(Spektrix),可按日期范围筛选,也可选定一种类型。
clarice_tickets_get_event按票务 ID 查询一场可售票的 Clarice 活动,包括简介以及首场和末场演出的信息。
clarice_tickets_list_performances某场可售票 Clarice 活动的所有演出,以及每场是否在售或已取消、线上售票时间段。
clarice_tickets_get_availability某场 Clarice 演出中仍可售的座位和轮椅位数量,以及场馆容量。
clarice_tickets_get_prices某场 Clarice 演出按票种和座位区域划分的票价。
dining
工具描述
dining_get_busy_meterUMD 三个餐厅当前的拥挤程度(较不拥挤、中度拥挤或极度拥挤),数据来自“Dining Hall Status”页面背后的服务。
dining_get_calendarUMD 餐饮服务提供的本学期重要日期:餐饮计划上线时间、节假日和假期营业时间、关闭日期,以及 Dining Dollar 到期时间。
dining_get_newsdining.umd.edu 上的最新文章,主要是“The Dish”月刊通讯,内容来自其 RSS Feed。
directory(可选登录)
工具描述
directory_search按姓氏(前缀;支持“Pin*”通配符)、全名、电子邮件地址、Directory ID 或电话号码搜索 UMD 校园目录中的人员。
directory_search_advanced按姓名各部分、电子邮件、工作电话、部门、隶属关系和机构搜索 UMD 校园目录。
directory_get_person按 Directory ID 查询 UMD 校园目录中的一人(即其 @umd.edu 邮箱中 @ 前面的部分)。
elms(登录)
工具描述
elms_whoamiELMS(Canvas)记录的已登录用户信息:姓名、登录 ID、电子邮件和时区。
elms_list_courses已登录学生在 ELMS(Canvas)上的课程,包含学期、教师和当前成绩情况。
elms_get_course一门 ELMS(Canvas)课程的信息,包含课程大纲、主页以及已启用的导航标签,便于了解其中是否有作业、模块、公告、文件或外部工具(Zoom、Piazza、Gradescope)。
elms_list_assignmentsELMS(Canvas)课程中的作业,按截止日期排序,每项均包含已登录学生的提交状态和得分。
elms_get_submission已登录学生针对一项 ELMS(Canvas)作业的提交信息:状态、得分、成绩以及教师的任何评语。
elms_get_grades已登录学生所选每门 ELMS(Canvas)课程的当前和最终成绩,或某一门课程的成绩。
elms_list_modulesELMS(Canvas)课程的模块及其项目(作业、文件、页面、链接)和完成状态。
elms_list_announcements在指定日期范围内(默认:过去 14 天)发布于一门或多门 ELMS(Canvas)课程的公告。
elms_get_todo已登录学生仍需提交的作业和经典测验,即 ELMS(Canvas)待办事项侧边栏中列出的内容。
elms_get_planner在指定日期范围内(默认:未来 14 天),已登录学生在所有 ELMS(Canvas)课程中即将到期或发生的事项:作业、测验、公告、活动和备注,以及提交状态。
elms_get_upcoming_events所有 ELMS(Canvas)课程中即将举行的日历活动和作业截止日期,与 Canvas 控制面板显示的内容一致。
elms_get_activity_stream已登录学生所参与的活跃 ELMS(Canvas)课程中的近期活动:新公告、讨论帖、成绩和消息。
elms_list_conversations已登录学生的 ELMS(Canvas)收件箱:对话主题、参与者和最新消息。
elms_get_conversation一条 ELMS(Canvas)收件箱对话及其中的所有消息。
go(登录)
工具描述
go_list_links当前登录用户在 go.umd.edu 各个集合中的短链接,默认按创建时间从新到旧排序。
go_get_link当前登录用户的某个 go.umd.edu 链接及其统计页面:目标地址、集合、备注、按小时、天和月统计的点击次数、点击最多的一天,以及点击来源。
go_create_link创建指向某个 URL 的 go.umd.edu 短链接,可选择关键词或自动生成关键词,并将其放入个人空间或用户的某个集合。
go_update_link更改当前登录用户某个 go.umd.edu 链接的指向、重命名其关键词、将其移至其他集合或编辑其备注。
go_delete_link删除当前登录用户的某个 go.umd.edu 链接。
go_get_qr_code可打开当前登录用户某个 go.umd.edu 链接的 PNG 二维码。
go_list_collections当前登录用户在 go.umd.edu 上加入的集合,以及每个集合的链接数和成员数。
go_create_collection创建一个 go.umd.edu 集合,并将当前登录用户设为首位成员。
go_update_collection重命名当前登录用户的某个 go.umd.edu 集合或更改其描述。
go_delete_collection删除当前登录用户的某个 go.umd.edu 集合(如果集合中仍有链接,则会拒绝删除)。
go_list_collection_members可以管理当前登录用户某个 go.umd.edu 集合中链接的人员。
go_add_collection_member通过 Directory ID,授予某位 UMD 人员访问当前登录用户某个 go.umd.edu 集合的权限。
go_remove_collection_member撤销某人访问当前登录用户某个 go.umd.edu 集合的权限。
go_lookup_users使用 go.umd.edu 自带的人员搜索,按姓名或 Directory ID 查找 UMD 人员。无需登录。
go_list_transfer_requests当前登录用户收到或发出的 go.umd.edu 链接转让待处理请求。
go_transfer_links向另一位 UMD 人员发出转让当前登录用户某些 go.umd.edu 链接的请求;对方接受后将成为这些链接的所有者。
go_accept_transfer_request接受他人在 go.umd.edu 上转让给当前登录用户的链接。
go_reject_transfer_request拒绝他人转让给当前登录用户的链接,或撤回当前登录用户发出的转让请求。
imleagues
工具描述
imleagues_list_leaguesIMLeagues 上 UMD 本学期的校内体育联赛,包含每个联赛的报名状态、报名截止日期和赛季日期。
imleagues_get_standingsIMLeagues 上 UMD 校内联赛的排名,包括整个联赛及各分区的排名,以及平分时的排名规则。
imleagues_list_handbooksUMD 校内体育部在 IMLeagues 上发布的手册和指南,涵盖全校或某项运动。
imleagues-member(登录)
工具描述
imleagues_member_list_my_teams已登录成员在 IMLeagues 上加入的 UMD 校内体育队伍,以及每支队伍的队长。
imleagues_member_get_leagueUMD 校内联赛的规则、各分区的比赛时段和剩余名额,以及各分区的所有队伍及其阵容人数和队长。
imleagues_member_get_teamUMD 校内体育队伍的联赛、分区、战绩和得分,其成员的姓名和角色,以及所有常规赛和季后赛的赛果与场地。
imleagues_member_get_game一场 UMD 校内体育比赛的信息:比赛时间和地点、状态、双方队伍的战绩和排名,以及最终比分和各时段比分。
jupiterp
工具描述
jupiterp_list_departmentsJupiterp 上的所有四字母院系代码及其名称。
jupiterp_list_courses来自 Jupiterp 对课程安排表抓取数据的 UMD 课程:课程名称、学分、通识教育类别、先修课程和选课限制说明,以及课程描述。
jupiterp_list_sectionsJupiterp 上当前学期的 UMD 课程班次:教师及其 Jupiterp slug、上课日期、时间和教室,以及座位、候补名单和保留名额数量。
jupiterp_list_instructorsJupiterp 上的 UMD 教师及其学生平均评分(综合 PlanetTerp 和 Jupiterp 评论),以及他们授课过的学期。
jupiterp_list_reviewsJupiterp 上经批准的 UMD 教师学生评论,包括从 PlanetTerp 导入的评论。
jupiterp_get_gradesJupiterp 上 Registrar 发布的 UMD 单个课程班次成绩分布,涵盖自 2010 年秋季学期以来的秋季和春季学期。
jupiterp_get_grade_summaryJupiterp 上按班次汇总的成绩分布:按课程、课程和学期、课程和教师、教师,或教师和学期汇总。
jupiterp_list_grade_termsJupiterp 提供成绩数据的学期,按时间从近到远排列,并附班次和课程数量,以及全校 GPA。
maps
工具描述
maps_list_buildingsUMD 校园地图(maps.umd.edu)上的建筑,包括 Testudo 使用的建筑编号和代码、建筑类别、类别和位置。
maps_get_building按编号或代码查询 UMD 校园地图上的一栋建筑:街道地址、总建筑面积和可分配面积、产权、建造和翻新年份,以及使用者。
maps_list_parking_lotsUMD 校园地图上的停车场和停车楼,包括各自的适用对象、需要停车许可证的时间、张贴的规定、车位和许可证数量,以及位置。
maps_list_closuresUMD 校园地图上发布的停车场、停车楼和道路封闭信息,包括封闭地点、日期和通知链接。
maps_list_amenities来自 UMD 校园地图的全性别或家庭卫生间、哺乳室、淋浴间、更衣台或电梯,按建筑和房间列出。
maps_list_dining_locations来自 UMD 校园地图的餐厅,包括餐饮站点、咖啡馆、设有商家的美食广场、餐馆、商店和食品储藏室。
maps_list_residence_halls来自 UMD 校园地图的 UMD 宿舍楼,包括社区、建造年份、布局、房间面积和共用卫生间类型。
nutrition
工具描述
nutrition_get_menu在指定日期,UMD 食堂各餐次和档口供应的菜品,以及每道菜的过敏原和饮食标签,数据来自 nutrition.umd.edu。
nutrition_get_recipeUMD 食堂菜单中某道菜的营养标签:份量、卡路里、营养成分及每日摄入量百分比、配料和过敏原。
planetterp
工具描述
planetterp_get_course在 PlanetTerp 上按课程代码查询 UMD 课程。
planetterp_list_courses按字母顺序列出 PlanetTerp 上的 UMD 课程,可指定一个院系。
planetterp_get_professor在 PlanetTerp 上按姓名查询 UMD 教授或助教。
planetterp_list_professors按字母顺序列出 PlanetTerp 上的 UMD 教授和助教。
planetterp_get_grades查询 PlanetTerp 上某门课程、某位教授或两者的成绩分布,并按班级分列。
planetterp_search在 PlanetTerp 上搜索课程和教授,查找代码或名称中包含查询内容的条目,与网站搜索栏的功能相同。
recwell
工具描述
recwell_get_facility_alerts当前 RecWell 设施通知:节假日和缩短开放时间、闭馆及规定变更,以分节形式呈现,并附上相关开放时间表。
recwell_list_facilitiesRecWell 设施列表,每项附有一段介绍和链接,并按室内或室外分组。
recwell_get_facilityRecWell 设施页面:介绍、各季节的常规开放时间(每学期一个标签页,以表格呈现)、使用规定、租赁和停车信息。
recwell_get_group_fitness_scheduleRecWell 每周团体健身课程表:课程、地点、教练、开始和结束时间及注册链接,可指定一个工作日。
recwell_list_club_sports所有 RecWell 俱乐部体育项目,以及各自的网站、联系邮箱和捐赠页面。
senate
工具描述
senate_list_legislationUniversity Senate(senate.umd.edu)正在审议的法案:本学年的法案及各法案的进展和审议人,或可追溯至 2001 年的往年法案档案。
senate_get_bill按 ID 或文档编号查询一项 University Senate 法案:提案、提案人、政策链接、相关法案,以及其各阶段的历史记录,包括日期、决定和每个阶段提交的 PDF。
senate_list_senatorsUniversity Senate 现任成员,以及每位成员的席位、代表群体、学院和任期结束时间。
senate_get_constituentUniversity Senate 如何按 UMD Directory ID 归档校园社区成员:其学院、部门、职称、群体和代表群体。
senate_list_committeesUniversity Senate 的常设委员会和特别委员会、其任命成员的 University 委员会,以及往届委员会和工作组;每项均附一段摘要。
senate_get_committee按名称查询一个 University Senate 委员会、University 委员会或往届委员会或工作组:其页面文本(职责、主席、联系方式)、现任成员及其席位和学院,以及正在审议的法案。
senate_list_past_committee_legislation各 University Senate 常设委员会审议过的所有法案,按委员会和学年分组,可追溯至 2001 年。
senate_get_committee_meetings某个 University Senate 常设委员会在一个学年的会议日期和时间,以及每场会议发布的议程。
senate_get_meetings一个学年的 University Senate 会议安排,包括每场会议发布的议程、材料、幻灯片和会议纪要,以及档案涵盖的年份。
terplink
工具描述
terplink_search_organizations按名称或关键词搜索 TerpLink 上约 1,000 个活跃的学生组织,也可选择 terplink_list_organization_categories 中的类别进行筛选。
terplink_get_organization查看一个 TerpLink 学生组织的完整资料:简介、电子邮箱、类型、主要联系人、社交媒体链接和邮寄地址。
terplink_list_organization_categoriesTerpLink 用于归类学生组织的类别(学术、文化/族裔、荣誉学会等)。
terplink_search_events按关键词、日期范围、主办组织、类别、主题或福利搜索 TerpLink 活动。
terplink_get_event查看一个 TerpLink 活动的完整详情:简介、场地或会议链接、主办方、类别、福利和 RSVP 名额。
terplink_list_event_categoriesTerpLink 活动使用的标签类别(学术、服务、体育与休闲等)。
terplink_get_news查看学生组织和院系在 TerpLink 上发布的新闻文章,按最新优先排序;也可按关键词或组织筛选。
terplink_get_article查看一篇 TerpLink 新闻文章的纯文本全文。
terplink_search_service_opportunities按关键词搜索为 UMD 学生列出的志愿服务和社区服务机会(镜像自 GivePulse)。
testudo-soc
工具描述
testudo_soc_list_termsUMD Schedule of Classes 当前列出的学期(约 4 个:当前学期及接下来的几个学期)。
testudo_soc_list_departmentsUMD Schedule of Classes 中某学期开设课程的院系(4 个字母的课程前缀)。
testudo_soc_list_coursesUMD Schedule of Classes 中某个院系在某学期开设的所有课程:课程名称、学分、评分方式、通识教育代码、先修要求和描述。
testudo_soc_get_courseUMD Schedule of Classes 中某学期的一门课程及其所有教学班:教师、名额、上课日期、时间、教室和授课方式。
testudo_soc_get_sectionsUMD Schedule of Classes 中某学期一门或多门课程的教学班:教师、名额、上课日期、时间、教室和授课方式。
testudo_soc_search_courses按照 UMD Schedule of Classes 搜索表单的方式搜索某学期的课程。
testudo_soc_autocomplete_coursesUMD Schedule of Classes 自动补全中,某学期课程 ID 以给定文本开头的课程 ID 和名称。
testudo_soc_autocomplete_instructorsUMD Schedule of Classes 自动补全中,某学期姓氏或名字包含给定文本的教师。
testudo_soc_list_gen_ed_categoriesUMD Schedule of Classes 为某学期列出的通识教育类别和要求代码(FSAW、DSHS、DVUP 等)。
testudo_soc_list_gen_ed_coursesUMD Schedule of Classes 中某学期满足一项通识教育要求的课程。
testudo_soc_list_syllabiUMD Schedule of Classes 教学大纲存储库中某门课程的往年教学大纲:各自对应的学期和教师。
testudo_soc_get_building根据教学班列出的建筑代码和教室编号查询教学楼:全名、校园建筑编号和地图链接。
testudo(登录)
工具描述
testudo_get_current_term从 Testudo 学生门户获取 UMD 当前的学期、注册状态和关键日期。
testudo_list_terms已登录学生可在指定 Testudo 功能中使用的学期:「schedule」列出有课程表的学期(与 testudo_get_schedule 搭配使用)、「grades」列出已公布成绩的学期、「enrollment_certification」列出可申请在读证明的学期、「graduation」列出可能出现毕业日期的所有学期、「graduation_application」列出开放毕业申请的学期,以及「grade_option」列出开放通过/不通过选项申请期的学期。
testudo_get_schedule从 Testudo 学生门户获取已登录学生某学期的课程表:每个已注册的课程班级及其授课教师、学分、授课方式和每周上课安排(日期、时间、教学楼和教室)。
testudo_get_grades从 Testudo 学生门户获取已登录学生某学期的成绩:学期结束后公布的最终成绩、学期进行期间的期中成绩,以及学期和累计 GPA。
testudo_get_unofficial_transcript从 Testudo 学生门户获取已登录学生的非正式成绩单(纯文本):转学学分、所有过往课程及其成绩,以及当前课程。
testudo_get_profile从 Testudo 学生门户获取大学存档的已登录学生联系信息:姓名、电子邮箱、电话号码、本地和永久地址,以及紧急联系人。
testudo_get_registration_appointment从 Testudo 学生门户获取已登录学生可以注册课程的时间:下一学期的注册预约时间、账户上的任何限制,以及存档的主修、辅修和证书项目。
testudo_get_request_status查询已登录学生通过 Testudo 学生门户提交的正式成绩单和在读证明申请状态,以及可能阻止新申请的司法或财务限制。
testudo_get_graduation_application_status从 Testudo 学生门户获取已登录学生的毕业申请信息:申请的学期、文凭上的姓名和邮寄地址,以及各学位的状态。
testudo_get_grade_options从 Testudo 学生门户获取已登录学生某学期各课程所选的评分方式(常规或通过/不通过),以及通过/不通过学分总数。
testudo_get_parent_access已登录学生授权访问其 Testudo 记录的家长或访客账户。
交通
工具描述
transportation_list_routes当前时刻表中的所有 Shuttle-UM 巴士线路(包括 104 College Park Metro 等常规线路和活动线路),以及每条线路今天是否运营,数据来自已发布的 GTFS 数据源。
transportation_get_route一条 Shuttle-UM 线路及其按顺序排列的站点(适用于指定日期最常见的行程模式)和线路折线,数据来自已发布的 GTFS 数据源。
transportation_list_stops已发布的 GTFS 数据源中的 Shuttle-UM 巴士站点,可按名称片段或与某个地点的距离筛选。
transportation_get_stop一个 Shuttle-UM 巴士站点的位置及所有途经该站的线路,数据来自已发布的 GTFS 数据源。
transportation_get_schedule某个日期的 Shuttle-UM 线路计划发车时间,可选择指定一个站点,数据来自已发布的 GTFS 数据源。
transportation_get_service_alertsShuttle-UM 系统的当前更新和警报(绕行、时刻表变更),以及 DOTS 时刻表页面链接的服务调整通知。
transportation_get_service_calendar学年期间的 Shuttle-UM 服务日历:每个假期、考试周和学期间隔的日期、服务是正常还是调整,以及包含详情的通知页面。

添加集成

集成是 src/integrations/ 下的一个文件夹,用于封装一个上游服务并声明它提供的 工具:

src/integrations/example/
  index.ts      # the Integration subclass, and nothing else
  schemas.ts    # input schemas, exported output schemas, and their inferred types
  mappers.ts    # Raw* types for the upstream payloads and the to*() functions (parsers.ts when scraping HTML)

同时提供公开侧和登录后侧的上游服务会拆分成位于同级文件夹的两个类 (testudo/soc 和 testudo/portal、activeterp/catalog 和 activeterp/member), 它们共享的内容放在旁边的 common.ts 中。

继承 src/integrations/base.ts 中的 Integration,声明 name 和 baseUrl,并用 @tool() 标记每个工具方法。MCP 工具名称为 <name>_<method>(在规范中传入 name 可覆盖此名称)。然后将此类添加到 src/integrations/index.ts 中的 createIntegrations()。

import { z } from 'zod';
import { Integration, tool } from '../base.js';
import { type Building, buildingSchema } from './schemas.js';

export class Example extends Integration {
  readonly name = 'example';
  readonly baseUrl = 'https://example.umd.edu/api';

  @tool({
    title: 'Get campus building',
    description: 'Look up a campus building by its code. No login needed.',
    input: { code: z.string().describe('Building code, e.g. "IRB"') },
    output: buildingSchema.shape,
  })
  async get_building({ code }: { code: string }): Promise<Building> {
    return this.get<Building>(`buildings/${code}`);
  }
}

规范中的所有内容都会提供给客户端,让模型在调用工具前了解工具的功能、输入和返回值:

  • description 和 title 会原样传递;annotations 会与默认值(只读、开放世界)合并。
  • input 会成为工具的 inputSchema。装饰器会在编译时检查方法的参数类型是否接受解析后的结构。
  • output(可选)会成为工具的 outputSchema。装饰器会在编译时检查方法是否返回匹配的对象。在运行时,会根据该结构验证值,并同时将其作为 structuredContent 和 JSON 文本块返回,以供仅读取文本的客户端使用。不在结构中的字段会被丢弃。

现有集成遵循以下约定:

  • 对每个输入和输出字段调用 .describe();相关文本会写入模型读取的 JSON Schema。描述结尾使用 “No login needed.” 或 “Requires login.”。
  • 只要上游的值集合已知,就使用 z.enum,并通过 src/common.ts 中的 CODE: 'value' 表和 decode();这样遇到意外的上游值时会作为工具错误提示。
  • 复用 src/common.ts 中的共享 schema(term、courseId、sectionId、weekday、isoDate、pagination 等)以及 src/lib/ 中的辅助工具:text.ts(空白转 null、拼接)、html.ts(HTML 转纯文本)、scrape.ts(cheerio 文本、链接和表格)、dates.ts(打印日期转 YYYY-MM-DD)。手动编写解析器之前,先考虑使用 npm 包。
  • this.get(path, query) 会获取 JSON,this.getText() 会获取相对于 baseUrl 的 HTML;this.postForm() 和 this.postJson() 会发送网站自身表单和脚本所发送的内容,this.request() 则是通用方法。查询值可以是数组(键会重复出现),每个请求都会在一分钟后超时。HTTP 错误(包括服务器提供的错误消息)、网络故障和输出 schema 不匹配都会自动转换为工具错误结果;可重写 handleError() 进行自定义处理。
  • 仍需服务器会话的匿名流程(例如保存在会话中的搜索、与 cookie 绑定的令牌),需要通过 src/lib/http.ts 中的 cookieFetcher() 重写 fetcher。每个登录会话只读取一次的值(例如 CSRF 令牌、账户 ID),则通过 src/lib/session.ts 中的 perSession() 获取。
单点登录背后的集成

如果上游需要 UMD 登录,请在集成中声明 service。此后,login 会同时登录该服务和其他所有服务,而 this.get() / this.getText() / this.request() 会携带应用的 cookie。在用户登录前,或应用拒绝该会话后,这些方法会抛出 AuthRequiredError,并将其转换为工具错误,提示模型调用 login。

export class StudentPortal extends Integration {
  readonly name = 'testudo';
  readonly baseUrl = 'https://app.testudo.umd.edu/services';
  override readonly service = {
    name: 'testudo',
    // Page that sends an anonymous browser through single sign-on and back into the app.
    loginUrl: 'https://app.testudo.umd.edu/main/',
    // Optional: when the browser counts as signed in. Default is "same origin as loginUrl".
    signedIn: (url: URL) => url.hash.startsWith('#/main'),
    // Optional: fields to POST to loginUrl for apps whose sign-in is a button, not a redirect.
    // loginForm: { login: 'Log in' },
    // Optional: a button to click on loginUrl when its form carries a per-page token the
    // browser must send (an anti-forgery token, a provider field).
    // loginClick: 'button.btn-sso-shibboleth',
    // Optional: when a response means the session is gone. Default: 401, or a redirect off
    // the app's origin or to signInPage.
    // expired: (response, requested, landed) => response.status === 403 || landed.pathname === '/expired',
    // Optional: the app's own sign-in page, for apps that bounce an expired session there
    // (same origin, HTTP 200) instead of answering 401 or redirecting to the IdP.
    // signInPage: (url: URL) => url.pathname === '/shortener/signin',
  };
}

项目布局

src/
  index.ts             # stdio entrypoint
  server.ts            # createServer(): registers every integration
  common.ts            # shared zod schemas and small helpers (terms, course ids, weekdays, enums)
  lib/                 # HTTP helper, sign-in hub (auth.ts), per-service Session, browser driver,
                       # text/HTML/scraping helpers
  integrations/
    base.ts            # Integration base class, @tool decorator, result helpers
    index.ts           # createIntegrations(): instantiate integrations here
    <name>/            # one folder per integration (see above)
    testudo/soc/       # public Schedule of Classes
    testudo/portal/    # student portal (login)
    grouper/NOTES.md   # research only; Grouper is VPN-only and not implemented

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。