Skip to main content
Glama
fix-a-lot

crawl4ai-local-for-windows

by fix-a-lot

Crawl4ai Local for Windows

ν•œκ΅­μ–΄ | English

Local MCP server for Crawl4ai on Windows. Runs directly on Windows without WSL.

πŸ€– Most of the code was generated with AI assistance.

See also:

Requirements

  • uv

  • Python 3.14 (installed automatically via uv)

Related MCP server: crawl4ai-mcp-server

Installation

uv sync

Running

🚨 This server is a stdio server β€” no need to keep it running like a network server. When connected to an agent as MCP, the agent automatically spins up the server instance.

# Check for the "πŸš€ Crawl4ai MCP server started." message, then exit
uv run main

βœ… After confirming the welcome message, press Ctrl+C to exit, then add the MCP to your agent.

# Tip: debugging mode (MCP Inspector)
uv run mcp dev src/crawl4ai_local_for_windows/server.py

Adding MCP to an Agent

Claude Code

claude mcp add --transport stdio --scope user crawl4ai -- uv run --directory <parent_location>/crawl4ai-local-for-windows main
  • parent_location: Write it like C:/dev/repo

  • e.g. claude mcp add --transport stdio --scope user crawl4ai -- uv run --directory C:/dev/repo/crawl4ai-local-for-windows main

# Check MCP installation
claude mcp list
claude mcp get crawl4ai

Hermes Agent

hermes mcp add crawl4ai --command "uv" --args "run" "--directory" "<parent_location>/crawl4ai-local-for-windows" "main"
  • parent_location: Write it like C:/dev/repo

  • e.g. C:/dev/repo/crawl4ai-local-for-windows

# Check MCP installation
hermes mcp list

Tools

crawl_markdown(url, wait_seconds=0, wait_selector="")

Crawl a URL and return the content as Markdown.

crawl_structured(url, selector, fields, wait_seconds=0, wait_selector="")

Extract repeated elements as JSON using CSS selectors.

crawl_structured(
    url="https://books.toscrape.com/",
    selector="article.product_pod",
    fields={"제λͺ©": "h3@title", "가격": ".price_color:text"},
)
# β†’ [{"제λͺ©": "A Light in the Attic", "가격": "Β£51.77"}, ...]

Field spec syntax:

Spec

Meaning

"td" or "td:text"

Text of the matched element

"a@href"

Attribute of a child element (element@attribute)

"@data-value"

Attribute of the base element itself

"td:nth-of-type(1)"

Nth element β€” use standard CSS (:eq() is not supported)

Both tools share the waiting options (see below).

crawl_screenshot(url, output_path)

Capture a full-page screenshot and save it to a file. Parent directories are created automatically.

πŸ›‘οΈ output_path is checked against a blocklist of known Windows system directories (C:\Windows, C:\Program Files, C:\Program Files (x86), C:\ProgramData, C:\System Volume Information, C:\$Recycle.Bin, C:\Users\All Users, C:\Users\Default) before the crawl even runs. A path that resolves into one of these (including via .. traversal) is rejected with an error message, so an agent can't accidentally overwrite system files. This is a blocklist, not a full sandbox β€” it guards against mistakes, not a determined attacker.

Browser Reuse & Crash Recovery

Instead of launching Chromium on every call (which is expensive), the server keeps one browser instance for the process lifetime. If the shared browser crashes mid-session, the server detects it and recovers automatically:

  • Crash detection matches Playwright collapse signatures only β€” Target page, context or browser has been closed, browser has crashed, browsertype.launch failures, etc. Network errors, anti-bot blocks, and timeouts are page-side causes and are never retried with a fresh browser.

  • On crash: dispose the dead instance β†’ launch a new one β†’ retry, up to _MAX_RECREATE_ATTEMPTS = 2 attempts.

  • Both failure paths are checked equally on every attempt: exceptions raised by arun() and result.success=False + crash message in error_message.

  • On the last attempt, a crash is still reported as a failure, but the crawler is not reset again β€” that cleanup already happened on the prior attempt, and resetting a second time could tear down an instance a concurrent request just recreated.

  • Preventive recycling (e.g., refresh every N pages) is intentionally left to Crawl4ai's built-in browser recycling; the server only reacts to actual collapses.

Concurrency note: multiple simultaneous arun() calls on the shared crawler are safe β€” Crawl4ai serializes page creation internally (_page_lock, GH-1198 fix) and manages context lifecycle with refcounting + LRU. Verified with concurrent multi-site smoke tests.

Waiting Options (Dynamic Pages)

For dynamic pages that render content late using JS, use the waiting options of crawl_markdown / crawl_structured.

# Method 1: Wait for a fixed duration (seconds)
crawl_markdown(url="https://example.com", wait_seconds=5)

# Method 2: Wait until a CSS selector appears (takes precedence over wait_seconds when specified)
crawl_markdown(url="https://example.com", wait_selector="div.result-list")

