A hosted, remote MCP server that gives your AI agent the same design tools humans use on jinero.online: 22 tools covering fonts (search, CSS, files, recognition by image), color math (contrast, shades, naming, extraction), curated palettes, code minify/convert/detect, SVG optimization and SCSS helpers. Every tool is a thin wrapper over the public REST API — one contract, one behavior. Published in the official MCP registry as online.jinero/jinero; the manifest lives at /.well-known/mcp/server.json.
# Remote endpoint (Streamable HTTP)
https://jinero.online/mcp
# Peek at the tool list without any client:
curl -s -X POST https://jinero.online/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Works with any MCP client that supports remote (Streamable HTTP) servers: Claude Code, Claude Desktop, Cursor, Cline, Zed, Gemini CLI and friends. Older clients that only speak stdio can bridge with npx mcp-remote https://jinero.online/mcp.
# Claude Code (CLI)
claude mcp add --transport http jinero https://jinero.online/mcp
// Claude Desktop / Cursor / Cline — mcpServers config
{
"mcpServers": {
"jinero": {
"type": "http",
"url": "https://jinero.online/mcp"
}
}
}
Every tool declares MCP annotations so clients and security scanners can verify the posture instead of guessing: all 22 tools are read-only and idempotent. Submitted code and SVG are parsed and transformed as text — never executed, never stored. Uploaded images (font recognition, color extraction) are processed in memory and deleted immediately. Only three tools fetch a user-supplied URL (recognize_font, extract_colors, svg_to_datauri) — they are marked open-world and the fetches are SSRF-guarded (public http(s) only, size-capped). Anonymous, no API key, rate-limited at 60 req/min per IP.
// Annotations served in tools/list for every tool
{
"readOnlyHint": true,
"idempotentHint": true,
"openWorldHint": false // true only on the 3 URL-fetching tools
}
Search the free font catalog by name, category, style tags, language coverage, variable/monospace flags and style count. Returns a paginated list of families with preview URLs and per-style metadata.
search_fonts
read-only
idempotent
| Parameter | Type | Description |
|---|---|---|
name |
string | Fuzzy name match. |
category |
string | Comma-separated categories, e.g. 'serif,sans'. |
langs |
string | Comma-separated language codes, e.g. 'latin,cyrillic' — ALL must be supported. |
style |
string | Comma-separated style tags (handwriting, script, display, slab, rounded, condensed, expanded, stencil, pixel, blackletter, outline, retro) — ALL must match. |
variable |
boolean | Only variable fonts. |
monospace |
boolean | Only monospace fonts. |
styles_min / styles_max |
integer | Bounds on the number of styles. |
order |
string | likes (default) · downloads · views · name · created_at. |
sort |
string | asc · desc. |
per_page / page |
integer | Pagination (per_page 1–100, default 24). |
// tools/call arguments
{ "name": "inter", "category": "sans", "per_page": 2 }
{
"current_page": 1,
"data": [
{
"name": "Inter Tight",
"slug": "inter-tight",
"category": "sans",
"variable": true,
"monospace": false,
"langs": ["latin", "cyrillic", "greek"],
"style_tags": [],
"styles_count": 18,
"downloads": 2800,
"likes_count": 1392,
"regular_url": "https://jinero.online/storage/fonts/inter-tight/inter-tight-regular.woff2",
"styles": [ { "weight": 100, "italic": false, "name": "Thin" }, "…" ]
}
],
"per_page": 2,
"total": 4
}
Identify which font is used in an image. Powered by our own CNN embedding model trained on the jinero catalog — it matches fonts by visual shape, so it needs no OCR and no readable text (Latin & Cyrillic). Send a tight crop of one line of text as a public image_url or as image_base64 (raw base64 / data URI — perfect for a local screenshot your agent just took). The image is processed in memory and deleted immediately. ~200 ms per call.
recognize_font
read-only
idempotent
fetches external URLs
| Parameter | Type | Description |
|---|---|---|
image_url |
string | Public http(s) URL of the image. Provide either this or image_base64. |
image_base64 |
string | Base64-encoded image (raw base64 or data:image/…;base64 URI), max 8 MB decoded. Provide either this or image_url. |
top_k |
integer | Number of font matches to return (3–20, default 8). |
// tools/call arguments — URL variant
{ "image_url": "https://example.com/heading-crop.png", "top_k": 5 }
// …or send a local screenshot directly
{ "image_base64": "data:image/png;base64,iVBORw0KGgo…", "top_k": 5 }
{
"matches": [
{ "slug": "lunasima", "name": "Lunasima", "category": "sans", "score": 0.8331,
"family_url": "https://jinero.online/fonts/lunasima" },
{ "slug": "tajawal", "name": "Tajawal", "category": "sans", "score": 0.8213,
"family_url": "https://jinero.online/fonts/tajawal" }
],
"note": "Matched by a trained CNN embedding (visual shape), no OCR."
}
Full metadata for one font family by slug: designer, license, category, language coverage, variable axes, every style, plus ready-made download/CSS/files URLs.
get_font
read-only
idempotent
| Parameter | Type | Description |
|---|---|---|
slug |
string | Family slug, e.g. 'inter', 'playfair-display'. |
// tools/call arguments
{ "slug": "inter" }
{
"name": "Inter",
"slug": "inter",
"category": "sans",
"designer": "Rasmus Andersson",
"license": "OFL",
"license_url": "https://openfontlicense.org/open-font-license-official-text/",
"variable": true,
"monospace": false,
"langs": ["latin", "cyrillic", "greek", "vietnamese"],
"styles_count": 18,
"download_url": "https://jinero.online/api/v1/fonts/inter/download",
"files_url": "https://jinero.online/api/v1/fonts/inter/files",
"css_url": "https://jinero.online/api/v1/fonts/css?family=inter",
"fonts": [ { "weight": 400, "italic": false, "name": "Regular" }, "…" ]
}
List every font file for a family — weight, italic flag, style name, format and a direct woff2/ttf URL with file size. Handy when the agent is writing custom @font-face rules or downloading specific weights.
get_font_files
read-only
idempotent
| Parameter | Type | Description |
|---|---|---|
slug |
string | Family slug, e.g. 'inter'. |
// tools/call arguments
{ "slug": "inter" }
{
"family": "Inter",
"slug": "inter",
"files": [
{ "weight": 100, "italic": false, "style": "Thin", "format": "woff2",
"url": "https://jinero.online/storage/fonts/inter/inter-thin.woff2", "size": 111816 },
{ "weight": 400, "italic": false, "style": "Regular", "format": "ttf",
"url": "https://jinero.online/storage/fonts/inter/inter-regular.ttf", "size": 876576 }
]
}
Generate ready-to-paste @font-face CSS for a family spec — Google-Fonts-compatible syntax, including variable ranges. Returns plain CSS text the agent can drop straight into a stylesheet.
get_fonts_css
read-only
idempotent
| Parameter | Type | Description |
|---|---|---|
family |
string | Family spec, e.g. "inter:wght@400,700" or a variable range "inter:[email protected]". |
display |
string | font-display value: swap (default) · auto · block · fallback · optional. |
// tools/call arguments
{ "family": "inter:wght@400,700", "display": "swap" }
/* jinero.online Fonts API */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('https://jinero.online/storage/fonts/inter/inter-regular.woff2') format('woff2');
}
/* … one block per requested weight … */
Return the direct ZIP download URL for a font family (all styles in TTF + WOFF2, plus a ready fonts.css). The tool does not download anything itself — it hands the URL to the user or agent.
get_font_download_url
read-only
idempotent
| Parameter | Type | Description |
|---|---|---|
slug |
string | Family slug, e.g. 'inter'. |
// tools/call arguments
{ "slug": "inter" }
{
"slug": "inter",
"download_url": "https://jinero.online/api/v1/fonts/inter/download"
}
WCAG 2.1 contrast ratio between a foreground and background color, with AA/AAA pass flags for normal and large text — the same sRGB math Lighthouse uses.
check_contrast
read-only
idempotent
| Parameter | Type | Description |
|---|---|---|
fg |
string | Foreground color: hex, rgb(), or hsl(). |
bg |
string | Background color, same formats. |
// tools/call arguments
{ "fg": "#1d4ed8", "bg": "#ffffff" }
{
"success": true,
"ratio": 6.29,
"ratio_string": "6.29:1",
"aa": { "normal": true, "large": true },
"aaa": { "normal": false, "large": true },
"thresholds": { "aa_normal": 4.5, "aa_large": 3, "aaa_normal": 7, "aaa_large": 4.5 }
}
A complete design-token set from one base color: tints, shades and five harmonic relationships (complementary, analogous, triadic, split-complementary, tetradic). Every color carries hex/rgb/hsl strings, luminance and a recommended text color.
get_color_shades
read-only
idempotent
| Parameter | Type | Description |
|---|---|---|
hex |
string | Base color: hex, rgb(), or hsl(). |
step |
string | Step percentage: 5, 10 (default), 20, 25. |
limit |
integer | Cap on tints/shades (default fills to ~100%). |
// tools/call arguments
{ "hex": "#3b82f6", "step": "20", "limit": 2 }
{
"success": true,
"base": { "hex": "#3b82f6", "hsl_string": "hsl(217, 91%, 60%)", "luminance": 0.2355,
"text_color": "#000000", "contrast_on_white": 3.68 },
"tints": [ { "percent": 20, "hex": "#629bf8", "…": "…" } ],
"shades": [ { "percent": 20, "hex": "#2f68c5", "…": "…" } ],
"harmonies": { "complementary": ["…"], "analogous": ["…"], "triadic": ["…"] }
}
The closest human-readable name for one or many colors — nearest perceptual match against a ~31,000-color dataset. Great for labeling extracted palettes or generated swatches.
name_color
read-only
idempotent
| Parameter | Type | Description |
|---|---|---|
hex |
string | One hex, or several comma-separated (up to 100), e.g. "#3b82f6,#000,#ff7f50". |
// tools/call arguments
{ "hex": "#3b82f6,#000,#ff7f50" }
{
"success": true,
"count": 3,
"colors": [
{ "input": "#3B82F6", "name": "Dodger Blue", "hex": "#3E82FC", "exact": false, "distance": 10.91 },
{ "input": "#000000", "name": "Black", "hex": "#000000", "exact": true, "distance": 0 },
{ "input": "#FF7F50", "name": "Coral", "hex": "#FF7F50", "exact": true, "distance": 0 }
]
}
Extract a dominant-color palette from an image — k-means clustering with balanced / vibrant / muted modes. Send a public image_url or image_base64 (raw base64 / data URI — perfect for a local screenshot). The image is processed in memory and never stored. Every color comes back named: a labeled palette in one call.
extract_colors
read-only
idempotent
fetches external URLs
| Parameter | Type | Description |
|---|---|---|
image_url |
string | Public image URL (server-side fetch, capped at 10 MB, image/* only). Provide either this or image_base64. |
image_base64 |
string | Base64-encoded image (raw base64 or data:image/…;base64 URI), max 10 MB decoded. Provide either this or image_url. |
count |
integer | How many colors to return: 2–16, default 8. |
mode |
string | balanced (default) · vibrant · muted. |
// tools/call arguments — URL variant
{ "image_url": "https://example.com/cover.jpg", "count": 6, "mode": "vibrant" }
// …or send a local screenshot directly
{ "image_base64": "data:image/png;base64,iVBORw0KGgo…", "count": 6 }
{
"success": true,
"mode": "vibrant",
"colors": [
{ "hex": "#f9f9f9", "percent": 90.8, "name": "White", "name_exact": false,
"rgb": { "r": 249, "g": 249, "b": 249 }, "hsl": { "h": 0, "s": 0, "l": 97.6 } },
{ "hex": "#1d1c1b", "percent": 5.8, "name": "Cod Gray", "name_exact": false, "…": "…" }
]
}
Search the curated color-palette catalog by name, tone, temperature, mood, harmony, exact color count and tags. Returns a paginated list — each palette with its hex colors and classification.
search_palettes
read-only
idempotent
| Parameter | Type | Description |
|---|---|---|
name |
string | Fuzzy name match. |
tone |
string | light · dark · mixed. |
temperature |
string | warm · cool · neutral. |
mood |
string | e.g. pastel, muted, earthy, vibrant, monochrome. |
harmony |
string | e.g. analogous, complementary, triadic, monochromatic. |
color_count |
integer | Exact number of colors (2–10). |
tags |
array | Tag slugs — ALL must match. |
order |
string | newest (default) · popular · name. |
per_page / page |
integer | Pagination (per_page 1–100, default 24). |
// tools/call arguments
{ "tone": "light", "mood": "pastel", "per_page": 1 }
{
"current_page": 1,
"data": [
{
"id": 6267,
"name": "5-Color Darling Bud Palette",
"colors": ["#ffffff", "#e7b7fb", "#b0cbfc", "#f98bf7", "#f7cefc"],
"color_count": 5,
"tone": "mixed",
"temperature": "neutral"
}
],
"total": 6267
}
One palette by id: its hex colors, name, tone, temperature, mood, harmony and tags.
get_palette
read-only
idempotent
| Parameter | Type | Description |
|---|---|---|
id |
integer | Palette id (from search_palettes). |
// tools/call arguments
{ "id": 6267 }
{
"success": true,
"palette": {
"id": 6267,
"name": "5-Color Darling Bud Palette",
"colors": ["#ffffff", "#e7b7fb", "#b0cbfc", "#f98bf7", "#f7cefc"],
"color_count": 5,
"tone": "mixed",
"temperature": "neutral",
"tags": []
}
}
Minify or beautify JS, CSS, HTML, SVG, JSON or XML. The code is only parsed and re-printed as text — never executed, never stored. Set type=auto to let the server sniff the language.
minify_code
read-only
idempotent
| Parameter | Type | Description |
|---|---|---|
code |
string | Source text to transform. |
type |
string | js · css · html · svg · json · xml · auto. |
mode |
string | minify (default) · beautify. |
keep_license |
boolean | Preserve /*! … */ license comments when minifying. |
// tools/call arguments
{ "code": ".a { color: #ffffff; margin: 0px; }", "type": "css" }
{
"success": true,
"type": "css",
"mode": "minify",
"output": ".a{color:#fff;margin:0}",
"original_size": 47,
"output_size": 23,
"savings_percent": 51.1
}
Detect the language/format of a code snippet — static analysis only, the snippet is never executed. Also reports which converters can take the detected format as input.
detect_code
read-only
idempotent
| Parameter | Type | Description |
|---|---|---|
code |
string | Snippet to inspect. Max 200,000 chars. |
// tools/call arguments
{ "code": "const x = () => 42;" }
{
"success": true,
"detected_type": "esm",
"confidence": "medium",
"available_targets": [ { "to": "cjs", "label": "ESM → CommonJS" } ]
}
Convert code between text formats — JSON↔YAML, JSON→TOML, CSS↔SCSS, ESM→CJS and more. Pure text transformation: the source is parsed and re-serialized, never executed, never stored. Use list_code_converters for the full list of from/to pairs and per-converter options.
convert_code
read-only
idempotent
| Parameter | Type | Description |
|---|---|---|
code |
string | Source code to convert. |
from |
string | Source format id (see list_code_converters). |
to |
string | Target format id. |
options |
object | Per-converter options (see optionsSchema in list_code_converters). |
// tools/call arguments
{ "code": "{\"name\":\"jinero\"}", "from": "json", "to": "yaml" }
{
"success": true,
"from": "json",
"to": "yaml",
"output": "name: jinero\n",
"notes": null
}
The registry of available converters: from/to ids, human labels and each converter's option schema. No parameters.
list_code_converters
read-only
idempotent
// tools/call arguments
{ }
{
"success": true,
"converters": [
{ "id": "json_to_yaml", "from": "json", "to": "yaml", "label": "JSON → YAML",
"optionsSchema": { "indent": [2, 4], "sortKeys": false } },
{ "id": "yaml_to_json", "from": "yaml", "to": "json", "label": "YAML → JSON", "…": "…" }
]
}
Optimize and clean SVG markup with SVGO — pure markup transformation, nothing is executed or stored. Returns the minified SVG plus before/after sizes.
optimize_svg
read-only
idempotent
| Parameter | Type | Description |
|---|---|---|
svg |
string | SVG source. Max 500,000 chars. |
preset |
string | safe · balanced (default) · aggressive. |
// tools/call arguments
{ "svg": "<svg xmlns=\"…\" width=\"24\" height=\"24\"><rect …/></svg>", "preset": "balanced" }
{
"success": true,
"preset": "balanced",
"output": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\"><path fill=\"#f00\" d=\"M2 2h20v20H2z\"/></svg>",
"original_size": 136,
"optimized_size": 106,
"savings_percent": 22.1
}
Encode an SVG (or a fetched image) as a CSS-ready data: URI — URL-encoded and base64 variants plus a ready background-image snippet. Provide either raw svg markup or a public url.
svg_to_datauri
read-only
idempotent
fetches external URLs
| Parameter | Type | Description |
|---|---|---|
svg |
string | Raw SVG markup. Mutually exclusive with url. |
url |
string | Public image URL the server will fetch. |
encoding |
string | utf8 · base64. Defaults: utf8 for SVG, base64 for raster. |
quotes |
string | single · double (default) — quote style in the CSS snippet. |
// tools/call arguments
{ "svg": "<svg xmlns=\"http://www.w3.org/2000/svg\"><circle r=\"4\"/></svg>" }
{
"success": true,
"mime_type": "image/svg+xml",
"primary_label": "URL-encoded Data URI",
"primary_output": "data:image/svg+xml,%3Csvg xmlns=%22http…%3E",
"secondary_label": "Base64 Data URI",
"secondary_output": "data:image/svg+xml;base64,PHN2ZyB4bWxu…",
"css_output": "background-image: url(\"data:image/svg+xml,%3Csvg…%3E\");"
}
The available SVG optimization presets and what each one does. No parameters.
list_svg_presets
read-only
idempotent
// tools/call arguments
{ }
{
"presets": [
{ "key": "safe", "name": "Safe", "description": "Minimal optimization, preserves most attributes" },
{ "key": "balanced", "name": "Balanced", "description": "Good compression with minimal visual changes" },
{ "key": "aggressive", "name": "Aggressive", "description": "Maximum compression, may affect some SVG features" }
]
}
Browse the SCSS mixin catalog — id, title and a one-liner for each, optionally filtered by group or fuzzy search. Set fields=full to include sources in the listing.
list_scss_mixins
read-only
idempotent
| Parameter | Type | Description |
|---|---|---|
group |
string | Bootstrap · Project · Pattern · Placeholder. |
search |
string | Fuzzy substring across id/title/description. |
fields |
string | summary (default) · full. |
// tools/call arguments
{ "search": "centerer", "fields": "summary" }
{
"success": true,
"count": 1,
"groups": ["Bootstrap", "Project", "Pattern", "Placeholder"],
"items": [
{ "id": "centerer", "title": "centerer()", "group": "Project",
"short": "Absolute centering helper with axis toggles." }
]
}
One SCSS mixin by id — full SCSS/Sass/Less source, parameters and a usage demo.
get_scss_mixin
read-only
idempotent
| Parameter | Type | Description |
|---|---|---|
id |
string | Mixin id (kebab-case), e.g. 'centerer', 'media-breakpoint-up'. |
// tools/call arguments
{ "id": "centerer" }
{
"success": true,
"mixin": {
"id": "centerer",
"title": "centerer()",
"group": "Project",
"short": "Absolute centering helper with axis toggles.",
"scss": "@mixin centerer($horizontal: true, $vertical: true) { … }",
"demo": "…",
"url": "https://jinero.online/dev/scss-mixins#centerer"
}
}
Calculate a fluid CSS clamp() expression for responsive sizing between two viewport widths. Pure calculation — returns the CSS snippet in px and rem variants plus the underlying math.
generate_clamp
read-only
idempotent
| Parameter | Type | Description |
|---|---|---|
min_fs |
number | Minimum size in px. |
max_fs |
number | Maximum size in px. |
min_vw |
number | Viewport width at min_fs (default 320). |
max_vw |
number | Viewport width at max_fs (default 1440). |
unit |
string | px · rem (default) · both. |
root |
number | Root font-size in px for rem conversion (default 16). |
// tools/call arguments
{ "min_fs": 16, "max_fs": 24 }
{
"success": true,
"css": "clamp(1rem, 0.8571rem + 0.7143vw, 1.5rem)",
"variants": {
"px": "clamp(16px, 13.7143px + 0.7143vw, 24px)",
"rem": "clamp(1rem, 0.8571rem + 0.7143vw, 1.5rem)"
},
"math": { "slope": 0.007143, "intercept_px": 13.7143, "vw_coefficient": 0.7143 }
}
About the jinero.online MCP server
A hosted Model Context Protocol server that puts Jinero's font, color, palette, code and SVG tools in the hands of any AI agent — 22 read-only, annotated tools over one URL.
Read-only by design
All 22 tools declare readOnlyHint + idempotentHint MCP annotations. Submitted code and SVG are parsed as text and never executed; images are processed in memory and never stored.
No key, no install
A hosted remote server over Streamable HTTP — add one URL to your MCP client and go. Anonymous, rate-limited at 60 req/min per IP.
Font recognition built in
recognize_font identifies fonts from a screenshot with our own CNN embedding model — by visual shape, no OCR, Latin & Cyrillic — via URL or base64.
One contract with the REST API
Every MCP tool calls the same controllers as the public REST API, so behavior, limits and response shapes stay identical across both surfaces.
Frequently Asked Questions
No. The server is anonymous and free, rate-limited at 60 requests/min per IP. It is published in the official MCP registry as online.jinero/jinero.
Every tool is read-only and idempotent, and says so via MCP annotations (readOnlyHint, idempotentHint) that your client can verify in tools/list. Code sent to minify/convert/detect is parsed as text and never executed. Only three tools fetch a URL you supply (recognize_font, extract_colors, svg_to_datauri); those fetches are SSRF-guarded and size-capped, and uploaded images are never stored.
Any MCP client with remote (Streamable HTTP) support: Claude Code, Claude Desktop, Cursor, Cline, Zed, Gemini CLI and others. Older stdio-only clients can bridge with npx mcp-remote https://jinero.online/mcp.
Two ways: a public image_url, or image_base64 with raw base64 / a data URI (max 8 MB decoded) — so an agent can send a local screenshot directly without hosting it anywhere. Recognition matches by visual letterform shape with our own CNN model, so it needs no OCR and works for Latin and Cyrillic.
Same engine, different transport. MCP tools call the same controllers as the documented REST endpoints, so parameters and response shapes match. Use REST from your own code; use MCP to hand the tools to an AI agent.
At https://jinero.online/.well-known/mcp/server.json, and in the official MCP registry (registry.modelcontextprotocol.io) under the name online.jinero/jinero.