---
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
