Troubleshooting Tutorial

This Tutorial helps you diagnose and resolve common issues with ToolUniverse.

Quick Diagnostic

Run this diagnostic script to check your ToolUniverse installation:

from tooluniverse import ToolUniverse

# Run basic system check
try:
    tu = ToolUniverse()
    tu.load_tools()
    print(f"✅ ToolUniverse working correctly! {len(tu.all_tools)} tools loaded.")
except Exception as e:
    print(f"❌ Issue detected: {e}")

Most common installation problems and solutions.

Installation Issues

ImportError: No module named ‘tooluniverse’

Symptom: Python can’t find the ToolUniverse module.

Diagnosis:

python -c "import tooluniverse; print(tooluniverse.__version__)"

Solutions:

pip install tooluniverse

Dependency conflicts

Symptom: Conflicting package versions during installation.

Check dependencies:

pip check

Solutions:

  1. Create clean environment:

    conda create -n tooluniverse python=3.10
    conda activate tooluniverse
    pip install tooluniverse
    
  2. Update conflicting packages:

    pip install --upgrade requests urllib3 certifi
    
  3. Install specific versions:

    pip install 'requests>=2.25.0,<3.0.0'
    

Runtime Errors

Tool not found errors

Symptom: ToolNotFoundError: Tool 'XYZ' not found

Diagnosis:

from tooluniverse import ToolUniverse

tu = ToolUniverse()
tu.load_tools()

# List available tools
print("Available tools:")
for tool_name in tu.list_tools():
    print(f"  - {tool_name}")

Solutions:

  1. Check tool name spelling:

    # Correct tool names
    correct_names = [
        "OpenTargets_get_associated_targets_by_disease_efoId",
        "PubChem_get_compound_info",
        "UniProt_get_function_by_accession"
    ]
    
  2. Verify tool is loaded:

    if "OpenTargets_tool" not in tu.list_tools():
        print("OpenTargets tool not loaded")
        # Check for missing dependencies
    
  3. Manual tool loading:

    from tooluniverse.opentargets_tool import OpenTargetsTool
    tool = OpenTargetsTool()
    tu.register_tool(tool)
    

API Authentication errors

Symptom: 401 Unauthorized, 403 Forbidden, or “API key required” errors.

Common API Error Codes

When you encounter API errors, check this reference table:

Error Code

Meaning

Solution

401 Unauthorized

Invalid or missing API key

Verify API key is correct and environment variable is set correctly. Check with echo $API_KEY_NAME

403 Forbidden

Valid key but insufficient permissions

Check account subscription level. May need to upgrade or request additional access from API provider.

429 Too Many Requests

Rate limit exceeded

Add API key for higher limits, enable caching with use_cache=True, or add delays. See Result Caching.

404 Not Found

Invalid resource identifier

Verify ID format (e.g., UniProt accession “P05067”, ChEMBL ID “CHEMBL25”). Check Glossary for ID formats.

502 Bad Gateway

Service temporarily unavailable

Wait 30-60 seconds and retry. Check API provider’s status page if error persists.

503 Service Unavailable

API endpoint overloaded or maintenance

Retry with exponential backoff (wait 2s, 4s, 8s…). Check provider status page.

Diagnosis:

import os

# Check if API keys are set (environment variables)
api_keys = {
    'NVIDIA_API_KEY': os.getenv('NVIDIA_API_KEY'),
    'NCBI_API_KEY': os.getenv('NCBI_API_KEY'),
    'SEMANTIC_SCHOLAR_API_KEY': os.getenv('SEMANTIC_SCHOLAR_API_KEY'),
    'DISGENET_API_KEY': os.getenv('DISGENET_API_KEY'),
    'USPTO_API_KEY': os.getenv('USPTO_API_KEY'),
    'FDA_API_KEY': os.getenv('FDA_API_KEY'),
    'OMIM_API_KEY': os.getenv('OMIM_API_KEY'),
}

for key, value in api_keys.items():
    status = "✓ Set" if value else "✗ Missing"
    print(f"{key}: {status}")

