TypeScript Model Context Protocol (MCP) server for ReviewWebsite. Includes CLI support and extensible structure for connecting AI systems (LLMs) to ReviewWebsite API
Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
ReviewWebsite MCP server provides 16 web scraping and SEO analysis tools with consistent schema structure and descriptions. All tools have documented input schemas with proper types and parameter descriptions. However, descriptions are formulaic and generic ('MCP Tool handler to...'), output schemas are not documented, and error handling lacks recovery guidance. No tool annotations (readOnlyHint, destructiveHint) despite all tools being read-only. Parameter descriptions meet minimum standards but lack actionable format constraints (enums where applicable, ranges for numeric values). Tool naming follows verb_noun convention and is clear, but no explicit guidance on when to use one tool vs. similar alternatives (e.g., convert_to_markdown vs. convert_multiple_to_markdown). No field naming mismatches detected, but response structure is not documented in source code.
Generic, formulaic tool descriptions lack LLM-optimized context. All 16 tools use boilerplate pattern 'MCP Tool handler to [action]' without explaining WHEN to use each tool, prerequisites, or when it should be chosen over similar tools (e.g., convert_to_markdown vs. convert_multiple_to_markdown, or summarize_url vs. summarize_website). Descriptions range 30-73 characters, within acceptable bounds, but provide minimal actionable guidance.
Output schemas not documented. Tool handler code in src/tools/reviewwebsite.tool.ts shows tools returning {content: [{type: 'text', text: string}]} for error cases via formatErrorForMcpTool(), but no documentation of successful response schemas for any tool. LLMs cannot plan downstream tool calls or data extraction without knowing what fields are returned. This violates the baseline that 100% of A+ tools have documented return types.
Recommendations
Rewrite tool descriptions to follow LLM-optimized pattern: [What] [When to use] [Key outputs]. Example: 'Convert a URL to Markdown using AI-powered content extraction. Use when you need readable, structured text from web pages. Returns: markdown_content, metadata, extraction_confidence.' Target 80-150 characters.
Document output schemas for all 16 tools. Add a 'Returns' section in each tool handler docstring specifying field names, types, and meaning. Example: 'Returns: {content: string (markdown), metadata: {title, url, author}, confidence: number (0-1)}'.
Remove api_key from all tool parameters. Move to server-side secret injection: read from process.env.REVIEWWEBSITE_API_KEY in the controller, not from tool args. Update tool parameter schemas to remove api_key entirely. Redact api_key in debug logging (code already does this, extend to parameter serialization).
Add tool annotations to all tools via @readOnlyHint since all are read-only. Syntax: annotate each tool with readOnlyHint=true when registering with the MCP SDK. This signals to agents that these tools are safe for unlimited retries.
Enhance parameter descriptions with actionable constraints. Replace 'AI model to use for conversion' with 'AI model (e.g., gpt-4, gpt-4-turbo, claude-3-opus, consult ReviewWebsite docs for current options)'. Replace 'Country code (default: us)' with 'Country code in ISO 3166-1 alpha-2 format (e.g., us, uk, de; default: us)'.
Add recovery guidance to error responses. Update formatErrorForMcpTool() to categorize errors: retryable (network timeouts → 'Retry in a moment'), user-fixable (invalid URL → 'Verify the URL is accessible'), or fatal (auth error → 'Check your API key and permissions'). Enrich errors with the invalid value and constraint violated.
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
Missing tool annotations despite all tools being read-only operations. No readOnlyHint, destructiveHint, or idempotentHint annotations visible in tool registration. Current spec (2026-07-28) supports tool annotations to signal operation safety to LLMs and agents. This is a current pattern that should be adopted.
Parameter descriptions lack actionable constraints. Many parameters (e.g., model, country, searchEngine) accept constrained values but descriptions provide no enum constraints, examples, or valid ranges in the description text. E.g., 'AI model to use for conversion' does not list which models are supported. 'Country code (default: us)' does not specify format (ISO 3166-1 alpha-2?) or list valid options. Format constraints must be in descriptions since LLMs do not reliably read JSON Schema pattern fields.
API key exposed as tool parameter in all 16 tools. Every tool accepts 'api_key' as a parameter. This is a critical security violation: credentials must never appear as tool parameters. Agent traces log every parameter, secrets in params leak into logs and prompt history. Should use server-side secret injection via environment variables.
Error handling lacks recovery guidance. Handler code shows formatErrorForMcpTool(error) calls, but source does not reveal what guidance those error messages provide. If errors return raw stack traces or generic messages, LLMs have no actionable next step. Example: 'Error converting URL to Markdown' alone tells the agent nothing about whether to retry, call a different tool, or ask the user.
Multiple near-duplicate tools lack clear disambiguation. convert_to_markdown vs. convert_multiple_to_markdown, summarize_url vs. summarize_website vs. summarize_multiple_urls, extract_data vs. extract_data_multiple all exist as separate tools. Descriptions do not explain when an LLM should choose the batch variant over looping the single variant, or vice versa. This forces the agent to reason about overlapping functionality.
Numeric parameters lack range constraints. delayAfterLoad, maxLinks, maxPages, maxLength, timeout, and viewport dimensions have no documented minimum/maximum values. LLMs could pass absurd values (e.g., delay=999999999 or maxPages=1000000) that break APIs or cause timeouts. Descriptions should state ranges (e.g., 'Delay in milliseconds (0-30000)').
Clarify batch vs. single-item tool selection. Add dependency hints to tool descriptions: 'Use convert_to_markdown for single URLs; use convert_multiple_to_markdown for batches of 2+ URLs to save tokens and improve performance.' Similar guidance for summarize_url / summarize_website / summarize_multiple_urls.
Create a 'Getting Started' example in README showing: (a) how to configure ReviewWebsite API key server-side, (b) a typical agent workflow (scrape_url → extract_data → summarize), and (c) error recovery patterns. This helps users understand tool composition.
Consider adding input validation with clear error messages. E.g., if url is not a valid HTTP(S) URL, return 'Invalid URL: must start with http:// or https://, got: ftp://example.com'. This lets LLMs self-correct on the next attempt.