# Ragatanga MCP SDK

SDK for integrating with the Ragatanga Management Control Protocol (MCP) server with Next.js 15, React 19, and WebSocket support.

> **Note:** This README documents version 0.8.7 features. Ensure your package.json version matches the documentation by running `npm version 0.8.7` before publishing.

## What's New in v0.8.7

### Major Improvements
- **Enhanced Transport Organization**:
  - Consistent module structure aligned with server implementation
  - Clear separation between HTTP, WebSocket, SSE, Arrow IPC, and standard transports
  - Unified transport interface for better maintainability
  - Improved transport type exports for TypeScript
  
- **Comprehensive Tenant Service**:
  - Complete tenant management API integration
  - Support for all tenant operations including CRUD and API key management
  - Error handling aligned with server implementation
  - Type-safe tenant and API key interfaces
  
- **Client-side Redis Caching**:
  - Redis-compatible client-side caching layer
  - Support for memory, localStorage, sessionStorage, and custom storage backends
  - Built-in rate limiting awareness
  - Cache statistics and management tools
  - Automatic cache invalidation and LRU eviction policy
  - Etag support for conditional requests

### Previous Improvements
- **Arrow IPC Transport**: Efficient binary data transfer using Apache Arrow format
- **Client ID Support**: Improved connection management with client identification
- **Type Improvements**: Enhanced TypeScript type definitions

## What's New in v0.8.1

### Major Improvements
- **Enhanced TypeScript Type System**:
  - Centralized type exports for easier imports
  - Modular type organization for improved code completion
  - Specialized type modules for SSE and WebSocket
  - Improved type documentation
  - Dedicated type paths for each component and transport

## What's New in v0.8.0

### Major Improvements
- **Client ID Support**:
  - Server now includes a unique client ID with every response
  - Clients automatically store and send back this ID with subsequent requests
  - Ensures proper message routing in multi-client environments
  - Improves connection stability in WebSocket and SSE connections
- **Transport Layer Enhancements**:
  - Improved connection management with persistent client identification
  - Enhanced message routing with client ID tracking
  - Better session management across disconnections and reconnects
- **Arrow IPC Transport**: Efficient binary data transfer using Apache Arrow format
- **MCP Protocol Compliance**: Updated to comply with MCP Protocol Revision 2024-11-05

### Previous Features (v0.7.0)
- **Module Resolution Fixes**: Updated exports field in package.json to properly expose modules with complete TypeScript typings support
- **Transport Layer Enhancements**:
  - Improved SSE implementation with better error handling, heartbeats, and reconnection logic
  - Enhanced WebSocket client with robust backoff strategy and connection lifecycle management
  - Added connection status tracking and callbacks
- **Tools Discovery and Execution**: Added support for the tools discovery endpoint and tool execution
- **MCPProvider Enhancements**:
  - Simplified provider implementation with error boundary handling
  - Reduced dependencies for better performance
  - Added context isolation to prevent unnecessary re-renders
- **Better Error Handling**: Comprehensive error handling throughout the SDK
- **Type Improvements**: Better type definitions for responses and parameters

## Features

- **Type-safe API Calls**: Built-in Zod schema validation ensures response types match expectations
- **Path Parameter Handling**: Type-safe URL path parameter handling
- **Modern Error Handling**: Detailed error reporting with proper error hierarchies
- **React Integration**: SWR-powered hooks for data fetching and state management
- **WebSocket Support**: Advanced real-time communication with multiplexing and message queuing
- **Next.js Support**: Built-in support for Next.js App Router and Server Components
- **Flexible Configuration**: Configurable client with sensible defaults
- **Arrow IPC**: Efficient binary data transfer using Apache Arrow format

## 📦 Installation and Usage

### Installation

```bash
npm install ragatanga-mcp-sdk
# or with yarn
yarn add ragatanga-mcp-sdk
# or with pnpm
pnpm add ragatanga-mcp-sdk
```

### Browser Compatibility

For client-side usage in Next.js or other browser environments, use the browser-safe version:

```typescript
// Import the browser-safe version
import { createClient } from 'ragatanga-mcp-sdk/browser';

// Create a client
const client = createClient({
  baseUrl: 'https://api.mcp.ai',
  apiKey: 'your-api-key'
});

// Use the client
const response = await client.get('/resources');
```

This version avoids Node.js-specific features that can cause issues in browser environments.

### Basic Usage

