# Psyche Tool Framework

Tool orchestration framework with Model Context Protocol (MCP) support for the
Psyche AI Virtual Assistant Platform.

## Overview

The Tool Framework provides comprehensive tool management and execution
capabilities:

- **Tool Registry**: Define and manage tools with OpenAPI-compatible schemas
- **Tool Router**: Intelligent execution with retries, caching, circuit breaker
- **MCP Server**: Model Context Protocol server for LLM integration
- **Mock Tools**: Pre-built mock implementations for development

## Architecture

```
src/tool_framework/
├── __init__.py           # Package exports
├── main.py               # FastAPI application
├── registry/             # Tool registry
│   ├── __init__.py
│   ├── types.py          # ToolDefinition, ParameterDefinition
│   ├── registry.py       # ToolRegistry implementation
│   └── validator.py      # Tool validation
├── router/               # Tool router
│   ├── __init__.py
│   ├── types.py          # ExecutionContext, ExecutionResult
│   ├── router.py         # ToolRouter implementation
│   ├── cache.py          # LRU cache
│   └── parser.py         # Tool call parser
├── mcp/                  # MCP implementation
│   ├── __init__.py
│   ├── server.py         # MCP server (stdio, HTTP, SSE)
│   └── adapters.py       # Resource and prompt providers
└── mock_tools/           # Mock tool implementations
    ├── __init__.py
    ├── crm_tools.py      # CRM mock tools
    ├── erp_tools.py      # ERP mock tools
    ├── calendar_tools.py # Calendar mock tools
    └── email_tools.py    # Email mock tools
```

## Features

### Tool Registry

- Tool definition with parameters, returns, metadata
- Semantic versioning with constraint matching
- Dependency resolution between tools
- Full-text search and filtering
- Usage tracking and analytics

### Tool Router

- Multi-format LLM support (Anthropic, OpenAI)
- Retry strategies (fixed, exponential, linear backoff)
- Circuit breaker for fault tolerance
- LRU caching with TTL
- Parallel and batch execution
- Pre/post execution hooks

### MCP Server

- JSON-RPC 2.0 protocol
- Multiple transports (stdio, HTTP, SSE)
- Resource and prompt providers
- Rate limiting and authentication
- Audit logging

## API Endpoints

### Health & Metrics

```
GET /health              # Service health
GET /ready               # Readiness check
GET /metrics             # Router metrics
```

### Tool Registry

```
GET /tools               # List all tools
GET /tools/{id}          # Get tool by ID
GET /tools/{id}/schema   # Get OpenAPI schema
POST /tools/search       # Search tools
GET /categories          # List categories
```

### Tool Execution

```
POST /execute            # Execute tool directly
POST /execute/llm        # Execute from LLM format
POST /execute/batch      # Batch execution
```

### Tool Health

```
GET /tools/{id}/health       # Get tool health
POST /tools/{id}/reset-circuit  # Reset circuit breaker
```

### MCP Endpoints

```
GET /mcp/tools           # MCP tools/list
POST /mcp/tools/call     # MCP tools/call
```

## Usage

### Registering a Tool

```python
from tool_framework import (
    ToolRegistry,
    ToolDefinition,
    ParameterDefinition,
    ParameterType,
    ToolCategory,
    tool,
)

registry = ToolRegistry()

# Using decorator
@tool(
    id="weather.get",
    name="Get Weather",
    description="Get current weather for a location",
    category=ToolCategory.UTILITY,
)
async def get_weather(location: str) -> dict:
    return {"location": location, "temperature": 72}

await registry.register(get_weather.__tool_definition__)

# Or manually
definition = ToolDefinition(
    id="calculator.add",
    name="Add Numbers",
    description="Add two numbers together",
    parameters=[
        ParameterDefinition(
            name="a",
            type=ParameterType.NUMBER,
            description="First number",
            required=True,
        ),
        ParameterDefinition(
            name="b",
            type=ParameterType.NUMBER,
            description="Second number",
            required=True,
        ),
    ],
    handler=lambda a, b: {"result": a + b},
)

await registry.register(definition)
```

