Copy-paste-ready code for every major agent framework and language
Use BotAnon as a fetch tool in your MCP server or Claude Code skill. Here's a complete PHP function for an MCP server:
PHP — MCP Server Fetch Tool// Example: PHP function an MCP server could use
function botanon_fetch(string $url, string $tag = 'claude_agent'): array {
$client = new \GuzzleHttp\Client();
$response = $client->get('https://botanon.com/api/fetch', [
'query' => [
'url' => $url,
'apikey' => getenv('BOTANON_API_KEY'),
'tag' => $tag,
'ua' => 'random',
],
'timeout' => 30,
]);
return json_decode((string)$response->getBody(), true);
}
Python — MCP Server Fetch Tool
import os
import requests
def botanon_fetch(url: str, tag: str = "claude_agent") -> dict:
"""Fetch a URL through BotAnon for anonymous access."""
resp = requests.get("https://botanon.com/api/fetch", params={
"url": url,
"apikey": os.environ["BOTANON_API_KEY"],
"tag": tag,
"ua": "random",
}, timeout=30)
resp.raise_for_status()
data = resp.json()
if not data["success"]:
raise Exception(f"BotAnon error: {data.get('error', 'unknown')}")
return data
Autonomous agents that scrape multiple URLs can loop through BotAnon with built-in rate limiting and error handling:
Python — Autonomous Agent Loopimport requests
import time
BOTANON_API = "https://botanon.com/api/fetch"
API_KEY = "YOUR_KEY"
def agent_fetch(url, tag="hermes_agent"):
resp = requests.get(BOTANON_API, params={
"url": url,
"apikey": API_KEY,
"tag": tag,
"ua": "random",
})
data = resp.json()
if data["success"]:
return data["body"]
raise Exception(f"Fetch failed: {data.get('error', 'unknown')}")
# Agent workflow example
urls = [
"https://example.com/pricing",
"https://example.com/about",
"https://example.com/contact",
]
for url in urls:
html = agent_fetch(url)
# Process html with your LLM...
print(f"Fetched {url}: {len(html)} bytes")
time.sleep(1) # Be respectful
Modern Node.js with the built-in fetch API — no dependencies needed:
const BOTANON_API = 'https://botanon.com/api/fetch';
async function agentFetch(url, tag = 'node_agent') {
const params = new URLSearchParams({
url, apikey: process.env.BOTANON_API_KEY, tag, ua: 'random'
});
const resp = await fetch(`${BOTANON_API}?${params}`);
const data = await resp.json();
if (!data.success) throw new Error(data.error);
return data;
}
// Use in your agent
const result = await agentFetch('https://example.com');
console.log(`HTTP ${result.http_code}, ${result.body_size} bytes via ${result.proxy.driver}`);
Quick command-line examples for testing or shell-based agent workflows:
Bash — Simple GETcurl -s 'https://botanon.com/api/fetch?url=https://example.com&apikey=YOUR_KEY&tag=shell' | jq .
Bash — POST with JSON data
curl -s -X POST https://botanon.com/api/fetch \
-H 'Content-Type: application/json' \
-d '{"url":"https://api.example.com/search","apikey":"YOUR_KEY","method":"POST","post_data":"{\"q\":\"test\"}","post_type":"json"}' | jq .
Bash — With compression
curl -s --compressed 'https://botanon.com/api/fetch?url=https://example.com&apikey=YOUR_KEY&compress=1' | jq .
Bash — Browser rendering (JS-heavy pages)
curl -s 'https://botanon.com/api/fetch?url=https://spa-app.com&apikey=YOUR_KEY&browser=1' | jq .body
BotAnon supports form POSTs, JSON POSTs, and custom headers for complex API interactions:
Python — Form POSTresp = requests.post("https://botanon.com/api/fetch", json={
"url": "https://example.com/login",
"apikey": "YOUR_KEY",
"method": "POST",
"post_data": "username=agent&password=secret",
"post_type": "form",
"tag": "login_agent",
})
data = resp.json()
print(data["body"])
Python — JSON POST
import json
resp = requests.post("https://botanon.com/api/fetch", json={
"url": "https://api.example.com/search",
"apikey": "YOUR_KEY",
"method": "POST",
"post_data": json.dumps({"query": "AI agents", "limit": 10}),
"post_type": "json",
"tag": "search_agent",
})
data = resp.json()
print(data["body"])
PHP — Custom User-Agent & Timeout
$response = $client->get('https://botanon.com/api/fetch', [
'query' => [
'url' => 'https://tough-target.com',
'apikey' => 'YOUR_KEY',
'ua' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/125.0.0.0',
'timeout' => 60,
'browser' => 1,
'tag' => 'tough_target',
],
]);
Always check the success field, implement retries with backoff, and use tags for debugging:
import requests
import time
def resilient_fetch(url, tag="my_agent", max_retries=3):
"""Fetch with automatic retries and exponential backoff."""
for attempt in range(max_retries):
try:
resp = requests.get("https://botanon.com/api/fetch", params={
"url": url,
"apikey": API_KEY,
"tag": f"{tag}_attempt_{attempt}",
"ua": "random",
"refresh": 1 if attempt > 0 else 0, # Force fresh on retry
}, timeout=30)
data = resp.json()
if data["success"]:
return data
# Non-retryable errors
if data.get("http_code") in [404, 401, 403]:
return data # Don't retry client errors
except requests.RequestException as e:
print(f"Request error: {e}")
if attempt < max_retries - 1:
wait = 2 ** attempt # 1s, 2s, 4s
print(f"Retrying in {wait}s...")
time.sleep(wait)
raise Exception(f"Failed after {max_retries} attempts: {url}")
PHP — Error Handling
function safe_fetch(string $url, string $tag): ?array {
try {
$client = new \GuzzleHttp\Client();
$response = $client->get('https://botanon.com/api/fetch', [
'query' => [
'url' => $url,
'apikey' => getenv('BOTANON_API_KEY'),
'tag' => $tag,
],
'timeout' => 30,
]);
$data = json_decode((string)$response->getBody(), true);
if (!$data['success']) {
error_log("BotAnon fetch failed [{$tag}]: " . ($data['error'] ?? 'unknown'));
return null;
}
return $data;
} catch (\Throwable $e) {
error_log("BotAnon exception [{$tag}]: " . $e->getMessage());
return null;
}
}