---
story_id: story_16
sprint_id: sprint_5
parent_story_id: story_0
status: not_started
priority: P0
assignee: backend
created_date: 2025-11-09
estimated_days: 5
phase: 4
---

# Story 16: Transport Layer Migration to SDK

**Parent Epic**: [Story 0](sprint_5_story_0.md) - Integrate Microsoft .NET MCP SDK
**Phase**: 4 - Transport Layer (Week 6)
**Priority**: P0 - Critical
**Estimated Effort**: 5 days (1 week)
**Dependencies**: Story 15 (Resource migration complete)

## User Story

**As** a backend developer,
**I want** to replace custom HTTP middleware with SDK transport layer,
**So that** we support both stdio (CLI) and HTTP/SSE (web) transports with minimal code.

## Business Value

- **Multi-Transport**: Support stdio (Claude Desktop) + HTTP/SSE (web clients)
- **Code Reduction**: Remove 150-200 lines of custom middleware
- **Standard Compliance**: SDK handles MCP transport specification
- **Future-Proof**: Easy to add WebSocket in future

## Current vs. Target Architecture

### Current (Custom Middleware)
```
┌─────────────────────────────┐
│  Custom HTTP Middleware     │
├─────────────────────────────┤
│  McpProtocolMiddleware      │
│  - JSON-RPC parsing         │
│  - Request routing          │
│  - Error handling           │
│                             │
│  ApiKeyAuthMiddleware       │
│  - API Key extraction       │
│  - Validation               │
│  - TenantContext setup      │
└─────────────────────────────┘
        ↓
   MCP Handlers
```

### Target (SDK Transport)
```
┌─────────────────────────────┐
│  SDK Transport Layer        │
├─────────────────────────────┤
│  stdio Transport            │
│  - Standard In/Out          │
│  - For CLI tools            │
│                             │
│  HTTP/SSE Transport         │
│  - REST API                 │
│  - Server-Sent Events       │
│  - For web clients          │
└─────────────────────────────┘
        ↓
   SDK Protocol Handler
        ↓
   Custom Auth/Authz
        ↓
   MCP Handlers
```

## Transport Configuration

### stdio Transport (Claude Desktop)
```csharp
services.AddMcpServer(options =>
{
    // stdio transport for CLI tools
    options.UseStdioTransport();
});
```

**Use Cases**:
- Claude Desktop
- VS Code Continue extension
- CLI tools (Cline, etc.)

**Characteristics**:
- Single-user mode
- Process lifetime tied to parent process
- No HTTP overhead
- Fast and simple

---

### HTTP/SSE Transport (Web Clients)
```csharp
services.AddMcpServer(options =>
{
    // HTTP/SSE transport for web clients
    options.UseHttpTransport(http =>
    {
        http.BasePath = "/mcp"; // Base URL
        http.EnableSse = true; // Server-Sent Events for notifications
        http.EnableCors = true; // CORS for web clients
    });
});

// Map MCP endpoints
app.MapMcpEndpoints("/mcp");
```

**Endpoints**:
- `POST /mcp/initialize` - Handshake
- `POST /mcp/tools/list` - List Tools
- `POST /mcp/tools/call` - Execute Tool
- `POST /mcp/resources/list` - List Resources
- `GET /mcp/resources/read` - Query Resource
- `GET /mcp/sse` - SSE stream for notifications

**Use Cases**:
- Web-based MCP clients
- Custom integrations
- Future ChatGPT plugin

**Characteristics**:
- Multi-user mode
- Stateless (requires API Key)
- Supports SSE for real-time updates
- CORS-enabled

---

## Custom Authentication Integration

