Server defines 2 tools with explicit schemas, descriptions, and parameter documentation. Naming follows verb_noun convention (convert_*). However, descriptions are minimal (under 100 chars each), parameter descriptions lack actionable constraints (no ranges, enums, or format guidance), and output schemas are entirely undocumented. Error handling returns isError: true with free-text messages but no recovery guidance. No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite both tools being write operations. Pagination and structured output patterns are absent. Security: file path parameters accept absolute paths without documented sanitization against path traversal attacks.
Tool descriptions are under 100 characters and lack context on WHEN to use each tool or WHAT distinguishes them. 'Convert a markdown file to JPEG image' does not explain when convert_md_to_jpeg should be called vs convert_mermaid_to_jpeg, or what preprocessing happens.
No output schema documented. LLMs cannot infer what fields the response contains, what paths are returned, or how to chain downstream operations. The code returns a hardcoded text response without structured output.
Parameter descriptions lack actionable constraints. 'Width of the output image (default: 2400)' does not specify valid range (min/max), units, or whether it must be > 0. 'Scale factor for mermaid diagrams (default: 2)' does not state valid range. 'JPEG quality (1-100, default: 95)' mentions range in prose but not as enum or min/max schema constraint.
convert_md_to_jpegconvert_mermaid_to_jpeg
Recommendations
Expand tool descriptions to 100-200 characters. Example: 'convert_md_to_jpeg: Renders markdown files as high-resolution JPEG images. Supports standard markdown syntax and embedded mermaid diagrams. Use when you need to convert .md documents to images for sharing or documentation. Returns the output file path and dimensions. Note: markdown-only files use convert_mermaid_to_jpeg for diagram-heavy content.'
Add explicit schema constraints to parameters. Example for width/height: add minValue: 100, maxValue: 8000 in schema and in description: 'Width in pixels (100 - 8000, default: 2400)'. For quality: add enum: [1, 25, 50, 75, 95, 100] or minValue: 1, maxValue: 100 in schema and description: 'JPEG quality 1 - 100 (default: 95)'.
Document and return a structured output schema. Change response from text to: {'type': 'object', 'properties': {'success': {'type': 'boolean'}, 'output_file': {'type': 'string', 'description': 'Absolute path to output JPEG'}, 'width': {'type': 'number'}, 'height': {'type': 'number'}, 'quality': {'type': 'number'}, 'file_size_bytes': {'type': 'number'}}, 'required': ['success', 'output_file']}. Include the output_file path in the response so downstream tools can reference it.
Add path sanitization. Validate that input_file and output_file do not contain '..', do not escape the intended directory, and are within a safe whitelist directory. Example: const safePath = path.resolve(baseDir, userPath); if (!safePath.startsWith(baseDir)) throw new Error('Path traversal denied');
Add tool annotations to both tools to signal they are destructive write operations. In ListToolsRequestSchema response, add 'destructiveHint': true to both tool definitions.
Both tools accept 'input_file' and 'output_file' as absolute file paths with no documented validation or sanitization. Code checks fs.existsSync() but does not prevent path traversal (e.g., ../../../etc/passwd). Security vulnerability: LLM could be tricked into reading/writing arbitrary files.
Both tools are WRITE operations (create files, modify filesystem) but lack tool annotations (destructiveHint, idempotentHint). No dry-run or confirmation support. Error handling returns free-text 'Error: <message>' with no recovery guidance, LLM cannot determine if the error is retryable, user-fixable, or fatal.
Error messages are generic: 'Error: <error.message>'. No contextual guidance. Example: if width or quality are out of range, the LLM gets 'Error: Invalid value' with no hint that it should adjust the parameter. Example: if output_file path is invalid, no suggestion of valid alternatives.
Output is always free-text: 'Successfully converted markdown to high-quality JPEG (2400x1600, quality: 95): /path/to/output.jpeg'. No structured JSON response. LLM cannot extract the output file path programmatically or plan further operations. Should return {'success': true, 'output_file': '...', 'width': ..., 'height': ..., 'quality': ...}.
convert_md_to_jpegconvert_mermaid_to_jpeg
Implement proper error categorization. Instead of generic 'Error: <message>', return: {'success': false, 'error_code': 'INVALID_PARAMETER|FILE_NOT_FOUND|PATH_TRAVERSAL|RENDER_TIMEOUT|INVALID_MARKDOWN|DISK_FULL', 'error_message': '<user-friendly message>', 'recovery_hint': '<next step>'}. Example: 'Invalid quality parameter: got 150, must be 1 - 100. Try with quality: 95 instead.'
Add parameter for output directory validation. Require an optional 'output_dir' parameter that defaults to the input file's directory, and reject output_file if it escapes that directory.
Document the behavior when input_file contains a mermaid diagram in convert_md_to_jpeg. Currently it auto-delegates to convert_mermaid_to_jpeg; make this explicit in the description and parameter docs.
Add limits to parameter ranges in schema. Example: {'width': {'type': 'number', 'minimum': 100, 'maximum': 8000, 'default': 2400}}. JSON Schema constraints are machine-readable and prevent LLMs from passing invalid values.
Consider adding a dry-run parameter to preview output dimensions and file size without actually writing the file. This prevents accidental misuse and supports confirmation workflows.