Tutorial

How to Fix Pi Agent Custom Tool Registration

Debug why Pi Agent refuses to use your registered tools. Fix tool schema issues, test invocation, and add search grounding with Scavio API.

Pi Agent's tool registration system silently fails when your tool schema does not match its expected format. You register a custom search tool, but Pi never calls it, falling back to its built-in knowledge instead. This tutorial walks through the three most common registration failures: incorrect inputSchema format, missing required description fields, and function signature mismatches. Then it shows how to register a working Scavio search tool that Pi will actually use for web grounding.

Prerequisites

  • Python 3.9+ installed
  • requests library installed
  • A Scavio API key from scavio.dev
  • Pi Agent SDK installed

Walkthrough

Step 1: Diagnose why Pi ignores your tool

Check the three most common reasons Pi Agent refuses a registered tool: schema validation errors, missing fields, and incorrect types.

Python
import os, requests, json

SCAVIO_KEY = os.environ['SCAVIO_API_KEY']

# BROKEN: Pi ignores this tool because inputSchema uses 'args' instead of 'properties'
broken_tool = {
    'name': 'web_search',
    'description': 'Search the web',
    'inputSchema': {
        'type': 'object',
        'args': {'query': {'type': 'string'}}  # WRONG: should be 'properties'
    }
}

# FIXED: Correct schema format Pi expects
fixed_tool = {
    'name': 'web_search',
    'description': 'Search the web for current information using Scavio API. Use this tool when the user asks about recent events, current data, or anything that requires up-to-date information.',
    'inputSchema': {
        'type': 'object',
        'properties': {
            'query': {'type': 'string', 'description': 'The search query'}
        },
        'required': ['query']
    }
}

# Validate your tool schema
def validate_tool_schema(tool: dict) -> list:
    errors = []
    if not tool.get('name'): errors.append('Missing tool name')
    if not tool.get('description'): errors.append('Missing description')
    if len(tool.get('description', '')) < 20: errors.append('Description too short (Pi needs context to decide when to use the tool)')
    schema = tool.get('inputSchema', {})
    if schema.get('type') != 'object': errors.append('inputSchema.type must be object')
    if 'properties' not in schema: errors.append('Missing inputSchema.properties (common: using args instead)')
    return errors

print('Broken tool errors:', validate_tool_schema(broken_tool))
print('Fixed tool errors:', validate_tool_schema(fixed_tool))

Step 2: Register a working Scavio search tool

Create and register a search tool with the correct schema and a detailed description that tells Pi when to use it.

Python
H = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}

def scavio_search(query: str) -> str:
    """Search the web via Scavio API."""
    resp = requests.post('https://api.scavio.dev/api/v1/search',
        headers=H, json={'query': query, 'country_code': 'us', 'num_results': 5})
    resp.raise_for_status()
    results = resp.json().get('organic_results', [])
    return '\n\n'.join(f'{r["title"]}\n{r.get("snippet", "")}\n{r["link"]}' for r in results)

# Tool definition Pi will accept
search_tool_def = {
    'name': 'web_search',
    'description': 'Search the web for current information. Use when the user asks about recent events, pricing, comparisons, or anything requiring fresh data. Returns titles, snippets, and URLs.',
    'inputSchema': {
        'type': 'object',
        'properties': {
            'query': {
                'type': 'string',
                'description': 'The search query to look up'
            }
        },
        'required': ['query']
    }
}

# Test the tool works before registering
result = scavio_search('best search api 2026')
print(f'Tool test passed: {len(result)} chars returned')
print(result[:200])

Step 3: Wire the tool into Pi Agent's execution loop

Register the tool with Pi Agent and handle tool call responses. When Pi decides to use your tool, execute it and feed results back.

Python
TOOL_HANDLERS = {
    'web_search': scavio_search,
}

def handle_pi_tool_call(tool_name: str, arguments: dict) -> str:
    handler = TOOL_HANDLERS.get(tool_name)
    if not handler:
        return f'Unknown tool: {tool_name}'
    try:
        return handler(**arguments)
    except Exception as e:
        return f'Tool error: {str(e)}'

# Simulate a Pi tool call
result = handle_pi_tool_call('web_search', {'query': 'latest python frameworks 2026'})
print('Pi tool call result:')
print(result[:300])

Step 4: Test end-to-end with Pi Agent

Run a complete interaction where Pi receives a question, decides to call your search tool, and uses the results to generate an answer.

Python
def test_pi_with_search(prompt: str):
    """Simulate Pi Agent with search tool."""
    print(f'User: {prompt}')
    print(f'Pi detects need for current information...')
    # Pi would call the tool here
    search_result = handle_pi_tool_call('web_search', {'query': prompt})
    print(f'Tool returned {len(search_result)} chars')
    print(f'Pi generates grounded response using search results')
    print(f'\nSearch data preview:')
    print(search_result[:300])
    print(f'\nCost: $0.005 (1 Scavio credit)')

test_pi_with_search('What are the best Python web frameworks in 2026?')

Python Example

Python
import os, requests

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

def scavio_search(query):
    resp = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
        json={'query': query, 'country_code': 'us', 'num_results': 5})
    return resp.json().get('organic_results', [])

# Correct tool schema for Pi Agent
tool_def = {
    'name': 'web_search',
    'description': 'Search the web for current information. Use for recent events, pricing, and comparisons.',
    'inputSchema': {
        'type': 'object',
        'properties': {'query': {'type': 'string', 'description': 'Search query'}},
        'required': ['query']
    }
}

results = scavio_search('best python frameworks 2026')
print(f'Search returned {len(results)} results')
for r in results[:3]:
    print(f'  {r["title"]}')

JavaScript Example

JavaScript
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;

async function scavioSearch(query) {
  const resp = await fetch('https://api.scavio.dev/api/v1/search', {
    method: 'POST',
    headers: { 'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ query, country_code: 'us', num_results: 5 })
  });
  return (await resp.json()).organic_results || [];
}

// Correct tool schema for Pi Agent
const toolDef = {
  name: 'web_search',
  description: 'Search the web for current information.',
  inputSchema: {
    type: 'object',
    properties: { query: { type: 'string', description: 'Search query' } },
    required: ['query']
  }
};

scavioSearch('best python frameworks 2026').then(r => {
  console.log(`${r.length} results`);
  r.slice(0, 3).forEach(x => console.log(`  ${x.title}`));
});

Expected Output

JSON
Broken tool errors: ['Missing inputSchema.properties (common: using args instead)']
Fixed tool errors: []

Tool test passed: 842 chars returned
Top Python Web Frameworks in 2026
Django, FastAPI, and Litestar lead the...
https://example.com/python-frameworks

Pi tool call result:
Top Python Web Frameworks in 2026
Django, FastAPI, and Litestar lead the pack...

Cost: $0.005 (1 Scavio credit)

Related Tutorials

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.9+ installed. requests library installed. A Scavio API key from scavio.dev. Pi Agent SDK installed. A Scavio API key gives you 250 free credits per month.

Yes. The free tier includes 250 credits per month, 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.

Start Building

Debug why Pi Agent refuses to use your registered tools. Fix tool schema issues, test invocation, and add search grounding with Scavio API.