Files
ColaFlow/docs/plans/sprint_5_story_16.md
Yaojia Wang 34a379750f
Some checks failed
Code Coverage / Generate Coverage Report (push) Has been cancelled
Tests / Run Tests (9.0.x) (push) Has been cancelled
Tests / Docker Build Test (push) Has been cancelled
Tests / Test Summary (push) Has been cancelled
Clean up
2025-11-15 08:58:48 +01:00

8.2 KiB

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

Story 16: Transport Layer Migration to SDK

Parent Epic: Story 0 - 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)

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)

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

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

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 - Configure SDK transports (stdio + HTTP/SSE) - 1 day
  • Task 2 - Migrate API Key authentication to SDK pipeline - 1 day
  • Task 3 - Migrate field-level authorization to SDK pipeline - 1 day
  • Task 4 - Remove custom middleware and test end-to-end - 1 day
  • Task 5 - 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