# MCP Proxy Usage Guide

This guide explains how to use the main `McpProxy` class to run the MCP Proxy with OAuth DCR support.

## Overview

The `McpProxy` class orchestrates all components to create a complete proxy that:
- Presents a stdio MCP interface to Kiro
- Translates between stdio and HTTP MCP protocols
- Manages OAuth DCR authentication automatically
- Handles HTTP communication with backend MCP server
- Provides graceful startup and shutdown

## Quick Start

### Using Environment Variables

The simplest way to run the proxy is to set environment variables and let the proxy load configuration automatically:

```bash
# Set required environment variables
export MCP_SERVER_URL="https://d3phcl5fqkzz01.cloudfront.net/mcp/"
export OAUTH_PROVIDER_URL="https://your-oauth-provider.com"

# Optional environment variables
export MCP_CLIENT_NAME="my-proxy-client"
export MCP_SCOPES="mcp:read,mcp:write"
export MCP_CONNECTION_TIMEOUT="30"
export MCP_RETRY_ATTEMPTS="3"
export MCP_LOG_LEVEL="info"

# Run the proxy
python -m mcp_proxy
```

### Using Python API

You can also create and configure the proxy programmatically:

```python
import asyncio
from mcp_proxy import McpProxy, ProxyConfig

async def main():
    # Create configuration
    config = ProxyConfig(
        mcp_server_url="https://d3phcl5fqkzz01.cloudfront.net/mcp/",
        oauth_provider_url="https://your-oauth-provider.com",
        client_name="my-proxy-client",
        scopes=["mcp:read", "mcp:write"],
        connection_timeout=30,
        retry_attempts=3,
        log_level="info",
    )
    
    # Create and run proxy
    proxy = McpProxy(config=config)
    await proxy.run()

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

## Configuration Options

### Required Configuration

- `mcp_server_url`: URL of the HTTP MCP server (e.g., `https://d3phcl5fqkzz01.cloudfront.net/mcp/`)
- `oauth_provider_url`: URL of the OAuth provider that supports DCR

### Optional Configuration

- `client_name`: OAuth client name (default: `"mcp-proxy-client"`)
- `scopes`: List of OAuth scopes (default: `["mcp:read", "mcp:write"]`)
- `connection_timeout`: Connection timeout in seconds (default: `30`)
- `retry_attempts`: Number of retry attempts for failed requests (default: `3`)
- `log_level`: Logging level - `"debug"`, `"info"`, `"warning"`, `"error"`, `"critical"` (default: `"info"`)
- `max_backoff_seconds`: Maximum backoff time for retries (default: `60`)

## Startup Sequence

When you start the proxy, it performs the following steps:

1. **Load Configuration**: Loads configuration from environment variables or uses provided config
2. **Set Up Logging**: Configures structured logging based on log level
3. **Initialize Authentication**: Performs OAuth DCR and obtains initial access token
4. **Initialize HTTP Client**: Creates authenticated HTTP client for backend communication
5. **Set Up Protocol Translator**: Initializes stdio <-> HTTP protocol translator
6. **Start Stdio Interface**: Starts stdio interface for communication with Kiro
7. **Install Signal Handlers**: Sets up graceful shutdown on SIGTERM/SIGINT

## Message Flow

The proxy handles messages as follows:

1. **Kiro sends JSON-RPC message** via stdin
2. **Stdio Interface** receives and queues the message
3. **Protocol Translator** converts stdio message to HTTP request
4. **Authenticated HTTP Client** attaches OAuth token and sends HTTP request
5. **Backend MCP Server** processes request and returns HTTP response
6. **Protocol Translator** converts HTTP response back to stdio message
7. **Stdio Interface** sends JSON-RPC response via stdout to Kiro

## Graceful Shutdown

The proxy supports graceful shutdown:

1. Receives shutdown signal (SIGTERM, SIGINT, or Ctrl+C)
2. Stops accepting new messages
3. Drains pending outgoing messages
4. Closes stdio interface
5. Closes authenticated HTTP client
6. Closes authentication manager
7. Cleans up all resources

## Error Handling

The proxy handles errors at multiple levels:

### Configuration Errors
- Invalid or missing configuration raises `ConfigurationError`
- Proxy validates all configuration parameters on startup

### Authentication Errors
- OAuth DCR failures are logged and retried with exponential backoff
- Token refresh failures trigger automatic re-registration
- 401 responses trigger automatic token refresh and request retry

### Network Errors
- Connection failures are retried with exponential backoff
- HTTP errors are translated to appropriate JSON-RPC errors
- Timeouts are handled gracefully with configurable limits

