A Python-based MCP server providing HTML DOM querying and automation capabilities without external dependencies
This server has a single tool 'find_nodes' with a basic implementation and significant quality gaps. The tool name lacks a proper action verb (should be 'search_nodes' or 'extract_nodes'), the description is minimal but present, and the input schema is visible but lacks proper JSON Schema type declarations. The tool performs only HTML string matching without proper DOM parsing, making it fragile for real-world use. No output schema is documented, no error handling is present, and the implementation exposes the internal architecture (simple regex-like search) rather than providing an abstraction. The server lacks any of the quality patterns expected in production-grade agent tools.
Simple simulated tag grabber that finds HTML nodes matching a query selector and extracts their inner text content
Tool name 'find_nodes' does not start with a strong action verb. 'find' is acceptable but ambiguous, 'search_nodes', 'extract_nodes', or 'query_html_nodes' would be clearer. LLMs may confuse this with other node-finding tools.
Input schema is visible in the Python code (raw_html_body and query_selector parameters with descriptions) but lacks explicit JSON Schema type declarations. Parameters are documented as strings with descriptions, but no formal JSON Schema 'type' field is visible in a schema object definition. This means the tool definition is inferred from Python annotations rather than explicitly registered with proper MCP schema.
No documented output schema. The code returns {'matched_nodes_text': nodes}, but there is no schema definition stating that the return value is an object with a 'matched_nodes_text' field containing an array of strings. LLMs cannot predict the structure without explicit documentation.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 31 | 2026-07-28+ | v2 |
No error handling or recovery guidance. The implementation uses string.find() and naive substring extraction, which will fail silently or return incorrect results on malformed HTML (e.g., nested tags, attributes with '>' characters, self-closing tags). No error response tells the LLM what to do if extraction fails.
Parameter 'query_selector' description says it accepts 'CSS query selector' but the implementation does not actually parse CSS selectors, it only strips whitespace and '#' characters and does a simple tag name match. Class selectors (e.g., '.myclass') and ID selectors (e.g., '#myid') are not properly supported. The description misleads about what the tool can do.
Tool description is superficial: 'Simple simulated tag grabber that finds HTML nodes matching a query selector and extracts their inner text content'. The word 'simulated' signals this is not a real HTML parser. No guidance on when to use this tool, what limitations it has, or what format the HTML must be in.
No input validation. The code does not validate that raw_html_body is valid HTML, that query_selector is a valid format, or that parameters are non-empty. An LLM can pass null, very large strings, or malicious payloads without feedback.
No pagination or result limiting. If raw_html_body contains thousands of matching tags, the matched_nodes_text array will be huge, consuming tokens and potentially causing context window overruns. No way to limit results or paginate.
Tool registration and MCP server framework unknown. The source shows only a Python class definition and example usage, but no explicit MCP server registration code, no transport layer (STDIO, HTTP, SSE), and no MCP message handlers visible. Cannot determine if this is a proper MCP server at all.