Solutions:

  1. Identify which API key you need:

    See API Keys and Authentication for a complete list of which tools require which API keys and how to obtain them.

  2. Set API keys in environment:

    # Linux/macOS
    export NVIDIA_API_KEY="your_key_here"
    export NCBI_API_KEY="your_ncbi_key"
    
    # Windows (Command Prompt)
    set NVIDIA_API_KEY=your_key_here
    
    # Windows (PowerShell)
    $env:NVIDIA_API_KEY="your_key_here"
    
  3. Use .env file (recommended):

    # Copy template and fill in your keys
    cp docs/.env.template .env
    nano .env  # or use any text editor
    
    from dotenv import load_dotenv
    load_dotenv()  # Load from .env file
    
  4. In Python code:

    import os
    os.environ['NVIDIA_API_KEY'] = 'your_key_here'
    os.environ['NCBI_API_KEY'] = 'your_ncbi_key'
    

Common API key issues:

  • Key is expired or invalid: Regenerate the key from the provider’s dashboard

  • Key has insufficient permissions: Check that the key has the necessary scopes/permissions

  • Key not loaded: Ensure environment variables are set before importing ToolUniverse

  • Typo in variable name: Double-check spelling (e.g., NVIDIA_API_KEY not NVIDIA_KEY)

Rate limiting errors

Symptom: 429 Too Many Requests or RateLimitExceeded

Understanding Rate Limits:

Many services limit how many requests you can make per second/minute. API keys typically provide much higher limits:

Service

Without API Key

With API Key

NCBI E-utilities

3 req/sec

10 req/sec (3x faster, set NCBI_API_KEY)

Semantic Scholar

1 req/sec

100 req/sec (100x faster, set SEMANTIC_SCHOLAR_API_KEY)

OpenFDA

40 req/min

240 req/min (6x faster, set FDA_API_KEY)

Solutions:

  1. Get an API key for higher limits:

    See API Keys and Authentication for how to obtain API keys for each service.

  2. Add delays between requests:

    import time
    
    for query in queries:
         result = tu.run(query)
         time.sleep(1)  # Wait 1 second between requests
    
  3. Use batch processing:

    # Process in smaller batches
    batch_size = 5
    for i in range(0, len(queries), batch_size):
         batch = queries[i:i+batch_size]
         results = tu.run_batch(batch)
         time.sleep(2)  # Pause between batches
    
  4. Enable caching to avoid redundant requests:

    import os
    os.environ["TOOLUNIVERSE_CACHE_DEFAULT_TTL"] = "3600"  # 1 hour
    result = tu.run(query, use_cache=True)
    

Network & Connectivity

Connection timeouts

Symptom: ConnectionTimeout or ReadTimeout errors.

Diagnosis:

import requests

# Test basic connectivity
try:
    response = requests.get('https://httpbin.org/delay/1', timeout=5)
    print(f"Network OK: {response.status_code}")
except requests.exceptions.Timeout:
    print("Network timeout - check connection")

Solutions:

  1. Increase timeout:

    tu = ToolUniverse(timeout=30)  # 30 second timeout
    
  2. Check network connection:

    ping google.com
    curl -I https://platform-api.opentargets.org
    
  3. Configure proxy (if needed):

    import os
    os.environ['HTTP_PROXY'] = 'http://proxy.company.com:8080'
    os.environ['HTTPS_PROXY'] = 'http://proxy.company.com:8080'
    

SSL Certificate errors

Symptom: SSLError or certificate verification failures.

Solutions:

  1. Update certificates:

    pip install --upgrade certifi requests urllib3
    
  2. Temporary bypass (not recommended for production):

    import ssl
    ssl._create_default_https_context = ssl._create_unverified_context
    
  3. Corporate firewall:

    Contact your IT department for proper certificate configuration.

Performance Issues

Slow query performance

Diagnosis:

import time
from tooluniverse import ToolUniverse

tu = ToolUniverse()

