Skip to content

Usage Examples

This guide provides practical examples for using the ICE Locator MCP Server in various scenarios.

Basic Search Examples

Search by Name

# Simple name search
result = await session.call_tool("search_by_name", {
    "first_name": "John",
    "last_name": "Doe"
})

# Enhanced name search with fuzzy matching
result = await session.call_tool("search_by_name", {
    "first_name": "José",
    "last_name": "García",
    "middle_name": "Luis",
    "fuzzy_match": True,
    "confidence_threshold": 0.8
})

Search by A-Number

# A-Number search with validation
result = await session.call_tool("search_by_alien_number", {
    "alien_number": "A123456789",
    "validate_format": True
})

# A-Number search without 'A' prefix
result = await session.call_tool("search_by_alien_number", {
    "alien_number": "123456789"
})

Search by Facility

# Search by facility name
result = await session.call_tool("search_by_facility", {
    "facility_name": "Houston Contract Detention Facility"
})

# Search by location
result = await session.call_tool("search_by_facility", {
    "city": "Houston",
    "state": "TX"
})

Advanced Search Examples

Natural Language Queries

# Parse natural language query
result = await session.call_tool("parse_natural_query", {
    "query": "Find Maria Rodriguez from Guatemala at Houston facility",
    "auto_execute": True,
    "confidence_threshold": 0.7
})

# Spanish language query
result = await session.call_tool("parse_natural_query", {
    "query": "Buscar a Juan Pérez en el centro de detención",
    "language": "es",
    "auto_execute": False
})

Bulk Search Operations

# Multiple searches at once
result = await session.call_tool("bulk_search", {
    "searches": [
        {
            "type": "name",
            "first_name": "John",
            "last_name": "Doe",
            "fuzzy_match": True
        },
        {
            "type": "alien_number",
            "alien_number": "A987654321"
        },
        {
            "type": "facility",
            "facility_name": "Example Detention Center"
        }
    ],
    "max_concurrent": 3,
    "include_summary": True
})

Client Integration Examples

Python Client with AsyncIO

import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

class ICELocatorClient:
    def __init__(self, config_path=None):
        self.server_params = StdioServerParameters(
            command="ice-locator-mcp",
            args=[],
            env={"ICE_LOCATOR_CONFIG": config_path} if config_path else {}
        )

    async def search_detainee(self, first_name, last_name, **kwargs):
        async with stdio_client(self.server_params) as (read, write):
            async with ClientSession(read, write) as session:
                await session.initialize()

                result = await session.call_tool("search_by_name", {
                    "first_name": first_name,
                    "last_name": last_name,
                    **kwargs
                })

                return result.content[0].text

    async def smart_search(self, query):
        async with stdio_client(self.server_params) as (read, write):
            async with ClientSession(read, write) as session:
                await session.initialize()

                result = await session.call_tool("parse_natural_query", {
                    "query": query,
                    "auto_execute": True
                })

                return result.content[0].text

# Usage
async def main():
    client = ICELocatorClient("/path/to/config.json")

    # Basic search
    result = await client.search_detainee("John", "Doe", fuzzy_match=True)
    print(result)

    # Smart search
    result = await client.smart_search("Find Maria in Houston facility")
    print(result)

if __name__ == "__main__":
    asyncio.run(main())

JavaScript/Node.js Client

import { Client } from '@modelcontextprotocol/client';
import { StdioTransport } from '@modelcontextprotocol/client/stdio';

class ICELocatorClient {
    constructor(configPath = null) {
        this.transport = new StdioTransport({
            command: 'ice-locator-mcp',
            args: [],
            env: configPath ? { ICE_LOCATOR_CONFIG: configPath } : {}
        });
        this.client = new Client(this.transport);
    }

    async initialize() {
        await this.client.initialize();
    }

    async searchByName(firstName, lastName, options = {}) {
        const result = await this.client.callTool('search_by_name', {
            first_name: firstName,
            last_name: lastName,
            ...options
        });
        return result.content[0].text;
    }

    async smartSearch(query) {
        const result = await this.client.callTool('parse_natural_query', {
            query: query,
            auto_execute: true
        });
        return result.content[0].text;
    }

    async close() {
        await this.client.close();
    }
}

