ScavioScavio
ProductPricingDocs
Sign InGet Started
  1. Home
  2. Tutorials
  3. How to Build a Search Layer for Agents-as-a-Service
Tutorial

How to Build a Search Layer for Agents-as-a-Service

Build a multi-tenant, credit-based search layer for agent service platforms. MCP-compatible, rate-limited, and cost-tracked.

Get Free API KeyAPI Docs

Agents-as-a-service platforms need a shared search layer that tracks credit usage per tenant, enforces rate limits, and works with MCP. This tutorial builds a search service layer that wraps Scavio API with multi-tenant credit tracking, per-tenant rate limiting, and MCP-compatible tool definitions. Each underlying search costs $0.005, and you can mark up for your tenants.

Prerequisites

  • Python 3.8+
  • requests library
  • A Scavio API key from scavio.dev
  • Basic understanding of multi-tenant architecture

Walkthrough

Step 1: Define the tenant credit system

Create a credit tracking system for multi-tenant search usage.

Python
import os, requests, json, time
from collections import defaultdict

API_KEY = os.environ['SCAVIO_API_KEY']
SH = {'x-api-key': API_KEY, 'Content-Type': 'application/json'}

class TenantCredits:
    def __init__(self):
        self.credits = {}  # tenant_id -> remaining credits
        self.usage = defaultdict(list)  # tenant_id -> [{timestamp, query, cost}]

    def add_tenant(self, tenant_id, credits):
        self.credits[tenant_id] = credits
        print(f'Tenant {tenant_id}: {credits} credits allocated')

    def use_credit(self, tenant_id, amount=1):
        if tenant_id not in self.credits:
            return False, 'Tenant not found'
        if self.credits[tenant_id] < amount:
            return False, 'Insufficient credits'
        self.credits[tenant_id] -= amount
        self.usage[tenant_id].append({'time': time.time(), 'cost': amount})
        return True, f'{self.credits[tenant_id]} credits remaining'

    def get_usage(self, tenant_id):
        return {'remaining': self.credits.get(tenant_id, 0),
                'used': len(self.usage.get(tenant_id, [])),
                'total_cost': sum(u['cost'] for u in self.usage.get(tenant_id, []))}

credits = TenantCredits()
credits.add_tenant('tenant_a', 1000)
credits.add_tenant('tenant_b', 500)
print(credits.get_usage('tenant_a'))

Step 2: Build the rate-limited search wrapper

Create a search function with per-tenant rate limiting and credit checking.

Python
class SearchLayer:
    def __init__(self):
        self.credits = TenantCredits()
        self.rate_limits = {}  # tenant_id -> {max_per_minute, window_start, count}

    def set_rate_limit(self, tenant_id, max_per_minute):
        self.rate_limits[tenant_id] = {'max': max_per_minute, 'start': time.time(), 'count': 0}

    def check_rate_limit(self, tenant_id):
        if tenant_id not in self.rate_limits:
            return True
        rl = self.rate_limits[tenant_id]
        now = time.time()
        if now - rl['start'] > 60:
            rl['start'] = now
            rl['count'] = 0
        if rl['count'] >= rl['max']:
            return False
        rl['count'] += 1
        return True

    def search(self, tenant_id, query, platform=None):
        if not self.check_rate_limit(tenant_id):
            return {'error': 'Rate limit exceeded', 'retry_after': 60}
        ok, msg = self.credits.use_credit(tenant_id)
        if not ok:
            return {'error': msg}
        body = {'query': query, 'country_code': 'us'}
        if platform: body['platform'] = platform
        data = requests.post('https://api.scavio.dev/api/v1/search',
            headers=SH, json=body).json()
        return {'results': data.get('organic_results', [])[:5],
                'credits_remaining': self.credits.credits.get(tenant_id, 0),
                'tenant': tenant_id}

layer = SearchLayer()
layer.credits.add_tenant('demo', 100)
layer.set_rate_limit('demo', 30)  # 30 searches/minute
result = layer.search('demo', 'best serp api 2026')
print(f'Results: {len(result.get("results", []))}, Credits: {result.get("credits_remaining")}')

Step 3: Add MCP-compatible tool definitions

Define search tools in MCP format for agent integration.

Python
def mcp_tool_definitions():
    """Return MCP-compatible tool definitions for the search layer."""
    return [
        {
            'name': 'search',
            'description': 'Search the web for current information. Supports platforms: google, reddit, youtube, amazon, walmart.',
            'inputSchema': {
                'type': 'object',
                'properties': {
                    'query': {'type': 'string', 'description': 'Search query'},
                    'platform': {'type': 'string', 'enum': ['google', 'reddit', 'youtube', 'amazon', 'walmart'],
                                 'description': 'Search platform (default: google)'}
                },
                'required': ['query']
            }
        },
        {
            'name': 'usage',
            'description': 'Check remaining search credits and usage stats.',
            'inputSchema': {'type': 'object', 'properties': {}}
        }
    ]

def handle_mcp_call(tenant_id, tool_name, args):
    """Handle an MCP tool call from an agent."""
    if tool_name == 'search':
        return layer.search(tenant_id, args['query'], args.get('platform'))
    elif tool_name == 'usage':
        return layer.credits.get_usage(tenant_id)
    return {'error': f'Unknown tool: {tool_name}'}

tools = mcp_tool_definitions()
print(f'MCP tools available: {[t["name"] for t in tools]}')
result = handle_mcp_call('demo', 'search', {'query': 'python tutorial', 'platform': 'reddit'})
print(f'MCP search result: {len(result.get("results", []))} results')

