Skip to main content
Glama
whed-tools

whed-tools

by Dasistaiden

WHED Tools — Higher Education Intelligence Pipeline

An MCP-native pipeline for collecting structured intelligence on higher education institutions, aligned with the IAU World Higher Education Database (WHED) schema.

Scrape → Extract → Validate → Save — the Host LLM performs extraction directly using MCP tools. No external LLM required.

Built on samirsaci/mcp-webscraper.


Overview

Step

How

Scrape

MCP crawl_website or standalone run_scraper.py — schema-driven crawl, PDF extraction

Extract

Host LLM reads scraped content, uses get_extraction_schema + get_db_context

Validate

validate_profile — Pydantic schema + WHED DB picklist checks

Save

save_profile — write to output/structured/


Related MCP server: evident

Architecture

┌─────────────────────────────────────────────────────────────────┐
│  HOST LLM  (Claude in Cursor / any MCP client)                  │
│                                                                 │
│  crawl_website(url)      →  get_extraction_schema()             │
│  scrape_url(url)             get_db_context(domain)            │
│                                     │                           │
│  Host LLM reads content and fills JSON                          │
│                                     │                           │
│  validate_profile(json)  →  save_profile(domain, json)           │
└─────────────────────────────────────────────────────────────────┘
         │                      │                       │
         ▼                      ▼                       ▼
   output/pages/           schema.py              output/structured/
   output/sites/           db_reference.py

Project Structure

mcp-webscraper/
├── MCP_server/
│   ├── server.py           # MCP entry — 9 tools (scrape + extraction)
│   ├── models/
│   └── utils/
│       └── web_scraper.py  # Scraper (static, Playwright, pdfplumber)
├── schema.py               # SchoolProfile, EXTRACTION_TEMPLATE, FIELD_URL_HINTS
├── db_reference.py         # WHED DB — picklists, reference examples, ground truth
├── run_scraper.py          # Standalone CLI — schema-driven crawl, PDF extraction
├── docs/
│   ├── USAGE_GUIDE.md      # Architecture, flow, outputs, comparison
│   ├── PROJECT_ITERATIONS.md
│   └── MCP_VS_N8N_COMPARISON.md
└── output/
    ├── pages/              # Per-page cache from crawl
    ├── sites/              # Combined site crawl
    ├── structured/         # MCP extraction output
    ├── ground_truth/       # WHED DB exports
    └── stages/             # Human review staging

Prerequisites

  • Python 3.10+

  • uv package manager

  • Cursor (for MCP usage)

  • MySQL with WHED database (optional — for DB grounding and comparison)


Installation

git clone https://github.com/your-username/mcp-webscraper.git
cd mcp-webscraper
uv sync
uv run playwright install chromium

Copy .env.example to .env and add WHED DB credentials (if available).

Connect MCP to Cursor

Add to .cursor/mcp.json:

{
  "mcpServers": {
    "whed-tools": {
      "command": "uv",
      "args": [
        "run",
        "--directory",
        "/path/to/mcp-webscraper",
        "python",
        "MCP_server/server.py"
      ]
    }
  }
}

MCP Tools (whed-tools)

Tool

Description

scrape_url

Fetch HTML from a URL

extract_data

Extract by CSS selector

extract_first

First matching element

batch_scrape

Multiple URLs

crawl_website

Discover and crawl site (schema_filter=True to skip irrelevant pages)

extract_pdf_text

Download a PDF and extract its text content

get_extraction_schema

WHED field template (REQUIRED only)

get_db_context

Picklists + reference example for domain

validate_profile

Pydantic + DB picklist validation

save_profile

Save profile to output/structured/

Example prompt

"Crawl https://www.example.edu and extract a WHED profile. Use get_extraction_schema and get_db_context, then validate and save."


Standalone Scripts

Scrape (schema-driven, with PDFs)

Edit run_scraper.py (TARGET_URL, MODE, etc.), then:

uv run python run_scraper.py
  • Uses schema.FIELD_URL_HINTS to follow only relevant URLs

  • Extracts text from PDFs via pdfplumber


Schema & DB Grounding

  • REQUIRED fields are in EXTRACTION_TEMPLATE; DEFERRED fields are in Pydantic but not prompted.

  • With WHED DB: picklists, few-shot examples, and post-validation reduce hallucination.

  • Edit schema.py to add or reactivate fields.


Documentation

Doc

Content

USAGE_GUIDE.md

Architecture, flow, and outputs

PROJECT_ITERATIONS.md

Evolution from Ollama to MCP-native

MCP_VS_N8N_COMPARISON.md

KPI comparison with N8N + Firecrawl


License

MIT — based on samirsaci/mcp-webscraper.

Available Tools

10 tools
batch_scrapeA
Scrape multiple URLs efficiently.

Args:
    urls: List of URLs to scrape
    javascript: Set to True if the sites need JavaScript rendering
    save_path: Optional file path to save all results as a JSON array (e.g. "C:/Users/me/Desktop/batch.json").
               If a directory is given, a timestamped filename is generated automatically.

Returns:
    List of scraping results for each URL

Inputs: urls (required), save_path, javascript. Returns: result

crawl_websiteA
Crawl a website to discover its structure and pages.

Args:
    start_url: Starting URL
    max_pages: Maximum pages to crawl (default 50)
    max_depth: Maximum link depth (default 3)
    same_domain_only: Stay on same domain (default True)
    schema_filter: When True, only follow URLs whose path contains keywords
                   relevant to the WHED schema (about, contact, course, program,
                   faculty, etc.). Skips login pages, media, and unrelated content.
                   Recommended for institution websites.
    save_path: Optional file path to save the site map as JSON (e.g. "C:/Users/me/Desktop/sitemap.json").
               If a directory is given, a timestamped filename is generated automatically.

Returns:
    Site map with discovered pages and statistics

Inputs: start_url (required), max_depth, max_pages, save_path, +2 more. Returns: result

extract_dataA
Scrape a webpage and extract specific data using CSS selectors.

Args:
    url: The webpage to scrape
    css_selectors: List of CSS selectors (e.g., ["h1", "a.link", "#content"])
    attributes: List of attributes to extract for each selector (e.g., ["text", "href", "text"])
               If not provided, defaults to "text" for all selectors
    javascript: Set to True for JavaScript-rendered sites
    save_path: Optional file path to save the result as JSON (e.g. "C:/Users/me/Desktop/result.json").
               If a directory is given, a timestamped filename is generated automatically.

Returns:
    Dictionary with extracted data for each selector

Example:
    extract_data(
        url="https://example.com",
        css_selectors=["h1", "a"],
        attributes=["text", "href"]
    )

Inputs: url (required), css_selectors (required), save_path, attributes, +1 more. Returns: result

extract_firstA
Extract the first matching element from a webpage.
Useful for getting single values like page title, main heading, etc.

Args:
    url: The webpage to scrape
    css_selector: CSS selector for the element (e.g., "h1", "title", "meta[name='description']")
    attribute: What to extract - "text" for content, or attribute name like "href", "content", "src"
    javascript: Set to True for JavaScript-rendered sites
    save_path: Optional file path to save the result as JSON (e.g. "C:/Users/me/Desktop/result.json").
               If a directory is given, a timestamped filename is generated automatically.

Returns:
    Dictionary with the extracted value

Example:
    extract_first(url="https://example.com", css_selector="title", attribute="text")

Inputs: url (required), css_selector (required), attribute, save_path, +1 more. Returns: result

extract_pdf_textA
Download a PDF and extract its text content using pdfplumber.
Useful for reading course handbooks, academic calendars, prospectuses,
and other PDF documents discovered during crawling.

Args:
    url: Direct URL to a PDF file
    max_size_mb: Skip PDFs larger than this (default 5 MB)
    max_chars: Cap extracted text length (default 30000 chars)