// Usage
async function main() {
    const client = new ICELocatorClient('/path/to/config.json');

    try {
        await client.initialize();

        // Basic search
        const result1 = await client.searchByName('John', 'Doe', {
            fuzzy_match: true,
            confidence_threshold: 0.8
        });
        console.log(result1);

        // Smart search
        const result2 = await client.smartSearch('Find Maria Rodriguez in Texas');
        console.log(result2);

    } finally {
        await client.close();
    }
}

main().catch(console.error);

Command Line Examples

Direct CLI Usage

# Basic name search
ice-locator-mcp search --first-name "John" --last-name "Doe"

# A-Number search
ice-locator-mcp search --alien-number "A123456789"

# Facility search
ice-locator-mcp search --facility "Houston Contract Detention"

# Natural language search
ice-locator-mcp smart-search "Find José García in California"

# Bulk search from file
ice-locator-mcp bulk-search --input searches.json --output results.json

Batch Processing

# Create batch search file
cat > batch_searches.json << EOF
{
  "searches": [
    {
      "type": "name",
      "first_name": "John",
      "last_name": "Doe"
    },
    {
      "type": "alien_number", 
      "alien_number": "A123456789"
    }
  ]
}
EOF

# Run batch search
ice-locator-mcp batch --file batch_searches.json --output results.json

Integration with AI Assistants

Claude Desktop Integration

{
  "mcpServers": {
    "ice-locator": {
      "command": "ice-locator-mcp",
      "args": ["--config", "/path/to/config.json"],
      "env": {
        "ICE_LOCATOR_LOG_LEVEL": "INFO"
      }
    }
  }
}

Example Claude conversation:

User: "Can you help me find information about someone in ICE custody named Maria Rodriguez?"

Claude: I can help you search for detainee information. Let me search for Maria Rodriguez in the ICE database.

[Uses search_by_name tool]

Based on the search, I found [results]. Here's what I found...

Custom AI Assistant Integration

class ImmigrationAssistant:
    def __init__(self):
        self.ice_client = ICELocatorClient()

    async def help_find_detainee(self, user_query):
        # Parse user intent
        if "A-number" in user_query or "alien number" in user_query:
            # Extract A-number and search
            a_number = self.extract_a_number(user_query)
            result = await self.ice_client.search_by_a_number(a_number)
        else:
            # Use natural language search
            result = await self.ice_client.smart_search(user_query)

        # Provide guidance
        guidance = self.generate_guidance(result)

        return {
            "search_results": result,
            "guidance": guidance,
            "resources": self.get_resources()
        }

Error Handling Examples

Robust Error Handling

import asyncio
from mcp.client.exceptions import McpError

async def robust_search(first_name, last_name):
    client = ICELocatorClient()

    try:
        result = await client.search_detainee(first_name, last_name)
        return {"status": "success", "data": result}

    except McpError as e:
        if "rate limit" in str(e).lower():
            # Wait and retry
            await asyncio.sleep(60)
            return await robust_search(first_name, last_name)
        else:
            return {"status": "error", "message": str(e)}

    except Exception as e:
        return {"status": "error", "message": f"Unexpected error: {e}"}

Retry Logic

async def search_with_retry(search_func, max_retries=3, delay=1):
    for attempt in range(max_retries):
        try:
            return await search_func()
        except Exception as e:
            if attempt == max_retries - 1:
                raise e

            # Exponential backoff
            wait_time = delay * (2 ** attempt)
            await asyncio.sleep(wait_time)

Performance Optimization Examples

Connection Pooling

class PooledICEClient:
    def __init__(self, pool_size=5):
        self.pool_size = pool_size
        self.connections = asyncio.Queue(maxsize=pool_size)
        self._initialized = False

    async def initialize(self):
        if self._initialized:
            return

        for _ in range(self.pool_size):
            client = ICELocatorClient()
            await self.connections.put(client)

        self._initialized = True

    async def search(self, *args, **kwargs):
        client = await self.connections.get()
        try:
            return await client.search_detainee(*args, **kwargs)
        finally:
            await self.connections.put(client)

Caching Results

import time
from functools import wraps

def cache_results(ttl=3600):
    cache = {}

    def decorator(func):
        @wraps(func)
        async def wrapper(*args, **kwargs):
            key = f"{func.__name__}:{hash((args, tuple(kwargs.items())))}"

            if key in cache:
                result, timestamp = cache[key]
                if time.time() - timestamp < ttl:
                    return result

            result = await func(*args, **kwargs)
            cache[key] = (result, time.time())
            return result

        return wrapper
    return decorator

