8.2 KiB
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- HandshakePOST /mcp/tools/list- List ToolsPOST /mcp/tools/call- Execute ToolPOST /mcp/resources/list- List ResourcesGET /mcp/resources/read- Query ResourceGET /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