Sumsub: Check Skills Version Detects version drift between the locally installed package and the canonical version published at , so that out-of-date skills don't silently produce stale or incorrect Sumsub behavior. This skill's one user-visible deliverable is the line. Running only computes it; the skill has not done its job until that line appears in your reply to the user. Treat emitting it exactly like emitting the result of any other tool call — not as an optional courtesy. Two-phase protocol (this is how the heads-up actually lands) Only your FINAL reply reaches the user, and you surfac…

\\\n | head -n1 || true\n)\"\n[ -n \"${LOCAL}\" ] || LOCAL=\"unknown\"\n\nREMOTE_RAW=\"$(\n curl --compressed -fsS \\\n --max-time 5 \\\n -H \"Accept: application/json, text/plain;q=0.9, */*;q=0.1\" \\\n -H \"X-Agent-Source: sumsub-skills\" \\\n -H \"X-Agent-Source-Ver: 1.6.0\" \\\n \"${VERSION_URL}\" 2>/dev/null || true\n)\"\n\nextract_semver() {\n # $1 = raw text, $2 = anchored field-name regex\n # Prints the first semver on a line whose key matches the regex.\n printf '%s\\n' \"$1\" \\\n | grep -iE \"$2\" \\\n | head -n1 \\\n | grep -oE '[0-9]+\\.[0-9]+\\.[0-9]+' \\\n | head -n1 || true\n}\n\n# Preferred: `agent-skills-version: x.y.z` line in the canonical llms.txt.\nREMOTE=\"$(extract_semver \"${REMOTE_RAW}\" '^[[:space:]]*-?[[:space:]]*agent-skills-version[[:space:]]*:')\"\n# Fallbacks: JSON `\"version\":` field (e.g. package.json) and a bare `version:` line.\n[ -n \"${REMOTE}\" ] || REMOTE=\"$(extract_semver \"${REMOTE_RAW}\" '\"version\"[[:space:]]*:')\"\n[ -n \"${REMOTE}\" ] || REMOTE=\"$(extract_semver \"${REMOTE_RAW}\" '^[[:space:]]*-?[[:space:]]*(skills-)?version[[:space:]]*:')\"\n[ -n \"${REMOTE}\" ] || REMOTE=\"unknown\"\n\nstatus=\"UNKNOWN\"\nif [ \"${LOCAL}\" != \"unknown\" ] && [ \"${REMOTE}\" != \"unknown\" ]; then\n IFS=. read -r lmaj lmin lpat \u003c\u003cEOF\n${LOCAL}\nEOF\n IFS=. read -r rmaj rmin rpat \u003c\u003cEOF\n${REMOTE}\nEOF\n if [ \"${lmaj}\" -eq \"${rmaj}\" ] && [ \"${lmin}\" -eq \"${rmin}\" ] && [ \"${lpat}\" -eq \"${rpat}\" ]; then\n status=\"UP_TO_DATE\"\n elif [ \"${rmaj}\" -gt \"${lmaj}\" ]; then\n status=\"MAJOR_BEHIND\"\n elif [ \"${rmaj}\" -eq \"${lmaj}\" ] && [ \"${rmin}\" -gt \"${lmin}\" ]; then\n status=\"MINOR_BEHIND\"\n elif [ \"${rmaj}\" -eq \"${lmaj}\" ] && [ \"${rmin}\" -eq \"${lmin}\" ] && [ \"${rpat}\" -gt \"${lpat}\" ]; then\n status=\"PATCH_BEHIND\"\n else\n status=\"AHEAD\"\n fi\nfi\n\n# Ready-to-render heads-up line. Empty for the silent verdicts (UP_TO_DATE,\n# UNKNOWN). For every other verdict this is the EXACT markdown the skill must\n# surface verbatim as the first line of its reply — single source of truth, so\n# the wording can't drift between an implicit and an explicit trigger.\nheadsup=\"\"\ncase \"${status}\" in\n PATCH_BEHIND)\n headsup=\"> ⚠️ **Sumsub skills update available** — you're on **${LOCAL}**, latest is **${REMOTE}** (patch). Run \\`npx skills add sumsub/agent-skills --all\\` to update (drop \\`--all\\` if your CLI reports an unknown flag).\" ;;\n MINOR_BEHIND)\n headsup=\"> ⚠️ **Sumsub skills out of date** — you're on **${LOCAL}**, latest is **${REMOTE}**. Run \\`npx skills add sumsub/agent-skills --all\\` to update (drop \\`--all\\` if your CLI reports an unknown flag).\" ;;\n MAJOR_BEHIND)\n headsup=\"> 🚨 **Sumsub skills significantly behind** (**${LOCAL} → ${REMOTE}**) — behavior may have changed. Run \\`npx skills add sumsub/agent-skills --all\\` before relying on results (drop \\`--all\\` if your CLI reports an unknown flag).\" ;;\n AHEAD)\n headsup=\"> ℹ️ Sumsub skills **${LOCAL}** are ahead of the published **${REMOTE}** — likely a local dev build. Proceeding.\" ;;\nesac\n\n# Cache the rendered blockquote next to the script so the Phase-2 render step\n# (render_headsup.sh) can re-emit it LAST — after the user's task — with no\n# second curl. A stable ${SKILL_DIR} path survives a differing parent shell\n# between the two invocations.\nHEADSUP_CACHE=\"${SKILL_DIR}/.headsup_cache\"\n\nprintf 'local=%s\\nremote=%s\\nstatus=%s\\n' \"${LOCAL}\" \"${REMOTE}\" \"${status}\"\nif [ -n \"${headsup}\" ]; then\n printf 'headsup=%s\\n' \"${headsup}\"\n printf '%s\\n' \"${headsup}\" > \"${HEADSUP_CACHE}\" 2>/dev/null || true\nelse\n # Silent verdict (UP_TO_DATE / UNKNOWN): never leave a stale line behind.\n rm -f \"${HEADSUP_CACHE}\" 2>/dev/null || true\nfi\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":5074,"content_sha256":"31a4d5cdade99061384eac210adec4be78d3e53de3f2bd07dbde82f036e4de05"},{"filename":"scripts/render_headsup.sh","content":"#!/usr/bin/env bash\n# Phase 2 of the version-drift heads-up: re-emit the line computed earlier by\n# check_version.sh, as the LAST tool call before the model composes its reply.\n#\n# Its ENTIRE stdout is the bare markdown blockquote (no local=/remote=/status=\n# keys), so it can be relayed verbatim with zero risk of a raw-stdout dump.\n# Prints nothing (exit 0) when there is no drift to report — the model then\n# stays silent about the version.\n#\n# Why a separate step: only the model's FINAL reply is user-visible, and it\n# surfaces what is freshest in context. Running this LAST — after the user's\n# task — makes the heads-up the most recent tool output, so it survives into\n# the final reply instead of being buried behind the task result.\nset -euo pipefail\n\nSKILL_DIR=\"${CLAUDE_SKILL_DIR:-\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")/..\" && pwd)\"}\"\nHEADSUP_CACHE=\"${SKILL_DIR}/.headsup_cache\"\n\nif [ -s \"${HEADSUP_CACHE}\" ]; then\n cat \"${HEADSUP_CACHE}\"\n exit 0\nfi\n\n# Cache missing (e.g. read-only dir, or check not run yet this session): fall\n# back to recomputing so we never stay silent when actually behind. We re-run\n# check_version.sh and keep only its headsup= line, stripped of the key.\ncheck_out=\"$(bash \"${SKILL_DIR}/scripts/check_version.sh\" 2>/dev/null || true)\"\nprintf '%s\\n' \"${check_out}\" | sed -n 's/^headsup=//p' | head -n1\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":1344,"content_sha256":"7216f84ff42ec76107c29ff134bd4243f261404ba9b86a673e14524ada9fba23"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Sumsub: Check Skills Version","type":"text"}]},{"type":"paragraph","content":[{"text":"Detects version drift between the locally installed ","type":"text"},{"text":"@sumsub/agent-skills","type":"text","marks":[{"type":"code_inline"}]},{"text":" package and the canonical version published at ","type":"text"},{"text":"https://api.sumsub.com/llms.txt","type":"text","marks":[{"type":"code_inline"}]},{"text":", so that out-of-date skills don't silently produce stale or incorrect Sumsub behavior.","type":"text"}]},{"type":"paragraph","content":[{"text":"This skill's one user-visible deliverable is the ","type":"text","marks":[{"type":"strong"}]},{"text":"headsup","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" line.","type":"text","marks":[{"type":"strong"}]},{"text":" Running ","type":"text"},{"text":"check_version.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" only ","type":"text"},{"text":"computes","type":"text","marks":[{"type":"em"}]},{"text":" it; the skill has not done its job until that line appears in your reply to the user. Treat emitting it exactly like emitting the result of any other tool call — not as an optional courtesy.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Two-phase protocol (this is how the heads-up actually lands)","type":"text"}]},{"type":"paragraph","content":[{"text":"Only your FINAL reply reaches the user, and you surface what is freshest in your context when you compose it. If you compute the heads-up first and then do a task, the task result becomes the freshest thing and the heads-up gets dropped. To prevent that, split the work into two phases:","type":"text"}]},{"type":"paragraph","content":[{"text":"Phase 1 — compute the verdict (before the task).","type":"text","marks":[{"type":"strong"}]},{"text":" Run ","type":"text"},{"text":"check_version.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":". It computes the verdict and caches the rendered heads-up. Note whether a ","type":"text"},{"text":"headsup=","type":"text","marks":[{"type":"code_inline"}]},{"text":" line was printed; do ","type":"text"},{"text":"not","type":"text","marks":[{"type":"strong"}]},{"text":" write anything to the user yet.","type":"text"}]},{"type":"paragraph","content":[{"text":"Phase 2 — render LAST, then compose.","type":"text","marks":[{"type":"strong"}]},{"text":" Carry out the user's actual Sumsub task. Then, as your ","type":"text"},{"text":"final action before writing the reply","type":"text","marks":[{"type":"strong"}]},{"text":" — after the task, after every other tool call — run:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"bash ${CLAUDE_SKILL_DIR}/scripts/render_headsup.sh","type":"text"}]},{"type":"paragraph","content":[{"text":"Treat its stdout exactly like the result of any tool you must surface: if it prints a blockquote, that blockquote is the ","type":"text"},{"text":"first line","type":"text","marks":[{"type":"strong"}]},{"text":" of your reply, verbatim, rendered as markdown; then the task answer follows. If it prints nothing, say nothing about the version. The render step is deliberately your ","type":"text"},{"text":"last","type":"text","marks":[{"type":"em"}]},{"text":" tool call so the heads-up is the freshest thing in context when you compose — that is what makes it survive into the final reply.","type":"text"}]},{"type":"paragraph","content":[{"text":"For an explicit \"are my skills up to date?\" question there is no other task, so Phase 1 already leaves the heads-up as the freshest output — just lead your reply with it; the Phase-2 render is a no-op you can skip.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When NOT to run the check","type":"text"}]},{"type":"paragraph","content":[{"text":"Do ","type":"text"},{"text":"not","type":"text","marks":[{"type":"strong"}]},{"text":" invoke this skill, run ","type":"text"},{"text":"check_version.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":", or mention Sumsub-skills version drift when:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"The user asks about ","type":"text"},{"text":"non-Sumsub","type":"text","marks":[{"type":"strong"}]},{"text":" tools or vendors (Onfido, Persona, Stripe, etc.) — even if the topic is KYC.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"The user asks about ","type":"text"},{"text":"generic package freshness","type":"text","marks":[{"type":"strong"}]},{"text":" (","type":"text"},{"text":"npm outdated","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"pip list --outdated","type":"text","marks":[{"type":"code_inline"}]},{"text":", etc.) for their own project — that is unrelated to the ","type":"text"},{"text":"@sumsub/agent-skills","type":"text","marks":[{"type":"code_inline"}]},{"text":" npm bundle.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"The user explicitly says they are ","type":"text"},{"text":"not","type":"text","marks":[{"type":"strong"}]},{"text":" asking about Sumsub.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Never append a \"by the way, want me to check your Sumsub skills?\" sidenote on unrelated answers.","type":"text"}]},{"type":"paragraph","content":[{"text":"Anti-pattern (npm outdated):","type":"text","marks":[{"type":"strong"}]},{"text":" ❌ ","type":"text"},{"text":"\"Want me to run sumsub-check-skills-version instead?\"","type":"text","marks":[{"type":"em"}]},{"text":" or mentioning ","type":"text"},{"text":"agent-skills-version","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"llms.txt","type":"text","marks":[{"type":"code_inline"}]},{"text":" — the user's npm question is complete once you've summarized ","type":"text"},{"text":"npm outdated","type":"text","marks":[{"type":"code_inline"}]},{"text":". Stop there.","type":"text"}]},{"type":"paragraph","content":[{"text":"Anti-pattern (vendor comparison):","type":"text","marks":[{"type":"strong"}]},{"text":" ❌ Mentioning Sumsub skills version while comparing Onfido vs Persona. Answer only what was asked.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When to run the check","type":"text"}]},{"type":"paragraph","content":[{"text":"Run it ","type":"text"},{"text":"once per session","type":"text","marks":[{"type":"strong"}]},{"text":", before the first Sumsub-related action. Concretely:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Before calling any ","type":"text"},{"text":"mcp__Sumsub_Dev__*","type":"text","marks":[{"type":"code_inline"}]},{"text":" tool for the first time in this session.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Before walking the user through any Sumsub workflow (creating an applicant, requesting a check, reading a transaction, building a verification link, etc.).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"When the user explicitly asks whether their Sumsub skills are up to date.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Do not re-run the network check","type":"text","marks":[{"type":"strong"}]},{"text":" (","type":"text"},{"text":"check_version.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":") within the same session — repeated ","type":"text"},{"text":"curl","type":"text","marks":[{"type":"code_inline"}]},{"text":"s add latency without value. The Phase-2 ","type":"text"},{"text":"render_headsup.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" step does ","type":"text"},{"text":"not","type":"text","marks":[{"type":"strong"}]},{"text":" re-check; it only re-emits the cached verdict, and it is mandatory every time you produce a Sumsub answer in a session that found drift.","type":"text"}]},{"type":"paragraph","content":[{"text":"The check is non-blocking only in the sense that you do ","type":"text"},{"text":"not","type":"text","marks":[{"type":"strong"}]},{"text":" pause or wait for the user before continuing — it does ","type":"text"},{"text":"not","type":"text","marks":[{"type":"strong"}]},{"text":" mean the heads-up is optional or skippable. Follow the two-phase protocol above, then proceed with the user's task in the same reply.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"How to run the check","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"bash ${CLAUDE_SKILL_DIR}/scripts/check_version.sh","type":"text"}]},{"type":"paragraph","content":[{"text":"It prints up to four ","type":"text"},{"text":"key=value","type":"text","marks":[{"type":"code_inline"}]},{"text":" lines on stdout:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"local=1.0.1\nremote=1.0.2\nstatus=PATCH_BEHIND\nheadsup=> ⚠️ **Sumsub skills update available** — you're on **1.0.1**, latest is **1.0.2** (patch). Run `npx skills add sumsub/agent-skills --all` to update.","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"local","type":"text","marks":[{"type":"code_inline"}]},{"text":" — installed version (baked into ","type":"text"},{"text":"references/version.txt","type":"text","marks":[{"type":"code_inline"}]},{"text":" at publish time).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"remote","type":"text","marks":[{"type":"code_inline"}]},{"text":" — canonical version parsed from the ","type":"text"},{"text":"agent-skills-version:","type":"text","marks":[{"type":"code_inline"}]},{"text":" line of the canonical ","type":"text"},{"text":"llms.txt","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"status","type":"text","marks":[{"type":"code_inline"}]},{"text":" — the verdict (see below).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"headsup","type":"text","marks":[{"type":"code_inline"}]},{"text":" — present only for non-silent verdicts; the ","type":"text"},{"text":"exact","type":"text","marks":[{"type":"strong"}]},{"text":" markdown line to surface. Don't emit it from here — Phase 1 just caches it; the Phase-2 ","type":"text"},{"text":"render_headsup.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" step re-prints it (as a clean blockquote) when you're ready to compose. Never echo the ","type":"text"},{"text":"local=","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"remote=","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"status=","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"headsup=","type":"text","marks":[{"type":"code_inline"}]},{"text":" keys themselves.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"The remote URL is ","type":"text"},{"text":"https://api.sumsub.com/llms.txt","type":"text","marks":[{"type":"code_inline"}]},{"text":". No credentials needed — it's a public static file. Override with the ","type":"text"},{"text":"SUMSUB_VERSION_URL","type":"text","marks":[{"type":"code_inline"}]},{"text":" environment variable for testing.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"How to handle each verdict","type":"text"}]},{"type":"paragraph","content":[{"text":"The ","type":"text"},{"text":"headsup","type":"text","marks":[{"type":"code_inline"}]},{"text":" text is produced once, by Phase 1, and re-emitted by Phase 2's ","type":"text"},{"text":"render_headsup.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":"; you never hand-write it. Whatever the render step prints becomes the first line of your reply, verbatim. If it prints nothing (silent verdict), say nothing about the version. The heads-up is shown ","type":"text"},{"text":"once per session","type":"text","marks":[{"type":"strong"}]},{"text":".","type":"text"}]},{"type":"paragraph","content":[{"text":"For reference, what each verdict means:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"status","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"headsup","type":"text","marks":[{"type":"code_inline"}]},{"text":" present?","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Meaning","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"UP_TO_DATE","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"no","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Installed version matches the published one — stay silent.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"PATCH_BEHIND","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"yes","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"A patch release is available — surface the line, then proceed.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"MINOR_BEHIND","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"yes","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"A minor release is available — surface the line, then proceed.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"MAJOR_BEHIND","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"yes","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Significantly behind; behavior may have changed — surface the line, then proceed.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"AHEAD","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"yes","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Local is newer than published (likely a dev build) — surface the line, then proceed.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"UNKNOWN","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"no","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Remote unreachable or unparseable — stay silent, never block the user.","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"Important: never block the user's request because of the verdict, and never show the heads-up more than once in the same session — if you've already shown it in this conversation, don't repeat it.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Worked example — implicit trigger","type":"text"}]},{"type":"paragraph","content":[{"text":"The most common case: the check runs as a background step before some other Sumsub task, verdict is non-","type":"text"},{"text":"UP_TO_DATE","type":"text","marks":[{"type":"code_inline"}]},{"text":". Order of operations:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Phase 1","type":"text","marks":[{"type":"strong"}]},{"text":" — run ","type":"text"},{"text":"check_version.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" (verdict ","type":"text"},{"text":"PATCH_BEHIND","type":"text","marks":[{"type":"code_inline"}]},{"text":", local ","type":"text"},{"text":"1.0.0","type":"text","marks":[{"type":"code_inline"}]},{"text":", remote ","type":"text"},{"text":"1.0.1","type":"text","marks":[{"type":"code_inline"}]},{"text":"; heads-up cached). Write nothing yet.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Do the task — look up the transaction.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Phase 2","type":"text","marks":[{"type":"strong"}]},{"text":" — run ","type":"text"},{"text":"render_headsup.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" as your last action; it prints the blockquote.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Compose the reply: blockquote first, task answer after.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"User: ","type":"text"},{"text":"\"look up sumsub transaction 65a3… — what risk score and which rules fired?\"","type":"text","marks":[{"type":"em"}]}]},{"type":"paragraph","content":[{"text":"Your reply:","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"⚠️ ","type":"text"},{"text":"Sumsub skills update available","type":"text","marks":[{"type":"strong"}]},{"text":" — you're on ","type":"text"},{"text":"1.0.0","type":"text","marks":[{"type":"strong"}]},{"text":", latest is ","type":"text"},{"text":"1.0.1","type":"text","marks":[{"type":"strong"}]},{"text":" (patch). Run ","type":"text"},{"text":"npx skills add sumsub/agent-skills --all","type":"text","marks":[{"type":"code_inline"}]},{"text":" to update.","type":"text"}]}]},{"type":"paragraph","content":[{"text":"Transaction ","type":"text"},{"text":"65a3…","type":"text","marks":[{"type":"code_inline"}]},{"text":": risk score 78 (RED), 2 rules fired — …answer the actual request here…","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Notes","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"The check needs no API credentials — the canonical ","type":"text"},{"text":"llms.txt","type":"text","marks":[{"type":"code_inline"}]},{"text":" is a public static file.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"The local version lives in ","type":"text"},{"text":"references/version.txt","type":"text","marks":[{"type":"code_inline"}]},{"text":" and is bumped together with ","type":"text"},{"text":"public/package.json","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"public/skills.json","type":"text","marks":[{"type":"code_inline"}]},{"text":" on every release.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If the canonical source moves (host change, or migration to a different file shape), set ","type":"text"},{"text":"SUMSUB_VERSION_URL","type":"text","marks":[{"type":"code_inline"}]},{"text":" to the new location; the script accepts an ","type":"text"},{"text":"agent-skills-version:","type":"text","marks":[{"type":"code_inline"}]},{"text":" line (preferred), a JSON ","type":"text"},{"text":"\"version\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" field, or a bare ","type":"text"},{"text":"version:","type":"text","marks":[{"type":"code_inline"}]},{"text":" line.","type":"text"}]}]}]}]},"metadata":{"date":"2026-11-02","name":"sumsub-check-skills-version","author":"@skillopedia","source":{"stars":7,"repo_name":"agent-skills","origin_url":"https://github.com/sumsub/agent-skills/blob/HEAD/skills/sumsub-check-skills-version/SKILL.md","repo_owner":"sumsub","body_sha256":"3814971fe6f54bc12e13776fa371a939e3b16117a9d2bae4d51290b30a77efc8","cluster_key":"153d6d78fa482cc0ca76b66eb8030bde3a3f92d83b6c2934abbea50347c1818e","clean_bundle":{"format":"clean-skill-bundle-v1","source":"sumsub/agent-skills/skills/sumsub-check-skills-version/SKILL.md","text_bytes":6424,"source_commit":"b7e17238a84b56d3b07c96a459d19a07e23f6020","skills_sh_rank":11037,"attachment_count":3,"text_attachments":3,"attachment_storage":"skill_attachments","binary_attachments":0},"cluster_size":1,"skill_md_path":"skills/sumsub-check-skills-version/SKILL.md","import_metadata":{"date":"2026-11-02","author":"@skillopedia","version":"v1","category":"integrations-apis","category_label":"Integrations"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"integrations-apis","import_tag":"skills-sh-top20k-2026-11","description":"Verify that the locally installed Sumsub agent-skills package is compatible with the published version before doing any Sumsub work. TRIGGER at the start of any task that touches Sumsub — Sumsub Dev MCP tools (mcp__Sumsub_Dev__*), KYC/AML workflows, applicants, checks, transactions, verification levels, verification links, questionnaires, fraud network, VASP lists, or anything Sumsub-related — so the user is warned before a stale skills package produces wrong results. Also use this skill when the user explicitly asks \"are my Sumsub skills up to date / current\", \"is there a newer version of the Sumsub skills\", or similar. Skip the actual update (the user runs `npx skills add sumsub/agent-skills --all` themselves) and skip any other Sumsub API or entity task — those have their own skills.","allowed-tools":"Bash"}},"renderedAt":1793666728182}

Sumsub: Check Skills Version Detects version drift between the locally installed package and the canonical version published at , so that out-of-date skills don't silently produce stale or incorrect Sumsub behavior. This skill's one user-visible deliverable is the line. Running only computes it; the skill has not done its job until that line appears in your reply to the user. Treat emitting it exactly like emitting the result of any other tool call — not as an optional courtesy. Two-phase protocol (this is how the heads-up actually lands) Only your FINAL reply reaches the user, and you surfac…