MCP Coursera Learning Server

MCP Coursera Learning Server

Enables searching, enrolling, and tracking Coursera courses and certificates through LibreChat, with multi-user secure authentication and caching.

Category
访问服务器

README

🎓 MCP Coursera Learning Server for LibreChat

A custom, secure, and production-ready Model Context Protocol (MCP) server that provides Coursera learning assistant capabilities to LibreChat. Search courses, retrieve detailed syllabi, dynamically enroll in courses, track learning progress, and extract verified accomplishments and certificates.

This server is specifically optimized for multi-user environments, featuring secure personal credential storage, isolated browser sessions, and advanced Cloudflare Turnstile bypass mechanisms.

Changelog:

  • 09/07/26:
    • Browser Context Isolation: Enforced strict per-request browser context segregation to guarantee no session leakage between LibreChat users.
    • Multi-step Login Support: Refactored authentication to handle Coursera's 2-step login page (Continue -> Next).
    • Cloudflare Turnstile Bypass: Implemented typing delays and natural pauses to simulate human behavior, alongside stealth JavaScript injections to mask automation flags.
    • Playwright Session State Persistence: Implemented saving cookies and storage states to disk per user (sessions/{userId}_state.json), reducing subsequent request time to 7-10s.
    • Smart Scroll with Retry Buffer: Re-implemented dynamic scrolling with 1.5s delays and 2-consecutive unchanged height checks to bypass slow lazy loading elements.
  • 05/07/26:
    • Force Overflow Auto: Programmatically injected scripts to override overflow hidden styles commonly applied by popup advertisements that block scrolling.
    • Anchor-Upwards Traversal Scraper: Overhauled scrapers to look for unique /learn/ and /accomplishments anchors and traverse parents, guaranteeing 100% data extraction.
    • Certificates Categorization: Supports extracting certificate types (Specialization vs Course) and public verification links from the /accomplishments page.
    • Smart SQLite Caching: Implemented a Key-Value caching system with customizable TTL (3 hours for courses, 12 hours for certificates) and support for a force_refresh override to ensure instantaneous API responses.

📂 Project Structure

mcp-coursera/
├── src/
│   ├── index.ts                 # Express server & Streamable HTTP transport + tools router
│   ├── db.ts                    # SQLite database manager (credentials storage & key-value cache)
│   ├── encrypt.ts               # AES-256-CBC encryption manager for user passwords
│   └── ...
├── data/                        # [Git Ignored] Local database storage & debug screenshots
│   ├── coursera.db              # SQLite Database
│   └── login_failed.png         # Automatic screenshot taken on login/anti-bot failure
├── Dockerfile                   # Multi-stage optimized Playwright container
├── docker-compose.yml           # Standalone deployment file
├── tsconfig.json                # TypeScript compiler config
└── package.json

🛠️ Tools Provided

Tool Arguments Required Description
search_courses query, difficulty, language, limit query Search Coursera for courses matching keywords.
get_course_details course_url course_url Extract syllabus, instructors, duration, skills, and certificate info.
enroll_course course_url, email?, password? course_url Automatically enroll in a course (uses saved credentials if not passed).
get_my_courses email?, password?, force_refresh? None Fetch enrolled courses, progress percentages, last accessed date, and status.
get_certificates email?, password?, force_refresh? None Extract titles, dates, issuer names, and public verification URLs of earned certificates.
unlink_coursera_account None None Securely delete your saved Coursera credentials and all cached data.

📸 Screenshots & Usage Examples

🔍 Searching Courses (search_courses)

Retrieve search results containing courses matching user keywords on Coursera: Search Course

📖 Extracting Course Syllabus (get_course_details)

Scrapes instructors, duration, skills, and weekly syllabus detail of any Coursera course: Course Details & Syllabus

📚 Tracking Progress (get_my_courses)

Fetches all enrolled courses with exact progress percentage metrics and completed status: My Enrolled Courses

🏆 Verifying Accomplishments & Certificates (get_certificates)

Extracts earned Course/Specialization certificates, dates, and official verification links: My Certificates


🔒 Multi-User Secure Authentication & Web Portal

Rather than hardcoding credentials globally, this server features a secure OAuth-like Web Portal where individual LibreChat users securely link their Coursera accounts:

1. Step-by-Step Account Linking Flow

  1. Identifier Extraction: The server extracts the user's ID (x-user-id header) from the incoming chat request.

  2. Dynamic Link Generation: If no credentials exist in the database, the tool interrupts execution and prompts a secure, personalized portal URL:

    Link User Prompt

  3. AES-256-CBC Encryption: The user clicks the link and enters their credentials securely in the Web Portal. The server encrypts the password using an AES-256-CBC algorithm with a host-configured ENCRYPTION_KEY before storing it in SQLite:

    Verify Account Portal

  4. Successful Integration: Once saved, the user is notified of successful account link in LibreChat, with zero password leakage to the LLM (AI) or chat history:

    Linked Account Info


