How I Built a Pay-Per-Use AI Toolkit: IteraTools Architecture Deep Dive
A technical look at x402 micropayments, MCP protocol integration, and how to build an API your AI agents will love.
The Problem: AI Agents Need Tools, But APIs Are Messy
Building AI agents is exhilarating—until you hit the tooling wall.
You want your Claude or GPT-4 agent to generate an image. So you sign up for Replicate. Then it needs to scrape a webpage, so you add Firecrawl. Then it needs to convert text to speech, so you integrate ElevenLabs. Then OCR, weather, QR codes, charts…
Before long, your agent has eight API keys, eight different SDKs, eight different rate limit strategies, and eight monthly subscriptions—most of which you barely use.
This is the problem I set out to solve with IteraTools.
The Solution: One API, 34+ Tools, Pay Per Use
IteraTools is a hosted multi-tool API that gives your AI agents access to 34+ capabilities through a single, unified interface:
- Media: Image generation (Flux), TTS, OCR, PDF generation
- Web: Scraping, browser automation (Playwright), URL shortening
- Data: Charts, QR codes, DNS lookup, WHOIS, IP geolocation
- Finance: Crypto prices, currency conversion
- Utilities: Weather, translation, code execution (E2B sandbox), holidays
Every tool speaks the same language: one base URL, one API key, consistent JSON responses.
But the really interesting part is how it handles payments.
The x402 Payment Protocol: Micropayments Without Subscriptions
Most APIs charge you monthly whether you use them or not. IteraTools uses x402, a payment protocol built on HTTP 402 (“Payment Required”).
Here’s how it works:
- Your agent calls
POST https://api.iteratools.com/image/generate - The server responds with
HTTP 402+ a payment requirement header - Your agent pays the exact amount (e.g.,
$0.003 USDC) on-chain - The server verifies the payment and returns the result
In practice, with the Python SDK, this is transparent:
from anthropic import Anthropic
import httpx
client = Anthropic()
api_key = "your-iteratools-api-key"
# Call IteraTools directly - payment handled automatically
def generate_image(prompt: str) -> str:
response = httpx.post(
"https://api.iteratools.com/image/generate",
headers={"X-API-Key": api_key},
json={"prompt": prompt, "width": 512, "height": 512}
)
return response.json()["url"]
def scrape_url(url: str) -> str:
response = httpx.post(
"https://api.iteratools.com/scrape",
headers={"X-API-Key": api_key},
json={"url": url}
)
return response.json()["content"]
def text_to_speech(text: str) -> str:
response = httpx.post(
"https://api.iteratools.com/tts",
headers={"X-API-Key": api_key},
json={"text": text, "voice": "en-US-AriaNeural"}
)
return response.json()["audio_url"]
Per-call pricing means you pay $0.001–$0.005 per request. No monthly fees. No waste.
MCP Integration: Claude Desktop in 30 Seconds
The Model Context Protocol (MCP) is Anthropic’s standard for giving AI models access to external tools. IteraTools ships a native MCP server.
Install:
npm install -g mcp-iteratools
Configure Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"iteratools": {
"command": "npx",
"args": ["mcp-iteratools"],
"env": {
"ITERATOOLS_API_KEY": "your-api-key-here"
}
}
}
}
Restart Claude Desktop, and you’ll see IteraTools listed under available tools. Claude can now generate images, scrape websites, run code, check DNS records—all within a single conversation, with zero additional setup.
The MCP server exposes all 34+ tools as individual MCP tools, with proper schemas and descriptions so Claude knows exactly when and how to use each one.
Code Example: A 3-Tool Python Agent
Here’s a real-world example: an agent that researches a company, generates a summary chart, and creates a voice briefing.
from anthropic import Anthropic
import httpx
import json
client = Anthropic()
API_KEY = "your-iteratools-api-key"
BASE_URL = "https://api.iteratools.com"
def call_tool(endpoint: str, payload: dict) -> dict:
r = httpx.post(
f"{BASE_URL}{endpoint}",
headers={"X-API-Key": API_KEY},
json=payload,
timeout=30
)
r.raise_for_status()
return r.json()
# Tool definitions for Claude
tools = [
{
"name": "scrape_website",
"description": "Scrape and extract text content from a URL",
"input_schema": {
"type": "object",
"properties": {
"url": {"type": "string", "description": "URL to scrape"}
},
"required": ["url"]
}
},
{
"name": "generate_chart",
"description": "Generate a bar or pie chart from data",
"input_schema": {
"type": "object",
"properties": {
"config": {
"type": "object",
"description": "Chart.js config object with type, data, and options"
}
},
"required": ["config"]
}
},
{
"name": "text_to_speech",
"description": "Convert text to an audio file",
"input_schema": {
"type": "object",
"properties": {
"text": {"type": "string"},
"voice": {"type": "string", "default": "en-US-AriaNeural"}
},
"required": ["text"]
}
}
]
def run_agent(company_url: str):
messages = [
{
"role": "user",
"content": f"Research {company_url}, then create a simple chart showing their key metrics (make them up if needed), and finally generate a short voice briefing summarizing what you found."
}
]
while True:
response = client.messages.create(
model="claude-opus-4-5",
max_tokens=1024,
tools=tools,
messages=messages
)
if response.stop_reason == "end_turn":
print("Agent done:", response.content[-1].text)
break
# Handle tool calls
tool_results = []
for block in response.content:
if block.type == "tool_use":
print(f" → Calling {block.name}...")
if block.name == "scrape_website":
result = call_tool("/scrape", {"url": block.input["url"]})
elif block.name == "generate_chart":
result = call_tool("/chart/generate", {
"config": block.input["config"],
"format": "png"
})
elif block.name == "text_to_speech":
result = call_tool("/tts", {
"text": block.input["text"],
"voice": block.input.get("voice", "en-US-AriaNeural")
})
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": json.dumps(result)
})
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": tool_results})
# Run it
run_agent("https://stripe.com")
Total cost for this workflow: about $0.007 USDC (scrape + chart + TTS). Compare that to paying three different API subscriptions.
Architecture: How It All Fits Together
Claude / GPT Agent
↓ (MCP or REST)
IteraTools API (api.iteratools.com)
↓
Route handler
↓
x402 auth middleware ←→ Payment verification
↓
Tool executor
├── Flux (image gen)
├── Playwright (browser)
├── E2B (code execution)
├── Node.js builtins (DNS, crypto)
└── Third-party APIs (weather, etc.)
The server runs on Node.js with Express. Each tool is a self-contained module. The x402 middleware sits in front of all endpoints, checking for a valid API key or on-chain payment before routing the request to the executor.
This architecture makes it trivial to add new tools: write a handler, add it to the router, update the MCP schema. Done.
What’s Next
A few things I’m working on:
- Streaming support — Long-running tasks (browser sessions, code execution) should stream results back to the agent in real time
- Tool chaining — Let you define multi-step pipelines server-side and execute them atomically with one API call
-
npm publish — The MCP package is ready, just needs publishing for
npxsupport without global install -
More tools —
/sentiment,/summarize,/email/sendare next on the roadmap
Try It
- API: api.iteratools.com
- Docs: iteratools.com
- MCP package: github.com/fredpsantos33/mcp-iteratools
If you’re building AI agents and tired of juggling APIs, give it a shot. The first few calls are free — just generate an API key and go.
Questions or feedback? Open an issue on GitHub or reach out in the comments below.
