Creator Guide

Complete guide to building, deploying, and monetizing tools on the Herald Network

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:

  1. Herald Account - Register at f3l1x.tech
  2. Herald Token - Generate from dashboard settings
  3. Base L2 Wallet - For receiving USDC payments
  4. 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

  1. Use clear descriptions - Help AI agents understand each parameter
  2. Mark required fields - Specify which parameters are mandatory
  3. Use enums for options - When there are fixed choices
  4. 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

  1. Compute costs - Cover your infrastructure
  2. Market rates - Check similar tools
  3. Value provided - Premium tools can charge more
  4. 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-noun format
  • 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


Support

  • Email: hello@f3l1x.tech