Web Retrieve Plugin
The Web Retrieve Plugin provides a web_retrieve tool that allows agents to fetch and analyze content from web URLs, with optional agentic processing for complex information extraction tasks.
Overview
The Web Retrieve plugin:
- Registers a
web_retrievetool for fetching web content - Operates in two modes: simple (direct fetch) and agentic (subagent processing)
- Pre-fetches content before spawning subagents to minimize tool call overhead
- Supports HTML (converted to text) and plain text content types
- Provides context management with configurable limits
Architecture
The plugin uses a layered architecture:
Main Agent
│
▼
┌─────────────────────────────────────────┐
│ web_retrieve(urls, prompt?) │
│ - Simple mode: returns content directly │
│ - Agentic mode: pre-fetches, spawns │
│ subagent with content + fetch_urls │
└────────────────────┬────────────────────┘
│ (if prompt provided)
▼
┌────────────────────┐
│ Subagent │
│ - Pre-fetched data │
│ - fetch_urls tool │
│ (with seeking) │
└────────────────────┘
Key design decisions:
- The main agent sees only
web_retrieve(single tool interface) - The subagent has
fetch_urlswith seeking support for paginating large content - Content is pre-fetched before subagent creation to avoid initial tool call
- Truncated content in simple mode suggests using agentic mode
Configuration
Basic Configuration
plugins:
- module: codumentor.plugins.webretrieve
class: WebRetrievePlugin
args:
enabled: true
timeout: 30 # Request timeout in seconds
max_urls: 5 # Maximum URLs per request
max_chars_per_url: 30000 # Maximum characters per URL
max_content_length: 500000 # Maximum raw content in bytes
target_agents: "main" # Only main agent gets this tool
Configuration with JavaScript Rendering
For sites that load content dynamically with JavaScript, configure js_rendering_mode:
plugins:
- module: codumentor.plugins.webretrieve
class: WebRetrievePlugin
args:
enabled: true
js_rendering_mode: "default" # JS rendering ON by default, agent can disable
timeout: 60 # Longer timeout for JS rendering
target_agents: "main"
JavaScript Rendering Modes
| Mode | Description | Tool Schema |
|---|---|---|
default | JS rendering ON by default, agent can disable per-call | Shows render_js parameter with default: true |
optional | JS rendering OFF by default, agent can enable per-call | Shows render_js parameter with default: false |
disabled | Never use JavaScript rendering | No render_js parameter shown |
When to use each mode:
default(recommended): Best for most use cases. Ensures JS-rendered content is always available by default, but allows the agent to disable JS rendering for faster fetching of static pages.optional: When you want JS rendering off by default, but allow the agent to enable it. Shows hints when content appears incomplete. May cause retry overhead.disabled: When JavaScript rendering is not needed or performance is critical.
Note: JavaScript rendering requires Playwright to be installed:
# Using pip:
pip install playwright
playwright install chromium
playwright install-deps chromium # Install system dependencies (may require sudo)
# Using uv:
uv pip install playwright
uv run playwright install chromium
uv run playwright install-deps chromium # Install system dependencies (may require sudo)
If js_rendering_mode is not disabled but Playwright is not installed, the plugin will:
- Log an error-level message with installation instructions
- Fall back to
js_rendering_mode="disabled" - The
render_jsparameter will not appear in the tool schema
Legacy support: The deprecated enable_js_rendering parameter is still supported:
enable_js_rendering: truemaps tojs_rendering_mode: "optional"enable_js_rendering: falsemaps tojs_rendering_mode: "disabled"
User Settings
Users can override the plugin's default js_rendering_mode via the Settings dialog in the UI (under "Extensions"). The user setting takes precedence over the plugin configuration.
Settings UI:
- Navigate to Settings → Extensions → Web Retrieve
- Select JavaScript Rendering mode: Default, Optional, or Disabled
How it works:
- Plugin configuration sets the default
js_rendering_mode - User's personal setting (if set) overrides the plugin default
- If neither is set and Playwright is available, defaults to
"default"
This allows administrators to set a sensible default while giving users control over their own experience.
Configuration Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable/disable the plugin |
timeout | integer | 30 | Request timeout in seconds |
max_urls | integer | 5 | Maximum number of URLs per request |
max_chars_per_url | integer | 30000 | Maximum characters returned per URL |
max_content_length | integer | 500000 | Maximum raw content per URL in bytes |
target_agents | string | "main" | Which agents get the tool: "main", "subagent", or "all" |
js_rendering_mode | string | "default" | JavaScript rendering mode: "default", "optional", or "disabled" |
enable_js_rendering | boolean | - | Deprecated. Use js_rendering_mode instead |
Tool Usage
Main Tool: web_retrieve
The web_retrieve tool provides these parameters:
- urls (required): One or more URLs to fetch
- Can be a single URL string or array of URLs
- Maximum:
max_urls(default: 5)
- prompt (optional): Task or question for processing the content
- If provided: spawns a subagent for intelligent content analysis
- If omitted: returns raw fetched content (simple mode)
- render_js (optional, when
js_rendering_modeis"default"or"optional"): Render JavaScript with headless browser - When
js_rendering_mode="default":trueby default; set tofalseto disable for faster static page fetching - When
js_rendering_mode="optional":falseby default; set totrueto enable for dynamic pages - Note: When
js_rendering_mode="disabled", this parameter is not available.
Subagent Tool: fetch_urls
The subagent has access to fetch_urls with additional parameters:
- urls (required): URLs to fetch
- offset (optional): Character offset to start reading (default: 0)
- limit (optional): Maximum characters to return
Modes of Operation
Simple Mode (no prompt)
When called without a prompt, the tool:
- Fetches the specified URLs concurrently
- Extracts text from HTML using html2text
- Returns content with truncation metadata
- Adds a note suggesting agentic mode if content was truncated
web_retrieve(urls="https://example.com/docs")
Output example:
## https://example.com/docs
*Showing first 30000 of 85000 characters*
[Content here...]
---
*Note: Some content was truncated. To extract specific information from
these pages, call web_retrieve again with a `prompt` parameter describing
what you need to find.*
Agentic Mode (with prompt)
When called with a prompt, the tool:
- Pre-fetches all URLs before spawning the subagent
- Creates a subagent with the pre-fetched content in its initial message
- Provides the subagent with
fetch_urlstool for follow-up fetches - The subagent analyzes content and completes the requested task
web_retrieve(
urls="https://example.com/pricing",
prompt="Find the pricing tiers and summarize the features of each tier"
)
The subagent can:
- Analyze the pre-fetched content immediately (no initial tool call needed)
- Use
fetch_urlswith offset/limit to read more of truncated content - Fetch additional URLs discovered in the content
Examples
Example 1: Quick Content Preview
Fetch a page to see what's there:
web_retrieve(urls="https://docs.python.org/3/library/asyncio.html")
Example 2: Extract Specific Information
When you need specific information from a page:
web_retrieve(
urls="https://docs.python.org/3/library/asyncio.html",
prompt="List all the main asyncio functions for running coroutines and their brief descriptions"
)
Example 3: Multi-Page Research
Research across multiple pages:
web_retrieve(
urls=["https://example.com/features", "https://example.com/pricing"],
prompt="Compare the features available in each pricing tier"
)
Example 4: Following Links
When you need the subagent to follow links:
web_retrieve(
urls="https://example.com/documentation",
prompt="Find the API authentication documentation and explain the OAuth2 flow"
)
The subagent can use fetch_urls to retrieve linked pages discovered in the initial content.
How It Works
Content Extraction
- HTML pages: Converted to markdown/text using html2text - Links are preserved - Images are ignored - Script and style tags are removed
- Plain text: Returned as-is
- Other content types: Rejected with error message
Context Management
The plugin implements several limits to manage context size:
- URL count limit (
max_urls): Limits concurrent fetches - Character limit (
max_chars_per_url): Truncates long content - Byte limit (
max_content_length): Limits raw HTTP response size
Pre-fetching Strategy
In agentic mode, URLs are pre-fetched before creating the subagent:
- All URLs are fetched concurrently
- Content is truncated per configured limits
- Truncation metadata is included
- Content is embedded in the subagent's initial prompt
- Subagent can immediately analyze without making tool calls
This reduces latency and token usage compared to having the subagent fetch content via tool calls.
Content Quality Detection
The plugin includes intelligent detection of potentially incomplete content, which is common with JavaScript-heavy websites:
- JavaScript Framework Detection: The raw HTML is analyzed for common framework indicators: - Next.js (
__NEXT_DATA__) - React (data-reactroot,_reactRootContainer) - Vue (data-v-attributes) - Angular (ng-version,ng-app) - Nuxt (__NUXT__) - Svelte (data-svelte) - Astro (data-astro)
- Content Quality Heuristics: Content is flagged as potentially incomplete when: - Extracted text is very short (< 200 characters) - Extraction ratio is very low (< 5% of raw HTML converted to text) - JavaScript frameworks are detected and extracted text is short (< 500 characters)
- Automatic Hints (only when
js_rendering_mode="optional"): When content may be incomplete, the tool adds a note to the output: ``Note: Content may be incomplete. JavaScript frameworks detected: Next.js, React. Consider using render_js=true for JavaScript-rendered pages.``
Note: Hints only appear when js_rendering_mode="optional" because:
- In
defaultmode, JS rendering is already enabled by default - In
disabledmode, the agent cannot enable JS rendering
This helps agents understand when they should retry with JavaScript rendering enabled.
Error Handling
The plugin handles various error scenarios:
- Invalid URL scheme: Only
httpandhttpsare supported - Network errors: Reported with specific error message
- Timeout: Configurable timeout with clear error message
- Unsupported content type: Returns error for non-text content
- Encoding issues: Falls back to UTF-8 with replacement characters
- Too many URLs: Returns error if URL count exceeds limit
Security
- URL validation: Only http/https schemes are allowed
- Redirect limits: Maximum 5 redirects followed
- Content size limits: Configurable limits prevent memory issues
- No file:// URLs: Local file access is not permitted
Caching
The plugin includes an automatic URL cache to improve performance and consistency:
- Cache TTL: Successful fetches are cached for 5 minutes
- Consistency: When the same URL is fetched multiple times (e.g., in simple mode then agentic mode, or when a subagent re-fetches), the cached content is returned
- Rate limiting mitigation: Caching helps avoid rate limiting issues from websites that detect repeated requests
- Scope: The cache is global across all tool instances in the same process
The cache is automatically managed and requires no configuration. To force a fresh fetch (bypassing cache), use the programmatic API with use_cache=False.
Troubleshooting
Content Not Extracted Properly
- Check content type: Only text/html and text/* are supported
- Try html2text: Install it for better HTML conversion:
pip install html2text - Check encoding: Site may use unusual encoding
Timeout Errors
- Increase timeout: Set
timeouthigher in plugin config - Check network: Verify URL is accessible
- Try fewer URLs: Reduce concurrent URL count
Truncated Content
- Use agentic mode: Add a
promptto enable subagent with seeking - Increase limits: Adjust
max_chars_per_urlif needed - Be specific: Describe exactly what you need in the prompt
Subagent Not Finding Information
- Check pre-fetched content: The content might be on a linked page
- Guide the subagent: Be specific about what to look for
- Provide context: Mention where on the page the information might be
Testing
Run the plugin tests with:
python -m unittest tests.test_web_retrieve_plugin -v
See Also
- Plugin Development Guide - Create custom plugins
- MCP Plugin - Alternative for integrating external tools
- Agentic Memory Plugin - Store retrieved information for future use