Skill: claudy-my-laudy/jina-ai-skill (version 1.0.0)

--- name: jina-reader description: "Fetch the markdown content of any webpage using Jina AI's Reader API (r.jina.ai), or search the web using Jina AI's Search API (s.jina.ai). Use this skill whenever you need to read a URL and get clean LLM-friendly markdown output, extract article/documentation content from a page, or search the web and retrieve rich results with content. Triggers on: read this URL, fetch this page, get the content of, what does this page say, summarize this link, search the web for, look up, or any request requiring clean markdown from a URL." --- # Jina Reader & Search Skill Two APIs, zero API key required (optional key for higher rate limits). ## Reader — Fetch a URL as Markdown **Simple (shell):** ```bash curl -s "https://r.jina.ai/<URL>" ``` **With script:** ```bash python3 skills/jina-reader/scripts/jina_read.py <URL> python3 skills/jina-reader/scripts/jina_read.py <URL> --no-images # strip images python3 skills/jina-reader/scripts/jina_read.py <URL> --json # structured JSON response ``` **With API key (set in .env):** ```bash JINA_API_KEY=your_key python3 skills/jina-reader/scripts/jina_read.py <URL> ``` **Useful request headers (for direct curl):** | Header | Purpose | |--------|---------| | `Authorization: Bearer <key>` | Higher rate limits | | `X-Return-Format: markdown` | Force markdown output | | `X-Remove-Selector: img` | Strip images | | `Accept: application/json` | JSON response with title, url, content | ## Search — Web Search via Jina **Simple (shell):** ```bash curl -s "https://s.jina.ai/<URL-encoded-query>" ``` **With script:** ```bash python3 skills/jina-reader/scripts/jina_search.py "your query" python3 skills/jina-reader/scripts/jina_search.py "your query" --json python3 skills/jina-reader/scripts/jina_search.py "your query" --json --results 3 ``` ## API Key | API | Without Key | With Key | |-----|-------------|----------| | Reader (`r.jina.ai`) | ✅ Works (rate-limited) | Higher limits | | Search (`s.jina.ai`) | ❌ Requires key | ✅ Works | Store as `JINA_API_KEY` in `.env`. Get a free key at: https://jina.ai/api-dashboard > **No key for search?** Use the `duckduckgo-search` skill as a fallback. ## Notes - Reader works on most pages including JS-heavy sites - Search returns up to 5 results by default, each with title, URL, and content summary - For very long pages, use `--no-images` to reduce token usage

path: scripts/jina_read.py
content: #!/usr/bin/env python3
"""
Jina Reader - Fetch a URL and return its markdown content via r.jina.ai
Usage: python3 jina_read.py <url> [--no-images] [--json]
"""

import sys
import os
import urllib.request
import urllib.parse
import json

def read_url(url, no_images=False, as_json=False):
    [REDACTED_SECRET]"JINA_API_KEY", "")
    endpoint = f"https://r.jina.ai/{url}"

    headers = {
        "X-Return-Format": "markdown",
        "User-Agent": "Mozilla/5.0",
    }
    if as_json:
        headers["Accept"] = "application/json"
    if [REDACTED_SECRET]"Authorization"] = f"Bearer {api_key}"
    if no_images:
        headers["X-Remove-Selector"] = "img"

    req = urllib.request.Request(endpoint, headers=headers)
    with urllib.request.urlopen(req, timeout=30) as resp:
        body = resp.read().decode("utf-8")

    if as_json:
        data = json.loads(body)
        return data
    return body

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: python3 jina_read.py <url> [--no-images] [--json]")
        sys.exit(1)

    url = sys.argv[1]
    no_images = "--no-images" in sys.argv
    as_json = "--json" in sys.argv

    result = read_url(url, no_images=no_images, as_json=as_json)

    if as_json:
        print(json.dumps(result, indent=2, ensure_ascii=False))
    else:
        print(result)


path: scripts/jina_search.py
content: #!/usr/bin/env python3
"""
Jina Search - Search the web via s.jina.ai and return markdown results
Usage: python3 jina_search.py <query> [--json] [--results N]
"""

import sys
import os
import urllib.request
import urllib.parse
import json

def search(query, as_json=False, max_results=5):
    [REDACTED_SECRET]"JINA_API_KEY", "")
    encoded_query = urllib.parse.quote(query)
    endpoint = f"https://s.jina.ai/{encoded_query}"

    headers = {
        "Accept": "application/json" if as_json else "text/plain",
        "X-Return-Format": "markdown",
        "User-Agent": "Mozilla/5.0",
    }
    if [REDACTED_SECRET]"Authorization"] = f"Bearer {api_key}"

    req = urllib.request.Request(endpoint, headers=headers)
    with urllib.request.urlopen(req, timeout=30) as resp:
        body = resp.read().decode("utf-8")

    if as_json:
        data = json.loads(body)
        # Trim to max_results if data is a list
        if isinstance(data, dict) and "data" in data:
            data["data"] = data["data"][:max_results]
        return data
    return body

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: python3 jina_search.py <query> [--json] [--results N]")
        sys.exit(1)

    args = sys.argv[1:]
    as_json = "--json" in args
    if "--json" in args:
        args.remove("--json")

    max_results = 5
    if "--results" in args:
        idx = args.index("--results")
        max_results = int(args[idx + 1])
        args.pop(idx + 1)
        args.pop(idx)

    query = " ".join(args)

    result = search(query, as_json=as_json, max_results=max_results)

    if as_json:
        print(json.dumps(result, indent=2, ensure_ascii=False))
    else:
        print(result)


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (HIGH)