```typescript
import { MCPClient } from 'ragatanga-mcp-sdk';

const client = new MCPClient({
  baseUrl: 'https://api.mcp.ai',
  apiKey: 'your-api-key', // Optional
  token: 'your-token',    // Optional
  tenantId: 'tenant-id'   // Optional
});

// Make API requests
const response = await client.getOntologies();
```

### React Integration

```tsx
import { MCPProvider, useMCPClient } from 'ragatanga-mcp-sdk/react';

function App() {
  return (
    <MCPProvider
      options={{
        baseUrl: 'https://api.mcp.ai',
        token: 'your-token'
      }}
      transport="websocket" // 'websocket', 'sse', or 'none'
      errorBoundary={true}
    >
      <YourComponent />
    </MCPProvider>
  );
}

function YourComponent() {
  const client = useMCPClient();

  // Use client to make API calls
  // ...
}
```

## Tenant Service

The SDK provides comprehensive tenant management capabilities:

```typescript
import { createTenantServiceClient } from 'ragatanga-mcp-sdk/client/tenant-service';

// Create a tenant service client
const tenantService = createTenantServiceClient({
  baseUrl: 'https://api.mcp.ai',
  token: 'your-token'
});

// List all tenants (admin only)
const tenants = await tenantService.listTenants();

// Get a specific tenant
const tenant = await tenantService.getTenant('tenant-id');

// Create a new tenant
const newTenant = await tenantService.createTenant({
  name: 'New Tenant',
  description: 'A new tenant for testing'
});

// Create an API key for a tenant
const apiKey = await tenantService.createApiKey({
  name: 'API Key 1',
  tenant_id: 'tenant-id'
});

// Resolve a tenant from an API key
const resolvedTenant = await tenantService.getTenantByApiKey('api-key-string');
```

## Client-side Redis Cache

The SDK includes a Redis-compatible client-side caching layer:

```typescript
import { createRedisCache } from 'ragatanga-mcp-sdk/client/redis-cache';

// Create a cache with custom options
const cache = createRedisCache({
  storage: 'localStorage',  // Use localStorage for persistence
  maxSize: 200,             // Store up to 200 items
  defaultTTL: 600,          // 10 minutes default TTL
  namespace: 'my-app'       // Custom namespace
});

// Store a value with a custom TTL and ETag
await cache.set('user:123', userData, { 
  ttl: 3600,                // 1 hour TTL
  etag: '"abc123"'          // ETag for conditional requests
});

// Retrieve a value
const { value, etag } = await cache.get('user:123');

// Check rate limits
if (cache.isRateLimited('/api/expensive-endpoint')) {
  console.log('Rate limited, try again later');
}

// Get cache statistics
const stats = cache.getStats();
console.log(`Cache hits: ${stats.hits}, misses: ${stats.misses}`);
```

## Using Types (v0.8.1+)

### Importing Types

```typescript
// Import core types from the types module
import { MCPOptions, MCPClientOptions } from 'ragatanga-mcp-sdk/types';

// Import WebSocket-specific types
import { WebSocketMessage } from 'ragatanga-mcp-sdk/websocket/types';

// Import SSE-specific types
import { SSEOptions, SSEConnectionStatus } from 'ragatanga-mcp-sdk/sse/types';

// Example of using types
const options: MCPOptions = {
  baseUrl: 'https://api.mcp.ai',
  apiKey: 'your-key'
};

// Create a strongly-typed message
const message: WebSocketMessage = {
  type: 'query',
  payload: { query: 'example' },
  client_id: 'client-123' // Client ID is properly typed
};
```

### Extending SDK Types

Instead of redefining types, you can extend the SDK types with your own additions:

```typescript
import { SSEOptions } from 'ragatanga-mcp-sdk/sse/types';

// Extend the SDK options with your own additions
interface EnhancedSSEOptions extends SSEOptions {
  showNotifications?: boolean;
  customProperty?: string;
}

// Use the extended type
function createCustomSSEClient(options: EnhancedSSEOptions) {
  // Implementation...
}
```

### Using with React Hooks

When creating custom hooks or components, use the appropriate import paths:

```typescript
// React-specific hooks
import {
  MCPProvider,
  useMCPClient,
  useQuery,
  useMutation,
  useWebSocket,
  useSSE,
  useMCPErrorHandler
} from 'ragatanga-mcp-sdk/react';

// Client and types
import { useState, useRef } from 'react';
import { MCPClient } from 'ragatanga-mcp-sdk';
import { MCPOptions } from 'ragatanga-mcp-sdk/types';
import { WebSocketMessage } from 'ragatanga-mcp-sdk/websocket/types';

function useCustomClient(options: MCPOptions) {
  const [messages, setMessages] = useState<WebSocketMessage[]>([]);
  const clientRef = useRef<MCPClient | null>(null);

  // Hook implementation...

  return { messages, client: clientRef.current };
}
```

## Using WebSockets

```tsx
import { useMCPWebSocket } from 'ragatanga-mcp-sdk/react';

function WebSocketComponent() {
  const ws = useMCPWebSocket();

  useEffect(() => {
    const subscription = ws.subscribe('entity_update', (data) => {
      console.log('Entity updated:', data);
    });

    // Cleanup subscription
    return () => subscription.unsubscribe();
  }, [ws]);

  // Resolve an entity by URI
  const handleResolve = () => {
    ws.resolveUri('entity://example/123', 2);
  };

  return (
    <button onClick={handleResolve}>Resolve Entity</button>
  );
}
```

## Using Server-Sent Events (SSE)

```tsx
import { useMCPSSE } from 'ragatanga-mcp-sdk/react';

function SSEComponent() {
  const sseClient = useMCPSSE();

  useEffect(() => {
    // Connect to SSE endpoint
    sseClient.connect();

    // Register event handlers
    const unsubscribe = sseClient.on('entity_update', (event) => {
      console.log('Entity updated:', event.data);
    });

    // Cleanup
    return () => {
      unsubscribe();
      sseClient.disconnect();
    };
  }, [sseClient]);

  return <div>Listening for entity updates...</div>;
}
```

## Tools API Integration

```typescript
// Fetch available tools
const tools = await client.getTools();

// Execute a tool with parameters
const result = await client.executeTool('search_entities', {
  query: 'example query',
  limit: 10
});

// Stream tool execution (for long-running operations)
await client.streamTool(
  'generate_text',
  { prompt: 'Hello, world!' },
  (chunk) => {
    console.log('Received chunk:', chunk);
  }
);
```

## Error Handling

### React Component Error Handling

```tsx
import { useMCPErrorHandler } from 'ragatanga-mcp-sdk/react';

function ErrorHandlingComponent() {
  useMCPErrorHandler((error, source) => {
    console.error(`Error in ${source}:`, error);
    // Handle the error (show notification, etc.)
  });

  return <div>Component with error handling</div>;
}
```

### Specialized Ontology Error Handling

```typescript
import { OntologyClient } from 'ragatanga-mcp-sdk';
import {
  OntologyEntityNotFoundError,
  OntologySparqlError
} from 'ragatanga-mcp-sdk/errors';

async function queryOntology() {
  const client = new OntologyClient({
    baseUrl: 'https://api.mcp.ai',
    token: 'your-token'
  });

  try {
    // Attempt to query the ontology
    await client.queryConcept({ uri: 'entity:uri' });
  } catch (error) {
    // Handle specific error types
    if (error instanceof OntologyEntityNotFoundError) {
      console.error(`Entity not found: ${error.entityUri}`);
    } else if (error instanceof OntologySparqlError) {
      console.error(`SPARQL error in query: ${error.query}`);
    } else {
      console.error('Unknown error:', error);
    }
  }
}
```

## Advanced Configuration

```tsx
<MCPProvider
  options={{
    baseUrl: 'https://api.mcp.ai',
    token: 'your-token',
    defaultFetchOptions: {
      credentials: 'include',
      headers: {
        'X-Custom-Header': 'value'
      }
    }
  }}
  transport="websocket"
  defaultHeaders={{
    'Content-Type': 'application/json'
  }}
  onError={(error, source) => {
    console.error(`Error in ${source}:`, error);
  }}
  errorBoundary={true}
  autoReconnect={true}
>
  {/* Your app */}
</MCPProvider>
```

## Examples

Check the `examples` directory for more usage examples, including:

- Basic API client usage
- React hooks with SWR
- WebSocket real-time communication
- Server-Sent Events (SSE) integration
- Next.js integration

## Publishing

To publish a new version of the SDK:

```bash
# Update version in package.json
npm version patch # or minor, or major

# Build the package
npm run build

# Publish to npm
npm publish
```

## License

MIT
