302 lines
8.2 KiB
Markdown
302 lines
8.2 KiB
Markdown
---
|
|
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
|