package registry import ( "context" "encoding/json" "fmt" ) // ToolDef describes a single MCP tool exposed by a skill. type ToolDef struct { Name string `json:"name"` Description string `json:"description"` InputSchema json.RawMessage `json:"inputSchema"` } // Skill is implemented by each skill package (tdd, review, etc.). type Skill interface { Name() string Tools() []ToolDef Handle(ctx context.Context, tool string, args json.RawMessage) (json.RawMessage, error) } // Registry routes MCP tool calls to the correct skill handler. type Registry struct { skills map[string]Skill // tool name → skill tools []ToolDef } func New() *Registry { return &Registry{ skills: make(map[string]Skill), tools: make([]ToolDef, 0), } } func (r *Registry) Register(s Skill) { for _, t := range s.Tools() { r.skills[t.Name] = s r.tools = append(r.tools, t) } } func (r *Registry) Tools() []ToolDef { return r.tools } func (r *Registry) Dispatch(ctx context.Context, tool string, args json.RawMessage) (json.RawMessage, error) { s, ok := r.skills[tool] if !ok { return nil, fmt.Errorf("unknown tool: %s", tool) } return s.Handle(ctx, tool, args) }