
Http Request
- 62 installs
- Updated February 27, 2026
- winsorllc/upgraded-carnival
Helps with ai & agent building tasks.
About
http-request is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- http-request
- AI & Agent Building
- AI-coding skill
Http Request by the numbers
- 62 all-time installs (skills.sh)
- +1 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #6,310 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Jul 27, 2026 (Skillselion catalog sync)
npx skills add https://github.com/winsorllc/upgraded-carnival --skill http-requestAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 62 |
|---|---|
| Last updated | February 27, 2026 |
| Repository | winsorllc/upgraded-carnival ↗ |
What it does
Helps with ai & agent building tasks.
Files
HTTP Request Skill
Make HTTP requests with enhanced output and JSON handling.
When to Use
✅ USE this skill when:
- "Make a GET request to..."
- "POST this JSON to..."
- "Call this API endpoint"
- "Download data from URL"
- "Test an API"
When NOT to Use
❌ DON'T use this skill when:
- Simple file downloads → use web-fetch/download.sh
- Browser automation → use browser-tools
- Web scraping → use web-fetch
Commands
GET Request
{baseDir}/request.sh GET "https://api.example.com/data"
{baseDir}/request.sh GET "https://api.example.com/data" --json
{baseDir}/request.sh GET "https://api.example.com/data" --header "Authorization: Bearer token"POST Request
{baseDir}/request.sh POST "https://api.example.com/create" --data '{"name": "test"}'
{baseDir}/request.sh POST "https://api.example.com/create" --file data.json
{baseDir}/request.sh POST "https://api.example.com/upload" --form "file=@upload.txt"PUT/PATCH/DELETE
{baseDir}/request.sh PUT "https://api.example.com/update/1" --data '{"name": "updated"}'
{baseDir}/request.sh PATCH "https://api.example.com/patch/1" --data '{"status": "active"}'
{baseDir}/request.sh DELETE "https://api.example.com/delete/1"With Authentication
{baseDir}/request.sh GET "https://api.example.com/private" --auth bearer:TOKEN
{baseDir}/request.sh GET "https://api.example.com/private" --auth basic:user:pass
{baseDir}/request.sh GET "https://api.example.com/private" --header "X-API-Key: secret"Custom Options
{baseDir}/request.sh GET "https://api.example.com" --timeout 60
{baseDir}/request.sh GET "https://api.example.com" --follow --max-redirects 5
{baseDir}/request.sh GET "https://api.example.com" --verboseOptions
--data <json>: Request body (JSON string)--file <path>: Read request body from file--form <data>: Form data or file upload (@filename)--header <header>: Custom header (can be repeated)--auth <type:credentials>: Authentication (bearer:TOKEN or basic:user:pass)--timeout <sec>: Request timeout (default: 30)--json: Format JSON response--verbose: Show request details--follow: Follow redirects--max-redirects <n>: Max redirects (default: 5)--out <file>: Save response to file
Examples
Get JSON and format:
{baseDir}/request.sh GET "https://jsonplaceholder.typicode.com/users" --jsonPOST data:
{baseDir}/request.sh POST "https://api.example.com/users" \
--data '{"name": "John", "email": "john@example.com"}' \
--jsonWith Bearer token:
{baseDir}/request.sh GET "https://api.example.com/protected" \
--auth bearer:your_token_hereUpload file:
{baseDir}/request.sh POST "https://api.example.com/upload" \
--form "file=@document.pdf"Notes
- Automatically adds Content-Type: application/json for JSON data
- Handles response body parsing
- Shows response headers with --verbose
- Supports multipart form data uploads
const https = require('https');
const http = require('http');
const { URL } = require('url');
const MAX_RESPONSE_SIZE = 10 * 1024 * 1024;
const DEFAULT_TIMEOUT = 30000;
function validateUrl(urlString) {
try {
const url = new URL(urlString);
if (!['http:', 'https:'].includes(url.protocol)) {
throw new Error('Only http:// and https:// URLs allowed');
}
const host = url.hostname.toLowerCase();
if (host === 'localhost' ||
host.startsWith('10.') ||
host.startsWith('192.168.') ||
host.startsWith('127.') ||
host.startsWith('0.') ||
host.endsWith('.local') ||
host.endsWith('.internal') ||
host === 'internal') {
throw new Error('Blocked: private/internal host');
}
return url;
} catch (e) {
throw new Error(`Invalid URL: ${e.message}`);
}
}
async function httpRequest(url, options = {}) {
const parsedUrl = validateUrl(url);
return new Promise((resolve, reject) => {
const client = parsedUrl.protocol === 'https:' ? https : http;
const reqOptions = {
hostname: parsedUrl.hostname,
port: parsedUrl.port || (parsedUrl.protocol === 'https:' ? 443 : 80),
path: parsedUrl.pathname + parsedUrl.search,
method: options.method || 'GET',
headers: options.headers || {},
timeout: options.timeout || DEFAULT_TIMEOUT
};
const req = client.request(reqOptions, (res) => {
let data = '';
let receivedSize = 0;
res.on('data', chunk => {
receivedSize += chunk.length;
if (receivedSize > MAX_RESPONSE_SIZE) {
req.destroy();
reject(new Error(`Response exceeds max size`));
}
data += chunk;
});
res.on('end', () => {
try {
const json = JSON.parse(data);
resolve({
status: res.statusCode,
headers: res.headers,
data: json
});
} catch (e) {
resolve({
status: res.statusCode,
headers: res.headers,
data: data
});
}
});
});
req.on('error', reject);
req.on('timeout', () => {
req.destroy();
reject(new Error('Request timeout'));
});
if (options.body) {
const bodyData = typeof options.body === 'string'
? options.body
: JSON.stringify(options.body);
req.write(bodyData);
}
req.end();
});
}
async function get(url, headers = {}) {
return httpRequest(url, { method: 'GET', headers });
}
async function post(url, data, headers = {}) {
return httpRequest(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json', ...headers },
body: data
});
}
async function put(url, data, headers = {}) {
return httpRequest(url, {
method: 'PUT',
headers: { 'Content-Type': 'application/json', ...headers },
body: data
});
}
async function del(url, headers = {}) {
return httpRequest(url, { method: 'DELETE', headers });
}
// Retry with exponential backoff
async function fetchWithRetry(url, options = {}, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await httpRequest(url, options);
} catch (error) {
if (i === maxRetries - 1) throw error;
const delay = Math.pow(2, i) * 1000;
await new Promise(r => setTimeout(r, delay));
}
}
}
async function main() {
const args = process.argv.slice(2);
const command = args[0];
const url = args[1];
if (!command || !url) {
console.log('Usage: node index.js <method> <url> [options]');
console.log('Methods: get, post, put, delete');
console.log('Examples:');
console.log(' node index.js get https://api.github.com/users/octocat');
console.log(' node index.js post https://httpbin.org/post --body \'{"test":true}\'');
process.exit(1);
}
try {
let response;
let headers = {};
let body = null;
// Parse additional args
for (let i = 2; i < args.length; i++) {
if (args[i] === '--header' && args[i + 1]) {
const [key, value] = args[++i].split(':');
headers[key] = value.trim();
} else if (args[i] === '--body' && args[i + 1]) {
body = args[++i];
}
}
switch (command.toLowerCase()) {
case 'get':
response = await get(url, headers);
break;
case 'post':
response = await post(url, body ? JSON.parse(body) : {}, headers);
break;
case 'put':
response = await put(url, body ? JSON.parse(body) : {}, headers);
break;
case 'delete':
response = await del(url, headers);
break;
default:
console.error('Unknown method:', command);
process.exit(1);
}
console.log(`Status: ${response.status}`);
console.log('Headers:', JSON.stringify(response.headers, null, 2));
console.log('\nData:');
console.log(typeof response.data === 'object'
? JSON.stringify(response.data, null, 2)
: response.data);
} catch (error) {
console.error('Error:', error.message);
process.exit(1);
}
}
if (require.main === module) {
main();
}
module.exports = {
httpRequest,
get,
post,
put,
del,
fetchWithRetry
};
#!/bin/bash
# HTTP Request Tool - Make HTTP requests with enhanced output
set -euo pipefail
usage() {
cat >&2 <<'EOF'
Usage: request.sh <method> <url> [options]
Methods:
GET, POST, PUT, PATCH, DELETE
Options:
--data <json> Request body (JSON string)
--file <path> Read request body from file
--form <data> Form data or file upload (@filename)
--header <header> Custom header (can be repeated)
--auth <type:creds> Authentication: bearer:TOKEN or basic:user:pass
--timeout <sec> Request timeout (default: 30)
--json Format JSON response
--verbose Show request/response details
--follow Follow redirects
--max-redirects <n> Max redirects (default: 5)
--out <file> Save response to file
-h, --help Show this help
Examples:
request.sh GET "https://api.example.com/data" --json
request.sh POST "https://api.example.com/create" --data '{"name":"test"}'
request.sh GET "https://api.example.com" --auth bearer:TOKEN
request.sh POST "https://api.example.com/upload" --form "file=@data.pdf"
EOF
exit 2
}
# Default values
METHOD=""
URL=""
DATA=""
FILE=""
FORM=""
HEADERS=()
AUTH=""
TIMEOUT=30
JSON=false
VERBOSE=false
FOLLOW=false
MAX_REDIRECTS=5
OUT=""
# Parse arguments
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
usage
;;
--data)
shift
DATA="$1"
;;
--file)
shift
FILE="$1"
;;
--form)
shift
FORM="$1"
;;
--header)
shift
HEADERS+=("-H" "$1")
;;
--auth)
shift
AUTH="$1"
;;
--timeout)
shift
TIMEOUT="$1"
;;
--json)
JSON=true
;;
--verbose)
VERBOSE=true
;;
--follow)
FOLLOW=true
;;
--max-redirects)
shift
MAX_REDIRECTS="$1"
;;
--out)
shift
OUT="$1"
;;
GET|POST|PUT|PATCH|DELETE)
METHOD="$1"
;;
http://*|https://*)
URL="$1"
;;
-*)
echo "Unknown option: $1" >&2
usage
;;
*)
if [[ -z "$METHOD" ]]; then
METHOD="$1"
elif [[ -z "$URL" ]]; then
URL="$1"
fi
;;
esac
shift
done
if [[ -z "$METHOD" ]]; then
echo "Error: HTTP method required" >&2
usage
fi
if [[ -z "$URL" ]]; then
echo "Error: URL required" >&2
usage
fi
# Build curl arguments
CURL_ARGS=("-X" "$METHOD" "-s" "-S")
# Add timeout
CURL_ARGS+=("--connect-timeout" "$TIMEOUT" "--max-time" "$TIMEOUT")
# Follow redirects
if [[ "$FOLLOW" == "true" ]]; then
CURL_ARGS+=("-L" "--max-redirs" "$MAX_REDIRECTS")
fi
# Add headers
for header in "${HEADERS[@]}"; do
CURL_ARGS+=("-H" "$header")
done
# Add authentication
if [[ -n "$AUTH" ]]; then
AUTH_TYPE="${AUTH%%:*}"
AUTH_VALUE="${AUTH#*:}"
case "$AUTH_TYPE" in
bearer)
CURL_ARGS+=("-H" "Authorization: Bearer $AUTH_VALUE")
;;
basic)
CURL_ARGS+=("-u" "$AUTH_VALUE")
;;
*)
echo "Error: Unknown auth type: $AUTH_TYPE" >&2
exit 1
;;
esac
fi
# Add request body
if [[ -n "$DATA" ]]; then
CURL_ARGS+=("-d" "$DATA")
# Auto-add JSON content type if not already set
if [[ "$DATA" == "{"* ]] && ! printf '%s\n' "${HEADERS[@]}" | grep -q "Content-Type"; then
CURL_ARGS+=("-H" "Content-Type: application/json")
fi
elif [[ -n "$FILE" ]]; then
if [[ ! -f "$FILE" ]]; then
echo "Error: File not found: $FILE" >&2
exit 1
fi
CURL_ARGS+=("-d" "@$FILE")
if [[ "$FILE" == *.json ]] && ! printf '%s\n' "${HEADERS[@]}" | grep -q "Content-Type"; then
CURL_ARGS+=("-H" "Content-Type: application/json")
fi
elif [[ -n "$FORM" ]]; then
CURL_ARGS+=("-F" "$FORM")
fi
# Verbose output
if [[ "$VERBOSE" == "true" ]]; then
echo "Request:" >&2
echo " Method: $METHOD" >&2
echo " URL: $URL" >&2
if [[ -n "$DATA" ]]; then
echo " Body: $DATA" >&2
fi
echo "" >&2
fi
# Make request
if [[ -n "$OUT" ]]; then
# Save to file
CURL_ARGS+=("-o" "$OUT")
curl "${CURL_ARGS[@]}" "$URL"
echo "Response saved to: $OUT"
else
# Output to stdout
RESPONSE=$(curl "${CURL_ARGS[@]}" "$URL" 2>&1)
if [[ "$JSON" == "true" ]]; then
# Format JSON
echo "$RESPONSE" | python3 -m json.tool 2>/dev/null || echo "$RESPONSE"
else
echo "$RESPONSE"
fi
fiRelated skills
AI & Agent Buildingagents