Skip to content

Cleanor

by cleanor.app · remote · local (npm) · no sign-in to list tools · v0.6.1 · published by app.cleanor

Zero-auth MCP: image optimize, cited storage/format data, and dev utilities LLMs get wrong.

Final · 1Changes · 15

22 tools: 1 do something that can't be undone, 15 change things and 6 only read.

Scanned Oct 21, 2026

5 checks matched something in the tool definitions. No finding is not a safety guarantee. How the checks work.

claude mcp add --transport http cleanor https://mcp.cleanor.app/mcp

Findings

Matches of fixed checks, with the text they matched.

5 warn
  • Warnuuid

    The server marks "uuid" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"idempotentHint":false,"openWorldHint":false}; The description's first verb is "generate": a word for a change.

    What this check looks for
  • Warncolor

    The server marks "color" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"idempotentHint":true,"openWorldHint":false}; The description's first verb is "convert": a word for a change.

    What this check looks for
  • The server marks "unit_convert" read-only (readOnlyHint: true), and its own name, description or input give the class "irreversible".

    Matched text

    annotations: {"readOnlyHint":true,"idempotentHint":true,"openWorldHint":false}; The name "unit_convert" says "convert": a word for a change.

    What this check looks for
  • The server marks "base_convert" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"idempotentHint":true,"openWorldHint":false}; The name "base_convert" says "convert": a word for a change.

    What this check looks for
  • The server marks "placeholder_image" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"idempotentHint":true,"openWorldHint":false}; The description's first verb is "generate": a word for a change.

    What this check looks for

Tools

Open a tool for its reasons and full description. Descriptions are the publisher's own words, shown as they are.

22 tools

Can't be undone 1Claude Code: ask
  • unit_convertConvert a value between units of length, mass, data size, time, speed or temperature.Can send data out1 finding

    Why it is in this group

    • The name "unit_convert" says "convert": a word for a change.
    • The input addresses people (input.to): what it sends cannot be taken back.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    What it can reach

    • outboundThe input takes a destination (input.to): what the tool writes goes there.

    Findings

    • Warn

      The server marks "unit_convert" read-only (readOnlyHint: true), and its own name, description or input give the class "irreversible".

      Matched text

      annotations: {"readOnlyHint":true,"idempotentHint":true,"openWorldHint":false}; The name "unit_convert" says "convert": a word for a change.

      What this check looks for
    Description, as the server wrote it
    Convert a value between units of length, mass, data size, time, speed or temperature. Supported units: mm, cm, m, km, in, ft, yd, mi, nmi, mg, g, kg, t, oz, lb, st, bit, byte, kb, kib, mb, mib, gb, gib, tb, tib, ms, s, min, h, day, week, mps, kph, mph, fps, knot, c, f, k. Use for exact conversions instead of approximating.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • idempotentHint: true
