whed-tools
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@whed-tools Extract WHED profile from https://harvard.edu"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 |
Extract | Host LLM reads scraped content, uses |
Validate |
|
Save |
|
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.pyProject 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 stagingPrerequisites
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 chromiumCopy .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 |
| Fetch HTML from a URL |
| Extract by CSS selector |
| First matching element |
| Multiple URLs |
| Discover and crawl site ( |
| Download a PDF and extract its text content |
| WHED field template (REQUIRED only) |
| Picklists + reference example for domain |
| Pydantic + DB picklist validation |
| Save profile to |
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.pyUses
schema.FIELD_URL_HINTSto follow only relevant URLsExtracts 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.pyto add or reactivate fields.
Documentation
Doc | Content |
Architecture, flow, and outputs | |
Evolution from Ollama to MCP-native | |
KPI comparison with N8N + Firecrawl |
License
MIT — based on samirsaci/mcp-webscraper.
Available Tools
10 toolsbatch_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
Scored across 10 tools
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.
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.
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.
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
Related MCP Connectors
Unified social scraper MCP — profiles, posts, videos across ~40 platforms via Streamable HTTP.
Web extraction MCP: page content, metadata, articles, contacts, email checks, URL probes.
Web scraping, extraction and search for AI agents. Hosted MCP with workspace API keys.
Citations, abstracts, PDFs, as one MCP tool through Apify
1
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA 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.2MIT
- AlicenseAqualityDmaintenanceAn 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.53Apache 2.0
- AlicenseNot gradedqualityBmaintenanceEnables users to build, run, and repair deterministic web scrapers through MCP tools, and to fetch scraped data without needing a model at runtime.45 npmApache 2.0
- AlicenseNot gradedqualityBmaintenanceEnables 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.4MIT