Verification Results (2026-08-25)

Comparison of 3 cases on a local test page that updates content via JS after 3 seconds:

Case

success

Captures Dynamic Content

No waiting option

True

❌ Returns only "Loading..."

wait_seconds=5

True

βœ… Accurately captures final content

wait_selector="#dynamic"

True

❌ Passes immediately if the element already exists in the initial HTML

Findings / Cautions

  1. wait_selector is only valid for "newly created elements." If the text of an element already present in the initial HTML (e.g., <article id="dynamic">Loading...</article>) changes later, the selector matches immediately and passes without waiting. For pages that update text dynamically, use wait_seconds.

  2. Extreme pages trigger anti-bot heuristics. Pages with minimal content and many script tags are flagged by Crawl4ai's anti-bot detector as Blocked by anti-bot protection: Structural: no_content_elements, script_heavy_shell, resulting in success=False. Although rare in production pages, testing should be done on pages containing basic static content (navigation bars, paragraphs, etc.).

Available Tools

2 tools
crawl_markdownB

μ£Όμ–΄μ§„ URL을 ν¬λ‘€λ§ν•΄μ„œ λ§ˆν¬λ‹€μš΄μœΌλ‘œ λ°˜ν™˜ν•œλ‹€.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must carry the full disclosure burden. It mentions crawling and markdown output but does not reveal network side effects, rate limits, following redirects, failure modes (unreachable URLs, non-HTML content), or whether it executes JavaScript. This leaves important behavioral traits undisclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, concise sentence fully states the action, the object, and the return format. There is no wasted text or irrelevant detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter tool this is minimally viable, but it lacks context about the expected markdown structure (full page vs filtered content), input URL restrictions, or output schema-level details beyond what the output schema likely provides. The existence of a sibling tool also suggests usage guidance would have made the description more complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has one `url` parameter with 0% description coverage. The description references 'given URL' but adds no extra meaning beyond the obvious fact that `url` is the input. Since the parameter is self-explanatory, this is adequate but adds little beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('crawl') on a specific resource (the given URL) and a clear output format (markdown). This naturally distinguishes it from the sibling tool 'crawl_screenshot', so an agent can immediately tell the two apart.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance about when to use this tool versus crawl_screenshot or any other alternative. The description only states what it does, not the conditions under which an agent should prefer it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

crawl_screenshotB

μŠ€ν¬λ¦°μƒ·μ„ 찍어 파일둜 μ €μž₯ν•œλ‹€.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes
output_pathYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It only states that a screenshot is saved to a file; it does not disclose overwrite behavior, file format, URL rendering expectations, or any side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single clear sentence with no filler. It is appropriately sized for a simple tool and states the core action upfront.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has only two required parameters and an output schema, so complexity is low. Still, with no annotations and no sibling comparison, the description leaves the agent to infer important operational details such as URL validity and output handling.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description should clarify the parameters. It does not explicitly explain that 'url' is the page to screenshot or that 'output_path' is the destination file, though the phrase 'saves to a file' hints at the latter. This is minimal but not nonexistent.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool takes a screenshot and saves it to a file. It names a specific verb ('screenshot') and resource (file output), making it easy to distinguish from the sibling crawl_markdown, which presumably produces markdown instead.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to use this tool versus crawl_markdown, or what requirements exist (e.g., valid URL, writable path). Usage must be inferred entirely from the tool name and terse description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

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

  1. 2 tool updatesv0.1.0
    • First observedcrawl_markdown
    • First observedcrawl_screenshot

TDQS

A3.6/5.0

Scored across 2 tools

Disambiguation5/5

The two tools are clearly distinct: one returns markdown content, the other saves a screenshot. There is no overlap in their purposes or outputs.

Naming Consistency5/5

Both tools follow the same verb_noun pattern with the 'crawl_' prefix, making the naming entirely predictable and consistent.

Tool Count4/5

With only two tools, the server is slightly under the typical 3-15 range, but the minimal set is reasonable for a focused crawler that only offers markdown and screenshot output.

Completeness3/5

The core crawling workflow is covered, but there are noticeable gaps such as raw HTML output, link extraction, or crawling options like depth or custom selectors. Agents may need to work around these missing capabilities.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    A locally-hosted MCP server that provides AI assistants with advanced web crawling capabilities, including structured data extraction, deep site crawling, and page screenshots. It enables users to convert single or multiple URLs into clean Markdown content for processing by LLMs without requiring external API keys for basic features.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    A lightweight MCP server that exposes Crawl4AI web scraping and crawling capabilities as tools for AI agents, enabling single-page scraping and multi-page crawling with adaptive stopping.
    108
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server for web scraping and browser automation, enabling AI agents to extract clean, token-efficient content from web pages.
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A local, dependency-free MCP server that gives AI agents controlled access to the active Windows desktop, enabling automated interaction with applications through screenshots, clicks, typing, and window management.
    54
    MIT