UNPKG

@agentman/chat-widget

Version:

Agentman Chat Widget for easy integration with web applications

657 lines (556 loc) 13.9 kB
# MCP Response Structure Specification ## Core Response Schema Every MCP response follows this structure to enable intelligent routing and rich UI rendering: ```typescript interface MCPResponse { // Required: Identifies the UI component type uiType: string; // Required: Minimal data for LLM understanding (token-efficient) structuredContent: { [key: string]: any; // Keep this as small as possible // Only include what the LLM needs to understand context }; // Optional: Text/markdown for model narration content?: Array<{ type: 'text' | 'markdown'; text: string; }>; // Required: Rich data for UI rendering (never sent to LLM) _meta: { [key: string]: any; // Full data for UI components // Can be as large as needed }; // Optional: UI-specific metadata uiMetadata?: { component: string; // Specific component name version: string; // Component version provider: string; // Data provider (shopify, calendar, etc.) priority?: 'high' | 'medium' | 'low'; renderMode?: 'immediate' | 'lazy' | 'progressive'; }; } ``` ## Response Types by Category ### 1. Product Display Responses #### Shopify Products Grid ```typescript interface ShopifyProductsResponse extends MCPResponse { uiType: 'shopify-products'; structuredContent: { // Minimal for LLM (5-10 products max) totalCount: number; priceRange: { min: number; max: number; currency: string; }; topProducts: Array<{ id: string; title: string; price: number; }>; categories: string[]; }; _meta: { // Full product data for UI products: Array<{ id: string; title: string; description: string; price: number; compareAtPrice?: number; images: Array<{ url: string; alt: string; }>; variants: Array<{ id: string; title: string; price: number; available: boolean; sku: string; }>; vendor: string; tags: string[]; rating?: number; reviewCount?: number; }>; // Filtering and sorting options filters: { categories: string[]; priceRanges: Array<{ min: number; max: number; label: string }>; vendors: string[]; tags: string[]; }; sortOptions: Array<{ value: string; label: string; default?: boolean; }>; // Pagination pagination: { page: number; pageSize: number; totalPages: number; totalItems: number; }; }; } ``` #### Single Product Detail ```typescript interface ProductDetailResponse extends MCPResponse { uiType: 'product-detail'; structuredContent: { id: string; title: string; price: number; available: boolean; category: string; }; _meta: { product: DetailedProduct; relatedProducts: Product[]; reviews: Review[]; shipping: ShippingInfo; returnPolicy: string; }; } ``` ### 2. Form Responses #### Lead Capture Form ```typescript interface LeadFormResponse extends MCPResponse { uiType: 'form-lead'; structuredContent: { formType: 'lead_capture'; purpose: string; requiredFields: string[]; estimatedTime: string; // "2 minutes" }; _meta: { formSchema: { id: string; title: string; description?: string; fields: Array<{ id: string; type: 'text' | 'email' | 'tel' | 'select' | 'textarea' | 'checkbox' | 'radio'; label: string; placeholder?: string; required: boolean; validation?: { pattern?: string; minLength?: number; maxLength?: number; min?: number; max?: number; customValidator?: string; errorMessage?: string; }; options?: Array<{ value: string; label: string; disabled?: boolean; }>; conditions?: Array<{ field: string; operator: 'equals' | 'not_equals' | 'contains' | 'greater_than' | 'less_than'; value: any; }>; }>; submitButton: { text: string; loadingText?: string; successText?: string; }; layout?: { type: 'single-column' | 'two-column' | 'grid'; columns?: number; }; }; submitConfig: { endpoint: string; method: 'POST' | 'PUT'; headers?: Record<string, string>; successMessage: string; errorMessage?: string; redirectUrl?: string; confirmationEmail?: boolean; }; prefillData?: Record<string, any>; analytics?: { formId: string; campaignId?: string; source?: string; }; }; } ``` #### Payment Form ```typescript interface PaymentFormResponse extends MCPResponse { uiType: 'form-payment'; structuredContent: { formType: 'payment'; amount: number; currency: string; purpose: string; secureFields: string[]; // Fields that need tokenization }; _meta: { formSchema: FormSchema; // Similar to lead form paymentConfig: { amount: number; currency: string; paymentMethods: Array<'card' | 'paypal' | 'apple_pay' | 'google_pay'>; stripePublicKey?: string; paypalClientId?: string; useTokenization: boolean; requiresBillingAddress: boolean; requiresShippingAddress: boolean; }; securityConfig: { tokenizationEndpoint: string; encryptionKey?: string; pciCompliant: boolean; }; }; } ``` #### Quick Choice Buttons ```typescript interface ChoiceFormResponse extends MCPResponse { uiType: 'form-choices'; structuredContent: { question: string; optionCount: number; multiSelect: boolean; }; _meta: { question: string; description?: string; choices: Array<{ id: string; label: string; description?: string; icon?: string; color?: string; value: any; disabled?: boolean; metadata?: Record<string, any>; }>; layout: { type: 'buttons' | 'cards' | 'list' | 'grid'; columns?: number; showIcons?: boolean; showDescriptions?: boolean; }; behavior: { multiSelect: boolean; minSelections?: number; maxSelections?: number; autoSubmit: boolean; confirmationRequired: boolean; }; }; } ``` ### 3. Data Visualization Responses #### Chart/Graph Display ```typescript interface ChartResponse extends MCPResponse { uiType: 'chart'; structuredContent: { chartType: 'line' | 'bar' | 'pie' | 'scatter'; dataPoints: number; summary: string; // "Sales increased 25% this month" }; _meta: { chartConfig: { type: string; title: string; subtitle?: string; data: { labels: string[]; datasets: Array<{ label: string; data: number[]; backgroundColor?: string | string[]; borderColor?: string; // ... other chart.js options }>; }; options: { responsive: boolean; maintainAspectRatio: boolean; legend?: object; scales?: object; // ... other chart.js options }; }; interactivity?: { clickable: boolean; hoverable: boolean; zoomable: boolean; downloadable: boolean; }; }; } ``` #### Table Display ```typescript interface TableResponse extends MCPResponse { uiType: 'table'; structuredContent: { rowCount: number; columnCount: number; summary: string; }; _meta: { columns: Array<{ id: string; label: string; type: 'string' | 'number' | 'date' | 'boolean' | 'currency'; sortable?: boolean; filterable?: boolean; width?: string; }>; rows: Array<Record<string, any>>; features?: { pagination?: boolean; pageSize?: number; sorting?: boolean; filtering?: boolean; exporting?: boolean; selecting?: boolean; }; }; } ``` ### 4. Interactive Components #### Calendar/Scheduling ```typescript interface CalendarResponse extends MCPResponse { uiType: 'calendar'; structuredContent: { availableSlots: number; dateRange: { start: string; end: string; }; timezone: string; }; _meta: { calendar: { availableSlots: Array<{ date: string; times: Array<{ start: string; end: string; available: boolean; }>; }>; duration: number; // minutes timezone: string; booking: { requiresApproval: boolean; confirmationEmail: boolean; reminderEmail: boolean; cancellationPolicy?: string; }; }; }; } ``` #### File Upload ```typescript interface FileUploadResponse extends MCPResponse { uiType: 'file-upload'; structuredContent: { purpose: string; maxFiles: number; maxSizeMB: number; }; _meta: { uploadConfig: { endpoint: string; method: 'POST' | 'PUT'; headers?: Record<string, string>; restrictions: { maxFiles: number; maxSizePerFile: number; // bytes maxTotalSize: number; // bytes allowedTypes: string[]; // MIME types or extensions }; features: { dragAndDrop: boolean; preview: boolean; progress: boolean; chunking?: boolean; resumable?: boolean; }; }; }; } ``` ### 5. Status/Confirmation Responses #### Success Confirmation ```typescript interface SuccessResponse extends MCPResponse { uiType: 'success'; structuredContent: { action: string; status: 'success'; message: string; }; _meta: { title: string; message: string; icon?: string; details?: { confirmationNumber?: string; timestamp?: string; nextSteps?: string[]; }; actions?: Array<{ label: string; action: string; primary?: boolean; }>; }; } ``` #### Error Response ```typescript interface ErrorResponse extends MCPResponse { uiType: 'error'; structuredContent: { error: string; code?: string; recoverable: boolean; }; _meta: { title: string; message: string; details?: string; recovery?: { suggestions: string[]; retryable: boolean; contactSupport?: boolean; }; }; } ``` ## Response Metadata Standards ### UI Type Naming Convention - Use kebab-case: `form-lead`, `shopify-products` - Prefix with provider when specific: `shopify-cart`, `stripe-payment` - Use generic names for common types: `table`, `chart`, `form` ### Version Management ```typescript interface VersionedResponse extends MCPResponse { uiMetadata: { component: 'ProductGrid'; version: '2.0.0'; // Semantic versioning minClientVersion?: '1.5.0'; // Minimum client version required deprecated?: boolean; migrationGuide?: string; // URL to migration docs }; } ``` ### Priority Hints ```typescript interface PriorityResponse extends MCPResponse { uiMetadata: { priority: 'high' | 'medium' | 'low'; renderMode: 'immediate' | 'lazy' | 'progressive'; preload?: boolean; // Hint to preload resources cacheStrategy?: 'none' | 'session' | 'persistent'; }; } ``` ## Best Practices ### 1. Token Optimization **DO:** - Keep `structuredContent` under 100 tokens when possible - Use summaries and aggregations - Include only fields the LLM needs for reasoning **DON'T:** - Send full product descriptions to LLM - Include base64 images in structuredContent - Duplicate data between structuredContent and _meta ### 2. Type Safety Always define TypeScript interfaces for your responses: ```typescript // Define specific response types type MyAppResponse = | ShopifyProductsResponse | LeadFormResponse | PaymentFormResponse | ChartResponse; // Type guard functions function isShopifyResponse(response: MCPResponse): response is ShopifyProductsResponse { return response.uiType === 'shopify-products'; } ``` ### 3. Backwards Compatibility When updating response structures: ```typescript interface BackwardsCompatibleResponse extends MCPResponse { uiType: 'product-grid'; // New structure _meta: { version: 2, products: NewProductFormat[]; }; // Legacy support _legacy?: { version: 1, items: OldProductFormat[]; }; } ``` ### 4. Error Handling Always include error information in responses: ```typescript interface ResponseWithError extends MCPResponse { error?: { code: string; message: string; details?: any; recoverable: boolean; }; } ``` ## Testing Response Structures ### Mock Response Generator ```typescript class MockResponseGenerator { static generateProductResponse(count: number = 10): ShopifyProductsResponse { return { uiType: 'shopify-products', structuredContent: { totalCount: count, priceRange: { min: 10, max: 100, currency: 'USD' }, topProducts: this.generateProducts(Math.min(5, count)), categories: ['Electronics', 'Clothing'] }, _meta: { products: this.generateProducts(count), filters: this.generateFilters(), sortOptions: this.generateSortOptions(), pagination: { page: 1, pageSize: 10, totalPages: Math.ceil(count/10), totalItems: count } } }; } // ... other mock generators } ``` ## Next Steps 1. See `CHAT_WIDGET_IMPLEMENTATION.md` for handling these responses 2. Check `COMPONENT_REGISTRY.md` for rendering components 3. Review `ROUTING_LOGIC.md` for routing decisions 4. Read `UNIVERSAL_FORM_SYSTEM.md` for form handling