Changes things 15Claude Code: ask
  • base_convertConvert an integer between number bases 2–36 (e.g.1 finding

    Why it is in this group

    • The name "base_convert" says "convert": a word for a change.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    Findings

    • Warn

      The server marks "base_convert" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"idempotentHint":true,"openWorldHint":false}; The name "base_convert" says "convert": a word for a change.

      What this check looks for
    Description, as the server wrote it
    Convert an integer between number bases 2–36 (e.g. hex to binary, decimal to base-36). Arbitrary precision via BigInt, so large values stay exact. Use for radix conversions instead of doing them by hand.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • idempotentHint: true
  • base64Encode text to Base64 or decode Base64 back to text (UTF-8 safe).No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    Encode text to Base64 or decode Base64 back to text (UTF-8 safe). Supports URL-safe alphabet. Use whenever you need to encode/decode data URIs, tokens, or config values instead of guessing the bytes.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • idempotentHint: true
  • colorConvert a color (hex, rgb() or hsl()) and return hex, RGB and HSL representations at once.1 finding

    Why it is in this group

    • The description's first verb is "convert": a word for a change.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    Findings

    • Warn

      The server marks "color" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"idempotentHint":true,"openWorldHint":false}; The description's first verb is "convert": a word for a change.

      What this check looks for
    Description, as the server wrote it
    Convert a color (hex, rgb() or hsl()) and return hex, RGB and HSL representations at once. Use when picking or translating colors for CSS, design tokens or themes.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • idempotentHint: true
  • color_paletteBuild a harmonious color palette from a base color using color-theory rules (complementary, analogous, triadic, tetradic, or monochromatic).No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    Build a harmonious color palette from a base color using color-theory rules (complementary, analogous, triadic, tetradic, or monochromatic). Returns each color as hex and HSL. Use to derive a theme or design tokens from one brand color.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • idempotentHint: true
  • hashCompute a cryptographic hash of text (SHA-1, SHA-256, SHA-384 or SHA-512) and return the hex digest.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    Compute a cryptographic hash of text (SHA-1, SHA-256, SHA-384 or SHA-512) and return the hex digest. Use for checksums, cache keys, or verifying content. MD5 is intentionally not offered (broken, and unavailable in Web Crypto). LLMs cannot compute these reliably by hand, so always use this tool instead of guessing.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • idempotentHint: true
  • hmacCompute an HMAC (keyed hash) of a message with a secret, using SHA-1/256/384/512, returned as hex or Base64.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    Compute an HMAC (keyed hash) of a message with a secret, using SHA-1/256/384/512, returned as hex or Base64. Use to sign webhook payloads or verify a signature instead of guessing. LLMs cannot compute this by hand.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • idempotentHint: true
  • image_format_savingsHow much smaller WebP, AVIF or JPEG XL are than JPEG at matched perceptual quality, from Cleanor Labs’ controlled benchmark.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    How much smaller WebP, AVIF or JPEG XL are than JPEG at matched perceptual quality, from Cleanor Labs’ controlled benchmark. Also reports the "HEIC conversion tax" (converting an iPhone HEIC to JPG/PNG makes it bigger). Use to justify a format choice when building a site or app.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • jwt_decodeDecode a JSON Web Token into its header and payload so you can inspect claims (iss, exp, sub, scopes).No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    Decode a JSON Web Token into its header and payload so you can inspect claims (iss, exp, sub, scopes). The signature is NOT verified and no secret is required or stored. Use to read a token during debugging.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • idempotentHint: true
  • placeholder_imageGenerate a lightweight SVG placeholder image at any size, with an optional label and custom background/text colors.1 finding

    Why it is in this group

    • The description's first verb is "generate": a word for a change.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    Findings

    • Warn

      The server marks "placeholder_image" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"idempotentHint":true,"openWorldHint":false}; The description's first verb is "generate": a word for a change.

      What this check looks for
    Description, as the server wrote it
    Generate a lightweight SVG placeholder image at any size, with an optional label and custom background/text colors. Dependency-free, pastes straight into a page or mockup. Use for wireframes and design stubs instead of hotlinking a placeholder service.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • idempotentHint: true
  • qr_codeEncode text or a URL as a QR code and return a crisp, dependency-free SVG you can paste straight into a page, deck or doc.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    Encode text or a URL as a QR code and return a crisp, dependency-free SVG you can paste straight into a page, deck or doc.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • regex_testTest a JavaScript regular expression against sample text and return whether it matches, plus every match with its captured groups and index.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    Test a JavaScript regular expression against sample text and return whether it matches, plus every match with its captured groups and index. Use to verify a pattern instead of reasoning about it in your head. Input and pattern are length-capped to keep it fast and safe.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • idempotentHint: true
  • slugifyTurn a title or phrase into a clean, URL-safe slug (lowercase, hyphenated, accents stripped).No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    Turn a title or phrase into a clean, URL-safe slug (lowercase, hyphenated, accents stripped). Use when generating page paths, filenames or anchor IDs.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • idempotentHint: true
  • storage_capacityHow many photos or minutes of video actually fit in a given storage size, corrected for real OS/filesystem overhead.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    How many photos or minutes of video actually fit in a given storage size, corrected for real OS/filesystem overhead. Backed by Cleanor Labs measured per-item sizes. Use for realistic sample copy, dashboards, or "how many photos fit in 128 GB" answers.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • url_parseBreak a URL into its components: scheme, host, port, path, decoded query parameters and fragment.Can send data outNo findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    What it can reach

    • outboundThe input takes a URL (input.url): a request to a URL can carry data to whoever runs it.
    Description, as the server wrote it
    Break a URL into its components: scheme, host, port, path, decoded query parameters and fragment. Use to inspect or debug a URL instead of parsing it by eye.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • idempotentHint: true
  • uuidGenerate one or more UUIDs.1 finding

    Why it is in this group

    • The description's first verb is "generate": a word for a change.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    Findings

    • Warn

      The server marks "uuid" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"idempotentHint":false,"openWorldHint":false}; The description's first verb is "generate": a word for a change.

      What this check looks for
    Description, as the server wrote it
    Generate one or more UUIDs. v4 is fully random; v7 is time-sortable (recommended for database keys). LLMs cannot produce cryptographically random or correctly-formatted UUIDs, so always use this tool.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • idempotentHint: false
