feat(backend): Implement MCP Protocol Handler (Story 5.1)
Implemented JSON-RPC 2.0 protocol handler for MCP communication, enabling AI agents to communicate with ColaFlow using the Model Context Protocol. **Implementation:** - JSON-RPC 2.0 data models (Request, Response, Error, ErrorCode) - MCP protocol models (Initialize, Capabilities, ClientInfo, ServerInfo) - McpProtocolHandler with method routing and error handling - Method handlers: initialize, resources/list, tools/list, tools/call - ASP.NET Core middleware for /mcp endpoint - Service registration and dependency injection setup **Testing:** - 28 unit tests covering protocol parsing, validation, and error handling - Integration tests for initialize handshake and error responses - All tests passing with >80% coverage **Changes:** - Created ColaFlow.Modules.Mcp.Contracts project - Created ColaFlow.Modules.Mcp.Domain project - Created ColaFlow.Modules.Mcp.Application project - Created ColaFlow.Modules.Mcp.Infrastructure project - Created ColaFlow.Modules.Mcp.Tests project - Registered MCP module in ColaFlow.API Program.cs - Added /mcp endpoint via middleware **Acceptance Criteria Met:** ✅ JSON-RPC 2.0 messages correctly parsed ✅ Request validation (jsonrpc: "2.0", method, params, id) ✅ Error responses conform to JSON-RPC 2.0 spec ✅ Invalid requests return proper error codes (-32700, -32600, -32601, -32602) ✅ MCP initialize method implemented ✅ Server capabilities returned (resources, tools, prompts) ✅ Protocol version negotiation works (1.0) ✅ Request routing to method handlers ✅ Unit test coverage > 80% ✅ All tests passing **Story**: docs/stories/sprint_5/story_5_1.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
397
docs/stories/sprint_5/story_5_5.md
Normal file
397
docs/stories/sprint_5/story_5_5.md
Normal file
@@ -0,0 +1,397 @@
|
||||
---
|
||||
story_id: story_5_5
|
||||
sprint_id: sprint_5
|
||||
phase: Phase 2 - Resources
|
||||
status: not_started
|
||||
priority: P0
|
||||
story_points: 8
|
||||
assignee: backend
|
||||
estimated_days: 3
|
||||
created_date: 2025-11-06
|
||||
dependencies: [story_5_1, story_5_2, story_5_3]
|
||||
---
|
||||
|
||||
# Story 5.5: Core MCP Resources Implementation
|
||||
|
||||
**Phase**: Phase 2 - Resources (Week 3-4)
|
||||
**Priority**: P0 CRITICAL
|
||||
**Estimated Effort**: 8 Story Points (3 days)
|
||||
|
||||
## User Story
|
||||
|
||||
**As an** AI Agent (Claude, ChatGPT)
|
||||
**I want** to read ColaFlow project data through MCP Resources
|
||||
**So that** I can understand project context and answer user questions
|
||||
|
||||
## Business Value
|
||||
|
||||
This is the first user-facing MCP feature. AI agents can now READ ColaFlow data, enabling:
|
||||
- AI-powered project queries ("Show me high-priority bugs")
|
||||
- Natural language reporting ("What's the status of Sprint 5?")
|
||||
- Context-aware AI assistance ("Who's assigned to this Story?")
|
||||
|
||||
**Impact**:
|
||||
- Enables 50% of M2 user stories (read-only AI features)
|
||||
- Foundation for future write operations (Phase 3)
|
||||
- Demonstrates MCP Server working end-to-end
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
### AC1: Projects Resources
|
||||
- [ ] `colaflow://projects.list` - List all projects
|
||||
- [ ] `colaflow://projects.get/{id}` - Get project details
|
||||
- [ ] Multi-tenant isolation (only current tenant's projects)
|
||||
- [ ] Response time < 200ms
|
||||
|
||||
### AC2: Issues Resources
|
||||
- [ ] `colaflow://issues.search` - Search issues with filters
|
||||
- [ ] `colaflow://issues.get/{id}` - Get issue details (Epic/Story/Task)
|
||||
- [ ] Query parameters: status, priority, assignee, type, project
|
||||
- [ ] Pagination support (limit, offset)
|
||||
- [ ] Response time < 200ms
|
||||
|
||||
### AC3: Sprints Resources
|
||||
- [ ] `colaflow://sprints.current` - Get current active Sprint
|
||||
- [ ] `colaflow://sprints.get/{id}` - Get Sprint details
|
||||
- [ ] Include Sprint statistics (total issues, completed, in progress)
|
||||
|
||||
### AC4: Users Resource
|
||||
- [ ] `colaflow://users.list` - List team members
|
||||
- [ ] Filter by project, role
|
||||
- [ ] Include user profile data (name, email, avatar)
|
||||
|
||||
### AC5: Resource Registration
|
||||
- [ ] All Resources auto-register at startup
|
||||
- [ ] `resources/list` returns complete catalog
|
||||
- [ ] Each Resource has URI, name, description, MIME type
|
||||
|
||||
### AC6: Testing
|
||||
- [ ] Unit tests for each Resource (> 80% coverage)
|
||||
- [ ] Integration tests for Resource endpoints
|
||||
- [ ] Multi-tenant isolation tests
|
||||
- [ ] Performance tests (< 200ms response time)
|
||||
|
||||
## Technical Design
|
||||
|
||||
### Resource Interface
|
||||
|
||||
```csharp
|
||||
public interface IMcpResource
|
||||
{
|
||||
string Uri { get; }
|
||||
string Name { get; }
|
||||
string Description { get; }
|
||||
string MimeType { get; }
|
||||
|
||||
Task<McpResourceContent> GetContentAsync(
|
||||
McpResourceRequest request,
|
||||
CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
public class McpResourceRequest
|
||||
{
|
||||
public string Uri { get; set; }
|
||||
public Dictionary<string, string> Params { get; set; } = new();
|
||||
}
|
||||
|
||||
public class McpResourceContent
|
||||
{
|
||||
public string Uri { get; set; }
|
||||
public string MimeType { get; set; }
|
||||
public string Text { get; set; } // JSON serialized data
|
||||
}
|
||||
```
|
||||
|
||||
### Example: ProjectsListResource
|
||||
|
||||
```csharp
|
||||
public class ProjectsListResource : IMcpResource
|
||||
{
|
||||
public string Uri => "colaflow://projects.list";
|
||||
public string Name => "Projects List";
|
||||
public string Description => "List all projects in current tenant";
|
||||
public string MimeType => "application/json";
|
||||
|
||||
private readonly IProjectRepository _projectRepo;
|
||||
private readonly ITenantContext _tenantContext;
|
||||
private readonly ILogger<ProjectsListResource> _logger;
|
||||
|
||||
public async Task<McpResourceContent> GetContentAsync(
|
||||
McpResourceRequest request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = _tenantContext.CurrentTenantId;
|
||||
|
||||
_logger.LogDebug(
|
||||
"Fetching projects list for tenant {TenantId}",
|
||||
tenantId);
|
||||
|
||||
var projects = await _projectRepo.GetAllAsync(
|
||||
tenantId,
|
||||
cancellationToken);
|
||||
|
||||
var projectDtos = projects.Select(p => new
|
||||
{
|
||||
id = p.Id,
|
||||
name = p.Name,
|
||||
key = p.Key,
|
||||
status = p.Status.ToString(),
|
||||
owner = new { id = p.OwnerId, name = p.Owner?.Name },
|
||||
issueCount = p.IssueCount,
|
||||
memberCount = p.MemberCount,
|
||||
createdAt = p.CreatedAt
|
||||
});
|
||||
|
||||
var json = JsonSerializer.Serialize(new { projects = projectDtos });
|
||||
|
||||
return new McpResourceContent
|
||||
{
|
||||
Uri = Uri,
|
||||
MimeType = MimeType,
|
||||
Text = json
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Resource Catalog Response
|
||||
|
||||
```json
|
||||
{
|
||||
"resources": [
|
||||
{
|
||||
"uri": "colaflow://projects.list",
|
||||
"name": "Projects List",
|
||||
"description": "List all projects in current tenant",
|
||||
"mimeType": "application/json"
|
||||
},
|
||||
{
|
||||
"uri": "colaflow://projects.get/{id}",
|
||||
"name": "Project Details",
|
||||
"description": "Get detailed information about a project",
|
||||
"mimeType": "application/json"
|
||||
},
|
||||
{
|
||||
"uri": "colaflow://issues.search",
|
||||
"name": "Issues Search",
|
||||
"description": "Search issues with filters (status, priority, assignee, etc.)",
|
||||
"mimeType": "application/json"
|
||||
},
|
||||
{
|
||||
"uri": "colaflow://issues.get/{id}",
|
||||
"name": "Issue Details",
|
||||
"description": "Get detailed information about an issue (Epic/Story/Task)",
|
||||
"mimeType": "application/json"
|
||||
},
|
||||
{
|
||||
"uri": "colaflow://sprints.current",
|
||||
"name": "Current Sprint",
|
||||
"description": "Get the currently active Sprint",
|
||||
"mimeType": "application/json"
|
||||
},
|
||||
{
|
||||
"uri": "colaflow://users.list",
|
||||
"name": "Team Members",
|
||||
"description": "List all team members in current tenant",
|
||||
"mimeType": "application/json"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Tasks
|
||||
|
||||
### Task 1: Resource Infrastructure (4 hours)
|
||||
- [ ] Create `IMcpResource` interface
|
||||
- [ ] Create `McpResourceRequest`, `McpResourceContent` DTOs
|
||||
- [ ] Create `IMcpResourceDispatcher` interface
|
||||
- [ ] Implement `McpResourceDispatcher` (route requests to Resources)
|
||||
- [ ] Update `McpProtocolHandler` to call dispatcher
|
||||
|
||||
**Files to Create**:
|
||||
- `ColaFlow.Modules.Mcp/Contracts/IMcpResource.cs`
|
||||
- `ColaFlow.Modules.Mcp/DTOs/McpResourceRequest.cs`
|
||||
- `ColaFlow.Modules.Mcp/DTOs/McpResourceContent.cs`
|
||||
- `ColaFlow.Modules.Mcp/Contracts/IMcpResourceDispatcher.cs`
|
||||
- `ColaFlow.Modules.Mcp/Services/McpResourceDispatcher.cs`
|
||||
|
||||
### Task 2: ProjectsListResource (3 hours)
|
||||
- [ ] Implement `ProjectsListResource` class
|
||||
- [ ] Query ProjectManagement repository
|
||||
- [ ] Apply TenantId filter
|
||||
- [ ] Serialize to JSON
|
||||
- [ ] Unit tests
|
||||
|
||||
**Files to Create**:
|
||||
- `ColaFlow.Modules.Mcp/Resources/ProjectsListResource.cs`
|
||||
- `ColaFlow.Modules.Mcp.Tests/Resources/ProjectsListResourceTests.cs`
|
||||
|
||||
### Task 3: ProjectsGetResource (2 hours)
|
||||
- [ ] Implement `ProjectsGetResource` class
|
||||
- [ ] Extract `{id}` from URI
|
||||
- [ ] Query project by ID + TenantId
|
||||
- [ ] Return 404 if not found or wrong tenant
|
||||
- [ ] Unit tests
|
||||
|
||||
**Files to Create**:
|
||||
- `ColaFlow.Modules.Mcp/Resources/ProjectsGetResource.cs`
|
||||
- `ColaFlow.Modules.Mcp.Tests/Resources/ProjectsGetResourceTests.cs`
|
||||
|
||||
### Task 4: IssuesSearchResource (4 hours)
|
||||
- [ ] Implement `IssuesSearchResource` class
|
||||
- [ ] Parse query params (status, priority, assignee, type, project)
|
||||
- [ ] Build dynamic query (EF Core)
|
||||
- [ ] Apply pagination (limit, offset)
|
||||
- [ ] Apply TenantId filter
|
||||
- [ ] Unit tests
|
||||
|
||||
**Files to Create**:
|
||||
- `ColaFlow.Modules.Mcp/Resources/IssuesSearchResource.cs`
|
||||
- `ColaFlow.Modules.Mcp.Tests/Resources/IssuesSearchResourceTests.cs`
|
||||
|
||||
### Task 5: IssuesGetResource (3 hours)
|
||||
- [ ] Implement `IssuesGetResource` class
|
||||
- [ ] Support Epic, Story, WorkTask lookup
|
||||
- [ ] Return full issue details (including parent/children)
|
||||
- [ ] Apply TenantId filter
|
||||
- [ ] Unit tests
|
||||
|
||||
**Files to Create**:
|
||||
- `ColaFlow.Modules.Mcp/Resources/IssuesGetResource.cs`
|
||||
- `ColaFlow.Modules.Mcp.Tests/Resources/IssuesGetResourceTests.cs`
|
||||
|
||||
### Task 6: SprintsCurrentResource (2 hours)
|
||||
- [ ] Implement `SprintsCurrentResource` class
|
||||
- [ ] Query active Sprint (status = InProgress)
|
||||
- [ ] Include Sprint statistics
|
||||
- [ ] Apply TenantId filter
|
||||
- [ ] Unit tests
|
||||
|
||||
**Files to Create**:
|
||||
- `ColaFlow.Modules.Mcp/Resources/SprintsCurrentResource.cs`
|
||||
- `ColaFlow.Modules.Mcp.Tests/Resources/SprintsCurrentResourceTests.cs`
|
||||
|
||||
### Task 7: UsersListResource (2 hours)
|
||||
- [ ] Implement `UsersListResource` class
|
||||
- [ ] Query users in current tenant
|
||||
- [ ] Filter by project (optional)
|
||||
- [ ] Include profile data (name, email, avatar URL)
|
||||
- [ ] Unit tests
|
||||
|
||||
**Files to Create**:
|
||||
- `ColaFlow.Modules.Mcp/Resources/UsersListResource.cs`
|
||||
- `ColaFlow.Modules.Mcp.Tests/Resources/UsersListResourceTests.cs`
|
||||
|
||||
### Task 8: Resource Registration (2 hours)
|
||||
- [ ] Create `IMcpRegistry` interface
|
||||
- [ ] Implement auto-discovery via Reflection
|
||||
- [ ] Register all Resources at startup
|
||||
- [ ] Implement `resources/list` method handler
|
||||
|
||||
**Files to Create**:
|
||||
- `ColaFlow.Modules.Mcp/Contracts/IMcpRegistry.cs`
|
||||
- `ColaFlow.Modules.Mcp/Services/McpRegistry.cs`
|
||||
|
||||
### Task 9: Integration Tests (4 hours)
|
||||
- [ ] Test end-to-end Resource requests
|
||||
- [ ] Test multi-tenant isolation (Tenant A cannot read Tenant B data)
|
||||
- [ ] Test pagination
|
||||
- [ ] Test query filters
|
||||
- [ ] Test performance (< 200ms)
|
||||
|
||||
**Files to Create**:
|
||||
- `ColaFlow.Modules.Mcp.Tests/Integration/McpResourcesIntegrationTests.cs`
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Unit Tests (> 80% coverage)
|
||||
- Each Resource class independently
|
||||
- Query building logic
|
||||
- JSON serialization
|
||||
- Error handling (not found, invalid params)
|
||||
|
||||
### Integration Tests
|
||||
- End-to-end Resource requests
|
||||
- Multi-tenant isolation verification
|
||||
- Pagination correctness
|
||||
- Performance benchmarks
|
||||
|
||||
### Manual Testing with Claude Desktop
|
||||
|
||||
```bash
|
||||
# Install MCP Inspector
|
||||
npm install -g @modelcontextprotocol/inspector
|
||||
|
||||
# Test projects.list
|
||||
mcp-inspector colaflow://projects.list
|
||||
|
||||
# Test issues.search with filters
|
||||
mcp-inspector colaflow://issues.search?status=InProgress&priority=High
|
||||
|
||||
# Test sprints.current
|
||||
mcp-inspector colaflow://sprints.current
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
**Prerequisites**:
|
||||
- Story 5.1 (MCP Protocol Handler) - Resource routing
|
||||
- Story 5.2 (API Key Management) - Authentication
|
||||
- Story 5.3 (MCP Domain Layer) - Domain entities
|
||||
- M1 ProjectManagement Module - Data source
|
||||
|
||||
**Blocks**:
|
||||
- Story 5.11 (Core MCP Tools) - Tools depend on Resources working
|
||||
|
||||
## Risks & Mitigation
|
||||
|
||||
| Risk | Impact | Probability | Mitigation |
|
||||
|------|--------|-------------|------------|
|
||||
| Performance slow (> 200ms) | Medium | Medium | Redis caching (Story 5.8), database indexes |
|
||||
| Multi-tenant leak | High | Low | 100% test coverage, Global Query Filters |
|
||||
| Query complexity | Medium | Medium | Limit query params, use IQueryable |
|
||||
| JSON serialization bugs | Low | Low | Unit tests, use System.Text.Json |
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] Code compiles without warnings
|
||||
- [ ] All 6 Resources implemented and working
|
||||
- [ ] Unit test coverage > 80%
|
||||
- [ ] Integration tests passing
|
||||
- [ ] Multi-tenant isolation verified (100%)
|
||||
- [ ] Performance < 200ms (P95)
|
||||
- [ ] Code reviewed and approved
|
||||
- [ ] XML documentation for public APIs
|
||||
- [ ] Resources registered and discoverable (`resources/list`)
|
||||
|
||||
## Notes
|
||||
|
||||
### Why This Story Matters
|
||||
- **First AI Integration**: AI can now read ColaFlow data
|
||||
- **Foundation for M2**: 50% of M2 features are read-only
|
||||
- **User Value**: Enables natural language project queries
|
||||
- **Milestone Demo**: Demonstrates MCP Server working
|
||||
|
||||
### Key Design Decisions
|
||||
1. **URI Scheme**: `colaflow://` custom protocol
|
||||
2. **JSON Responses**: All Resources return JSON
|
||||
3. **Pagination**: Limit/offset for large result sets
|
||||
4. **Filtering**: Query params for fine-grained control
|
||||
5. **Multi-Tenant**: TenantContext ensures data isolation
|
||||
|
||||
### Performance Optimization
|
||||
- Use `AsNoTracking()` for read-only queries (30% faster)
|
||||
- Add database indexes on commonly filtered columns
|
||||
- Implement Redis caching (Story 5.8) for hot Resources
|
||||
- Limit pagination size (max 100 items)
|
||||
|
||||
### Resource URI Design Guidelines
|
||||
- Use descriptive names: `projects.list`, `issues.search`
|
||||
- Use `{id}` for parameterized URIs: `projects.get/{id}`
|
||||
- Use query params for filters: `issues.search?status=InProgress`
|
||||
- Keep URIs stable (versioning if needed)
|
||||
|
||||
### Reference Materials
|
||||
- MCP Resources Spec: https://modelcontextprotocol.io/docs/concepts/resources
|
||||
- Sprint 5 Plan: `docs/plans/sprint_5.md`
|
||||
- Architecture Design: `docs/M2-MCP-SERVER-ARCHITECTURE.md`
|
||||
Reference in New Issue
Block a user