### Protocol Errors
- Invalid JSON-RPC messages return proper error responses
- Unsupported methods return method not found errors
- Message correlation is maintained across all error scenarios

## Advanced Usage

### Using as Async Context Manager

```python
async def main():
    config = ProxyConfig(...)
    
    async with McpProxy(config=config) as proxy:
        # Proxy is started automatically
        await proxy.wait_for_shutdown()
    # Proxy is stopped automatically
```

### Manual Start/Stop

```python
async def main():
    proxy = McpProxy(config=config)
    
    try:
        await proxy.start()
        # Do something...
        await proxy.wait_for_shutdown()
    finally:
        await proxy.stop()
```

### Checking Proxy Status

```python
proxy = McpProxy(config=config)

# Check if running
if proxy.is_running:
    print("Proxy is running")

# Get configuration
config = proxy.config
print(f"Server URL: {config.mcp_server_url}")
```

## Logging

The proxy uses structured logging with the following features:

- **Structured Output**: JSON format for machine parsing (when not in TTY)
- **Human-Readable**: Colored console output for development (when in TTY)
- **Context Variables**: Automatic inclusion of request IDs, session IDs, etc.
- **Log Levels**: Configurable from debug to critical

Example log output:
```
2024-01-15T10:30:45.123Z [info] Starting MCP Proxy
2024-01-15T10:30:45.234Z [info] Configuration loaded successfully
2024-01-15T10:30:45.345Z [info] Authentication manager initialized successfully
2024-01-15T10:30:45.456Z [info] HTTP client initialized successfully
2024-01-15T10:30:45.567Z [info] Protocol translator initialized successfully
2024-01-15T10:30:45.678Z [info] Stdio interface started successfully
2024-01-15T10:30:45.789Z [info] MCP Proxy started successfully
```

## Troubleshooting

### Proxy Won't Start

1. Check that required environment variables are set:
   ```bash
   echo $MCP_SERVER_URL
   echo $OAUTH_PROVIDER_URL
   ```

2. Verify URLs are valid and accessible:
   ```bash
   curl -I $MCP_SERVER_URL
   ```

3. Check logs for specific error messages

### Authentication Failures

1. Verify OAuth provider URL is correct
2. Check that OAuth provider supports DCR (RFC 7591)
3. Ensure network connectivity to OAuth provider
4. Review authentication logs for detailed error messages

### Connection Issues

1. Verify MCP server URL is correct and accessible
2. Check network connectivity and firewall rules
3. Increase connection timeout if needed:
   ```bash
   export MCP_CONNECTION_TIMEOUT="60"
   ```

### Message Processing Errors

1. Enable debug logging:
   ```bash
   export MCP_LOG_LEVEL="debug"
   ```

2. Check for protocol translation errors in logs
3. Verify JSON-RPC message format from Kiro
4. Review HTTP response format from backend server

## Examples

See the `examples/` directory for complete working examples:

- `examples/run_proxy.py`: Basic proxy setup and execution
- `examples/authenticated_client_example.py`: Using the authenticated HTTP client directly

## API Reference

### McpProxy Class

```python
class McpProxy:
    """Main MCP Proxy orchestrator."""
    
    def __init__(self, config: Optional[ProxyConfig] = None):
        """Initialize the proxy with optional configuration."""
    
    async def start(self) -> None:
        """Start the proxy and all components."""
    
    async def stop(self) -> None:
        """Stop the proxy gracefully."""
    
    async def run(self) -> None:
        """Start and run until shutdown signal."""
    
    async def wait_for_shutdown(self) -> None:
        """Wait for shutdown signal."""
    
    @property
    def is_running(self) -> bool:
        """Check if proxy is running."""
    
    @property
    def config(self) -> Optional[ProxyConfig]:
        """Get current configuration."""
```

## Requirements Satisfied

This implementation satisfies the following requirements:

- **Requirement 3.1**: Performs OAuth DCR with OAuth provider on startup
- **Requirement 2.1**: Establishes connections to HTTP MCP server
- **Requirement 1.1**: Presents valid stdio MCP server interface to Kiro
- **Requirement 6.3**: Maintains operation logs for debugging
- **Requirement 6.4**: Provides clear diagnostic information on failures

## Next Steps

- See `DEVELOPMENT.md` for development and testing guidelines
- See `ARCHITECTURE.md` for detailed architecture documentation
- See task 11.2 for comprehensive error handling and logging enhancements
- See task 11.3 for integration testing