Only reads 6Claude Code: allow
  • countAccurately count characters (Unicode code points), UTF-16 units, words, lines and UTF-8 bytes in text.No findings

    Why it is in this group

    • The name "count" says "count": a word for reading.
    Description, as the server wrote it
    Accurately count characters (Unicode code points), UTF-16 units, words, lines and UTF-8 bytes in text. LLMs are notoriously bad at counting, so always use this tool for "how many characters/words" questions.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • idempotentHint: true
  • cron_describeParse a standard 5-field cron expression (minute hour day-of-month month day-of-week) into a plain-English breakdown and the next few run times in UTC.No findings

    Why it is in this group

    • The name "cron_describe" says "describe": a word for reading.
    Description, as the server wrote it
    Parse a standard 5-field cron expression (minute hour day-of-month month day-of-week) into a plain-English breakdown and the next few run times in UTC. Use to sanity-check a schedule instead of guessing what the fields mean.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • idempotentHint: false
  • datetimeGet the current date/time, or convert a given timestamp, into a target IANA timezone with ISO, Unix and human-readable forms.No findings

    Why it is in this group

    • The description's first verb is "get": a word for reading.
    Description, as the server wrote it
    Get the current date/time, or convert a given timestamp, into a target IANA timezone with ISO, Unix and human-readable forms. Pass a Unix timestamp (seconds or ms) or an ISO string as input; omit it for "now". LLMs cannot know the real current time, so use this instead of guessing.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • idempotentHint: false
  • diffCompute a line-by-line diff between two texts, marking removed lines with "-", added with "+" and unchanged with two spaces, plus a change count.No findings

    Why it is in this group

    • The name "diff" says "diff": a word for reading.
    Description, as the server wrote it
    Compute a line-by-line diff between two texts, marking removed lines with "-", added with "+" and unchanged with two spaces, plus a change count. Use to see exactly what changed instead of comparing by eye. Capped at 1000 lines per side.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • idempotentHint: true
  • json_formatValidate JSON and pretty-print or minify it, optionally sorting object keys.No findings

    Why it is in this group

    • The description's first verb is "validate": a word for reading.
    Description, as the server wrote it
    Validate JSON and pretty-print or minify it, optionally sorting object keys. Returns a precise parse error (with position) if invalid. Use to check and clean JSON instead of eyeballing it.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • idempotentHint: true
  • optimize_imageFetch an image from a public URL and re-encode it smaller (WebP/AVIF/JPEG), optionally resizing to a target width.Reads text others writeNo findings

    Why it is in this group

    • The description's first verb is "fetch": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    • untrusted-inputThe description's first sentence says "fetch" and "url": it reads web pages, which anyone can write.
    Description, as the server wrote it
    Fetch an image from a public URL and re-encode it smaller (WebP/AVIF/JPEG), optionally resizing to a target width. Returns the optimized image plus before/after byte sizes. Use this when an AI-generated or dropped-in asset (hero image, screenshot, illustration) is too large to ship.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: true

This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.

Exfil surface

Which tools read private data, which read text someone else can write, and which can send data out. One of each is a path a prompt injection can use.

No private-data, untrusted-input, outbound path in this server alone: no tool is tagged private-data.

Reads private data0
Reads files, mail, messages, databases, secrets, calendars or repositories.
Reads text others write1
Brings in text someone else can write: web pages, inbound email, messages, issues and comments.
Can send data out2
Can carry data to people or systems: it sends, posts or publishes, or takes a recipient, channel or URL.

Other servers in the same agent add their own tools to these paths. Audit your whole setup to see them together.

Install

Pinned to version 0.6.1. Values in angle brackets are yours to fill in.

claude mcp add --transport http cleanor https://mcp.cleanor.app/mcp

Run in a terminal.

Claude Code permissions

Allow the reads, ask before a change or a way out, deny the deletes. Paste into .claude/settings.json.

.claude/settings.json
{
  "permissions": {
    "allow": [
      "mcp__cleanor__optimize_image",
      "mcp__cleanor__json_format",
      "mcp__cleanor__count",
      "mcp__cleanor__cron_describe",
      "mcp__cleanor__datetime",
      "mcp__cleanor__diff"
    ],
    "ask": [
      "mcp__cleanor__storage_capacity",
      "mcp__cleanor__image_format_savings",
      "mcp__cleanor__qr_code",
      "mcp__cleanor__hash",
      "mcp__cleanor__uuid",
      "mcp__cleanor__base64",
      "mcp__cleanor__jwt_decode",
      "mcp__cleanor__color",
      "mcp__cleanor__slugify",
      "mcp__cleanor__regex_test",
      "mcp__cleanor__unit_convert",
      "mcp__cleanor__url_parse",
      "mcp__cleanor__base_convert",
      "mcp__cleanor__hmac",
      "mcp__cleanor__placeholder_image",
      "mcp__cleanor__color_palette"
    ],
    "deny": []
  }
}

Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. A read that can send data out (it takes a URL, say) asks first too. It assumes the server is installed as cleanor. Review it before you use it.

Capability tags behind 3 rules
  • mcp__cleanor__optimize_image untrusted-input
  • mcp__cleanor__unit_convert outbound
  • mcp__cleanor__url_parse outbound