An MCP server that gives AI agents 35 fast, local, privacy-first tools: PDF text extraction and editing, image processing, exact math, QR codes, crypto, timezone conversion, regex, diff and more. No network, no data leaves the machine.
Strong foundation with 35 well-named, verb-prefixed tools and consistent schema structure using Zod. All tools have descriptions (avg 120 chars) and input schemas with type definitions. However, output schemas are undocumented, LLMs cannot predict return structure. Error handling is minimal (generic catch-all). Parameter descriptions are present but often lack constraints (ranges, formats, examples). No tool annotations (readOnlyHint/destructiveHint). Missing idempotency guidance for write operations. Composition is sound, tools are single-purpose and chainable.
Decode Base64 back to text.
Encode text to Base64.
Hash a password with bcrypt, using a chosen cost factor.
Check whether a password matches a bcrypt hash.
Evaluate a math expression exactly. Supports arithmetic, powers, roots, trig, and unit conversions like '5 km to miles'. Use this instead of doing math yourself.
Convert text between cases: upper, lower, title, sentence, camel, snake, kebab, constant.
Convert a hex color (#rrggbb) into RGB and HSL values.
Output schemas are completely undocumented. Tools return text strings via generic handler wrapper, but LLMs cannot predict structure (JSON, plain text, object fields). This violates pattern:tool and forces LLMs to guess downstream field names.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). Write tools (qr_generate, image_*, pdf_*) are not marked as destructive, preventing agents from reasoning about side effects and retry safety.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 61 | 2026-07-28+ | v2 |
Convert CSV text into a JSON array of objects using the header row as keys.
Compare two blocks of text and show a precise line-by-line diff (added, removed, unchanged).
Validate and reformat JSON. Pretty-prints by default, or minifies. Reports errors clearly.
Generate one or more random UUIDs (version 4).
Generate a cryptographic hash of text. Supports md5, sha1, sha256, sha384, sha512.
Compute an HMAC signature of a message with a secret key. Supports sha256, sha1, sha512.
Compress an image to reduce file size, keeping its format. Lower quality = smaller file.
Convert an image to another format: png, jpeg, webp, avif, gif or tiff.
Crop a rectangular region out of an image.
Convert an image to grayscale (black and white).
Report an image's format, dimensions, color channels and file size.
Resize an image. Give width, height, or both. 'fit' controls how it fits the box.
Rotate an image by any angle (degrees, clockwise).
Overlay a line of text as a watermark on an image (bottom corner).
Combine one or more images (PNG or JPG) into a single PDF, one image per page.
Decode a JWT and show its header and payload as readable JSON. Does NOT verify the signature.
Extract the readable text from a PDF so the agent can actually read the document. Use this to read a PDF's contents.
Report page count, PDF metadata (title, author) and file size.
Merge several PDF files into one, in the order given.
Rotate every page of a PDF by 90, 180 or 270 degrees.
Extract a range of pages from a PDF into a new PDF. Pages are 1-based and inclusive.
Generate a QR code image (PNG) from text or a URL and save it to a file.
Apply a regular expression to text and return every match exactly. Use this instead of scanning text yourself, which is error prone.
Convert any text into a clean URL slug (lowercase, dashes, no accents or symbols).
Count words, characters, sentences and lines in text, with an estimated reading time.
Convert a date and time from one timezone to another. Use IANA zone names like 'America/New_York' or 'Asia/Tokyo'. Use this instead of doing timezone math yourself.
Decode a percent-encoded URL string back to text.
Percent-encode text for safe use in a URL.
Error handling is minimal. Generic catch-all in index.ts returns only error message text. No error classification (retryable vs user-fixable vs fatal), no recovery guidance, no invalid value echoing. Violates pattern:recovery-guide.
Parameter descriptions lack constraint details. E.g., 'size' in qr_generate has min/max in schema but description doesn't mention the 64-2048 pixel range. 'algorithm' enums are in schema but not explained in description text. LLMs cannot read JSON Schema, they rely on description prose.
No pagination or result limits documented. Tools like csv_to_json, pdf_extract_text (maxChars=20000 default) could return large results. No guidance on when results are truncated or how to request more data.