Step 4: Generate tenant usage reports

Build usage reports for billing and monitoring.

Python
def tenant_report(tenant_id):
    usage = layer.credits.get_usage(tenant_id)
    print(f'\n=== Tenant Report: {tenant_id} ===')
    print(f'  Credits remaining: {usage["remaining"]}')
    print(f'  Searches used: {usage["used"]}')
    print(f'  Total cost (internal): ${usage["total_cost"] * 0.005:.3f}')
    # Calculate billing at markup
    markup = 2.0  # 2x markup
    billed = usage['total_cost'] * 0.005 * markup
    print(f'  Billed to tenant (2x markup): ${billed:.3f}')
    print(f'  Margin: ${billed - usage["total_cost"] * 0.005:.3f}')

def platform_report():
    print(f'\n=== Platform Usage Report ===')
    total_searches = 0
    total_revenue = 0
    for tenant_id in layer.credits.credits:
        usage = layer.credits.get_usage(tenant_id)
        total_searches += usage['used']
        revenue = usage['total_cost'] * 0.005 * 2  # 2x markup
        total_revenue += revenue
        print(f'  {tenant_id}: {usage["used"]} searches, ${revenue:.3f} billed')
    internal_cost = total_searches * 0.005
    print(f'\n  Total searches: {total_searches}')
    print(f'  Internal cost: ${internal_cost:.3f}')
    print(f'  Total revenue: ${total_revenue:.3f}')
    print(f'  Profit: ${total_revenue - internal_cost:.3f}')

# Simulate some usage
for i in range(5):
    layer.search('demo', f'test query {i}')
tenant_report('demo')
platform_report()

Python Example

Python
import os, requests
SH = {'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'}

credits = {'tenant_a': 100}

def tenant_search(tenant_id, query):
    if credits.get(tenant_id, 0) <= 0:
        return {'error': 'No credits'}
    data = requests.post('https://api.scavio.dev/api/v1/search',
        headers=SH, json={'query': query, 'country_code': 'us'}).json()
    credits[tenant_id] -= 1
    print(f'[{tenant_id}] "{query}": {len(data.get("organic_results", []))} results ({credits[tenant_id]} credits left)')
    return data.get('organic_results', [])[:3]

tenant_search('tenant_a', 'serp api')

JavaScript Example

JavaScript
const SH = { 'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json' };
const credits = { tenant_a: 100 };

async function tenantSearch(tenantId, query) {
  if ((credits[tenantId] || 0) <= 0) return { error: 'No credits' };
  const data = await fetch('https://api.scavio.dev/api/v1/search', {
    method: 'POST', headers: SH,
    body: JSON.stringify({ query, country_code: 'us' })
  }).then(r => r.json());
  credits[tenantId]--;
  console.log(`[${tenantId}] "${query}": ${(data.organic_results||[]).length} results (${credits[tenantId]} left)`);
  return (data.organic_results || []).slice(0, 3);
}
await tenantSearch('tenant_a', 'serp api');

Expected Output

JSON
Tenant demo: 100 credits allocated

Results: 5, Credits: 99
MCP tools available: ['search', 'usage']
MCP search result: 5 results

=== Tenant Report: demo ===
  Credits remaining: 93
  Searches used: 7
  Total cost (internal): $0.035
  Billed to tenant (2x markup): $0.070
  Margin: $0.035

=== Platform Usage Report ===
  demo: 7 searches, $0.070 billed
  Total searches: 7
  Internal cost: $0.035
  Profit: $0.035

Related Tutorials

  • How to Build a Custom MCP Search Server
  • How to Build a LangGraph Search Agent with Budget Control
  • How to Build an Agent Context Bridge for Search Results

Frequently Asked Questions

Most developers complete this tutorial in 15 to 30 minutes. You will need a Scavio API key (free tier works) and a working Python or JavaScript environment.

Python 3.8+. requests library. A Scavio API key from scavio.dev. Basic understanding of multi-tenant architecture. A Scavio API key gives you 50 free credits on signup.

Yes. The free tier includes 50 credits on signup, which is more than enough to complete this tutorial and prototype a working solution.

Scavio has a native LangChain package (langchain-scavio), an MCP server, and a plain REST API that works with any HTTP client. This tutorial uses the raw REST API, but you can adapt to your framework of choice.

Related Resources

Use Case

MCP Search Gateway for Multi-Agent Systems

Read more
Best Of

Best Search API for Deep Research Agents in 2026

Read more
Best Of

Best Search APIs for Agentic Stacks in 2026

Read more
Use Case

Agents-as-a-Service Data Layer

Read more
Comparison

MCP Search Integration vs Direct API Integration

Read more
Solution

Give AI Agents Multi-Source Search via MCP

Read more

Start Building

Build a multi-tenant, credit-based search layer for agent service platforms. MCP-compatible, rate-limited, and cost-tracked.

Get Free API KeyRead the Docs
ScavioScavio

Real-time search API for AI agents. Search every platform, not just Google.

Product

  • Features
  • Pricing
  • Dashboard
  • Affiliates

Developers

  • Documentation
  • API Reference
  • Quickstart
  • MCP Integration
  • Python SDK

Alternatives

  • Tavily Alternative
  • SerpAPI Alternative
  • Firecrawl Alternative
  • Exa Alternative

Tools

  • JSON Formatter
  • cURL to Code
  • Token Counter
  • All Tools

© 2026 Scavio. All rights reserved.

Featured on TAAFT
Terms of ServicePrivacy Policy