Creator Guide¶
This guide covers everything you need to know about creating, registering, and monetizing tools on the Herald Network.
Overview¶
As a tool creator on Herald Network, you can:
- Build MCP-compatible tools that AI agents can invoke
- Set your own pricing in USDC
- Receive instant payments via x402 protocol on Base L2
- Earn 70% of every tool invocation
Revenue Model¶
| Recipient | Share | Description |
|---|---|---|
| Tool Creator | 70% | Direct to your wallet |
| F3L1X Treasury | 20% | Platform maintenance |
| Validator Pool | 10% | Quality assurance |
Prerequisites¶
Before you begin, ensure you have:
- Herald Account - Register at f3l1x.tech
- Herald Token - Generate from dashboard settings
- Base L2 Wallet - For receiving USDC payments
- Working Realm - Your tool must be hosted in an active realm
Required Environment Variables¶
# Your Herald authentication token
HERALD_TOKEN=your_token_here
# Your realm's unique identifier
REALM_NAME=my-tool-realm
# Wallet for receiving payments
PAYMENT_WALLET=0x742d35Cc6634C0532925a3b844Bc8e7595f42263
Step 1: Create Your Realm¶
A realm is a service that hosts your tools. Each realm runs on its own port and can contain multiple tools.
Realm Structure¶
my-tool-realm/
├── config/
│ ├── settings.py
│ └── urls.py
├── apps/
│ └── tools/
│ ├── services.py # Tool logic
│ ├── views.py # HTTP handlers
│ └── herald_tools.py # MCP tool definitions
├── manage.py
└── requirements.txt
Register Your Realm with Herald¶
curl -X POST http://127.0.0.1:8014/api/realms/register \
-H "Authorization: Bearer $HERALD_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "my-tool-realm",
"port": 8045,
"description": "AI image analysis tools"
}'
Step 2: Define Your Tool¶
Tools follow the MCP (Model Context Protocol) specification. Each tool needs:
- Name - Unique identifier (e.g., f3l1x/analyze-image)
- Description - What the tool does
- Input Schema - JSON Schema for parameters
- Internal Action - Herald action to invoke
Tool Definition Example¶
# apps/tools/herald_tools.py
TOOL_DEFINITIONS = [
{
"name": "f3l1x/analyze-image",
"description": "Analyze image content, extract text via OCR, detect objects",
"input_schema": {
"type": "object",
"properties": {
"image_url": {
"type": "string",
"description": "URL of image to analyze"
},
"mode": {
"type": "string",
"enum": ["quick", "detailed"],
"description": "Analysis depth"
}
},
"required": ["image_url"]
},
"internal_action": "analyze_image",
"price": "0.01",
"currency": "USDC"
}
]
Input Schema Best Practices¶
- Use clear descriptions - Help AI agents understand each parameter
- Mark required fields - Specify which parameters are mandatory
- Use enums for options - When there are fixed choices
- Set sensible defaults - Reduce friction for callers
{
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Search query to execute",
"minLength": 1,
"maxLength": 500
},
"limit": {
"type": "integer",
"description": "Maximum results to return",
"default": 10,
"minimum": 1,
"maximum": 100
},
"format": {
"type": "string",
"enum": ["json", "csv", "markdown"],
"default": "json"
}
},
"required": ["query"]
}
Step 3: Implement Tool Logic¶
Your tool's internal action handles the actual work. Keep it stateless and idempotent.
Service Implementation¶
# apps/tools/services.py
import httpx
from typing import Dict, Any
async def analyze_image(*, image_url: str, mode: str = "quick") -> Dict[str, Any]:
"""
Analyze image and return structured results.
Args:
image_url: URL of image to analyze
mode: "quick" for fast analysis, "detailed" for comprehensive
Returns:
Dictionary with analysis results
"""
# Download image
async with httpx.AsyncClient() as client:
response = await client.get(image_url)
image_data = response.content
# Run analysis (using your AI model)
if mode == "quick":
result = await quick_analysis(image_data)
else:
result = await detailed_analysis(image_data)
return {
"success": True,
"mode": mode,
"objects_detected": result.objects,
"text_extracted": result.ocr_text,
"confidence": result.confidence
}
async def quick_analysis(image_data: bytes) -> AnalysisResult:
"""Fast single-pass analysis."""
# Your implementation here
pass
async def detailed_analysis(image_data: bytes) -> AnalysisResult:
"""Multi-pass comprehensive analysis."""
# Your implementation here
pass
Error Handling¶
Tools should return structured errors:
from dataclasses import dataclass
from typing import Optional
@dataclass
class ToolError:
code: str
message: str
details: Optional[dict] = None
def analyze_image(*, image_url: str, mode: str = "quick"):
try:
# ... analysis logic
return {"success": True, "data": result}
except ImageDownloadError as e:
return {
"success": False,
"error": {
"code": "IMAGE_DOWNLOAD_FAILED",
"message": f"Could not download image: {e}",
"details": {"url": image_url}
}
}
except AnalysisError as e:
return {
"success": False,
"error": {
"code": "ANALYSIS_FAILED",
"message": str(e)
}
}
Step 4: Register Your Tool¶
Once implemented, register your tool with Herald Network.
Registration Request¶
curl -X POST http://127.0.0.1:8014/api/tools/register \
-H "Authorization: Bearer $HERALD_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"realm": "my-tool-realm",
"name": "f3l1x/analyze-image",
"description": "Analyze image content, extract text via OCR, detect objects",
"input_schema": {
"type": "object",
"properties": {
"image_url": {"type": "string"},
"mode": {"type": "string", "enum": ["quick", "detailed"]}
},
"required": ["image_url"]
},
"internal_action": "analyze_image",
"price": "0.01",
"currency": "USDC",
"price_unit": "per_call",
"rate_limit": 100
}'
Successful Response¶
{
"success": true,
"tool_id": "550e8400-e29b-41d4-a716-446655440000",
"created": true,
"name": "f3l1x/analyze-image",
"realm": "my-tool-realm",
"price": "0.01"
}
Registration Validation¶
Herald validates:
- Realm exists - Must be registered and online
- Name unique - No duplicate tool names
- Schema valid - Must be valid JSON Schema
- Price format - Decimal string (e.g., "0.01")
Step 5: Configure Payment Wallet¶
Register a wallet to receive earnings.
curl -X POST http://127.0.0.1:8014/api/wallets/register \
-H "Authorization: Bearer $HERALD_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"realm": "my-tool-realm",
"address": "0x742d35Cc6634C0532925a3b844Bc8e7595f42263",
"network": "eip155:8453"
}'
Supported Networks¶
| Network | Chain ID | Description |
|---|---|---|
| Base Mainnet | eip155:8453 | Primary payment network |
| Base Sepolia | eip155:84532 | Testnet for development |
Step 6: Test Your Tool¶
Local Testing¶
# Invoke directly without payment (for testing)
curl -X POST http://127.0.0.1:8014/api/tools/f3l1x%2Fanalyze-image/invoke \
-H "Authorization: Bearer $HERALD_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"arguments": {
"image_url": "https://example.com/test-image.png",
"mode": "quick"
},
"caller_realm": "test"
}'
Check Invocation Status¶
curl http://127.0.0.1:8014/api/invocations/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer $HERALD_TOKEN"
Pricing Strategies¶
Pricing Models¶
| Model | Use Case | Example |
|---|---|---|
| Per call | Simple operations | $0.001 per query |
| Per unit | Volume-based | $0.01 per 1000 tokens |
| Tiered | Quality levels | Quick=$0.01, Detailed=$0.05 |
| Free tier | Growth strategy | First 100 calls free |
Pricing Considerations¶
- Compute costs - Cover your infrastructure
- Market rates - Check similar tools
- Value provided - Premium tools can charge more
- Volume expectations - High volume enables lower prices
Update Pricing¶
curl -X PATCH http://127.0.0.1:8014/api/tools/f3l1x%2Fanalyze-image \
-H "Authorization: Bearer $HERALD_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"price": "0.02",
"price_unit": "per_call"
}'
Monitoring & Analytics¶
View Tool Statistics¶
curl http://127.0.0.1:8014/api/tools/f3l1x%2Fanalyze-image/stats \
-H "Authorization: Bearer $HERALD_TOKEN"
Response¶
{
"tool": "f3l1x/analyze-image",
"period": "30d",
"total_calls": 1452,
"successful_calls": 1420,
"failed_calls": 32,
"total_revenue": "14.52",
"your_earnings": "10.164",
"avg_latency_ms": 320,
"p95_latency_ms": 890
}
View Earnings¶
curl http://127.0.0.1:8014/api/realms/my-tool-realm/earnings \
-H "Authorization: Bearer $HERALD_TOKEN"
Best Practices¶
1. Tool Design¶
- Single responsibility - One tool, one purpose
- Clear naming -
namespace/verb-nounformat - Comprehensive schemas - Include descriptions and constraints
- Graceful errors - Return structured error responses
2. Performance¶
- Set timeouts - Don't let requests hang indefinitely
- Async operations - Use async/await for I/O
- Cache when appropriate - Reduce redundant computation
- Monitor latency - Track p95 response times
3. Reliability¶
- Health checks - Herald monitors your realm status
- Graceful degradation - Handle partial failures
- Idempotency - Same input should produce same output
- Rate limiting - Protect against abuse
4. Security¶
- Validate inputs - Never trust incoming data
- Sanitize outputs - Prevent injection attacks
- Secure secrets - Use environment variables
- Audit logging - Track suspicious activity
Troubleshooting¶
Common Issues¶
| Issue | Cause | Solution |
|---|---|---|
| Registration fails | Invalid schema | Validate JSON Schema syntax |
| Tool not found | URL encoding | Use %2F for / in tool names |
| Payment not received | Wrong wallet network | Verify network is eip155:8453 |
| Invocation timeout | Tool too slow | Optimize or increase timeout |
| 503 errors | Realm offline | Check realm is running |
Debug Mode¶
Enable verbose logging:
# settings.py
LOGGING = {
'version': 1,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'loggers': {
'herald': {
'handlers': ['console'],
'level': 'DEBUG',
},
},
}
Example: Complete Tool¶
Here's a complete example of a code review tool:
Tool Definition¶
# herald_tools.py
CODE_REVIEW_TOOL = {
"name": "f3l1x/review-code",
"description": "AI-powered code review with security analysis",
"input_schema": {
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "Source code to review",
"maxLength": 50000
},
"language": {
"type": "string",
"description": "Programming language",
"enum": ["python", "javascript", "typescript", "go", "rust"]
},
"focus": {
"type": "array",
"items": {
"type": "string",
"enum": ["security", "performance", "style", "bugs"]
},
"default": ["security", "bugs"]
}
},
"required": ["code"]
},
"internal_action": "review_code",
"price": "0.05",
"currency": "USDC"
}
Service Implementation¶
# services.py
from typing import List, Dict, Any
import openai
async def review_code(
*,
code: str,
language: str = "python",
focus: List[str] = None
) -> Dict[str, Any]:
"""
Perform AI-powered code review.
"""
focus = focus or ["security", "bugs"]
prompt = f"""Review this {language} code for: {', '.join(focus)}
```{language}
{code}
Provide structured feedback with severity levels."""
response = await openai.ChatCompletion.acreate(
model="gpt-4",
messages=[{"role": "user", "content": prompt}],
temperature=0.3
)
# Parse response into structured format
review = parse_review_response(response.choices[0].message.content)
return {
"success": True,
"language": language,
"issues_found": len(review.issues),
"issues": review.issues,
"summary": review.summary,
"score": review.score
}
### Registration
```bash
curl -X POST http://127.0.0.1:8014/api/tools/register \
-H "Authorization: Bearer $HERALD_TOKEN" \
-H "Content-Type: application/json" \
-d @code_review_tool.json
Next Steps¶
- Herald Tools API Reference - Complete API documentation
- x402 Protocol - Understanding micropayments
- Validator Guide - Earn by validating tools
- Realm Architecture - Deep dive into realms
Support¶
- Email: hello@f3l1x.tech