Returns:
    Dictionary with extracted text, page count, and character count.
    Returns success=False if the PDF is too large, image-based, or unreadable.

Inputs: url (required), max_chars, max_size_mb. Returns: result

get_db_contextA
Return WHED database reference data for a given institution domain.

Provides two types of grounding to reduce hallucination:
  1. Picklists — valid enum values (institution types, funding, divisions, etc.)
  2. Reference example — a complete record from the same country

Args:
    domain: Institution website domain (e.g. 'www.ampa.edu.au')

Returns:
    Dictionary with picklists, country code, and a reference example

Inputs: domain (required). Returns: result

get_extraction_schemaA
Return the WHED extraction schema (REQUIRED fields only).

The host LLM should use this template to know which fields to extract
from scraped website content. Each field includes its type and priority.

Typical workflow:
  1. crawl_website / scrape_url  → get site content
  2. get_extraction_schema       → know what to extract
  3. get_db_context(domain)      → get allowed values & reference example
  4. (Host LLM extracts data)
  5. validate_profile(json)      → check the extraction
  6. save_profile(domain, json)  → persist the result

Inputs: no named parameters. Returns: result

save_profileA
Save a validated institution profile to disk as JSON.

Args:
    domain: Institution domain (e.g. 'www.ampa.edu.au'), used as filename
    profile_json: JSON string of the profile to save
    output_dir: Directory to save into (default: output/structured)

Returns:
    Dictionary with save status and file path

Inputs: domain (required), profile_json (required), output_dir. Returns: result

scrape_urlA
Scrape a webpage and return its HTML content.

Args:
    url: The webpage URL to scrape
    javascript: Set to True for JavaScript-rendered sites (slower but handles dynamic content)
    wait_seconds: How long to wait for JavaScript to load (only used when javascript=True)
    save_path: Optional file path to save the result as JSON (e.g. "C:/Users/me/Desktop/result.json").
               If a directory is given, a timestamped filename is generated automatically.

Returns:
    Dictionary with html content, status code, and load time

Inputs: url (required), save_path, javascript, wait_seconds. Returns: result

validate_profileA
Validate an extracted institution profile against the Pydantic schema
and WHED database picklists.

Args:
    profile_json: JSON string of the extracted profile
                  (must match the structure from get_extraction_schema)

Returns:
    Dictionary with validation status, cleaned data, and any warnings

Inputs: profile_json (required). Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 10 tools

    Disambiguation4/5

    Most tools target distinct stages or actions: raw scraping, multi-selector extraction, single-element extraction, batch scraping, and crawling. Some overlap remains among the scraping tools, but descriptions clarify boundaries well enough for an agent to choose correctly.

    Naming Consistency5/5

    All tool names use snake_case and are action-oriented. The verb_noun pattern is consistent throughout, with only minor modifiers like batch_scrape and extract_first remaining readable and predictable.

    Tool Count5/5

    Ten tools is well-scoped for a scraping, extraction, validation, and persistence pipeline. Each tool has a clear role and the set avoids unnecessary redundancy.

    Completeness4/5

    The surface covers content acquisition via scraping, crawling, and PDF extraction, plus schema guidance, database context, validation, and saving. It lacks explicit retrieval or update operations for saved profiles, but the core WHED extraction workflow is otherwise complete.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      A general-purpose MCP server for crawling and extracting structured data from any website. Supports tools for crawling, single-page extraction, search-and-crawl, and schema extraction.
      2
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      An agent-agnostic web extraction and fetch layer that turns URLs into verified, typed data with confidence scores via MCP, REST, or SDK, orchestrating scraping engines behind a resilience ladder and supporting structured extraction against any schema.
      5
      3
      Apache 2.0
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables users to build, run, and repair deterministic web scrapers through MCP tools, and to fetch scraped data without needing a model at runtime.
      45 npm
      Apache 2.0
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables turning any website into a self-healing, typed JSON API with parameterized lookups, automatic drift detection/healing, and MCP-native exposure of sources as typed lookup tools.
      4
      MIT