@cache_results(ttl=1800)  # 30 minute cache
async def cached_search(first_name, last_name):
    client = ICELocatorClient()
    return await client.search_detainee(first_name, last_name)

Testing Examples

Unit Testing

import pytest
from unittest.mock import AsyncMock, patch

@pytest.mark.asyncio
async def test_search_by_name():
    with patch('ice_locator_mcp.server.search_by_name') as mock_search:
        mock_search.return_value = {
            "status": "found",
            "results": [{"name": "John Doe", "alien_number": "A123456789"}]
        }

        client = ICELocatorClient()
        result = await client.search_detainee("John", "Doe")

        assert "John Doe" in result
        mock_search.assert_called_once()

Integration Testing

@pytest.mark.integration
@pytest.mark.asyncio
async def test_end_to_end_search():
    client = ICELocatorClient()

    # Test with known good data
    result = await client.search_detainee("Test", "User")

    # Verify result format
    assert isinstance(result, str)
    assert len(result) > 0

Monitoring and Logging Examples

Custom Logging

import logging
import structlog

# Configure structured logging
logging.basicConfig(
    format="%(message)s",
    stream=sys.stdout,
    level=logging.INFO,
)

structlog.configure(
    processors=[
        structlog.stdlib.filter_by_level,
        structlog.stdlib.add_logger_name,
        structlog.stdlib.add_log_level,
        structlog.processors.JSONRenderer()
    ],
    context_class=dict,
    logger_factory=structlog.stdlib.LoggerFactory(),
    wrapper_class=structlog.stdlib.BoundLogger,
    cache_logger_on_first_use=True,
)

logger = structlog.get_logger("ice_locator_client")

async def logged_search(first_name, last_name):
    logger.info("Starting search", first_name=first_name, last_name=last_name)

    try:
        client = ICELocatorClient()
        result = await client.search_detainee(first_name, last_name)

        logger.info("Search completed", 
                   result_length=len(result),
                   status="success")

        return result

    except Exception as e:
        logger.error("Search failed", error=str(e), status="error")
        raise

Metrics Collection

import time
from dataclasses import dataclass
from typing import Dict, List

@dataclass
class SearchMetrics:
    total_searches: int = 0
    successful_searches: int = 0
    failed_searches: int = 0
    average_response_time: float = 0.0
    response_times: List[float] = None

    def __post_init__(self):
        if self.response_times is None:
            self.response_times = []

class MetricsCollector:
    def __init__(self):
        self.metrics = SearchMetrics()

    async def timed_search(self, search_func, *args, **kwargs):
        start_time = time.time()

        try:
            result = await search_func(*args, **kwargs)
            self.metrics.successful_searches += 1
            return result

        except Exception as e:
            self.metrics.failed_searches += 1
            raise

        finally:
            response_time = time.time() - start_time
            self.metrics.response_times.append(response_time)
            self.metrics.total_searches += 1

            # Update average
            self.metrics.average_response_time = (
                sum(self.metrics.response_times) / len(self.metrics.response_times)
            )

    def get_stats(self) -> Dict:
        return {
            "total_searches": self.metrics.total_searches,
            "success_rate": (
                self.metrics.successful_searches / self.metrics.total_searches
                if self.metrics.total_searches > 0 else 0
            ),
            "average_response_time": self.metrics.average_response_time,
            "min_response_time": min(self.metrics.response_times) if self.metrics.response_times else 0,
            "max_response_time": max(self.metrics.response_times) if self.metrics.response_times else 0
        }

Security Examples

Secure Configuration

import os
from cryptography.fernet import Fernet

class SecureConfig:
    def __init__(self, key_file="config.key"):
        self.key_file = key_file
        self.cipher = self._load_or_create_key()

    def _load_or_create_key(self):
        if os.path.exists(self.key_file):
            with open(self.key_file, 'rb') as f:
                key = f.read()
        else:
            key = Fernet.generate_key()
            with open(self.key_file, 'wb') as f:
                f.write(key)
            os.chmod(self.key_file, 0o600)  # Owner read/write only

        return Fernet(key)

    def encrypt_config(self, config_data):
        encrypted = self.cipher.encrypt(config_data.encode())
        return encrypted

    def decrypt_config(self, encrypted_data):
        decrypted = self.cipher.decrypt(encrypted_data)
        return decrypted.decode()

These examples demonstrate various ways to integrate and use the ICE Locator MCP Server effectively while maintaining security, performance, and reliability.