### Preserve API Key Authentication
```csharp
services.AddMcpServer(options =>
{
    options.UseStdioTransport();
    options.UseHttpTransport();

    // Custom authentication handler
    options.AddAuthentication<ApiKeyAuthenticationHandler>();
});

public class ApiKeyAuthenticationHandler : IMcpAuthenticationHandler
{
    private readonly IMcpApiKeyService _apiKeyService;
    private readonly ITenantContext _tenantContext;

    public async Task<McpAuthenticationResult> AuthenticateAsync(
        McpRequest request,
        CancellationToken cancellationToken)
    {
        // Extract API Key from header
        var apiKey = request.Headers["X-Api-Key"];

        if (string.IsNullOrEmpty(apiKey))
        {
            return McpAuthenticationResult.Fail("API Key required");
        }

        // Validate API Key (existing logic)
        var validationResult = await _apiKeyService.ValidateAsync(
            apiKey,
            cancellationToken);

        if (!validationResult.IsValid)
        {
            return McpAuthenticationResult.Fail("Invalid API Key");
        }

        // Setup TenantContext
        _tenantContext.SetTenant(validationResult.TenantId);

        return McpAuthenticationResult.Success(new McpPrincipal
        {
            TenantId = validationResult.TenantId,
            UserId = validationResult.UserId,
            ApiKeyId = validationResult.ApiKeyId
        });
    }
}
```

---

### Preserve Field-Level Authorization
```csharp
services.AddMcpServer(options =>
{
    // Custom authorization handler
    options.AddAuthorization<FieldLevelAuthorizationHandler>();
});

public class FieldLevelAuthorizationHandler : IMcpAuthorizationHandler
{
    private readonly IFieldPermissionService _fieldPermission;

    public async Task<bool> AuthorizeAsync(
        McpPrincipal principal,
        string operation,
        object resource,
        CancellationToken cancellationToken)
    {
        // Check field-level permissions
        return await _fieldPermission.HasAccessAsync(
            principal.TenantId,
            principal.UserId,
            operation,
            resource,
            cancellationToken);
    }
}
```

## Acceptance Criteria

- [ ] stdio transport works (Claude Desktop compatible)
- [ ] HTTP/SSE transport works (web client compatible)
- [ ] API Key authentication functional
- [ ] Field-level permissions enforced
- [ ] Custom middleware removed (McpProtocolMiddleware, ApiKeyAuthMiddleware)
- [ ] Zero breaking changes for existing MCP clients
- [ ] CORS configured for web clients
- [ ] SSE notifications working

## Tasks Breakdown

- [ ] [Task 1](sprint_5_story_16_task_1.md) - Configure SDK transports (stdio + HTTP/SSE) - 1 day
- [ ] [Task 2](sprint_5_story_16_task_2.md) - Migrate API Key authentication to SDK pipeline - 1 day
- [ ] [Task 3](sprint_5_story_16_task_3.md) - Migrate field-level authorization to SDK pipeline - 1 day
- [ ] [Task 4](sprint_5_story_16_task_4.md) - Remove custom middleware and test end-to-end - 1 day
- [ ] [Task 5](sprint_5_story_16_task_5.md) - CORS configuration and SSE notification testing - 1 day

**Progress**: 0/5 tasks completed (0%)

## Testing Strategy

### stdio Transport Tests
- Claude Desktop connection
- Tool calls via stdio
- Resource queries via stdio
- Error handling

### HTTP/SSE Transport Tests
- HTTP POST endpoints
- SSE connection establishment
- Real-time notifications
- CORS preflight requests

### Authentication Tests
- Valid API Key
- Invalid API Key
- Expired API Key
- Missing API Key

### Authorization Tests
- Field-level permission checks
- Unauthorized field access attempts

## Code to Remove

After migration complete:
- `McpProtocolMiddleware.cs` (~150 lines)
- `ApiKeyAuthMiddleware.cs` (~80 lines)
- `McpEndpointRouting.cs` (~100 lines)

**Total**: ~330 lines removed

## Success Metrics

- **Code Reduction**: -330 lines (middleware)
- **Transport Support**: 2 transports (stdio + HTTP/SSE)
- **Compatibility**: 100% (Claude Desktop + web clients)
- **Performance**: No regression (<5ms overhead)

## Definition of Done

- [ ] SDK transports configured (stdio + HTTP/SSE)
- [ ] Custom middleware removed
- [ ] API Key authentication working
- [ ] Field-level permissions enforced
- [ ] Integration tests pass (both transports)
- [ ] Claude Desktop compatibility verified
- [ ] Web client compatibility verified
- [ ] Code reviewed and approved

---

**Created**: 2025-11-09 by Product Manager Agent
**Owner**: Backend Team
**Start Date**: 2025-12-30 (Week 6)
**Target Date**: 2026-01-03 (End of Week 6)
**Status**: Not Started
