Loading...
Loading...
Web content fetching and URL retrieval via curl and WebFetch — replaces the Fetch MCP server (fetch_html, fetch_json, fetch_markdown, fetch_txt). Use this skill when a specific URL is provided and the user wants its content. Covers HTTP GET/POST, JSON API consumption with jq, HTML retrieval, markdown conversion, plain text extraction, authenticated requests, redirects, cookies, and timeouts. Trigger phrases: "fetch this URL", "get the page content", "download HTML", "call this API", "curl this endpoint", "grab the JSON", "fetch markdown from", "retrieve web content", "hit this endpoint", "scrape this page", "read this URL", "pull data from API", "make an HTTP request", "extract page content", "get article text". NOT for web searches without a URL — use tavily for that.
npx skill4agent add mathews-tom/praxis-skills web-fetchcurlWebFetch| Fetch MCP Tool | Replacement | When to Use |
|---|---|---|
| | Raw HTML needed for parsing |
| | API responses, structured data |
| | Readable page content (default output is markdown) |
| | Plain text extraction |
WebFetchcurlWebFetchcurlcurl -sL "https://example.com/page"| Flag | Purpose |
|---|---|
| Silent mode — suppress progress meter |
| Follow redirects (3xx) |
| Save to file instead of stdout |
| Headers only (HEAD request) |
| Include response headers in output |
xmllintpython3curl -sL "https://example.com" | python3 -c "
from html.parser import HTMLParser
import sys
class TitleParser(HTMLParser):
def __init__(self):
super().__init__()
self.in_title = False
self.title = ''
def handle_starttag(self, tag, attrs):
self.in_title = tag == 'title'
def handle_data(self, data):
if self.in_title:
self.title += data
def handle_endtag(self, tag):
if tag == 'title':
self.in_title = False
p = TitleParser()
p.feed(sys.stdin.read())
print(p.title)
"curl -s "https://api.example.com/v1/data" \
-H "Accept: application/json" | jq '.'# Extract specific fields
curl -s "https://api.example.com/users" | jq '.[] | {name, email}'
# Filter by condition
curl -s "https://api.example.com/items" | jq '[.[] | select(.status == "active")]'
# Count results
curl -s "https://api.example.com/items" | jq 'length'
# Get nested value
curl -s "https://api.example.com/config" | jq '.database.host'# Strip HTML tags for plain text
curl -sL "https://example.com/page" | python3 -c "
import html.parser, sys
class Stripper(html.parser.HTMLParser):
def __init__(self):
super().__init__()
self.text = []
def handle_data(self, d):
self.text.append(d)
def get_text(self):
return ''.join(self.text)
s = Stripper()
s.feed(sys.stdin.read())
print(s.get_text())
"WebFetchcurl -s "https://api.example.com/data" \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json"curl -s "https://api.example.com/data" \
-H "X-API-Key: $API_KEY"curl -s "https://api.example.com/data?api_key=$API_KEY"curl -s -u "username:$PASSWORD" "https://api.example.com/data"curl -s -X POST "https://api.example.com/items" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_TOKEN" \
-d '{
"name": "item-name",
"value": 42
}' | jq '.'curl -s -X POST "https://api.example.com/upload" \
-F "file=@./document.pdf" \
-F "description=Uploaded via curl"curl -s -X PUT "https://api.example.com/items/123" \
-H "Content-Type: application/json" \
-d '{"name": "updated-name", "value": 99}' | jq '.'curl -s -X PATCH "https://api.example.com/items/123" \
-H "Content-Type: application/json" \
-d '{"value": 100}' | jq '.'curl -s -X DELETE "https://api.example.com/items/123" \
-H "Authorization: Bearer $API_TOKEN"PAGE=1
while true; do
RESPONSE=$(curl -s "https://api.example.com/items?page=$PAGE&per_page=50" \
-H "Authorization: Bearer $API_TOKEN")
COUNT=$(echo "$RESPONSE" | jq 'length')
echo "$RESPONSE" | jq '.[]'
[ "$COUNT" -lt 50 ] && break
PAGE=$((PAGE + 1))
donecurl -s --connect-timeout 10 --max-time 30 \
--retry 3 --retry-delay 2 \
"https://api.example.com/data"curl -sI "https://example.com" | grep -i "content-type"HTTP_CODE=$(curl -s -o /tmp/response.json -w "%{http_code}" "https://api.example.com/data")
echo "Status: $HTTP_CODE"
cat /tmp/response.json | jq '.'# Save cookies
curl -s -c /tmp/cookies.txt "https://example.com/login" \
-d "user=admin&pass=$PASSWORD"
# Reuse cookies
curl -s -b /tmp/cookies.txt "https://example.com/dashboard"| HTTP Status | Meaning | Resolution |
|---|---|---|
| 301/302 | Redirect | Add |
| 401 | Unauthorized | Check token/credentials; verify env var is set |
| 403 | Forbidden | Insufficient permissions or IP restriction |
| 404 | Not Found | Verify URL path; resource may be deleted |
| 429 | Rate Limited | Respect |
| 500 | Server Error | Retry once; if persistent, report upstream |
| SSL error | Certificate issue | Do not use |
| Timeout | Network/server slow | Increase |
curl -sI -o /dev/null -w "%{http_code}" "https://example.com"curlWebFetchjqheadpython3-o$ENV_VAR-L-s