@@ -4,67 +4,31 @@ import (
 	"encoding/json"
 	"fmt"
 	"os"
-	"reflect"
-	"slices"
-	"strings"
 
 	"github.com/charmbracelet/crush/internal/config"
+	"github.com/invopop/jsonschema"
 )
 
-// JSONSchema represents a JSON Schema
-type JSONSchema struct {
-	Schema               string                 `json:"$schema,omitempty"`
-	Title                string                 `json:"title,omitempty"`
-	Description          string                 `json:"description,omitempty"`
-	Type                 string                 `json:"type,omitempty"`
-	Properties           map[string]*JSONSchema `json:"properties,omitempty"`
-	Items                *JSONSchema            `json:"items,omitempty"`
-	Required             []string               `json:"required,omitempty"`
-	AdditionalProperties any                    `json:"additionalProperties,omitempty"`
-	Enum                 []any                  `json:"enum,omitempty"`
-	Default              any                    `json:"default,omitempty"`
-	Definitions          map[string]*JSONSchema `json:"definitions,omitempty"`
-	Ref                  string                 `json:"$ref,omitempty"`
-	OneOf                []*JSONSchema          `json:"oneOf,omitempty"`
-	AnyOf                []*JSONSchema          `json:"anyOf,omitempty"`
-	AllOf                []*JSONSchema          `json:"allOf,omitempty"`
-	Not                  *JSONSchema            `json:"not,omitempty"`
-	Format               string                 `json:"format,omitempty"`
-	Pattern              string                 `json:"pattern,omitempty"`
-	MinLength            *int                   `json:"minLength,omitempty"`
-	MaxLength            *int                   `json:"maxLength,omitempty"`
-	Minimum              *float64               `json:"minimum,omitempty"`
-	Maximum              *float64               `json:"maximum,omitempty"`
-	ExclusiveMinimum     *float64               `json:"exclusiveMinimum,omitempty"`
-	ExclusiveMaximum     *float64               `json:"exclusiveMaximum,omitempty"`
-	MultipleOf           *float64               `json:"multipleOf,omitempty"`
-	MinItems             *int                   `json:"minItems,omitempty"`
-	MaxItems             *int                   `json:"maxItems,omitempty"`
-	UniqueItems          *bool                  `json:"uniqueItems,omitempty"`
-	MinProperties        *int                   `json:"minProperties,omitempty"`
-	MaxProperties        *int                   `json:"maxProperties,omitempty"`
-}
-
-// SchemaGenerator generates JSON schemas from Go types
-type SchemaGenerator struct {
-	definitions map[string]*JSONSchema
-	visited     map[reflect.Type]bool
-}
-
-// NewSchemaGenerator creates a new schema generator
-func NewSchemaGenerator() *SchemaGenerator {
-	return &SchemaGenerator{
-		definitions: make(map[string]*JSONSchema),
-		visited:     make(map[reflect.Type]bool),
+func main() {
+	// Create a new reflector
+	r := &jsonschema.Reflector{
+		// Use anonymous schemas to avoid ID conflicts
+		Anonymous: true,
+		// Expand the root struct instead of referencing it
+		ExpandedStruct:            true,
+		AllowAdditionalProperties: true,
 	}
-}
 
-func main() {
-	// Enable mock providers to avoid API calls during schema generation
-	config.UseMockProviders = true
+	// Generate schema for the main Config struct
+	schema := r.Reflect(&config.Config{})
+
+	// Enhance the schema with additional information
+	enhanceSchema(schema)
 
-	generator := NewSchemaGenerator()
-	schema := generator.GenerateSchema()
+	// Set the schema metadata
+	schema.Version = "https://json-schema.org/draft/2020-12/schema"
+	schema.Title = "Crush Configuration"
+	schema.Description = "Configuration schema for the Crush application"
 
 	// Pretty print the schema
 	encoder := json.NewEncoder(os.Stdout)
@@ -75,226 +39,23 @@ func main() {
 	}
 }
 
-// GenerateSchema generates the complete JSON schema for the Crush configuration
-func (g *SchemaGenerator) GenerateSchema() *JSONSchema {
-	// Generate schema for the main Config struct
-	configType := reflect.TypeOf(config.Config{})
-	configSchema := g.generateTypeSchema(configType)
-
-	// Create the root schema
-	schema := &JSONSchema{
-		Schema:      "http://json-schema.org/draft-07/schema#",
-		Title:       "Crush Configuration",
-		Description: "Configuration schema for the Crush application",
-		Type:        configSchema.Type,
-		Properties:  configSchema.Properties,
-		Required:    configSchema.Required,
-		Definitions: g.definitions,
-	}
-
-	// Add custom enhancements
-	g.enhanceSchema(schema)
-
-	return schema
-}
-
-// generateTypeSchema generates a JSON schema for a given Go type
-func (g *SchemaGenerator) generateTypeSchema(t reflect.Type) *JSONSchema {
-	// Handle pointers
-	if t.Kind() == reflect.Ptr {
-		return g.generateTypeSchema(t.Elem())
-	}
-
-	// Check if we've already processed this type
-	if g.visited[t] {
-		// Return a reference to avoid infinite recursion
-		return &JSONSchema{
-			Ref: fmt.Sprintf("#/definitions/%s", t.Name()),
-		}
-	}
-
-	switch t.Kind() {
-	case reflect.String:
-		return &JSONSchema{Type: "string"}
-	case reflect.Bool:
-		return &JSONSchema{Type: "boolean"}
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
-		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
-		return &JSONSchema{Type: "integer"}
-	case reflect.Float32, reflect.Float64:
-		return &JSONSchema{Type: "number"}
-	case reflect.Slice, reflect.Array:
-		itemSchema := g.generateTypeSchema(t.Elem())
-		return &JSONSchema{
-			Type:  "array",
-			Items: itemSchema,
-		}
-	case reflect.Map:
-		valueSchema := g.generateTypeSchema(t.Elem())
-		return &JSONSchema{
-			Type:                 "object",
-			AdditionalProperties: valueSchema,
-		}
-	case reflect.Struct:
-		return g.generateStructSchema(t)
-	case reflect.Interface:
-		// For interface{} types, allow any value
-		return &JSONSchema{}
-	default:
-		// Fallback for unknown types
-		return &JSONSchema{}
-	}
-}
-
-// generateStructSchema generates a JSON schema for a struct type
-func (g *SchemaGenerator) generateStructSchema(t reflect.Type) *JSONSchema {
-	// Mark as visited to prevent infinite recursion
-	g.visited[t] = true
-
-	schema := &JSONSchema{
-		Type:       "object",
-		Properties: make(map[string]*JSONSchema),
-	}
-
-	var required []string
-
-	for i := range t.NumField() {
-		field := t.Field(i)
-
-		// Skip unexported fields
-		if !field.IsExported() {
-			continue
-		}
-
-		// Get JSON tag
-		jsonTag := field.Tag.Get("json")
-		if jsonTag == "-" {
-			continue
-		}
-
-		// Parse JSON tag
-		jsonName, options := parseJSONTag(jsonTag)
-		if jsonName == "" {
-			jsonName = strings.ToLower(field.Name)
-		}
-
-		// Generate field schema
-		fieldSchema := g.generateTypeSchema(field.Type)
-
-		// Add description from field name if not present
-		if fieldSchema.Description == "" {
-			fieldSchema.Description = generateFieldDescription(field.Name, field.Type)
-		}
-
-		// Check if field is required (not omitempty and not a pointer)
-		if !slices.Contains(options, "omitempty") && field.Type.Kind() != reflect.Ptr {
-			required = append(required, jsonName)
-		}
-
-		schema.Properties[jsonName] = fieldSchema
-	}
-
-	if len(required) > 0 {
-		schema.Required = required
-	}
-
-	// Store in definitions if it's a named type
-	if t.Name() != "" {
-		g.definitions[t.Name()] = schema
-	}
-
-	return schema
-}
-
-// parseJSONTag parses a JSON struct tag
-func parseJSONTag(tag string) (name string, options []string) {
-	if tag == "" {
-		return "", nil
-	}
-
-	parts := strings.Split(tag, ",")
-	name = parts[0]
-	if len(parts) > 1 {
-		options = parts[1:]
-	}
-	return name, options
-}
-
-// generateFieldDescription generates a description for a field based on its name and type
-func generateFieldDescription(fieldName string, fieldType reflect.Type) string {
-	// Convert camelCase to words
-	words := camelCaseToWords(fieldName)
-	description := strings.Join(words, " ")
-
-	// Add type-specific information
-	switch fieldType.Kind() {
-	case reflect.Bool:
-		if !strings.Contains(strings.ToLower(description), "enable") &&
-			!strings.Contains(strings.ToLower(description), "disable") {
-			description = "Enable " + strings.ToLower(description)
-		}
-	case reflect.Slice:
-		if !strings.HasSuffix(description, "s") {
-			description = description + " list"
-		}
-	case reflect.Map:
-		description = description + " configuration"
-	}
-
-	return description
-}
-
-// camelCaseToWords converts camelCase to separate words
-func camelCaseToWords(s string) []string {
-	var words []string
-	var currentWord strings.Builder
-
-	for i, r := range s {
-		if i > 0 && r >= 'A' && r <= 'Z' {
-			if currentWord.Len() > 0 {
-				words = append(words, currentWord.String())
-				currentWord.Reset()
-			}
-		}
-		currentWord.WriteRune(r)
-	}
-
-	if currentWord.Len() > 0 {
-		words = append(words, currentWord.String())
-	}
-
-	return words
-}
-
-// enhanceSchema adds custom enhancements to the generated schema
-func (g *SchemaGenerator) enhanceSchema(schema *JSONSchema) {
+// enhanceSchema adds additional enhancements to the generated schema
+func enhanceSchema(schema *jsonschema.Schema) {
 	// Add provider enums
-	g.addProviderEnums(schema)
+	addProviderEnums(schema)
 
 	// Add model enums
-	g.addModelEnums(schema)
-
-	// Add agent enums
-	g.addAgentEnums(schema)
+	addModelEnums(schema)
 
 	// Add tool enums
-	g.addToolEnums(schema)
-
-	// Add MCP type enums
-	g.addMCPTypeEnums(schema)
-
-	// Add model type enums
-	g.addModelTypeEnums(schema)
-
-	// Add default values
-	g.addDefaultValues(schema)
+	addToolEnums(schema)
 
-	// Add custom descriptions
-	g.addCustomDescriptions(schema)
+	// Add default context paths
+	addDefaultContextPaths(schema)
 }
 
 // addProviderEnums adds provider enums to the schema
-func (g *SchemaGenerator) addProviderEnums(schema *JSONSchema) {
+func addProviderEnums(schema *jsonschema.Schema) {
 	providers := config.Providers()
 	var providerIDs []any
 	for _, p := range providers {
@@ -302,22 +63,24 @@ func (g *SchemaGenerator) addProviderEnums(schema *JSONSchema) {
 	}
 
 	// Add to PreferredModel provider field
-	if preferredModelDef, exists := schema.Definitions["PreferredModel"]; exists {
-		if providerProp, exists := preferredModelDef.Properties["provider"]; exists {
-			providerProp.Enum = providerIDs
+	if schema.Definitions != nil {
+		if preferredModelDef, exists := schema.Definitions["PreferredModel"]; exists {
+			if providerProp, exists := preferredModelDef.Properties.Get("provider"); exists {
+				providerProp.Enum = providerIDs
+			}
 		}
-	}
 
-	// Add to ProviderConfig ID field
-	if providerConfigDef, exists := schema.Definitions["ProviderConfig"]; exists {
-		if idProp, exists := providerConfigDef.Properties["id"]; exists {
-			idProp.Enum = providerIDs
+		// Add to ProviderConfig ID field
+		if providerConfigDef, exists := schema.Definitions["ProviderConfig"]; exists {
+			if idProp, exists := providerConfigDef.Properties.Get("id"); exists {
+				idProp.Enum = providerIDs
+			}
 		}
 	}
 }
 
 // addModelEnums adds model enums to the schema
-func (g *SchemaGenerator) addModelEnums(schema *JSONSchema) {
+func addModelEnums(schema *jsonschema.Schema) {
 	providers := config.Providers()
 	var modelIDs []any
 	for _, p := range providers {
@@ -327,205 +90,66 @@ func (g *SchemaGenerator) addModelEnums(schema *JSONSchema) {
 	}
 
 	// Add to PreferredModel model_id field
-	if preferredModelDef, exists := schema.Definitions["PreferredModel"]; exists {
-		if modelIDProp, exists := preferredModelDef.Properties["model_id"]; exists {
-			modelIDProp.Enum = modelIDs
-		}
-	}
-}
-
-// addAgentEnums adds agent ID enums to the schema
-func (g *SchemaGenerator) addAgentEnums(schema *JSONSchema) {
-	agentIDs := []any{
-		string(config.AgentCoder),
-		string(config.AgentTask),
-	}
-
-	if agentDef, exists := schema.Definitions["Agent"]; exists {
-		if idProp, exists := agentDef.Properties["id"]; exists {
-			idProp.Enum = agentIDs
+	if schema.Definitions != nil {
+		if preferredModelDef, exists := schema.Definitions["PreferredModel"]; exists {
+			if modelIDProp, exists := preferredModelDef.Properties.Get("model_id"); exists {
+				modelIDProp.Enum = modelIDs
+			}
 		}
 	}
 }
 
 // addToolEnums adds tool enums to the schema
-func (g *SchemaGenerator) addToolEnums(schema *JSONSchema) {
+func addToolEnums(schema *jsonschema.Schema) {
 	tools := []any{
 		"bash", "edit", "fetch", "glob", "grep", "ls", "sourcegraph", "view", "write", "agent",
 	}
 
-	if agentDef, exists := schema.Definitions["Agent"]; exists {
-		if allowedToolsProp, exists := agentDef.Properties["allowed_tools"]; exists {
-			if allowedToolsProp.Items != nil {
-				allowedToolsProp.Items.Enum = tools
+	if schema.Definitions != nil {
+		if agentDef, exists := schema.Definitions["Agent"]; exists {
+			if allowedToolsProp, exists := agentDef.Properties.Get("allowed_tools"); exists {
+				if allowedToolsProp.Items != nil {
+					allowedToolsProp.Items.Enum = tools
+				}
 			}
 		}
 	}
 }
 
-// addMCPTypeEnums adds MCP type enums to the schema
-func (g *SchemaGenerator) addMCPTypeEnums(schema *JSONSchema) {
-	mcpTypes := []any{
-		string(config.MCPStdio),
-		string(config.MCPSse),
+// addDefaultContextPaths adds default context paths to the schema
+func addDefaultContextPaths(schema *jsonschema.Schema) {
+	defaultContextPaths := []any{
+		".github/copilot-instructions.md",
+		".cursorrules",
+		".cursor/rules/",
+		"CLAUDE.md",
+		"CLAUDE.local.md",
+		"GEMINI.md",
+		"gemini.md",
+		"crush.md",
+		"crush.local.md",
+		"Crush.md",
+		"Crush.local.md",
+		"CRUSH.md",
+		"CRUSH.local.md",
 	}
 
-	if mcpDef, exists := schema.Definitions["MCP"]; exists {
-		if typeProp, exists := mcpDef.Properties["type"]; exists {
-			typeProp.Enum = mcpTypes
-		}
-	}
-}
-
-// addModelTypeEnums adds model type enums to the schema
-func (g *SchemaGenerator) addModelTypeEnums(schema *JSONSchema) {
-	modelTypes := []any{
-		string(config.LargeModel),
-		string(config.SmallModel),
-	}
-
-	if agentDef, exists := schema.Definitions["Agent"]; exists {
-		if modelProp, exists := agentDef.Properties["model"]; exists {
-			modelProp.Enum = modelTypes
-		}
-	}
-}
-
-// addDefaultValues adds default values to the schema
-func (g *SchemaGenerator) addDefaultValues(schema *JSONSchema) {
-	// Add default context paths
-	if optionsDef, exists := schema.Definitions["Options"]; exists {
-		if contextPathsProp, exists := optionsDef.Properties["context_paths"]; exists {
-			contextPathsProp.Default = []any{
-				".github/copilot-instructions.md",
-				".cursorrules",
-				".cursor/rules/",
-				"CLAUDE.md",
-				"CLAUDE.local.md",
-				"GEMINI.md",
-				"gemini.md",
-				"crush.md",
-				"crush.local.md",
-				"Crush.md",
-				"Crush.local.md",
-				"CRUSH.md",
-				"CRUSH.local.md",
+	if schema.Definitions != nil {
+		if optionsDef, exists := schema.Definitions["Options"]; exists {
+			if contextPathsProp, exists := optionsDef.Properties.Get("context_paths"); exists {
+				contextPathsProp.Default = defaultContextPaths
 			}
 		}
-		if dataDirProp, exists := optionsDef.Properties["data_directory"]; exists {
-			dataDirProp.Default = ".crush"
-		}
-		if debugProp, exists := optionsDef.Properties["debug"]; exists {
-			debugProp.Default = false
-		}
-		if debugLSPProp, exists := optionsDef.Properties["debug_lsp"]; exists {
-			debugLSPProp.Default = false
-		}
-		if disableAutoSummarizeProp, exists := optionsDef.Properties["disable_auto_summarize"]; exists {
-			disableAutoSummarizeProp.Default = false
-		}
-	}
-
-	// Add default MCP type
-	if mcpDef, exists := schema.Definitions["MCP"]; exists {
-		if typeProp, exists := mcpDef.Properties["type"]; exists {
-			typeProp.Default = string(config.MCPStdio)
-		}
-	}
-
-	// Add default TUI options
-	if tuiOptionsDef, exists := schema.Definitions["TUIOptions"]; exists {
-		if compactModeProp, exists := tuiOptionsDef.Properties["compact_mode"]; exists {
-			compactModeProp.Default = false
-		}
-	}
-
-	// Add default provider disabled
-	if providerConfigDef, exists := schema.Definitions["ProviderConfig"]; exists {
-		if disabledProp, exists := providerConfigDef.Properties["disabled"]; exists {
-			disabledProp.Default = false
-		}
-	}
-
-	// Add default agent disabled
-	if agentDef, exists := schema.Definitions["Agent"]; exists {
-		if disabledProp, exists := agentDef.Properties["disabled"]; exists {
-			disabledProp.Default = false
-		}
-	}
-
-	// Add default LSP disabled
-	if lspConfigDef, exists := schema.Definitions["LSPConfig"]; exists {
-		if disabledProp, exists := lspConfigDef.Properties["enabled"]; exists {
-			disabledProp.Default = true
-		}
 	}
-}
 
-// addCustomDescriptions adds custom descriptions to improve the schema
-func (g *SchemaGenerator) addCustomDescriptions(schema *JSONSchema) {
-	// Enhance main config descriptions
+	// Also add to root properties if they exist
 	if schema.Properties != nil {
-		if modelsProp, exists := schema.Properties["models"]; exists {
-			modelsProp.Description = "Preferred model configurations for large and small model types"
-		}
-		if providersProp, exists := schema.Properties["providers"]; exists {
-			providersProp.Description = "LLM provider configurations"
-		}
-		if agentsProp, exists := schema.Properties["agents"]; exists {
-			agentsProp.Description = "Agent configurations for different tasks"
-		}
-		if mcpProp, exists := schema.Properties["mcp"]; exists {
-			mcpProp.Description = "Model Control Protocol server configurations"
-		}
-		if lspProp, exists := schema.Properties["lsp"]; exists {
-			lspProp.Description = "Language Server Protocol configurations"
-		}
-		if optionsProp, exists := schema.Properties["options"]; exists {
-			optionsProp.Description = "General application options and settings"
-		}
-	}
-
-	// Enhance specific field descriptions
-	if providerConfigDef, exists := schema.Definitions["ProviderConfig"]; exists {
-		if apiKeyProp, exists := providerConfigDef.Properties["api_key"]; exists {
-			apiKeyProp.Description = "API key for authenticating with the provider"
-		}
-		if baseURLProp, exists := providerConfigDef.Properties["base_url"]; exists {
-			baseURLProp.Description = "Base URL for the provider API (required for custom providers)"
-		}
-		if extraHeadersProp, exists := providerConfigDef.Properties["extra_headers"]; exists {
-			extraHeadersProp.Description = "Additional HTTP headers to send with requests"
-		}
-		if extraParamsProp, exists := providerConfigDef.Properties["extra_params"]; exists {
-			extraParamsProp.Description = "Additional provider-specific parameters"
-		}
-	}
-
-	if agentDef, exists := schema.Definitions["Agent"]; exists {
-		if allowedToolsProp, exists := agentDef.Properties["allowed_tools"]; exists {
-			allowedToolsProp.Description = "List of tools this agent is allowed to use (if nil, all tools are allowed)"
-		}
-		if allowedMCPProp, exists := agentDef.Properties["allowed_mcp"]; exists {
-			allowedMCPProp.Description = "Map of MCP servers this agent can use and their allowed tools"
-		}
-		if allowedLSPProp, exists := agentDef.Properties["allowed_lsp"]; exists {
-			allowedLSPProp.Description = "List of LSP servers this agent can use (if nil, all LSPs are allowed)"
-		}
-		if contextPathsProp, exists := agentDef.Properties["context_paths"]; exists {
-			contextPathsProp.Description = "Custom context paths for this agent (additive to global context paths)"
-		}
-	}
-
-	if mcpDef, exists := schema.Definitions["MCP"]; exists {
-		if commandProp, exists := mcpDef.Properties["command"]; exists {
-			commandProp.Description = "Command to execute for stdio MCP servers"
-		}
-		if urlProp, exists := mcpDef.Properties["url"]; exists {
-			urlProp.Description = "URL for SSE MCP servers"
-		}
-		if headersProp, exists := mcpDef.Properties["headers"]; exists {
-			headersProp.Description = "HTTP headers for SSE MCP servers"
+		if optionsProp, exists := schema.Properties.Get("options"); exists {
+			if optionsProp.Properties != nil {
+				if contextPathsProp, exists := optionsProp.Properties.Get("context_paths"); exists {
+					contextPathsProp.Default = defaultContextPaths
+				}
+			}
 		}
 	}
 }
  
  
  
    
    @@ -1,492 +1,47 @@
 {
-  "$schema": "http://json-schema.org/draft-07/schema#",
-  "title": "Crush Configuration",
-  "description": "Configuration schema for the Crush application",
-  "type": "object",
-  "properties": {
-    "agents": {
-      "description": "Agent configurations for different tasks",
-      "type": "object",
-      "additionalProperties": {
-        "type": "object",
-        "properties": {
-          "allowed_lsp": {
-            "description": "List of LSP servers this agent can use (if nil, all LSPs are allowed)",
-            "type": "array",
-            "items": {
-              "type": "string"
-            }
-          },
-          "allowed_mcp": {
-            "description": "Map of MCP servers this agent can use and their allowed tools",
-            "type": "object",
-            "additionalProperties": {
-              "type": "array",
-              "items": {
-                "type": "string"
-              }
-            }
-          },
-          "allowed_tools": {
-            "description": "List of tools this agent is allowed to use (if nil, all tools are allowed)",
-            "type": "array",
-            "items": {
-              "type": "string",
-              "enum": [
-                "bash",
-                "edit",
-                "fetch",
-                "glob",
-                "grep",
-                "ls",
-                "sourcegraph",
-                "view",
-                "write",
-                "agent"
-              ]
-            }
-          },
-          "context_paths": {
-            "description": "Custom context paths for this agent (additive to global context paths)",
-            "type": "array",
-            "items": {
-              "type": "string"
-            }
-          },
-          "description": {
-            "description": "Description",
-            "type": "string"
-          },
-          "disabled": {
-            "description": "Disabled",
-            "type": "boolean",
-            "default": false
-          },
-          "id": {
-            "description": "I D",
-            "type": "string",
-            "enum": [
-              "coder",
-              "task"
-            ]
-          },
-          "model": {
-            "description": "Model",
-            "type": "string",
-            "enum": [
-              "large",
-              "small"
-            ]
-          },
-          "name": {
-            "description": "Name",
-            "type": "string"
-          }
-        },
-        "required": [
-          "id",
-          "name",
-          "disabled",
-          "model",
-          "allowed_tools",
-          "allowed_mcp",
-          "allowed_lsp",
-          "context_paths"
-        ]
-      }
-    },
-    "lsp": {
-      "description": "Language Server Protocol configurations",
-      "type": "object",
-      "additionalProperties": {
-        "type": "object",
-        "properties": {
-          "args": {
-            "description": "Args",
-            "type": "array",
-            "items": {
-              "type": "string"
-            }
-          },
-          "command": {
-            "description": "Command",
-            "type": "string"
-          },
-          "enabled": {
-            "description": "Disabled",
-            "type": "boolean",
-            "default": true
-          },
-          "options": {
-            "description": "Options"
-          }
-        },
-        "required": [
-          "enabled",
-          "command",
-          "args",
-          "options"
-        ]
-      }
-    },
-    "mcp": {
-      "description": "Model Control Protocol server configurations",
-      "type": "object",
-      "additionalProperties": {
-        "type": "object",
-        "properties": {
-          "args": {
-            "description": "Args",
-            "type": "array",
-            "items": {
-              "type": "string"
-            }
-          },
-          "command": {
-            "description": "Command to execute for stdio MCP servers",
-            "type": "string"
-          },
-          "env": {
-            "description": "Env list",
-            "type": "array",
-            "items": {
-              "type": "string"
-            }
-          },
-          "headers": {
-            "description": "HTTP headers for SSE MCP servers",
-            "type": "object",
-            "additionalProperties": {
-              "type": "string"
-            }
-          },
-          "type": {
-            "description": "Type",
-            "type": "string",
-            "enum": [
-              "stdio",
-              "sse"
-            ],
-            "default": "stdio"
-          },
-          "url": {
-            "description": "URL for SSE MCP servers",
-            "type": "string"
-          }
-        },
-        "required": [
-          "command",
-          "env",
-          "args",
-          "type",
-          "url",
-          "headers"
-        ]
-      }
-    },
-    "models": {
-      "description": "Preferred model configurations for large and small model types",
-      "type": "object",
-      "properties": {
-        "large": {
-          "description": "Large",
-          "type": "object",
-          "properties": {
-            "max_tokens": {
-              "description": "Max Tokens",
-              "type": "integer"
-            },
-            "model_id": {
-              "description": "Model I D",
-              "type": "string",
-              "enum": [
-                "claude-3-opus",
-                "claude-3-haiku",
-                "claude-3-5-sonnet-20241022",
-                "claude-3-5-haiku-20241022",
-                "gpt-4",
-                "gpt-3.5-turbo",
-                "gpt-4-turbo",
-                "gpt-4o",
-                "gpt-4o-mini",
-                "o1-preview",
-                "o1-mini",
-                "gemini-2.5-pro",
-                "gemini-2.5-flash",
-                "grok-beta",
-                "anthropic/claude-3.5-sonnet",
-                "anthropic/claude-3.5-haiku"
-              ]
-            },
-            "provider": {
-              "description": "Provider",
-              "type": "string",
-              "enum": [
-                "anthropic",
-                "openai",
-                "gemini",
-                "xai",
-                "openrouter"
-              ]
-            },
-            "reasoning_effort": {
-              "description": "Reasoning Effort",
-              "type": "string"
-            },
-            "think": {
-              "description": "Enable think",
-              "type": "boolean"
-            }
-          },
-          "required": [
-            "model_id",
-            "provider"
-          ]
-        },
-        "small": {
-          "description": "Small",
-          "$ref": "#/definitions/PreferredModel"
-        }
-      },
-      "required": [
-        "large",
-        "small"
-      ]
-    },
-    "options": {
-      "description": "General application options and settings",
-      "type": "object",
+  "$schema": "https://json-schema.org/draft/2020-12/schema",
+  "$defs": {
+    "Agent": {
       "properties": {
-        "context_paths": {
-          "description": "Context Paths",
-          "type": "array",
-          "items": {
-            "type": "string"
-          },
-          "default": [
-            ".github/copilot-instructions.md",
-            ".cursorrules",
-            ".cursor/rules/",
-            "CLAUDE.md",
-            "CLAUDE.local.md",
-            "GEMINI.md",
-            "gemini.md",
-            "crush.md",
-            "crush.local.md",
-            "Crush.md",
-            "Crush.local.md",
-            "CRUSH.md",
-            "CRUSH.local.md"
-          ]
-        },
-        "data_directory": {
-          "description": "Data Directory",
+        "id": {
           "type": "string",
-          "default": ".crush"
+          "enum": [
+            "coder",
+            "task",
+            "coder",
+            "task"
+          ],
+          "title": "Agent ID",
+          "description": "Unique identifier for the agent"
         },
-        "debug": {
-          "description": "Enable debug",
-          "type": "boolean",
-          "default": false
+        "name": {
+          "type": "string",
+          "title": "Name",
+          "description": "Display name of the agent"
         },
-        "debug_lsp": {
-          "description": "Enable debug l s p",
-          "type": "boolean",
-          "default": false
+        "description": {
+          "type": "string",
+          "title": "Description",
+          "description": "Description of what the agent does"
         },
-        "disable_auto_summarize": {
-          "description": "Disable Auto Summarize",
+        "disabled": {
           "type": "boolean",
+          "title": "Disabled",
+          "description": "Whether this agent is disabled",
           "default": false
         },
-        "tui": {
-          "description": "T U I",
-          "type": "object",
-          "properties": {
-            "compact_mode": {
-              "description": "Enable compact mode",
-              "type": "boolean",
-              "default": false
-            }
-          },
-          "required": [
-            "compact_mode"
-          ]
-        }
-      },
-      "required": [
-        "context_paths",
-        "tui",
-        "debug",
-        "debug_lsp",
-        "disable_auto_summarize",
-        "data_directory"
-      ]
-    },
-    "providers": {
-      "description": "LLM provider configurations",
-      "type": "object",
-      "additionalProperties": {
-        "type": "object",
-        "properties": {
-          "api_key": {
-            "description": "API key for authenticating with the provider",
-            "type": "string"
-          },
-          "base_url": {
-            "description": "Base URL for the provider API (required for custom providers)",
-            "type": "string"
-          },
-          "default_large_model": {
-            "description": "Default Large Model",
-            "type": "string"
-          },
-          "default_small_model": {
-            "description": "Default Small Model",
-            "type": "string"
-          },
-          "disabled": {
-            "description": "Disabled",
-            "type": "boolean",
-            "default": false
-          },
-          "extra_headers": {
-            "description": "Additional HTTP headers to send with requests",
-            "type": "object",
-            "additionalProperties": {
-              "type": "string"
-            }
-          },
-          "extra_params": {
-            "description": "Additional provider-specific parameters",
-            "type": "object",
-            "additionalProperties": {
-              "type": "string"
-            }
-          },
-          "id": {
-            "description": "I D",
-            "type": "string",
-            "enum": [
-              "anthropic",
-              "openai",
-              "gemini",
-              "xai",
-              "openrouter"
-            ]
-          },
-          "models": {
-            "description": "Models",
-            "type": "array",
-            "items": {
-              "type": "object",
-              "properties": {
-                "can_reason": {
-                  "description": "Enable can reason",
-                  "type": "boolean"
-                },
-                "context_window": {
-                  "description": "Context Window",
-                  "type": "integer"
-                },
-                "cost_per_1m_in": {
-                  "description": "Cost Per1 M In",
-                  "type": "number"
-                },
-                "cost_per_1m_in_cached": {
-                  "description": "Cost Per1 M In Cached",
-                  "type": "number"
-                },
-                "cost_per_1m_out": {
-                  "description": "Cost Per1 M Out",
-                  "type": "number"
-                },
-                "cost_per_1m_out_cached": {
-                  "description": "Cost Per1 M Out Cached",
-                  "type": "number"
-                },
-                "default_max_tokens": {
-                  "description": "Default Max Tokens",
-                  "type": "integer"
-                },
-                "has_reasoning_effort": {
-                  "description": "Enable has reasoning effort",
-                  "type": "boolean"
-                },
-                "id": {
-                  "description": "I D",
-                  "type": "string"
-                },
-                "model": {
-                  "description": "Name",
-                  "type": "string"
-                },
-                "reasoning_effort": {
-                  "description": "Reasoning Effort",
-                  "type": "string"
-                },
-                "supports_attachments": {
-                  "description": "Enable supports images",
-                  "type": "boolean"
-                }
-              },
-              "required": [
-                "id",
-                "model",
-                "cost_per_1m_in",
-                "cost_per_1m_out",
-                "cost_per_1m_in_cached",
-                "cost_per_1m_out_cached",
-                "context_window",
-                "default_max_tokens",
-                "can_reason",
-                "reasoning_effort",
-                "has_reasoning_effort",
-                "supports_attachments"
-              ]
-            }
-          },
-          "provider_type": {
-            "description": "Provider Type",
-            "type": "string"
-          }
-        },
-        "required": [
-          "id",
-          "provider_type",
-          "disabled"
-        ]
-      }
-    }
-  },
-  "required": [
-    "models",
-    "options"
-  ],
-  "definitions": {
-    "Agent": {
-      "type": "object",
-      "properties": {
-        "allowed_lsp": {
-          "description": "List of LSP servers this agent can use (if nil, all LSPs are allowed)",
-          "type": "array",
-          "items": {
-            "type": "string"
-          }
-        },
-        "allowed_mcp": {
-          "description": "Map of MCP servers this agent can use and their allowed tools",
-          "type": "object",
-          "additionalProperties": {
-            "type": "array",
-            "items": {
-              "type": "string"
-            }
-          }
+        "model": {
+          "type": "string",
+          "enum": [
+            "large",
+            "small",
+            "large",
+            "small"
+          ],
+          "title": "Model Type",
+          "description": "Type of model to use (large or small)"
         },
         "allowed_tools": {
-          "description": "List of tools this agent is allowed to use (if nil, all tools are allowed)",
-          "type": "array",
           "items": {
             "type": "string",
             "enum": [
@@ -501,652 +56,200 @@
               "write",
               "agent"
             ]
-          }
-        },
-        "context_paths": {
-          "description": "Custom context paths for this agent (additive to global context paths)",
+          },
           "type": "array",
-          "items": {
-            "type": "string"
-          }
-        },
-        "description": {
-          "description": "Description",
-          "type": "string"
-        },
-        "disabled": {
-          "description": "Disabled",
-          "type": "boolean",
-          "default": false
-        },
-        "id": {
-          "description": "I D",
-          "type": "string",
-          "enum": [
-            "coder",
-            "task"
-          ]
-        },
-        "model": {
-          "description": "Model",
-          "type": "string",
-          "enum": [
-            "large",
-            "small"
-          ]
+          "title": "Allowed Tools",
+          "description": "List of tools this agent is allowed to use (if nil all tools are allowed)"
         },
-        "name": {
-          "description": "Name",
-          "type": "string"
-        }
-      },
-      "required": [
-        "id",
-        "name",
-        "disabled",
-        "model",
-        "allowed_tools",
-        "allowed_mcp",
-        "allowed_lsp",
-        "context_paths"
-      ]
-    },
-    "Config": {
-      "type": "object",
-      "properties": {
-        "agents": {
-          "description": "Agent configurations for different tasks",
-          "type": "object",
+        "allowed_mcp": {
           "additionalProperties": {
-            "type": "object",
-            "properties": {
-              "allowed_lsp": {
-                "description": "List of LSP servers this agent can use (if nil, all LSPs are allowed)",
-                "type": "array",
-                "items": {
-                  "type": "string"
-                }
-              },
-              "allowed_mcp": {
-                "description": "Map of MCP servers this agent can use and their allowed tools",
-                "type": "object",
-                "additionalProperties": {
-                  "type": "array",
-                  "items": {
-                    "type": "string"
-                  }
-                }
-              },
-              "allowed_tools": {
-                "description": "List of tools this agent is allowed to use (if nil, all tools are allowed)",
-                "type": "array",
-                "items": {
-                  "type": "string",
-                  "enum": [
-                    "bash",
-                    "edit",
-                    "fetch",
-                    "glob",
-                    "grep",
-                    "ls",
-                    "sourcegraph",
-                    "view",
-                    "write",
-                    "agent"
-                  ]
-                }
-              },
-              "context_paths": {
-                "description": "Custom context paths for this agent (additive to global context paths)",
-                "type": "array",
-                "items": {
-                  "type": "string"
-                }
-              },
-              "description": {
-                "description": "Description",
-                "type": "string"
-              },
-              "disabled": {
-                "description": "Disabled",
-                "type": "boolean",
-                "default": false
-              },
-              "id": {
-                "description": "I D",
-                "type": "string",
-                "enum": [
-                  "coder",
-                  "task"
-                ]
-              },
-              "model": {
-                "description": "Model",
-                "type": "string",
-                "enum": [
-                  "large",
-                  "small"
-                ]
-              },
-              "name": {
-                "description": "Name",
-                "type": "string"
-              }
+            "items": {
+              "type": "string"
             },
-            "required": [
-              "id",
-              "name",
-              "disabled",
-              "model",
-              "allowed_tools",
-              "allowed_mcp",
-              "allowed_lsp",
-              "context_paths"
-            ]
-          }
-        },
-        "lsp": {
-          "description": "Language Server Protocol configurations",
+            "type": "array"
+          },
           "type": "object",
-          "additionalProperties": {
-            "type": "object",
-            "properties": {
-              "args": {
-                "description": "Args",
-                "type": "array",
-                "items": {
-                  "type": "string"
-                }
-              },
-              "command": {
-                "description": "Command",
-                "type": "string"
-              },
-              "enabled": {
-                "description": "Disabled",
-                "type": "boolean",
-                "default": true
-              },
-              "options": {
-                "description": "Options"
-              }
-            },
-            "required": [
-              "enabled",
-              "command",
-              "args",
-              "options"
-            ]
-          }
+          "title": "Allowed MCP",
+          "description": "Map of MCP servers this agent can use and their allowed tools"
         },
-        "mcp": {
-          "description": "Model Control Protocol server configurations",
-          "type": "object",
-          "additionalProperties": {
-            "type": "object",
-            "properties": {
-              "args": {
-                "description": "Args",
-                "type": "array",
-                "items": {
-                  "type": "string"
-                }
-              },
-              "command": {
-                "description": "Command to execute for stdio MCP servers",
-                "type": "string"
-              },
-              "env": {
-                "description": "Env list",
-                "type": "array",
-                "items": {
-                  "type": "string"
-                }
-              },
-              "headers": {
-                "description": "HTTP headers for SSE MCP servers",
-                "type": "object",
-                "additionalProperties": {
-                  "type": "string"
-                }
-              },
-              "type": {
-                "description": "Type",
-                "type": "string",
-                "enum": [
-                  "stdio",
-                  "sse"
-                ],
-                "default": "stdio"
-              },
-              "url": {
-                "description": "URL for SSE MCP servers",
-                "type": "string"
-              }
-            },
-            "required": [
-              "command",
-              "env",
-              "args",
-              "type",
-              "url",
-              "headers"
-            ]
-          }
-        },
-        "models": {
-          "description": "Preferred model configurations for large and small model types",
-          "type": "object",
-          "properties": {
-            "large": {
-              "description": "Large",
-              "type": "object",
-              "properties": {
-                "max_tokens": {
-                  "description": "Max Tokens",
-                  "type": "integer"
-                },
-                "model_id": {
-                  "description": "Model I D",
-                  "type": "string",
-                  "enum": [
-                    "claude-3-opus",
-                    "claude-3-haiku",
-                    "claude-3-5-sonnet-20241022",
-                    "claude-3-5-haiku-20241022",
-                    "gpt-4",
-                    "gpt-3.5-turbo",
-                    "gpt-4-turbo",
-                    "gpt-4o",
-                    "gpt-4o-mini",
-                    "o1-preview",
-                    "o1-mini",
-                    "gemini-2.5-pro",
-                    "gemini-2.5-flash",
-                    "grok-beta",
-                    "anthropic/claude-3.5-sonnet",
-                    "anthropic/claude-3.5-haiku"
-                  ]
-                },
-                "provider": {
-                  "description": "Provider",
-                  "type": "string",
-                  "enum": [
-                    "anthropic",
-                    "openai",
-                    "gemini",
-                    "xai",
-                    "openrouter"
-                  ]
-                },
-                "reasoning_effort": {
-                  "description": "Reasoning Effort",
-                  "type": "string"
-                },
-                "think": {
-                  "description": "Enable think",
-                  "type": "boolean"
-                }
-              },
-              "required": [
-                "model_id",
-                "provider"
-              ]
-            },
-            "small": {
-              "description": "Small",
-              "$ref": "#/definitions/PreferredModel"
-            }
+        "allowed_lsp": {
+          "items": {
+            "type": "string"
           },
-          "required": [
-            "large",
-            "small"
-          ]
+          "type": "array",
+          "title": "Allowed LSP",
+          "description": "List of LSP servers this agent can use (if nil all LSPs are allowed)"
         },
-        "options": {
-          "description": "General application options and settings",
-          "type": "object",
-          "properties": {
-            "context_paths": {
-              "description": "Context Paths",
-              "type": "array",
-              "items": {
-                "type": "string"
-              },
-              "default": [
-                ".github/copilot-instructions.md",
-                ".cursorrules",
-                ".cursor/rules/",
-                "CLAUDE.md",
-                "CLAUDE.local.md",
-                "GEMINI.md",
-                "gemini.md",
-                "crush.md",
-                "crush.local.md",
-                "Crush.md",
-                "Crush.local.md",
-                "CRUSH.md",
-                "CRUSH.local.md"
-              ]
-            },
-            "data_directory": {
-              "description": "Data Directory",
-              "type": "string",
-              "default": ".crush"
-            },
-            "debug": {
-              "description": "Enable debug",
-              "type": "boolean",
-              "default": false
-            },
-            "debug_lsp": {
-              "description": "Enable debug l s p",
-              "type": "boolean",
-              "default": false
-            },
-            "disable_auto_summarize": {
-              "description": "Disable Auto Summarize",
-              "type": "boolean",
-              "default": false
-            },
-            "tui": {
-              "description": "T U I",
-              "type": "object",
-              "properties": {
-                "compact_mode": {
-                  "description": "Enable compact mode",
-                  "type": "boolean",
-                  "default": false
-                }
-              },
-              "required": [
-                "compact_mode"
-              ]
-            }
+        "context_paths": {
+          "items": {
+            "type": "string"
           },
-          "required": [
-            "context_paths",
-            "tui",
-            "debug",
-            "debug_lsp",
-            "disable_auto_summarize",
-            "data_directory"
-          ]
-        },
-        "providers": {
-          "description": "LLM provider configurations",
-          "type": "object",
-          "additionalProperties": {
-            "type": "object",
-            "properties": {
-              "api_key": {
-                "description": "API key for authenticating with the provider",
-                "type": "string"
-              },
-              "base_url": {
-                "description": "Base URL for the provider API (required for custom providers)",
-                "type": "string"
-              },
-              "default_large_model": {
-                "description": "Default Large Model",
-                "type": "string"
-              },
-              "default_small_model": {
-                "description": "Default Small Model",
-                "type": "string"
-              },
-              "disabled": {
-                "description": "Disabled",
-                "type": "boolean",
-                "default": false
-              },
-              "extra_headers": {
-                "description": "Additional HTTP headers to send with requests",
-                "type": "object",
-                "additionalProperties": {
-                  "type": "string"
-                }
-              },
-              "extra_params": {
-                "description": "Additional provider-specific parameters",
-                "type": "object",
-                "additionalProperties": {
-                  "type": "string"
-                }
-              },
-              "id": {
-                "description": "I D",
-                "type": "string",
-                "enum": [
-                  "anthropic",
-                  "openai",
-                  "gemini",
-                  "xai",
-                  "openrouter"
-                ]
-              },
-              "models": {
-                "description": "Models",
-                "type": "array",
-                "items": {
-                  "type": "object",
-                  "properties": {
-                    "can_reason": {
-                      "description": "Enable can reason",
-                      "type": "boolean"
-                    },
-                    "context_window": {
-                      "description": "Context Window",
-                      "type": "integer"
-                    },
-                    "cost_per_1m_in": {
-                      "description": "Cost Per1 M In",
-                      "type": "number"
-                    },
-                    "cost_per_1m_in_cached": {
-                      "description": "Cost Per1 M In Cached",
-                      "type": "number"
-                    },
-                    "cost_per_1m_out": {
-                      "description": "Cost Per1 M Out",
-                      "type": "number"
-                    },
-                    "cost_per_1m_out_cached": {
-                      "description": "Cost Per1 M Out Cached",
-                      "type": "number"
-                    },
-                    "default_max_tokens": {
-                      "description": "Default Max Tokens",
-                      "type": "integer"
-                    },
-                    "has_reasoning_effort": {
-                      "description": "Enable has reasoning effort",
-                      "type": "boolean"
-                    },
-                    "id": {
-                      "description": "I D",
-                      "type": "string"
-                    },
-                    "model": {
-                      "description": "Name",
-                      "type": "string"
-                    },
-                    "reasoning_effort": {
-                      "description": "Reasoning Effort",
-                      "type": "string"
-                    },
-                    "supports_attachments": {
-                      "description": "Enable supports images",
-                      "type": "boolean"
-                    }
-                  },
-                  "required": [
-                    "id",
-                    "model",
-                    "cost_per_1m_in",
-                    "cost_per_1m_out",
-                    "cost_per_1m_in_cached",
-                    "cost_per_1m_out_cached",
-                    "context_window",
-                    "default_max_tokens",
-                    "can_reason",
-                    "reasoning_effort",
-                    "has_reasoning_effort",
-                    "supports_attachments"
-                  ]
-                }
-              },
-              "provider_type": {
-                "description": "Provider Type",
-                "type": "string"
-              }
-            },
-            "required": [
-              "id",
-              "provider_type",
-              "disabled"
-            ]
-          }
+          "type": "array",
+          "title": "Context Paths",
+          "description": "Custom context paths for this agent (additive to global context paths)"
         }
       },
+      "type": "object",
       "required": [
-        "models",
-        "options"
+        "model"
       ]
     },
     "LSPConfig": {
-      "type": "object",
       "properties": {
-        "args": {
-          "description": "Args",
-          "type": "array",
-          "items": {
-            "type": "string"
-          }
-        },
-        "command": {
-          "description": "Command",
-          "type": "string"
-        },
         "enabled": {
-          "description": "Disabled",
           "type": "boolean",
+          "title": "Enabled",
+          "description": "Whether this LSP server is enabled",
           "default": true
         },
+        "command": {
+          "type": "string",
+          "title": "Command",
+          "description": "Command to execute for the LSP server"
+        },
+        "args": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array",
+          "title": "Arguments",
+          "description": "Command line arguments for the LSP server"
+        },
         "options": {
-          "description": "Options"
+          "title": "Options",
+          "description": "LSP server specific options"
         }
       },
+      "type": "object",
       "required": [
-        "enabled",
-        "command",
-        "args",
-        "options"
+        "command"
       ]
     },
     "MCP": {
-      "type": "object",
       "properties": {
-        "args": {
-          "description": "Args",
-          "type": "array",
-          "items": {
-            "type": "string"
-          }
-        },
         "command": {
-          "description": "Command to execute for stdio MCP servers",
-          "type": "string"
+          "type": "string",
+          "title": "Command",
+          "description": "Command to execute for stdio MCP servers"
         },
         "env": {
-          "description": "Env list",
-          "type": "array",
           "items": {
             "type": "string"
-          }
+          },
+          "type": "array",
+          "title": "Environment",
+          "description": "Environment variables for the MCP server"
         },
-        "headers": {
-          "description": "HTTP headers for SSE MCP servers",
-          "type": "object",
-          "additionalProperties": {
+        "args": {
+          "items": {
             "type": "string"
-          }
+          },
+          "type": "array",
+          "title": "Arguments",
+          "description": "Command line arguments for the MCP server"
         },
         "type": {
-          "description": "Type",
           "type": "string",
           "enum": [
+            "stdio",
+            "sse",
             "stdio",
             "sse"
           ],
+          "title": "Type",
+          "description": "Type of MCP connection",
           "default": "stdio"
         },
         "url": {
-          "description": "URL for SSE MCP servers",
-          "type": "string"
+          "type": "string",
+          "title": "URL",
+          "description": "URL for SSE MCP servers"
+        },
+        "headers": {
+          "additionalProperties": {
+            "type": "string"
+          },
+          "type": "object",
+          "title": "Headers",
+          "description": "HTTP headers for SSE MCP servers"
         }
       },
+      "type": "object",
       "required": [
         "command",
-        "env",
-        "args",
-        "type",
-        "url",
-        "headers"
+        "type"
       ]
     },
     "Model": {
-      "type": "object",
       "properties": {
-        "can_reason": {
-          "description": "Enable can reason",
-          "type": "boolean"
+        "id": {
+          "type": "string",
+          "title": "Model ID",
+          "description": "Unique identifier for the model"
         },
-        "context_window": {
-          "description": "Context Window",
-          "type": "integer"
+        "model": {
+          "type": "string",
+          "title": "Model Name",
+          "description": "Display name of the model"
         },
         "cost_per_1m_in": {
-          "description": "Cost Per1 M In",
-          "type": "number"
-        },
-        "cost_per_1m_in_cached": {
-          "description": "Cost Per1 M In Cached",
-          "type": "number"
+          "type": "number",
+          "minimum": 0,
+          "title": "Input Cost",
+          "description": "Cost per 1 million input tokens"
         },
         "cost_per_1m_out": {
-          "description": "Cost Per1 M Out",
-          "type": "number"
+          "type": "number",
+          "minimum": 0,
+          "title": "Output Cost",
+          "description": "Cost per 1 million output tokens"
         },
-        "cost_per_1m_out_cached": {
-          "description": "Cost Per1 M Out Cached",
-          "type": "number"
+        "cost_per_1m_in_cached": {
+          "type": "number",
+          "minimum": 0,
+          "title": "Cached Input Cost",
+          "description": "Cost per 1 million cached input tokens"
         },
-        "default_max_tokens": {
-          "description": "Default Max Tokens",
-          "type": "integer"
+        "cost_per_1m_out_cached": {
+          "type": "number",
+          "minimum": 0,
+          "title": "Cached Output Cost",
+          "description": "Cost per 1 million cached output tokens"
         },
-        "has_reasoning_effort": {
-          "description": "Enable has reasoning effort",
-          "type": "boolean"
+        "context_window": {
+          "type": "integer",
+          "minimum": 1,
+          "title": "Context Window",
+          "description": "Maximum context window size in tokens"
         },
-        "id": {
-          "description": "I D",
-          "type": "string"
+        "default_max_tokens": {
+          "type": "integer",
+          "minimum": 1,
+          "title": "Default Max Tokens",
+          "description": "Default maximum tokens for responses"
         },
-        "model": {
-          "description": "Name",
-          "type": "string"
+        "can_reason": {
+          "type": "boolean",
+          "title": "Can Reason",
+          "description": "Whether the model supports reasoning capabilities"
         },
         "reasoning_effort": {
-          "description": "Reasoning Effort",
-          "type": "string"
+          "type": "string",
+          "title": "Reasoning Effort",
+          "description": "Default reasoning effort level for reasoning models"
+        },
+        "has_reasoning_effort": {
+          "type": "boolean",
+          "title": "Has Reasoning Effort",
+          "description": "Whether the model supports reasoning effort configuration"
         },
         "supports_attachments": {
-          "description": "Enable supports images",
-          "type": "boolean"
+          "type": "boolean",
+          "title": "Supports Images",
+          "description": "Whether the model supports image attachments"
         }
       },
+      "type": "object",
       "required": [
         "id",
         "model",
  
  
  
    
    @@ -14,6 +14,7 @@ import (
 
 	"github.com/charmbracelet/crush/internal/fur/provider"
 	"github.com/charmbracelet/crush/internal/logging"
+	"github.com/invopop/jsonschema"
 )
 
 const (
@@ -55,18 +56,18 @@ const (
 )
 
 type Model struct {
-	ID                 string  `json:"id"`
-	Name               string  `json:"model"`
-	CostPer1MIn        float64 `json:"cost_per_1m_in"`
-	CostPer1MOut       float64 `json:"cost_per_1m_out"`
-	CostPer1MInCached  float64 `json:"cost_per_1m_in_cached"`
-	CostPer1MOutCached float64 `json:"cost_per_1m_out_cached"`
-	ContextWindow      int64   `json:"context_window"`
-	DefaultMaxTokens   int64   `json:"default_max_tokens"`
-	CanReason          bool    `json:"can_reason"`
-	ReasoningEffort    string  `json:"reasoning_effort"`
-	HasReasoningEffort bool    `json:"has_reasoning_effort"`
-	SupportsImages     bool    `json:"supports_attachments"`
+	ID                 string  `json:"id" jsonschema:"title=Model ID,description=Unique identifier for the model"`
+	Name               string  `json:"model" jsonschema:"title=Model Name,description=Display name of the model"`
+	CostPer1MIn        float64 `json:"cost_per_1m_in" jsonschema:"title=Input Cost,description=Cost per 1 million input tokens,minimum=0"`
+	CostPer1MOut       float64 `json:"cost_per_1m_out" jsonschema:"title=Output Cost,description=Cost per 1 million output tokens,minimum=0"`
+	CostPer1MInCached  float64 `json:"cost_per_1m_in_cached" jsonschema:"title=Cached Input Cost,description=Cost per 1 million cached input tokens,minimum=0"`
+	CostPer1MOutCached float64 `json:"cost_per_1m_out_cached" jsonschema:"title=Cached Output Cost,description=Cost per 1 million cached output tokens,minimum=0"`
+	ContextWindow      int64   `json:"context_window" jsonschema:"title=Context Window,description=Maximum context window size in tokens,minimum=1"`
+	DefaultMaxTokens   int64   `json:"default_max_tokens" jsonschema:"title=Default Max Tokens,description=Default maximum tokens for responses,minimum=1"`
+	CanReason          bool    `json:"can_reason" jsonschema:"title=Can Reason,description=Whether the model supports reasoning capabilities"`
+	ReasoningEffort    string  `json:"reasoning_effort" jsonschema:"title=Reasoning Effort,description=Default reasoning effort level for reasoning models"`
+	HasReasoningEffort bool    `json:"has_reasoning_effort" jsonschema:"title=Has Reasoning Effort,description=Whether the model supports reasoning effort configuration"`
+	SupportsImages     bool    `json:"supports_attachments" jsonschema:"title=Supports Images,description=Whether the model supports image attachments"`
 }
 
 type VertexAIOptions struct {
@@ -76,46 +77,46 @@ type VertexAIOptions struct {
 }
 
 type ProviderConfig struct {
-	ID           provider.InferenceProvider `json:"id"`
-	BaseURL      string                     `json:"base_url,omitempty"`
-	ProviderType provider.Type              `json:"provider_type"`
-	APIKey       string                     `json:"api_key,omitempty"`
-	Disabled     bool                       `json:"disabled"`
-	ExtraHeaders map[string]string          `json:"extra_headers,omitempty"`
+	ID           provider.InferenceProvider `json:"id,omitempty" jsonschema:"title=Provider ID,description=Unique identifier for the provider"`
+	BaseURL      string                     `json:"base_url,omitempty" jsonschema:"title=Base URL,description=Base URL for the provider API (required for custom providers)"`
+	ProviderType provider.Type              `json:"provider_type" jsonschema:"title=Provider Type,description=Type of the provider (openai, anthropic, etc.)"`
+	APIKey       string                     `json:"api_key,omitempty" jsonschema:"title=API Key,description=API key for authenticating with the provider"`
+	Disabled     bool                       `json:"disabled,omitempty" jsonschema:"title=Disabled,description=Whether this provider is disabled,default=false"`
+	ExtraHeaders map[string]string          `json:"extra_headers,omitempty" jsonschema:"title=Extra Headers,description=Additional HTTP headers to send with requests"`
 	// used for e.x for vertex to set the project
-	ExtraParams map[string]string `json:"extra_params,omitempty"`
+	ExtraParams map[string]string `json:"extra_params,omitempty" jsonschema:"title=Extra Parameters,description=Additional provider-specific parameters"`
 
-	DefaultLargeModel string `json:"default_large_model,omitempty"`
-	DefaultSmallModel string `json:"default_small_model,omitempty"`
+	DefaultLargeModel string `json:"default_large_model,omitempty" jsonschema:"title=Default Large Model,description=Default model ID for large model type"`
+	DefaultSmallModel string `json:"default_small_model,omitempty" jsonschema:"title=Default Small Model,description=Default model ID for small model type"`
 
-	Models []Model `json:"models,omitempty"`
+	Models []Model `json:"models,omitempty" jsonschema:"title=Models,description=List of available models for this provider"`
 }
 
 type Agent struct {
-	ID          AgentID `json:"id"`
-	Name        string  `json:"name"`
-	Description string  `json:"description,omitempty"`
+	ID          AgentID `json:"id,omitempty" jsonschema:"title=Agent ID,description=Unique identifier for the agent,enum=coder,enum=task"`
+	Name        string  `json:"name,omitempty" jsonschema:"title=Name,description=Display name of the agent"`
+	Description string  `json:"description,omitempty" jsonschema:"title=Description,description=Description of what the agent does"`
 	// This is the id of the system prompt used by the agent
-	Disabled bool `json:"disabled"`
+	Disabled bool `json:"disabled,omitempty" jsonschema:"title=Disabled,description=Whether this agent is disabled,default=false"`
 
-	Model ModelType `json:"model"`
+	Model ModelType `json:"model" jsonschema:"title=Model Type,description=Type of model to use (large or small),enum=large,enum=small"`
 
 	// The available tools for the agent
 	//  if this is nil, all tools are available
-	AllowedTools []string `json:"allowed_tools"`
+	AllowedTools []string `json:"allowed_tools,omitempty" jsonschema:"title=Allowed Tools,description=List of tools this agent is allowed to use (if nil all tools are allowed)"`
 
 	// this tells us which MCPs are available for this agent
 	//  if this is empty all mcps are available
 	//  the string array is the list of tools from the AllowedMCP the agent has available
 	//  if the string array is nil, all tools from the AllowedMCP are available
-	AllowedMCP map[string][]string `json:"allowed_mcp"`
+	AllowedMCP map[string][]string `json:"allowed_mcp,omitempty" jsonschema:"title=Allowed MCP,description=Map of MCP servers this agent can use and their allowed tools"`
 
 	// The list of LSPs that this agent can use
 	//  if this is nil, all LSPs are available
-	AllowedLSP []string `json:"allowed_lsp"`
+	AllowedLSP []string `json:"allowed_lsp,omitempty" jsonschema:"title=Allowed LSP,description=List of LSP servers this agent can use (if nil all LSPs are allowed)"`
 
 	// Overrides the context paths for this agent
-	ContextPaths []string `json:"context_paths"`
+	ContextPaths []string `json:"context_paths,omitempty" jsonschema:"title=Context Paths,description=Custom context paths for this agent (additive to global context paths)"`
 }
 
 type MCPType string
@@ -126,69 +127,70 @@ const (
 )
 
 type MCP struct {
-	Command string            `json:"command"`
-	Env     []string          `json:"env"`
-	Args    []string          `json:"args"`
-	Type    MCPType           `json:"type"`
-	URL     string            `json:"url"`
-	Headers map[string]string `json:"headers"`
+	Command string   `json:"command" jsonschema:"title=Command,description=Command to execute for stdio MCP servers"`
+	Env     []string `json:"env,omitempty" jsonschema:"title=Environment,description=Environment variables for the MCP server"`
+	Args    []string `json:"args,omitempty" jsonschema:"title=Arguments,description=Command line arguments for the MCP server"`
+	Type    MCPType  `json:"type" jsonschema:"title=Type,description=Type of MCP connection,enum=stdio,enum=sse,default=stdio"`
+	URL     string   `json:"url,omitempty" jsonschema:"title=URL,description=URL for SSE MCP servers"`
+	// TODO: maybe make it possible to get the value from the env
+	Headers map[string]string `json:"headers,omitempty" jsonschema:"title=Headers,description=HTTP headers for SSE MCP servers"`
 }
 
 type LSPConfig struct {
-	Disabled bool     `json:"enabled"`
-	Command  string   `json:"command"`
-	Args     []string `json:"args"`
-	Options  any      `json:"options"`
+	Disabled bool     `json:"enabled,omitempty" jsonschema:"title=Enabled,description=Whether this LSP server is enabled,default=true"`
+	Command  string   `json:"command" jsonschema:"title=Command,description=Command to execute for the LSP server"`
+	Args     []string `json:"args,omitempty" jsonschema:"title=Arguments,description=Command line arguments for the LSP server"`
+	Options  any      `json:"options,omitempty" jsonschema:"title=Options,description=LSP server specific options"`
 }
 
 type TUIOptions struct {
-	CompactMode bool `json:"compact_mode"`
+	CompactMode bool `json:"compact_mode" jsonschema:"title=Compact Mode,description=Enable compact mode for the TUI,default=false"`
 	// Here we can add themes later or any TUI related options
 }
 
 type Options struct {
-	ContextPaths         []string   `json:"context_paths"`
-	TUI                  TUIOptions `json:"tui"`
-	Debug                bool       `json:"debug"`
-	DebugLSP             bool       `json:"debug_lsp"`
-	DisableAutoSummarize bool       `json:"disable_auto_summarize"`
+	ContextPaths         []string   `json:"context_paths,omitempty" jsonschema:"title=Context Paths,description=List of paths to search for context files"`
+	TUI                  TUIOptions `json:"tui,omitempty" jsonschema:"title=TUI Options,description=Terminal UI configuration options"`
+	Debug                bool       `json:"debug,omitempty" jsonschema:"title=Debug,description=Enable debug logging,default=false"`
+	DebugLSP             bool       `json:"debug_lsp,omitempty" jsonschema:"title=Debug LSP,description=Enable LSP debug logging,default=false"`
+	DisableAutoSummarize bool       `json:"disable_auto_summarize,omitempty" jsonschema:"title=Disable Auto Summarize,description=Disable automatic conversation summarization,default=false"`
 	// Relative to the cwd
-	DataDirectory string `json:"data_directory"`
+	DataDirectory string `json:"data_directory,omitempty" jsonschema:"title=Data Directory,description=Directory for storing application data,default=.crush"`
 }
 
 type PreferredModel struct {
-	ModelID  string                     `json:"model_id"`
-	Provider provider.InferenceProvider `json:"provider"`
+	ModelID  string                     `json:"model_id" jsonschema:"title=Model ID,description=ID of the preferred model"`
+	Provider provider.InferenceProvider `json:"provider" jsonschema:"title=Provider,description=Provider for the preferred model"`
 	// ReasoningEffort overrides the default reasoning effort for this model
-	ReasoningEffort string `json:"reasoning_effort,omitempty"`
+	ReasoningEffort string `json:"reasoning_effort,omitempty" jsonschema:"title=Reasoning Effort,description=Override reasoning effort for this model"`
 	// MaxTokens overrides the default max tokens for this model
-	MaxTokens int64 `json:"max_tokens,omitempty"`
+	MaxTokens int64 `json:"max_tokens,omitempty" jsonschema:"title=Max Tokens,description=Override max tokens for this model,minimum=1"`
 
 	// Think indicates if the model should think, only applicable for anthropic reasoning models
-	Think bool `json:"think,omitempty"`
+	Think bool `json:"think,omitempty" jsonschema:"title=Think,description=Enable thinking for reasoning models,default=false"`
 }
 
 type PreferredModels struct {
-	Large PreferredModel `json:"large"`
-	Small PreferredModel `json:"small"`
+	Large PreferredModel `json:"large,omitempty" jsonschema:"title=Large Model,description=Preferred model configuration for large model type"`
+	Small PreferredModel `json:"small,omitempty" jsonschema:"title=Small Model,description=Preferred model configuration for small model type"`
 }
 
 type Config struct {
-	Models PreferredModels `json:"models"`
+	Models PreferredModels `json:"models,omitempty" jsonschema:"title=Models,description=Preferred model configurations for large and small model types"`
 	// List of configured providers
-	Providers map[provider.InferenceProvider]ProviderConfig `json:"providers,omitempty"`
+	Providers map[provider.InferenceProvider]ProviderConfig `json:"providers,omitempty" jsonschema:"title=Providers,description=LLM provider configurations"`
 
 	// List of configured agents
-	Agents map[AgentID]Agent `json:"agents,omitempty"`
+	Agents map[AgentID]Agent `json:"agents,omitempty" jsonschema:"title=Agents,description=Agent configurations for different tasks"`
 
 	// List of configured MCPs
-	MCP map[string]MCP `json:"mcp,omitempty"`
+	MCP map[string]MCP `json:"mcp,omitempty" jsonschema:"title=MCP,description=Model Control Protocol server configurations"`
 
 	// List of configured LSPs
-	LSP map[string]LSPConfig `json:"lsp,omitempty"`
+	LSP map[string]LSPConfig `json:"lsp,omitempty" jsonschema:"title=LSP,description=Language Server Protocol configurations"`
 
 	// Miscellaneous options
-	Options Options `json:"options"`
+	Options Options `json:"options,omitempty" jsonschema:"title=Options,description=General application options and settings"`
 }
 
 var (
@@ -502,27 +504,23 @@ func mergeAgents(base, global, local *Config) {
 		}
 		for agentID, newAgent := range cfg.Agents {
 			if _, ok := base.Agents[agentID]; !ok {
-				// New agent - apply defaults
-				newAgent.ID = agentID // Ensure the ID is set correctly
+				newAgent.ID = agentID
 				if newAgent.Model == "" {
-					newAgent.Model = LargeModel // Default model type
+					newAgent.Model = LargeModel
 				}
-				// Context paths are always additive - start with global, then add custom
 				if len(newAgent.ContextPaths) > 0 {
 					newAgent.ContextPaths = append(base.Options.ContextPaths, newAgent.ContextPaths...)
 				} else {
-					newAgent.ContextPaths = base.Options.ContextPaths // Use global context paths only
+					newAgent.ContextPaths = base.Options.ContextPaths
 				}
 				base.Agents[agentID] = newAgent
 			} else {
 				baseAgent := base.Agents[agentID]
 
-				// Special handling for known agents - only allow model changes
 				if agentID == AgentCoder || agentID == AgentTask {
 					if newAgent.Model != "" {
 						baseAgent.Model = newAgent.Model
 					}
-					// For known agents, only allow MCP and LSP configuration
 					if newAgent.AllowedMCP != nil {
 						baseAgent.AllowedMCP = newAgent.AllowedMCP
 					}
@@ -534,7 +532,6 @@ func mergeAgents(base, global, local *Config) {
 						baseAgent.ContextPaths = append(baseAgent.ContextPaths, newAgent.ContextPaths...)
 					}
 				} else {
-					// Custom agents - allow full merging
 					if newAgent.Name != "" {
 						baseAgent.Name = newAgent.Name
 					}
@@ -544,13 +541,11 @@ func mergeAgents(base, global, local *Config) {
 					if newAgent.Model != "" {
 						baseAgent.Model = newAgent.Model
 					} else if baseAgent.Model == "" {
-						baseAgent.Model = LargeModel // Default fallback
+						baseAgent.Model = LargeModel
 					}
 
-					// Boolean fields - always update (including false values)
 					baseAgent.Disabled = newAgent.Disabled
 
-					// Slice/Map fields - update if provided (including empty slices/maps)
 					if newAgent.AllowedTools != nil {
 						baseAgent.AllowedTools = newAgent.AllowedTools
 					}
@@ -560,7 +555,6 @@ func mergeAgents(base, global, local *Config) {
 					if newAgent.AllowedLSP != nil {
 						baseAgent.AllowedLSP = newAgent.AllowedLSP
 					}
-					// Context paths are additive for custom agents too
 					if len(newAgent.ContextPaths) > 0 {
 						baseAgent.ContextPaths = append(baseAgent.ContextPaths, newAgent.ContextPaths...)
 					}
@@ -596,6 +590,7 @@ func mergeProviderConfigs(base, global, local *Config) {
 			continue
 		}
 		for providerName, p := range cfg.Providers {
+			p.ID = providerName
 			if _, ok := base.Providers[providerName]; !ok {
 				base.Providers[providerName] = p
 			} else {
@@ -616,36 +611,36 @@ func mergeProviderConfigs(base, global, local *Config) {
 	base.Providers = finalProviders
 }
 
-func providerDefaultConfig(providerId provider.InferenceProvider) ProviderConfig {
-	switch providerId {
+func providerDefaultConfig(providerID provider.InferenceProvider) ProviderConfig {
+	switch providerID {
 	case provider.InferenceProviderAnthropic:
 		return ProviderConfig{
-			ID:           providerId,
+			ID:           providerID,
 			ProviderType: provider.TypeAnthropic,
 		}
 	case provider.InferenceProviderOpenAI:
 		return ProviderConfig{
-			ID:           providerId,
+			ID:           providerID,
 			ProviderType: provider.TypeOpenAI,
 		}
 	case provider.InferenceProviderGemini:
 		return ProviderConfig{
-			ID:           providerId,
+			ID:           providerID,
 			ProviderType: provider.TypeGemini,
 		}
 	case provider.InferenceProviderBedrock:
 		return ProviderConfig{
-			ID:           providerId,
+			ID:           providerID,
 			ProviderType: provider.TypeBedrock,
 		}
 	case provider.InferenceProviderAzure:
 		return ProviderConfig{
-			ID:           providerId,
+			ID:           providerID,
 			ProviderType: provider.TypeAzure,
 		}
 	case provider.InferenceProviderOpenRouter:
 		return ProviderConfig{
-			ID:           providerId,
+			ID:           providerID,
 			ProviderType: provider.TypeOpenAI,
 			BaseURL:      "https://openrouter.ai/api/v1",
 			ExtraHeaders: map[string]string{
@@ -655,18 +650,18 @@ func providerDefaultConfig(providerId provider.InferenceProvider) ProviderConfig
 		}
 	case provider.InferenceProviderXAI:
 		return ProviderConfig{
-			ID:           providerId,
+			ID:           providerID,
 			ProviderType: provider.TypeXAI,
 			BaseURL:      "https://api.x.ai/v1",
 		}
 	case provider.InferenceProviderVertexAI:
 		return ProviderConfig{
-			ID:           providerId,
+			ID:           providerID,
 			ProviderType: provider.TypeVertexAI,
 		}
 	default:
 		return ProviderConfig{
-			ID:           providerId,
+			ID:           providerID,
 			ProviderType: provider.TypeOpenAI,
 		}
 	}
@@ -1433,3 +1428,27 @@ func (c *Config) validateCompleteness(errors *ValidationErrors) {
 		}
 	}
 }
+
+// JSONSchemaExtend adds custom schema properties for AgentID
+func (AgentID) JSONSchemaExtend(schema *jsonschema.Schema) {
+	schema.Enum = []any{
+		string(AgentCoder),
+		string(AgentTask),
+	}
+}
+
+// JSONSchemaExtend adds custom schema properties for ModelType
+func (ModelType) JSONSchemaExtend(schema *jsonschema.Schema) {
+	schema.Enum = []any{
+		string(LargeModel),
+		string(SmallModel),
+	}
+}
+
+// JSONSchemaExtend adds custom schema properties for MCPType
+func (MCPType) JSONSchemaExtend(schema *jsonschema.Schema) {
+	schema.Enum = []any{
+		string(MCPStdio),
+		string(MCPSse),
+	}
+}