# Time a query
start_time = time.time()
result = tu.run({"name": "tool_name", "arguments": {}})
elapsed = time.time() - start_time

print(f"Query took {elapsed:.2f} seconds")

Optimization strategies:

  1. Enable caching:

    import os
    os.environ["TOOLUNIVERSE_CACHE_DEFAULT_TTL"] = "3600"  # 1 hour
    tu = ToolUniverse()
    result = tu.run(..., use_cache=True)
    
  2. Use async operations:

    import asyncio
    
    async def run_queries():
         tasks = [tu.run_async(query) for query in queries]
         results = await asyncio.gather(*tasks)
         return results
    
  3. Batch similar queries:

    # Instead of individual queries by gene symbol, prefer accession-based queries
    accession_info = []
    for accession in accessions:
         info = tu.run({
             "name": "UniProt_get_function_by_accession",
             "arguments": {"accession": accession}
         })
         accession_info.append(info)
    
    # Use batch processing
    queries = [
         {"name": "UniProt_get_function_by_accession", "arguments": {"accession": accession}}
         for accession in accessions
    ]
    results = tu.run_batch(queries)
    

Memory usage issues

Symptom: High memory consumption or MemoryError.

Diagnosis:

import psutil
import os

process = psutil.Process(os.getpid())
memory_mb = process.memory_info().rss / 1024 / 1024
print(f"Memory usage: {memory_mb:.1f} MB")

Solutions:

  1. Process data in chunks:

    def process_large_dataset(data, chunk_size=100):
         for i in range(0, len(data), chunk_size):
             chunk = data[i:i+chunk_size]
             yield tu.run_batch(chunk)
    
  2. Clear cache periodically:

    tu.clear_cache()
    
  3. Use generators for large results:

    def yield_results(queries):
         for query in queries:
             yield tu.run(query)
    

MCP Server Issues

MCP server won’t start

Symptom: Server fails to start or crashes immediately.

Diagnosis:

# Test server directly
tooluniverse-smcp --debug

Solutions:

  1. Check port availability:

    # Check if port is in use
    lsof -i :3000  # Linux/Mac
    netstat -an | findstr :3000  # Windows
    
  2. Use different port:

    tooluniverse-smcp --port 3001
    
  3. Check permissions:

    # Ensure user can bind to port
    sudo tooluniverse-smcp  # If needed
    

Claude/AI assistant not finding tools

Diagnosis:

  1. Verify MCP server is running:

    curl http://localhost:3000/health
    
  2. Check Claude configuration:

    Ensure MCP server is properly configured in Claude Desktop settings.

Solutions:

  1. Restart both server and Claude

  2. Check Claude logs for connection errors

  3. Verify tool registration:

    # In MCP server
    tools = tu.list_tools()
    print(f"Registered {len(tools)} tools")
    

Advanced Debugging

Enable debug logging

import logging

# Enable debug logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger('tooluniverse')
logger.setLevel(logging.DEBUG)

# Now run your code
tu = ToolUniverse()

Capture detailed error information

import traceback

try:
    result = tu.run(query)
except Exception as e:
    print(f"Error: {e}")
    print(f"Type: {type(e).__name__}")
    print("Traceback:")
    traceback.print_exc()

Profile performance bottlenecks

import cProfile
import pstats

# Profile your code
profiler = cProfile.Profile()
profiler.enable()

# Your ToolUniverse code here
tu = ToolUniverse()
result = tu.run(query)

profiler.disable()

# Analyze results
stats = pstats.Stats(profiler)
stats.sort_stats('cumulative')
stats.print_stats(10)

Getting Help

If none of these solutions work:

  1. Check the FAQ: Comprehensive FAQ

  2. Search GitHub issues: Issues

  3. Create a bug report with:

    • ToolUniverse version: tooluniverse.__version__

    • Python version: python --version

    • Operating system

    • Full error message and traceback

    • Minimal code example that reproduces the issue

  4. Join our community: Discord server link

from tooluniverse.diagnostics import run_diagnostic
print(run_diagnostic())

Include this output in your bug report.