From mk
Fetches arbitrary URLs and returns clean markdown. Useful when Claude needs content from blogs, RFCs, GitHub issues, or vendor docs not covered by curated documentation skills.
How this skill is triggered — by the user, by Claude, or both
Slash command
/mk:web-to-markdown <url> [--wtm-accept-risk] [--wtm-approve]When to use
Use when fetching an arbitrary external page (blog, RFC, GitHub issue, vendor doc) not covered by mk:docs-finder. NOT for library/framework docs (see mk:docs-finder).
<url> [--wtm-accept-risk] [--wtm-approve]The summary Claude sees in its skill listing — used to decide when to auto-load this skill
<!--
references/gotchas.mdreferences/security.mdscripts/fetch_as_markdown.pyscripts/html_to_markdown.pyscripts/http_fetch.pyscripts/injection_detect.pyscripts/injection_patterns.pyscripts/persist_fetch.pyscripts/rate_limit.pyscripts/requirements.txtscripts/robots_cache.pyscripts/secret_scrub.pytests/test_e2e_offline.pytests/test_smoke_real_urls.pyFetch arbitrary URLs and return clean markdown with injection defense.
"summarize https://example.com/blog" → skill fires automaticallymk:docs-finder for libraries/frameworks)--wtm-accept-risk delegation gatemk:docs-finder (Context7, Context Hub, WebSearch)mk:agent-browsermk:playwright-cliWebFetch tool (proxied by the runtime vendor)User: "fetch https://docs.example.com/api and explain the auth flow"
Agent: [invokes mk:web-to-markdown directly]
--wtm-accept-risk)mk:research → mk:web-to-markdown --wtm-accept-risk <url>
mk:intake → mk:web-to-markdown --wtm-accept-risk <url>
Other skills MUST pass --wtm-accept-risk to delegate. Without it, the skill refuses the call and returns ERROR: cross-skill delegation requires --wtm-accept-risk flag. This forces conscious crossing of the trust boundary and creates an audit trail.
--wtm-approve)mk:docs-finder --wtm-approve <url>
# → skips Context7 / chub / WebSearch tiers
# → goes directly to mk:web-to-markdown
Used when the user knows the target URL is not in any curated index and wants to skip the wasted hops.
See references/security.md for the full threat model, attack surface, and defense architecture.
Non-negotiable defenses:
huge_tree=Falseprivacy-block.sh hook-layer enforcement of SSRF + cache/manifest read blocksinjection-audit.py post-write library scan (called from persist_fetch.persist via scan_file import, not CLI).claude/scripts/bin/setup-workflow --system-deps. This is intentional — 200MB Chromium download is not worth the 5% of pages that need it.rm -rf .claude/cache/web-fetches/*. v2 will add TTL auto-cleanup.ls-based discovery. Use the manifest index.jsonl (behind privacy-block) to search.SKILL.md — this file (entrypoint + frontmatter)references/security.md — master security spec (threat model, defenses, enforcement layers)references/gotchas.mdscripts/fetch_as_markdown.pyscripts/persist_fetch.pyscripts/injection_detect.pyscripts/requirements.txt —tests/test_smoke_real_urls.pyStatic fetch (always):
.claude/skills/.venv/bin/pip install -r scripts/requirements.txt
# requests, readability-lxml, html2text, lxml, charset-normalizer
JS rendering (opt-in via .claude/scripts/bin/setup-workflow --system-deps):
.claude/skills/.venv/bin/pip install playwright==1.58.0
.claude/skills/.venv/bin/playwright install chromium # ~200MB one-time
To enable JS rendering at runtime, set MEOWKIT_WEB_FETCH_JS=1 before invoking the skill. All three gates must be open: Playwright installed, MEOWKIT_WEB_FETCH_JS=1, and js=True per-call argument. See references/security.md for the three-layer JS gate spec.
npx claudepluginhub ngocsangyem/meowkit --plugin mkFetches web content as clean Markdown with 80% fewer tokens than raw HTML. Handles JS-heavy sites, documentation, and articles via auto, AI, or browser rendering.
Converts website URLs to markdown.new links for cleaner Markdown views of docs, blogs, GitHub issues, and articles. Useful for reading and extracting text content.
Fetches any URL and returns clean Markdown via local trafilatura, with Exa MCP fallback for JS-rendered or anti-bot pages. Use instead of built-in WebFetch for reading, scraping, or summarizing web pages.