# TASK 1.4: Configure MCP Client for MySQL Data Access

## Summary

Set up the Model Context Protocol (MCP) client using the official MCP C# SDK to connect to the `benborla/mcp-server-mysql` server. The MCP tools will be retrieved and passed directly to the agent as `AITool` objects, following the Microsoft Agent Framework integration pattern.

## Dependencies

- None (can be done in parallel with TASK 1.1-1.3)

## Architecture

The Microsoft Agent Framework integrates with MCP via the [official MCP C# SDK](https://github.com/modelcontextprotocol/csharp-sdk). The pattern is:

1. Create an `McpClient` via `McpClientFactory.CreateAsync()` with a `StdioClientTransport`
2. Call `mcpClient.ListToolsAsync()` to get available tools
3. Cast tools to `AITool` and pass them to the agent

No custom `IMcpClient` wrapper is needed - the SDK provides everything.

## Files to Modify

### 1. `backend/Directory.Packages.props`

Add the MCP C# SDK package:

```xml
<PackageVersion Include="ModelContextProtocol" Version="0.2.0-preview.1" />
```

> **Note:** Check for the latest version at https://www.nuget.org/packages/ModelContextProtocol

### 2. `backend/Kds.Ai.AnomalyDetector/Kds.Ai.AnomalyDetector.csproj`

Add package reference:

```xml
<ItemGroup>
  <PackageReference Include="ModelContextProtocol" />
</ItemGroup>
```

## Files to Create

### 3. `backend/Kds.Ai.AnomalyDetector/Settings/McpMySqlSettings.cs`

```csharp
using System.ComponentModel.DataAnnotations;

namespace Kds.Ai.AnomalyDetector.Settings;

public sealed class McpMySqlSettings
{
    /// <summary>
    /// Command to run the MCP server (e.g., "npx")
    /// </summary>
    [Required]
    public required string Command { get; init; }
    
    /// <summary>
    /// Arguments for the MCP server command (e.g., ["-y", "benborla-mcp-server-mysql"])
    /// </summary>
    [Required]
    public required string[] Arguments { get; init; }
    
    /// <summary>
    /// Environment variables to pass to the MCP server process
    /// (MySQL connection details: MYSQL_HOST, MYSQL_PORT, MYSQL_USER, MYSQL_PASS, MYSQL_DB)
    /// </summary>
    public Dictionary<string, string> EnvironmentVariables { get; init; } = new();
}
```

### 4. `backend/Kds.Ai.AnomalyDetector/Mcp/McpToolProvider.cs`

Factory that creates an MCP client and retrieves tools:

```csharp
using Kds.Ai.AnomalyDetector.Settings;
using Microsoft.Extensions.AI;
using ModelContextProtocol.Client;

namespace Kds.Ai.AnomalyDetector.Mcp;

/// <summary>
/// Manages the MCP client lifecycle and provides tools from the MySQL MCP server.
/// </summary>
public sealed class McpToolProvider(McpMySqlSettings settings) : IAsyncDisposable
{
    private McpClient? _client;

    /// <summary>
    /// Creates the MCP client and connects to the MySQL MCP server.
    /// </summary>
    public async Task<McpClient> GetClientAsync(CancellationToken ct = default)
    {
        if (_client is not null)
        {
            return _client;
        }

        var transport = new StdioClientTransport(new StdioClientTransportOptions
        {
            Name = "mysql-mcp-server",
            Command = settings.Command,
            Arguments = settings.Arguments,
            EnvironmentVariables = settings.EnvironmentVariables
        });

        _client = await McpClient.CreateAsync(transport, cancellationToken: ct);
        return _client;
    }

    /// <summary>
    /// Retrieves available tools from the MCP server as AITool objects
    /// that can be passed directly to an agent.
    /// </summary>
    public async Task<IList<AITool>> GetToolsAsync(CancellationToken ct = default)
    {
        var client = await GetClientAsync(ct);
        var tools = await client.ListToolsAsync(cancellationToken: ct);
        return [.. tools.Cast<AITool>()];
    }

    public async ValueTask DisposeAsync()
    {
        if (_client is not null)
        {
            await _client.DisposeAsync();
            _client = null;
        }
    }
}
```

> **Note:** In TASK 6.1, `McpToolProvider` will be refactored to `internal sealed` and an `IMcpToolProvider` interface will be extracted for testability.

### 5. `backend/Kds.Ai.AnomalyDetector/DependencyInjectionExtensions.cs`

```csharp
using Kds.Ai.AnomalyDetector.Mcp;
using Kds.Ai.AnomalyDetector.Settings;
using Kds.Ai.Core;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;

namespace Kds.Ai.AnomalyDetector;

public static class DependencyInjectionExtensions
{
    public static IHostApplicationBuilder AddAnomalyDetectorModule(this IHostApplicationBuilder builder)
    {
        builder.AddOptions<McpMySqlSettings>();

        builder.Services.AddSingleton<McpToolProvider>(provider =>
        {
            var settings = provider.GetRequiredService<IOptions<McpMySqlSettings>>();
            return new McpToolProvider(settings.Value);
        });

        return builder;
    }
}
```

> **Note:** In TASK 6.1, this registration will change to `AddSingleton<IMcpToolProvider, McpToolProvider>` when the interface is extracted.

## Configuration Example

In `appsettings.json` or environment configuration:

```json
{
  "McpMySqlSettings": {
    "Command": "npx",
    "Arguments": ["-y", "benborla-mcp-server-mysql"],
    "EnvironmentVariables": {
      "MYSQL_HOST": "localhost",
      "MYSQL_PORT": "3306",
      "MYSQL_USER": "root",
      "MYSQL_PASS": "password",
      "MYSQL_DB": "kdsdev"
    }
  }
}
```

## Usage Pattern (Preview)

When building the agent (in later tasks), the MCP tools will be passed directly:

```csharp
var mcpToolProvider = serviceProvider.GetRequiredService<McpToolProvider>();
var mcpTools = await mcpToolProvider.GetToolsAsync(ct);

// Pass MCP tools to the agent - the agent can call mysql_query via function calling
AIAgent agent = chatClient.AsAIAgent(
    instructions: systemPrompt,
    tools: [.. mcpTools]);
```

## Acceptance Criteria

- [ ] `ModelContextProtocol` package added to `Directory.Packages.props`
- [ ] Package reference added to `Kds.Ai.AnomalyDetector.csproj`
- [ ] `McpMySqlSettings` settings class created
- [ ] `McpToolProvider` created using official MCP C# SDK patterns
- [ ] DI extensions created with provider registration
- [ ] Solution builds without errors

## Notes

- The `benborla/mcp-server-mysql` server exposes a `mysql_query` tool that accepts SQL queries
- MCP tools are automatically converted to `AITool` objects compatible with Microsoft Agent Framework
- The MCP client connects via stdio transport (launches server as subprocess)
- `McpToolProvider` manages the client lifecycle and should be disposed properly
- No custom MCP client wrapper is needed - use the official SDK directly