### Executing Tools

```python
from tool_framework import ToolRouter, ExecutionContext

router = ToolRouter(registry=registry)

# Direct execution
result = await router.execute(
    tool_id="calculator.add",
    arguments={"a": 5, "b": 3},
    context=ExecutionContext(request_id="req-001"),
)

print(result.data)  # {"result": 8}

# From LLM tool call
llm_tool_call = {
    "id": "call_123",
    "name": "calculator.add",
    "input": {"a": 5, "b": 3},
}

result = await router.execute_from_llm(
    tool_call=llm_tool_call,
    context=ExecutionContext(request_id="req-002"),
)

# Format for LLM response
formatted = router.format_result_for_llm(result, format="anthropic")
```

### MCP Server

```python
from tool_framework.mcp import MCPServer

# Create server
server = MCPServer(registry=registry)

# Run in stdio mode (for Claude Desktop integration)
await server.run_stdio()

# Or HTTP mode
await server.run_http(host="0.0.0.0", port=8012)
```

## Configuration

### Environment Variables

| Variable            | Description               | Default |
| ------------------- | ------------------------- | ------- |
| `SERVICE_PORT`      | REST API port             | 8011    |
| `MCP_PORT`          | MCP HTTP server port      | 8012    |
| `ENABLE_MOCK_TOOLS` | Register mock tools       | true    |
| `LOG_LEVEL`         | Log level                 | INFO    |
| `CACHE_SIZE`        | LRU cache size            | 1000    |
| `CACHE_TTL`         | Cache TTL in seconds      | 300     |
| `MAX_RETRIES`       | Default max retries       | 3       |
| `TIMEOUT_SECONDS`   | Default execution timeout | 30      |

## Development

### Using Nx

```bash
# Install dependencies
nx install psyche-tool-framework

# Run REST API server
nx serve psyche-tool-framework

# Run MCP server (stdio mode)
nx serve-mcp psyche-tool-framework

# Run MCP server (HTTP mode)
nx serve-mcp-http psyche-tool-framework

# Run tests
nx test psyche-tool-framework
nx test-unit psyche-tool-framework
nx test-integration psyche-tool-framework

# Run tests with coverage
nx test-cov psyche-tool-framework

# Lint and format
nx lint psyche-tool-framework
nx format psyche-tool-framework

# Docker
nx docker-build psyche-tool-framework
nx docker-run psyche-tool-framework
```

### Direct Poetry Commands

```bash
cd apps/psyche/tool-framework
poetry install
poetry run pytest
poetry run uvicorn tool_framework.main:app --reload --host 0.0.0.0 --port 8011
```

## Mock Tools

The framework includes mock tools for development:

### CRM Tools

- `crm.get_customer` - Get customer details
- `crm.search_customers` - Search customers
- `crm.get_account_details` - Get account info
- `crm.get_opportunities` - List opportunities
- `crm.create_note` - Create a note

### ERP Tools

- `erp.check_inventory` - Check stock levels
- `erp.get_product_details` - Get product info
- `erp.search_products` - Search products
- `erp.create_order` - Create an order
- `erp.get_order_status` - Check order status

### Calendar Tools

- `calendar.get_availability` - Check availability
- `calendar.create_meeting` - Schedule meeting
- `calendar.reschedule_meeting` - Reschedule
- `calendar.get_upcoming_meetings` - List meetings

### Email Tools

- `email.send_email` - Send email
- `email.send_template` - Send templated email
- `email.get_email_history` - Get email history
- `email.track_email` - Track email status

## Performance Targets

| Operation        | Target Latency |
| ---------------- | -------------- |
| Tool lookup      | < 5ms          |
| Simple execution | < 50ms         |
| Cached execution | < 5ms          |
| Batch (10 tools) | < 500ms        |
| Search           | < 100ms        |

## License

Proprietary - Oshun Platform
