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:
128
docs/stories/sprint_5/story_5_6.md
Normal file
128
docs/stories/sprint_5/story_5_6.md
Normal file
@@ -0,0 +1,128 @@
|
||||
---
|
||||
story_id: story_5_6
|
||||
sprint_id: sprint_5
|
||||
phase: Phase 2 - Resources
|
||||
status: not_started
|
||||
priority: P0
|
||||
story_points: 3
|
||||
assignee: backend
|
||||
estimated_days: 1
|
||||
created_date: 2025-11-06
|
||||
dependencies: [story_5_5]
|
||||
---
|
||||
|
||||
# Story 5.6: Resource Registration & Discovery
|
||||
|
||||
**Phase**: Phase 2 - Resources (Week 3-4)
|
||||
**Priority**: P0 CRITICAL
|
||||
**Estimated Effort**: 3 Story Points (1 day)
|
||||
|
||||
## User Story
|
||||
|
||||
**As an** AI Agent
|
||||
**I want** to discover available MCP Resources dynamically
|
||||
**So that** I know what data I can access from ColaFlow
|
||||
|
||||
## Business Value
|
||||
|
||||
Dynamic Resource discovery enables:
|
||||
- AI agents to explore available capabilities
|
||||
- Easy addition of new Resources without code changes
|
||||
- Version compatibility checking
|
||||
- Documentation generation
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
### AC1: Auto-Discovery
|
||||
- [ ] All `IMcpResource` implementations auto-registered at startup
|
||||
- [ ] Use Assembly scanning (Reflection)
|
||||
- [ ] Singleton registration in DI container
|
||||
|
||||
### AC2: Resource Catalog
|
||||
- [ ] `resources/list` method returns all Resources
|
||||
- [ ] Each Resource includes: URI, name, description, MIME type
|
||||
- [ ] Response conforms to MCP specification
|
||||
|
||||
### AC3: Resource Versioning
|
||||
- [ ] Support for Resource versioning (future-proof)
|
||||
- [ ] Optional `version` field in Resource metadata
|
||||
|
||||
### AC4: Configuration
|
||||
- [ ] Enable/disable Resources via `appsettings.json`
|
||||
- [ ] Filter Resources by tenant (optional)
|
||||
|
||||
### AC5: Testing
|
||||
- [ ] Unit tests for registry logic
|
||||
- [ ] Integration test for `resources/list`
|
||||
|
||||
## Technical Design
|
||||
|
||||
```csharp
|
||||
public interface IMcpRegistry
|
||||
{
|
||||
void RegisterResource(IMcpResource resource);
|
||||
IMcpResource? GetResource(string uri);
|
||||
IReadOnlyList<IMcpResource> GetAllResources();
|
||||
}
|
||||
|
||||
public class McpRegistry : IMcpRegistry
|
||||
{
|
||||
private readonly Dictionary<string, IMcpResource> _resources = new();
|
||||
|
||||
public void RegisterResource(IMcpResource resource)
|
||||
{
|
||||
_resources[resource.Uri] = resource;
|
||||
}
|
||||
|
||||
public IMcpResource? GetResource(string uri)
|
||||
{
|
||||
return _resources.TryGetValue(uri, out var resource) ? resource : null;
|
||||
}
|
||||
|
||||
public IReadOnlyList<IMcpResource> GetAllResources()
|
||||
{
|
||||
return _resources.Values.ToList().AsReadOnly();
|
||||
}
|
||||
}
|
||||
|
||||
// Auto-registration
|
||||
public static class McpServiceExtensions
|
||||
{
|
||||
public static IServiceCollection AddMcpResources(
|
||||
this IServiceCollection services)
|
||||
{
|
||||
var assembly = typeof(IMcpResource).Assembly;
|
||||
var resourceTypes = assembly.GetTypes()
|
||||
.Where(t => typeof(IMcpResource).IsAssignableFrom(t)
|
||||
&& !t.IsInterface && !t.IsAbstract);
|
||||
|
||||
foreach (var type in resourceTypes)
|
||||
{
|
||||
services.AddSingleton(typeof(IMcpResource), type);
|
||||
}
|
||||
|
||||
services.AddSingleton<IMcpRegistry, McpRegistry>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Tasks
|
||||
|
||||
- [ ] Create `IMcpRegistry` interface (1 hour)
|
||||
- [ ] Implement `McpRegistry` class (2 hours)
|
||||
- [ ] Implement auto-discovery via Reflection (2 hours)
|
||||
- [ ] Implement `resources/list` handler (1 hour)
|
||||
- [ ] Add configuration support (1 hour)
|
||||
- [ ] Unit tests (2 hours)
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] All Resources auto-registered
|
||||
- [ ] `resources/list` returns complete catalog
|
||||
- [ ] Unit tests passing
|
||||
- [ ] Code reviewed
|
||||
|
||||
## Reference
|
||||
|
||||
- MCP Spec: https://modelcontextprotocol.io/docs/concepts/resources
|
||||
Reference in New Issue
Block a user