⚡ Smart SQLite Caching

Scraping dynamic web pages using a headless browser can take 15-20 seconds per request. To deliver an outstanding user experience, this server implements an SQLite-based Key-Value Cache:

  • Course Progress Cache: Cached for 3 hours (under key "courses").
  • Certificates Cache: Cached for 12 hours (under key "certificates").
  • Bypassing Cache (force_refresh): Users can force a real-time scrape (e.g., when they just completed a course) by asking the AI to "refresh my progress" or "check again". The Agent will set the force_refresh: true parameter, bypassing the cache.

🛡️ Bypassing Cloudflare Turnstile

Coursera uses Cloudflare Turnstile to protect its login interface. Headless Chromium running inside a Docker container is highly prone to being flagged. This server bypasses detection using:

  1. Human-like Interaction (Humanization):
    • Typing Delays: Instead of immediate form filling, characters are typed one-by-one with a delay of 150ms for emails and 200ms for passwords.
    • Natural Pauses: Natural delays of 1.5s - 3.5s are placed between gtyping and clicking actions to simulate human reaction times.
  2. Stealth Script Injections:
    • Nullifies navigator.webdriver to conceal browser automation.
    • Mocks the window.chrome object and populates a dummy list of navigator.plugins.
  3. Localization Alignment:
    • Configures Locale to en-US and Timezone to Asia/Ho_Chi_Minh (customizable) to force the Coursera interface to English, ensuring high accuracy text pattern matching.

🚀 Installation & Deployment (Docker Compose)

This server is designed to run alongside LibreChat as a sibling service.

Step 1: Directory Setup

libre/
├── LibreChat/              ← LibreChat repository root
│   ├── docker-compose.override.yml
│   └── librechat.yaml
└── mcp-coursera/           ← This MCP server repository
    ├── src/
    ├── Dockerfile
    └── .env

Step 2: Configure Environment Variables

Copy .env.example to .env inside mcp-coursera/ and configure:

PORT=3014
ENCRYPTION_KEY=generate_a_secure_32_character_hex_key_here
SERVER_URL=http://localhost:3014

Step 3: Add to docker-compose.override.yml

Add the mcp-coursera service to your LibreChat/docker-compose.override.yml:

services:
  mcp-coursera:
    container_name: mcp-coursera
    build: ../mcp-coursera
    restart: always
    env_file:
      - ../mcp-coursera/.env
    environment:
      NODE_ENV: ${NODE_ENV:-production}
      PORT: 3014
    ports:
      - "3014:3014" # Maps Web Portal to host
    volumes:
      - ../mcp-coursera/data:/app/data # Persists database and screenshot data
    networks:
      - default

Step 4: Register in librechat.yaml

Add the server registration to your librechat.yaml:

mcpSettings:
  allowedDomains:
    - mcp-coursera

mcpServers:
  coursera-learning:
    type: streamable-http
    url: http://mcp-coursera:3014/mcp
    title: Coursera Learning MCP
    description: Access Coursera learning progress, certificates, and course enrollment.
    timeout: 120000 # Increased timeout to handle multi-step login and navigation retry
    headers:
      x-user-id: '{{LIBRECHAT_USER_ID}}'

💡 Recommended Agent System Instructions

Paste the following into your Agent's Instructions / System Prompt in LibreChat:

You are a Learning Assistant with access to Coursera tools.

1. Checking Progress & Certificates:
   When asked to check course progress, certificates, or enroll, invoke the respective tools.
   
2. Handling "Authentication required" Errors:
   If a tool returns an error message like: "Authentication required. Please link your Coursera account securely at: http://...", you MUST present this exact URL returned by the tool to the user as a clickable markdown link. DO NOT replace the userId parameter with placeholders like "xxxx" or "unknown", use the real dynamic URL provided.
   
3. Security Warning:
   NEVER ask the user to type their Coursera password directly into the chat. If they try to do so, politely reject it and instruct them to use the secure link instead.

4. Cache Refreshing:
   Default calls to get_my_courses and get_certificates use cached data. If the user explicitly asks to "update", "refresh", or "check again", set the `force_refresh` parameter to `true`.

5. Unlinking Account:
   If the user wants to log out or remove their credentials, invoke the `unlink_coursera_account` tool.

🔧 Debugging & Troubleshooting

Screenshot Debugging

If a tool execution fails or experiences an anti-bot challenge:

  1. Open the local directory mcp-coursera/data/ on the host machine.
  2. Open login_failed.png to view the exact visual state of the browser.

Inspecting logs

docker logs -f mcp-coursera

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选