@brander/mcp-tools 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8395,10 +8395,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8395
8395
  "submitText": "Submit Button Text",
8396
8396
  "submitAction": "${Object.values(pK).join("|")}",
8397
8397
  "resetButton": false
8398
- }`,defaultProps:{submitAction:pK.SUBMIT},toolSchema:{input_schema:ea(lMe)}},cMe=jt({title:Ve().describe("Main page title"),subtitle:Ve().optional().describe("Page description or subtitle")}),M4t={id:Se.HEADER,componentName:Pi.HEADER,toolSchema:{input_schema:ea(cMe)}},uMe=jt({src:Ve().describe("Image source URL"),alt:Ve().describe("Alt text for accessibility"),title:Ve().optional().describe("Image title"),caption:Ve().optional().describe("Image caption"),width:wo().optional().describe("Image width"),height:wo().optional().describe("Image height")}),C4t={id:Se.IMAGE,componentName:Pi.IMAGE,toolSchema:{input_schema:ea(uMe)}},dMe=jt({id:Ve().describe("Item ID"),title:Ve().describe("Item name"),subtitle:Ve().optional().describe("Brief description"),image:Ve().optional().describe("Image URL"),price:Ve().optional().describe("Item price with currency symbol (e.g., '99.99$')"),category:Ve().optional().describe("Item category"),stock:wo().optional().describe("Number of items in stock"),rating:wo().optional().describe("Item rating (0-5)"),description:Ve().optional().describe("Detailed description (optional)")}),I4t={id:Se.ITEM_CARD,componentName:Pi.ITEM_CARD,toolSchema:{input_schema:ea(dMe)}},pMe=jt({title:Ve().optional().describe("Grid title"),items:Ai(jt({id:Ve().describe("Item ID"),title:Ve().describe("Item name"),description:Ve().optional().describe("Item description"),price:Ve().describe("Item price"),image:Ve().optional().describe("REAL image URL that represents the item (NO placeholder URLs) for example: https://images.unsplash.com/photo-XXXXX)"),category:Ve().optional().describe("Item category"),rating:wo().optional().describe("Rating score"),stock:wo().optional().describe("Stock quantity")})).describe("Grid items"),pageSize:wo().optional().describe("Number of items per page")}),_4t={id:Se.ITEM_GRID,componentName:Pi.ITEM_GRID,toolSchema:{input_schema:ea(pMe)}},fMe=jt({title:Ve().describe("Chart title"),labels:Ai(Ve()).describe("X-axis labels (should be relevant to the context for example: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'])"),data:Ai(wo()).describe("Chart data")}),$4t={id:Se.LINE_CHART,componentName:Pi.LINE_CHART,toolSchema:{input_schema:ea(fMe)}},hMe=jt({title:Ve().describe("Chart title"),data:Ai(jt({label:Ve().describe("Segment label"),value:wo().describe("Segment value"),color:Ve().optional().describe("Segment color")})).describe("Pie chart segments")}),A4t={id:Se.PIE_CHART,componentName:Pi.PIE_CHART,toolSchema:{input_schema:ea(hMe)}},yMe=jt({stats:Ai(jt({id:Ve().describe("Unique stat identifier"),title:Ve().describe("Stat title"),value:Ve().describe("Main value"),period:Ve().optional().describe("Period (This Month, This Year, etc.)"),trend:jt({direction:ha(["up","down","neutral"]),percentage:Ve().describe("Trend percentage")}).optional().describe("Trend direction"),subtitle:Ve().optional().describe("Additional context")})).describe("Array of statistics (generate 4 if not requested differently)")}),P4t={id:Se.STATS_GRID,componentName:Pi.STATS_GRID,toolSchema:{input_schema:ea(yMe)}};Se.HEADER+"",Se.STATS_GRID+"",Se.DATA_TABLE+"",Se.LINE_CHART+"",Se.ITEM_GRID+"",Se.ITEM_CARD+"",Se.DETAILS_DATA+"",Se.IMAGE+"",Se.PIE_CHART+"",Se.CHAT_BUBBLE+"",Se.FORM+"",Se.BUTTON+"",Se.BAR_CHART+"",Se.ALERT+"";Se.HEADER,Se.STATS_GRID,Se.DATA_TABLE,Se.LINE_CHART,Se.PIE_CHART,Se.BAR_CHART,Se.DETAILS_DATA,Se.ITEM_GRID,Se.ITEM_CARD,Se.IMAGE,Se.FORM,Se.BUTTON,Se.CHAT_BUBBLE,Se.ALERT;const L4t=Kxt("elementType",[jt({elementType:Ri("header"),props:cMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("chat-bubble"),props:aMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("stats-grid"),props:yMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("data-table"),props:oMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("line-chart"),props:fMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("pie-chart"),props:hMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("bar-chart"),props:rMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("item-grid"),props:pMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("item-card"),props:dMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("image"),props:uMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("details-data"),props:sMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("form"),props:lMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("button"),props:iMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("alert"),props:nMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")})]);jt({elements:Ai(L4t).describe("Ordered array of elements to render. Each element has an elementType and props.")});function N2(e,t){e.sendMessage({role:"user",content:[{type:"text",text:t}]})}function L0e(e,t){return e.replace(/\[(\w+)]/g,(n,r)=>{const i=t[r];return i!=null?String(i):`[${r}]`})}function T4t(e){return Object.entries(e).filter(([,n])=>n!=null&&n!=="").map(([n,r])=>`${n}: ${String(r)}`).join(", ")}function O4t(e,t,n,r){return i=>{if(e){if(i.isFormSubmission&&i.formData){const a=T4t(i.formData),o=i.title||"Form Submission";N2(e,`${o}: ${a}`);return}if(i.buttonType==="action"&&i.action){N2(e,String(i.action));return}if(t){const a=L0e(t,i);N2(e,a);return}if(i._directQuery){N2(e,String(i._directQuery));return}if(n){const a=L0e(n,i);N2(e,a)}}}}const E4t={success:!0,error:!0,warning:!0,info:!0},Di=(e,t,n)=>K.createElement(e[t],n);function j4t(e){const t=e?jgt:zgt;return{[Se.HEADER]:({props:n})=>Di(t,Se.HEADER,{title:n.title,subtitle:n.subtitle}),[Se.CHAT_BUBBLE]:({props:n})=>Di(t,Se.CHAT_BUBBLE,{text:n.text||"",markdown:n.markdown}),[Se.STATS_GRID]:({props:n,onClick:r})=>{const a=(n.stats||[]).map(o=>({...o,onClick:()=>r(o)}));return Di(t,Se.STATS_GRID,{stats:a})},[Se.DATA_TABLE]:({props:n,onClick:r,isStreaming:i})=>{const a=n.rows||[],o=n.columns||[],s=i?a.filter(c=>Object.values(c).some(d=>d!=null&&d!=="")):a,l=c=>{const d=o.filter(p=>p.key!=="id").slice(0,2);if(d.length>0){const p=d.map(h=>`${h.label}: ${c[h.key]??""}`).join(", ");r({...c,_directQuery:`Show details for ${p}`})}else r(c)};return Di(t,Se.DATA_TABLE,{loading:i&&s.length===0,title:n.title,columns:o,rows:s,pageSize:n.pageSize,onRowClick:l,hideDownload:!0})},[Se.LINE_CHART]:({props:n,onClick:r})=>{const i=a=>r({...a,chartTitle:n.title});return Di(t,Se.LINE_CHART,{title:n.title,labels:n.labels||[],data:n.data||[],onChartClick:i})},[Se.PIE_CHART]:({props:n,onClick:r})=>{const i=a=>r({...a,chartTitle:n.title});return Di(t,Se.PIE_CHART,{title:n.title,data:n.data||[],onPointClick:i})},[Se.BAR_CHART]:({props:n,onClick:r,isStreaming:i})=>{const a=n.categories||[],o=n.series||[];return Di(t,Se.BAR_CHART,{loading:i&&(a.length===0||o.length===0),id:n.id,title:n.title,categories:a,series:o,stacked:n.stacked,showLegend:n.showLegend,onBarClick:r})},[Se.ITEM_GRID]:({props:n,onClick:r,isStreaming:i})=>{const a=Array.isArray(n.items)?n.items:[];return Di(t,Se.ITEM_GRID,{loading:i&&a.length===0,title:n.title,items:a,pageSize:n.pageSize,onItemClick:r})},[Se.ITEM_CARD]:({props:n,onClick:r})=>Di(t,Se.ITEM_CARD,{title:n.title,subtitle:n.subtitle,image:n.image,price:n.price,category:n.category,rating:n.rating,stock:n.stock,description:n.description,onClick:()=>r(n)}),[Se.IMAGE]:({props:n})=>Di(t,Se.IMAGE,{src:n.src,alt:n.alt}),[Se.DETAILS_DATA]:({props:n,isStreaming:r})=>{const i=Array.isArray(n.items)?n.items:[];return Di(t,Se.DETAILS_DATA,{loading:r&&i.length===0,items:i})},[Se.FORM]:({props:n,onClick:r})=>{const i=n.submitButton,a=n.fields||[],o=i?.label||n.submitText||"Submit";return Di(t,Se.FORM,{title:n.title,description:n.description,fields:n.fields||[],submitText:o,submitAction:i?.action||n.submitAction,onSubmit:s=>{const l=s.formData,c=a.filter(p=>l[p.id]!==void 0&&l[p.id]!==null&&l[p.id]!=="").map(p=>`${p.label}: ${String(l[p.id])}`),d=n.title||"Form Submission";r({_directQuery:`${o} — ${d}: ${c.join(", ")}`})}})},[Se.BUTTON]:({props:n,onClick:r})=>Di(t,Se.BUTTON,{id:n.id,label:n.label,variant:n.variant||"primary",type:n.type||"action",action:n.action,url:n.url,size:n.size,disabled:n.disabled,startIcon:n.startIcon,endIcon:n.endIcon,onClick:()=>r({id:n.id,label:n.label,action:n.action,buttonType:n.type||"action"})}),[Se.ALERT]:({props:n,onClick:r})=>Di(t,Se.ALERT,{id:n.id,severity:E4t[n.severity]?n.severity:"info",title:n.title,message:n.message||"",variant:n.variant,closeable:n.closeable,showIcon:n.showIcon,actionText:n.actionText,onActionClick:()=>r({id:n.id,severity:n.severity,message:n.message,actionQuery:n.actionQuery,actionType:"alert_action_click"})})}}class z4t extends K.Component{constructor(){super(...arguments),this.state={hasError:!1}}static getDerivedStateFromError(){return{hasError:!0}}render(){return this.state.hasError?I.jsx(eD,{sx:{p:2,borderRadius:1,bgcolor:"rgba(239,68,68,0.08)",border:"1px solid rgba(239,68,68,0.2)"},children:I.jsxs(qRe,{variant:"body2",sx:{color:"#ef4444",fontSize:"0.8rem"},children:["Failed to render ",this.props.elementType]})}):this.props.children}}const R4t=WEe`
8398
+ }`,defaultProps:{submitAction:pK.SUBMIT},toolSchema:{input_schema:ea(lMe)}},cMe=jt({title:Ve().describe("Main page title"),subtitle:Ve().optional().describe("Page description or subtitle")}),M4t={id:Se.HEADER,componentName:Pi.HEADER,toolSchema:{input_schema:ea(cMe)}},uMe=jt({src:Ve().describe("Image source URL"),alt:Ve().describe("Alt text for accessibility"),title:Ve().optional().describe("Image title"),caption:Ve().optional().describe("Image caption"),width:wo().optional().describe("Image width"),height:wo().optional().describe("Image height")}),C4t={id:Se.IMAGE,componentName:Pi.IMAGE,toolSchema:{input_schema:ea(uMe)}},dMe=jt({id:Ve().describe("Item ID"),title:Ve().describe("Item name"),subtitle:Ve().optional().describe("Brief description"),image:Ve().optional().describe("Image URL"),price:Ve().optional().describe("Item price with currency symbol (e.g., '99.99$')"),category:Ve().optional().describe("Item category"),stock:wo().optional().describe("Number of items in stock"),rating:wo().optional().describe("Item rating (0-5)"),description:Ve().optional().describe("Detailed description (optional)")}),I4t={id:Se.ITEM_CARD,componentName:Pi.ITEM_CARD,toolSchema:{input_schema:ea(dMe)}},pMe=jt({title:Ve().optional().describe("Grid title"),items:Ai(jt({id:Ve().describe("Item ID"),title:Ve().describe("Item name"),description:Ve().optional().describe("Item description"),price:Ve().describe("Item price"),image:Ve().optional().describe("REAL image URL"),category:Ve().optional().describe("Item category"),rating:wo().optional().describe("Rating score"),stock:wo().optional().describe("Stock quantity")})).describe("Grid items"),pageSize:wo().optional().describe("Number of items per page")}),_4t={id:Se.ITEM_GRID,componentName:Pi.ITEM_GRID,toolSchema:{input_schema:ea(pMe)}},fMe=jt({title:Ve().describe("Chart title"),labels:Ai(Ve()).describe("X-axis labels (should be relevant to the context for example: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'])"),data:Ai(wo()).describe("Chart data")}),$4t={id:Se.LINE_CHART,componentName:Pi.LINE_CHART,toolSchema:{input_schema:ea(fMe)}},hMe=jt({title:Ve().describe("Chart title"),data:Ai(jt({label:Ve().describe("Segment label"),value:wo().describe("Segment value"),color:Ve().optional().describe("Segment color")})).describe("Pie chart segments")}),A4t={id:Se.PIE_CHART,componentName:Pi.PIE_CHART,toolSchema:{input_schema:ea(hMe)}},yMe=jt({stats:Ai(jt({id:Ve().describe("Unique stat identifier"),title:Ve().describe("Stat title"),value:Ve().describe("Main value"),period:Ve().optional().describe("Period (This Month, This Year, etc.)"),trend:jt({direction:ha(["up","down","neutral"]),percentage:Ve().describe("Trend percentage")}).optional().describe("Trend direction"),subtitle:Ve().optional().describe("Additional context")})).describe("Array of statistics (generate 4 if not requested differently)")}),P4t={id:Se.STATS_GRID,componentName:Pi.STATS_GRID,toolSchema:{input_schema:ea(yMe)}};Se.HEADER+"",Se.STATS_GRID+"",Se.DATA_TABLE+"",Se.LINE_CHART+"",Se.ITEM_GRID+"",Se.ITEM_CARD+"",Se.DETAILS_DATA+"",Se.IMAGE+"",Se.PIE_CHART+"",Se.CHAT_BUBBLE+"",Se.FORM+"",Se.BUTTON+"",Se.BAR_CHART+"",Se.ALERT+"";Se.HEADER,Se.STATS_GRID,Se.DATA_TABLE,Se.LINE_CHART,Se.PIE_CHART,Se.BAR_CHART,Se.DETAILS_DATA,Se.ITEM_GRID,Se.ITEM_CARD,Se.IMAGE,Se.FORM,Se.BUTTON,Se.CHAT_BUBBLE,Se.ALERT;const L4t=Kxt("elementType",[jt({elementType:Ri("header"),props:cMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("chat-bubble"),props:aMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("stats-grid"),props:yMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("data-table"),props:oMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("line-chart"),props:fMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("pie-chart"),props:hMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("bar-chart"),props:rMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("item-grid"),props:pMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("item-card"),props:dMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("image"),props:uMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("details-data"),props:sMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("form"),props:lMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("button"),props:iMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")}),jt({elementType:Ri("alert"),props:nMe,clickQuery:Ve().optional().describe("Optional query to send when this element is clicked")})]);jt({elements:Ai(L4t).describe("Ordered array of elements to render. Each element has an elementType and props.")});function N2(e,t){e.sendMessage({role:"user",content:[{type:"text",text:t}]})}function L0e(e,t){return e.replace(/\[(\w+)]/g,(n,r)=>{const i=t[r];return i!=null?String(i):`[${r}]`})}function T4t(e){return Object.entries(e).filter(([,n])=>n!=null&&n!=="").map(([n,r])=>`${n}: ${String(r)}`).join(", ")}function O4t(e,t,n,r){return i=>{if(e){if(i.isFormSubmission&&i.formData){const a=T4t(i.formData),o=i.title||"Form Submission";N2(e,`${o}: ${a}`);return}if(i.buttonType==="action"&&i.action){N2(e,String(i.action));return}if(t){const a=L0e(t,i);N2(e,a);return}if(i._directQuery){N2(e,String(i._directQuery));return}if(n){const a=L0e(n,i);N2(e,a)}}}}const E4t={success:!0,error:!0,warning:!0,info:!0},Di=(e,t,n)=>K.createElement(e[t],n);function j4t(e){const t=e?jgt:zgt;return{[Se.HEADER]:({props:n})=>Di(t,Se.HEADER,{title:n.title,subtitle:n.subtitle}),[Se.CHAT_BUBBLE]:({props:n})=>Di(t,Se.CHAT_BUBBLE,{text:n.text||"",markdown:n.markdown}),[Se.STATS_GRID]:({props:n,onClick:r})=>{const a=(n.stats||[]).map(o=>({...o,onClick:()=>r(o)}));return Di(t,Se.STATS_GRID,{stats:a})},[Se.DATA_TABLE]:({props:n,onClick:r,isStreaming:i})=>{const a=n.rows||[],o=n.columns||[],s=i?a.filter(c=>Object.values(c).some(d=>d!=null&&d!=="")):a,l=c=>{const d=o.filter(p=>p.key!=="id").slice(0,2);if(d.length>0){const p=d.map(h=>`${h.label}: ${c[h.key]??""}`).join(", ");r({...c,_directQuery:`Show details for ${p}`})}else r(c)};return Di(t,Se.DATA_TABLE,{loading:i&&s.length===0,title:n.title,columns:o,rows:s,pageSize:n.pageSize,onRowClick:l,hideDownload:!0})},[Se.LINE_CHART]:({props:n,onClick:r})=>{const i=a=>r({...a,chartTitle:n.title});return Di(t,Se.LINE_CHART,{title:n.title,labels:n.labels||[],data:n.data||[],onChartClick:i})},[Se.PIE_CHART]:({props:n,onClick:r})=>{const i=a=>r({...a,chartTitle:n.title});return Di(t,Se.PIE_CHART,{title:n.title,data:n.data||[],onPointClick:i})},[Se.BAR_CHART]:({props:n,onClick:r,isStreaming:i})=>{const a=n.categories||[],o=n.series||[];return Di(t,Se.BAR_CHART,{loading:i&&(a.length===0||o.length===0),id:n.id,title:n.title,categories:a,series:o,stacked:n.stacked,showLegend:n.showLegend,onBarClick:r})},[Se.ITEM_GRID]:({props:n,onClick:r,isStreaming:i})=>{const a=Array.isArray(n.items)?n.items:[];return Di(t,Se.ITEM_GRID,{loading:i&&a.length===0,title:n.title,items:a,pageSize:n.pageSize,onItemClick:r})},[Se.ITEM_CARD]:({props:n,onClick:r})=>Di(t,Se.ITEM_CARD,{title:n.title,subtitle:n.subtitle,image:n.image,price:n.price,category:n.category,rating:n.rating,stock:n.stock,description:n.description,onClick:()=>r(n)}),[Se.IMAGE]:({props:n})=>Di(t,Se.IMAGE,{src:n.src,alt:n.alt}),[Se.DETAILS_DATA]:({props:n,isStreaming:r})=>{const i=Array.isArray(n.items)?n.items:[];return Di(t,Se.DETAILS_DATA,{loading:r&&i.length===0,items:i})},[Se.FORM]:({props:n,onClick:r})=>{const i=n.submitButton,a=n.fields||[],o=i?.label||n.submitText||"Submit";return Di(t,Se.FORM,{title:n.title,description:n.description,fields:n.fields||[],submitText:o,submitAction:i?.action||n.submitAction,onSubmit:s=>{const l=s.formData,c=a.filter(p=>l[p.id]!==void 0&&l[p.id]!==null&&l[p.id]!=="").map(p=>`${p.label}: ${String(l[p.id])}`),d=n.title||"Form Submission";r({_directQuery:`${o} — ${d}: ${c.join(", ")}`})}})},[Se.BUTTON]:({props:n,onClick:r})=>Di(t,Se.BUTTON,{id:n.id,label:n.label,variant:n.variant||"primary",type:n.type||"action",action:n.action,url:n.url,size:n.size,disabled:n.disabled,startIcon:n.startIcon,endIcon:n.endIcon,onClick:()=>r({id:n.id,label:n.label,action:n.action,buttonType:n.type||"action"})}),[Se.ALERT]:({props:n,onClick:r})=>Di(t,Se.ALERT,{id:n.id,severity:E4t[n.severity]?n.severity:"info",title:n.title,message:n.message||"",variant:n.variant,closeable:n.closeable,showIcon:n.showIcon,actionText:n.actionText,onActionClick:()=>r({id:n.id,severity:n.severity,message:n.message,actionQuery:n.actionQuery,actionType:"alert_action_click"})})}}class z4t extends K.Component{constructor(){super(...arguments),this.state={hasError:!1}}static getDerivedStateFromError(){return{hasError:!0}}render(){return this.state.hasError?I.jsx(eD,{sx:{p:2,borderRadius:1,bgcolor:"rgba(239,68,68,0.08)",border:"1px solid rgba(239,68,68,0.2)"},children:I.jsxs(qRe,{variant:"body2",sx:{color:"#ef4444",fontSize:"0.8rem"},children:["Failed to render ",this.props.elementType]})}):this.props.children}}const R4t=WEe`
8399
8399
  from { opacity: 0; transform: translateY(8px); }
8400
8400
  to { opacity: 1; transform: translateY(0); }
8401
- `;function D4t({elements:e,mcpApp:t,projectSettings:n,isStreaming:r}){const i=K.useRef(0);K.useEffect(()=>{r||(i.current=e.length)},[r,e.length]);const a=n?.elementStyleVariant==="classic",o=K.useMemo(()=>j4t(a),[a]),s=e.filter(l=>n?.elementVisibility?n.elementVisibility[l.elementType]!==!1:!0);return I.jsx(eD,{sx:{display:"flex",flexDirection:"column",gap:2},children:s.map((l,c)=>{const d=o[l.elementType];if(!d)return null;const p=O4t(t,l.clickQuery,l.clickBehavior.queryTemplate,l.clickBehavior.entityName),h=r&&c>=i.current;return I.jsx(eD,{sx:h?{animation:`${R4t} 0.3s ease-out forwards`}:void 0,children:I.jsx(z4t,{elementType:l.elementType,children:I.jsx(d,{props:l.props,onClick:p,isStreaming:r})})},r?`${l.elementType}-${c}-stream`:`${l.elementType}-${c}`)})})}function N4t({screenData:e,mcpApp:t,isStreaming:n}){const r=fxe(e.brandSettings),i=K.useMemo(()=>gqe(e.brandSettings),[e.brandSettings]);return I.jsxs(ARe,{theme:i,children:[I.jsx(GRe,{}),I.jsx(JRe,{brandSettings:e.brandSettings,children:I.jsx(eD,{sx:{...r.containerSx,p:2,bgcolor:r.isDarkMode?"#0a0a0a":"#f5f5f5"},children:I.jsx(D4t,{elements:e.elements,mcpApp:t,projectSettings:e.projectSettings,isStreaming:n})})})]})}const F4t={[Se.HEADER]:{queryTemplate:"Show main [title]",description:"Headers typically don't have clickable items"},[Se.DATA_TABLE]:{queryTemplate:"Show details for [title] (ID: [id])",description:"Table rows lead to detail view of the item"},[Se.ITEM_GRID]:{queryTemplate:"Show details for [title] (ID: [id])",description:"Grid items lead to detail view of the item"},[Se.ITEM_CARD]:{queryTemplate:"Show details for [title] (ID: [id])",description:"Item cards lead to detail view"},[Se.STATS_GRID]:{queryTemplate:"Show analytics for [title]",description:"KPI/stat cards lead to analytics view"},[Se.LINE_CHART]:{queryTemplate:"Show [label] data from [chartTitle]",description:"Chart points lead to detailed data table"},[Se.PIE_CHART]:{queryTemplate:"Show [label] data from [chartTitle]",description:"Chart segments lead to detailed data table"},[Se.IMAGE]:{queryTemplate:"Show details for [title] (ID: [id])",description:"Images lead to detail view"},[Se.DETAILS_DATA]:{queryTemplate:"Show details for [title] (ID: [id])",description:"Detail cards typically stay in details view"},[Se.CHAT_BUBBLE]:{queryTemplate:"Continue conversation",description:"Text responses that don't need interaction"},[Se.FORM]:{queryTemplate:"Submit form data for [formSummary]",description:"Form submissions trigger data processing"},[Se.BUTTON]:{queryTemplate:"[action]",description:"Button action triggers the configured query"},[Se.BAR_CHART]:{queryTemplate:"Show [entity] table for [category]",description:"Bar chart clicks lead to detailed data table for that category"},[Se.ALERT]:{queryTemplate:"[actionQuery]",description:"Alert action button triggers the configured query"}};function q4t(e){return F4t[e]}const mMe="brander-project-config",B4t={primaryColor:"#6366f1",secondaryColor:"#8b5cf6",accentColor:"#6366f1",brandName:"",iconUrl:"",fontStyle:{fontFamily:"'Inter', sans-serif",weight:400,displayName:"Inter"},layoutStyle:{spacing:16,elevation:1,displayName:"Default"},darkMode:!0,borderRadius:12,shadowIntensity:.5,grayPalette:{gray50:"#f8fafc",gray100:"#f1f5f9",gray200:"#e2e8f0",gray300:"#cbd5e1",gray400:"#94a3b8",gray500:"#64748b",gray600:"#475569",gray700:"#334155",gray800:"#1e293b",gray900:"#0f172a"},primaryTextColor:"#f8fafc",secondaryTextColor:"#94a3b8",tertiaryTextColor:"#64748b"};function U4t(){try{const e=localStorage.getItem(mMe);return e?JSON.parse(e):null}catch{return null}}function H4t(e){try{localStorage.setItem(mMe,JSON.stringify(e))}catch{}}function V4t(){const e=window.__BRANDER_INITIAL_CONFIG__,t=U4t();return console.warn("[Brander] Startup —",e?`INJECTED — primaryColor=${e.brandSettings?.primaryColor}, brandName=${e.brandSettings?.brandName}`:t?`localStorage — primaryColor=${t.brandSettings?.primaryColor}, brandName=${t.brandSettings?.brandName}`:"NO CACHED CONFIG — will use DEFAULT_BRAND_SETTINGS on first stream"),{brandSettings:e?.brandSettings??t?.brandSettings,projectSettings:e?.projectSettings??t?.projectSettings,screenVisibility:e?.screenVisibility??t?.screenVisibility,customScreens:e?.customScreens??t?.customScreens,apiConfig:t?.apiConfig}}const nB=new eEe({name:"brander-element-renderer",version:"0.1.0"});let Fm=null,$N=null;const Jg=V4t();let pJ=Jg.brandSettings,gMe=Jg.projectSettings,vMe=Jg.screenVisibility,kMe=Jg.customScreens,bMe=Jg.apiConfig;function Z4t(e,t){const n=pJ||B4t;console.warn("[Brander] buildStreamingScreenData — using brand:",pJ?`CACHED — primaryColor=${n.primaryColor}`:`DEFAULT — primaryColor=${n.primaryColor} (no cached settings yet)`);const r=e.filter(i=>i.elementType&&typeof i.elementType=="string").map(i=>{const a=i.elementType,o=q4t(a);return{elementType:a,props:i.props||{},clickQuery:i.clickQuery,clickBehavior:{queryTemplate:o?.queryTemplate??null,entityName:a}}});return r.length===0?null:{elementType:"screen",elements:r,brandSettings:n,projectSettings:gMe,screenVisibility:vMe,customScreens:kMe,apiConfig:t}}function W4t(){const[e,t]=K.useState(null),[n,r]=K.useState(!1);return K.useEffect(()=>{Fm=t,$N=r,window.__BRANDER_SET_TOOL_DATA__=t},[]),e?I.jsx(N4t,{screenData:e,mcpApp:nB,isStreaming:n}):null}nB.ontoolinputpartial=e=>{const t=e.arguments?.elements;if(!t||!Fm||!$N)return;const n=Z4t(t,bMe);n&&($N(!0),Fm(n))};nB.ontoolresult=e=>{const t=e.structuredContent;console.warn("[Brander] ontoolresult — structuredContent present:",!!t,t?`primaryColor=${t.brandSettings?.primaryColor}`:"(no structuredContent)"),t&&Fm&&(pJ=t.brandSettings,gMe=t.projectSettings,vMe=t.screenVisibility,kMe=t.customScreens,bMe=t.apiConfig,H4t({brandSettings:t.brandSettings,projectSettings:t.projectSettings,screenVisibility:t.screenVisibility,customScreens:t.customScreens,apiConfig:t.apiConfig}),console.warn("[Brander] ontoolresult — saved to localStorage, primaryColor=",t.brandSettings?.primaryColor),$N?.(!1),Fm(t))};const G4t=CCe.createRoot(document.getElementById("root"));G4t.render(I.jsx(W4t,{}));nB.connect();</script>
8401
+ `;function D4t({elements:e,mcpApp:t,projectSettings:n,isStreaming:r}){const i=K.useRef(0);K.useEffect(()=>{r||(i.current=e.length)},[r,e.length]);const a=n?.elementStyleVariant==="classic",o=K.useMemo(()=>j4t(a),[a]),s=e.filter(l=>n?.elementVisibility?n.elementVisibility[l.elementType]!==!1:!0);return I.jsx(eD,{sx:{display:"flex",flexDirection:"column",gap:2},children:s.map((l,c)=>{const d=o[l.elementType];if(!d)return null;const p=O4t(t,l.clickQuery,l.clickBehavior.queryTemplate,l.clickBehavior.entityName),h=r&&c>=i.current;return I.jsx(eD,{sx:h?{animation:`${R4t} 0.3s ease-out forwards`}:void 0,children:I.jsx(z4t,{elementType:l.elementType,children:I.jsx(d,{props:l.props,onClick:p,isStreaming:r})})},r?`${l.elementType}-${c}-stream`:`${l.elementType}-${c}`)})})}function N4t({screenData:e,mcpApp:t,isStreaming:n}){const r=fxe(e.brandSettings),i=K.useMemo(()=>gqe(e.brandSettings),[e.brandSettings]);return I.jsxs(ARe,{theme:i,children:[I.jsx(GRe,{}),I.jsx(JRe,{brandSettings:e.brandSettings,children:I.jsx(eD,{sx:{...r.containerSx,p:2,bgcolor:r.isDarkMode?"#0a0a0a":"#f5f5f5"},children:I.jsx(D4t,{elements:e.elements,mcpApp:t,projectSettings:e.projectSettings,isStreaming:n})})})]})}const F4t={[Se.HEADER]:{queryTemplate:"Show main [title]",description:"Headers typically don't have clickable items"},[Se.DATA_TABLE]:{queryTemplate:"Show details for [title] (ID: [id])",description:"Table rows lead to detail view of the item"},[Se.ITEM_GRID]:{queryTemplate:"Show details for [title] (ID: [id])",description:"Grid items lead to detail view of the item"},[Se.ITEM_CARD]:{queryTemplate:"Show details for [title] (ID: [id])",description:"Item cards lead to detail view"},[Se.STATS_GRID]:{queryTemplate:"Show analytics for [title]",description:"KPI/stat cards lead to analytics view"},[Se.LINE_CHART]:{queryTemplate:"Show [label] data from [chartTitle]",description:"Chart points lead to detailed data table"},[Se.PIE_CHART]:{queryTemplate:"Show [label] data from [chartTitle]",description:"Chart segments lead to detailed data table"},[Se.IMAGE]:{queryTemplate:"Show details for [title] (ID: [id])",description:"Images lead to detail view"},[Se.DETAILS_DATA]:{queryTemplate:"Show details for [title] (ID: [id])",description:"Detail cards typically stay in details view"},[Se.CHAT_BUBBLE]:{queryTemplate:"Continue conversation",description:"Text responses that don't need interaction"},[Se.FORM]:{queryTemplate:"Submit form data for [formSummary]",description:"Form submissions trigger data processing"},[Se.BUTTON]:{queryTemplate:"[action]",description:"Button action triggers the configured query"},[Se.BAR_CHART]:{queryTemplate:"Show [seriesName] data for [category]",description:"Bar chart clicks lead to detailed data table for that category"},[Se.ALERT]:{queryTemplate:"[actionQuery]",description:"Alert action button triggers the configured query"}};function q4t(e){return F4t[e]}const mMe="brander-project-config",B4t={primaryColor:"#6366f1",secondaryColor:"#8b5cf6",accentColor:"#6366f1",brandName:"",iconUrl:"",fontStyle:{fontFamily:"'Inter', sans-serif",weight:400,displayName:"Inter"},layoutStyle:{spacing:16,elevation:1,displayName:"Default"},darkMode:!0,borderRadius:12,shadowIntensity:.5,grayPalette:{gray50:"#f8fafc",gray100:"#f1f5f9",gray200:"#e2e8f0",gray300:"#cbd5e1",gray400:"#94a3b8",gray500:"#64748b",gray600:"#475569",gray700:"#334155",gray800:"#1e293b",gray900:"#0f172a"},primaryTextColor:"#f8fafc",secondaryTextColor:"#94a3b8",tertiaryTextColor:"#64748b"};function U4t(){try{const e=localStorage.getItem(mMe);return e?JSON.parse(e):null}catch{return null}}function H4t(e){try{localStorage.setItem(mMe,JSON.stringify(e))}catch{}}function V4t(){const e=window.__BRANDER_INITIAL_CONFIG__,t=U4t();return console.warn("[Brander] Startup —",e?`INJECTED — primaryColor=${e.brandSettings?.primaryColor}, brandName=${e.brandSettings?.brandName}`:t?`localStorage — primaryColor=${t.brandSettings?.primaryColor}, brandName=${t.brandSettings?.brandName}`:"NO CACHED CONFIG — will use DEFAULT_BRAND_SETTINGS on first stream"),{brandSettings:e?.brandSettings??t?.brandSettings,projectSettings:e?.projectSettings??t?.projectSettings,screenVisibility:e?.screenVisibility??t?.screenVisibility,customScreens:e?.customScreens??t?.customScreens,apiConfig:t?.apiConfig}}const nB=new eEe({name:"brander-element-renderer",version:"0.1.0"});let Fm=null,$N=null;const Jg=V4t();let pJ=Jg.brandSettings,gMe=Jg.projectSettings,vMe=Jg.screenVisibility,kMe=Jg.customScreens,bMe=Jg.apiConfig;function Z4t(e,t){const n=pJ||B4t;console.warn("[Brander] buildStreamingScreenData — using brand:",pJ?`CACHED — primaryColor=${n.primaryColor}`:`DEFAULT — primaryColor=${n.primaryColor} (no cached settings yet)`);const r=e.filter(i=>i.elementType&&typeof i.elementType=="string").map(i=>{const a=i.elementType,o=q4t(a);return{elementType:a,props:i.props||{},clickQuery:i.clickQuery,clickBehavior:{queryTemplate:o?.queryTemplate??null,entityName:a}}});return r.length===0?null:{elementType:"screen",elements:r,brandSettings:n,projectSettings:gMe,screenVisibility:vMe,customScreens:kMe,apiConfig:t}}function W4t(){const[e,t]=K.useState(null),[n,r]=K.useState(!1);return K.useEffect(()=>{Fm=t,$N=r,window.__BRANDER_SET_TOOL_DATA__=t},[]),e?I.jsx(N4t,{screenData:e,mcpApp:nB,isStreaming:n}):null}nB.ontoolinputpartial=e=>{const t=e.arguments?.elements;if(!t||!Fm||!$N)return;const n=Z4t(t,bMe);n&&($N(!0),Fm(n))};nB.ontoolresult=e=>{const t=e.structuredContent;console.warn("[Brander] ontoolresult — structuredContent present:",!!t,t?`primaryColor=${t.brandSettings?.primaryColor}`:"(no structuredContent)"),t&&Fm&&(pJ=t.brandSettings,gMe=t.projectSettings,vMe=t.screenVisibility,kMe=t.customScreens,bMe=t.apiConfig,H4t({brandSettings:t.brandSettings,projectSettings:t.projectSettings,screenVisibility:t.screenVisibility,customScreens:t.customScreens,apiConfig:t.apiConfig}),console.warn("[Brander] ontoolresult — saved to localStorage, primaryColor=",t.brandSettings?.primaryColor),$N?.(!1),Fm(t))};const G4t=CCe.createRoot(document.getElementById("root"));G4t.render(I.jsx(W4t,{}));nB.connect();</script>
8402
8402
  </head>
8403
8403
  <body>
8404
8404
  <div id="root"></div>
@@ -4,6 +4,12 @@
4
4
  import { BrandSettings, ProjectConfig } from "./brand-types.js";
5
5
  interface BrandLoaderOptions {
6
6
  projectId: string;
7
+ /**
8
+ * Public design-partner key (bux_dp_xxx). This is a publishable identifier
9
+ * (like a Stripe publishable key) — it scopes API access to a specific project
10
+ * but does not grant write access or expose secrets. Safe to embed in client
11
+ * configs, MCP tool results, and localStorage.
12
+ */
7
13
  betaKey: string;
8
14
  apiBaseUrl?: string;
9
15
  brandSettingsPath?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"brand-loader.d.ts","sourceRoot":"","sources":["../../../src/brand/brand-loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,aAAa,EAA0B,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAExF,UAAU,kBAAkB;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CA4B3F;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAG3F"}
1
+ {"version":3,"file":"brand-loader.d.ts","sourceRoot":"","sources":["../../../src/brand/brand-loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,aAAa,EAA0B,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAExF,UAAU,kBAAkB;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CA4B3F;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAG3F"}
@@ -69,7 +69,7 @@ async function loadConfigFromApi(options) {
69
69
  const response = await fetch(url.toString(), {
70
70
  method: "GET",
71
71
  headers: {
72
- "Content-Type": "application/json",
72
+ Accept: "application/json",
73
73
  },
74
74
  });
75
75
  if (!response.ok) {
@@ -14,7 +14,11 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
14
14
  export interface BranderToolsConfig {
15
15
  /** BranderUX project ID — identifies which project's brand + screens to load */
16
16
  projectId: string;
17
- /** Beta design partner key (bux_dp_xxx) for authentication */
17
+ /**
18
+ * Public design-partner key (bux_dp_xxx). This is a publishable identifier — it
19
+ * scopes API access to a specific project but does not grant write access or expose
20
+ * secrets. Safe to include in client-side configs and version control.
21
+ */
18
22
  betaKey: string;
19
23
  /** BranderUX API base URL (defaults to https://branderux.com) */
20
24
  apiBaseUrl?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/register.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQpE,MAAM,WAAW,kBAAkB;IACjC,gFAAgF;IAChF,SAAS,EAAE,MAAM,CAAC;IAElB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAEhB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,iFAAiF;IACjF,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,IAAI,CAAC,CA2Bf"}
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/register.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQpE,MAAM,WAAW,kBAAkB;IACjC,gFAAgF;IAChF,SAAS,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,iFAAiF;IACjF,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,IAAI,CAAC,CA2Bf"}
@@ -1 +1 @@
1
- {"version":3,"file":"resource-registry.d.ts","sourceRoot":"","sources":["../../../src/resource/resource-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAGxD,eAAO,MAAM,YAAY,kCAAkC,CAAC;AAkB5D;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,GAAG,IAAI,CAwBhG"}
1
+ {"version":3,"file":"resource-registry.d.ts","sourceRoot":"","sources":["../../../src/resource/resource-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAGxD,eAAO,MAAM,YAAY,kCAAkC,CAAC;AAoB5D;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,GAAG,IAAI,CAwBhG"}
@@ -16,7 +16,9 @@ function injectInitialConfig(html, projectConfig) {
16
16
  screenVisibility: projectConfig.screenVisibility,
17
17
  customScreens: projectConfig.customScreens,
18
18
  };
19
- const script = `<script>window.__BRANDER_INITIAL_CONFIG__=${JSON.stringify(config)};</script>`;
19
+ // Escape </ sequences to prevent script tag injection (e.g. "</script>" in config values)
20
+ const safeJson = JSON.stringify(config).replace(/</g, "\\u003c");
21
+ const script = `<script>window.__BRANDER_INITIAL_CONFIG__=${safeJson};</script>`;
20
22
  // Insert before closing </head> so it runs before the app bundle
21
23
  return html.replace("</head>", `${script}</head>`);
22
24
  }
@@ -9,6 +9,7 @@ interface ElementInfo {
9
9
  name: string;
10
10
  description: string;
11
11
  }
12
+ export declare const ELEMENT_INFO: ElementInfo[];
12
13
  /** Get element info by type (for names, click behaviors, summaries) */
13
14
  export declare function getElementDefinition(elementType: string): ElementInfo | undefined;
14
15
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"element-definitions.d.ts","sourceRoot":"","sources":["../../../src/tools/element-definitions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AA6CD,uEAAuE;AACvE,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAEjF"}
1
+ {"version":3,"file":"element-definitions.d.ts","sourceRoot":"","sources":["../../../src/tools/element-definitions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,YAAY,EAAE,WAAW,EAuCrC,CAAC;AAIF,uEAAuE;AACvE,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAEjF"}
@@ -4,7 +4,7 @@
4
4
  * Inlined here so the compiled dist/server can run as standalone Node.js without
5
5
  * depending on @brander/elements TypeScript source at runtime (CJS/ESM interop issue).
6
6
  */
7
- const ELEMENT_INFO = [
7
+ export const ELEMENT_INFO = [
8
8
  { id: "header", name: "Header", description: "Page header with title and subtitle" },
9
9
  { id: "stats-grid", name: "Stats Grid", description: "Grid of KPI statistics with trends" },
10
10
  {
@@ -257,6 +257,21 @@ export declare const generateScreenInputSchema: z.ZodObject<{
257
257
  clickQuery: z.ZodOptional<z.ZodString>;
258
258
  }, z.core.$strip>], "elementType">>;
259
259
  }, z.core.$strip>;
260
- /** Tool description for generate_screen */
261
- export declare const GENERATE_SCREEN_DESCRIPTION: string;
260
+ interface DescriptionConfig {
261
+ elementVisibility?: Record<string, boolean>;
262
+ customScreens?: Array<{
263
+ name: string;
264
+ config?: {
265
+ elements?: Array<{
266
+ elementType?: string;
267
+ }>;
268
+ };
269
+ elements?: Array<{
270
+ elementType?: string;
271
+ }>;
272
+ }>;
273
+ }
274
+ /** Build the generate_screen tool description dynamically from project config */
275
+ export declare function buildGenerateScreenDescription(config?: DescriptionConfig): string;
276
+ export {};
262
277
  //# sourceMappingURL=generate-screen-schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generate-screen-schema.d.ts","sourceRoot":"","sources":["../../../src/tools/generate-screen-schema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA+OxB,2DAA2D;AAC3D,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAIpC,CAAC;AAEH,2CAA2C;AAC3C,eAAO,MAAM,2BAA2B,QAO8H,CAAC"}
1
+ {"version":3,"file":"generate-screen-schema.d.ts","sourceRoot":"","sources":["../../../src/tools/generate-screen-schema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA6OxB,2DAA2D;AAC3D,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAIpC,CAAC;AAMH,UAAU,iBAAiB;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C,aAAa,CAAC,EAAE,KAAK,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,EAAE,KAAK,CAAC;gBAAE,WAAW,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,CAAC;QACxD,QAAQ,CAAC,EAAE,KAAK,CAAC;YAAE,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAC5C,CAAC,CAAC;CACJ;AAED,iFAAiF;AACjF,wBAAgB,8BAA8B,CAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAqCjF"}
@@ -6,6 +6,7 @@
6
6
  * (Avoids CJS/ESM interop issues — brander-elements is CJS but mcp-tools is ESM.)
7
7
  */
8
8
  import { z } from "zod";
9
+ import { ELEMENT_INFO } from "./element-definitions.js";
9
10
  // ============================================================================
10
11
  // ELEMENT PROP SCHEMAS (14 element types)
11
12
  // ============================================================================
@@ -87,10 +88,7 @@ const itemGridPropsSchema = z.object({
87
88
  title: z.string().describe("Item name"),
88
89
  description: z.string().optional().describe("Item description"),
89
90
  price: z.string().describe("Item price"),
90
- image: z
91
- .string()
92
- .optional()
93
- .describe("REAL image URL (e.g., https://images.unsplash.com/...)"),
91
+ image: z.string().optional().describe("Image URL"),
94
92
  category: z.string().optional().describe("Item category"),
95
93
  rating: z.number().optional().describe("Rating score"),
96
94
  stock: z.number().optional().describe("Stock quantity"),
@@ -217,11 +215,34 @@ export const generateScreenInputSchema = z.object({
217
215
  .array(screenElementSchema)
218
216
  .describe("Ordered array of elements to render. Each element has an elementType and props."),
219
217
  });
220
- /** Tool description for generate_screen */
221
- export const GENERATE_SCREEN_DESCRIPTION = "**REQUIRED FOR ALL VISUAL RESPONSES** - Render branded, interactive UI components. " +
222
- "You MUST use this tool instead of writing React code for dashboards, data tables, charts, stats, or any visual content. " +
223
- "Provide an ordered array of elements: for dashboards use header + stats-grid + data-table + charts; " +
224
- "for simple text use chat-bubble. For clickable elements, add a `clickQuery` with placeholders [field] for dynamic values. " +
225
- "Example: clickQuery: 'Show detailed analytics for [title] including sales trends and inventory'. " +
226
- "Use [title], [id], [name] placeholders that will be filled when user clicks. DO NOT write React code - use this tool. " +
227
- "Available elements: header, chat-bubble, stats-grid, data-table, line-chart, pie-chart, bar-chart, item-grid, item-card, image, details-data, form, button, alert.";
218
+ /** Build the generate_screen tool description dynamically from project config */
219
+ export function buildGenerateScreenDescription(config) {
220
+ const elementVisibility = config?.elementVisibility ?? {};
221
+ const customScreens = config?.customScreens ?? [];
222
+ // Filter elements by visibility (default = enabled if not in map)
223
+ const enabledElements = ELEMENT_INFO.filter((e) => elementVisibility[e.id] !== false);
224
+ const enabledSet = new Set(enabledElements.map((e) => e.id));
225
+ const elementList = enabledElements.map((e) => e.id).join(", ");
226
+ // Build screen patterns from the project's custom screens
227
+ const patterns = [];
228
+ for (const screen of customScreens) {
229
+ const els = (screen.config?.elements ?? screen.elements ?? [])
230
+ .map((e) => e.elementType)
231
+ .filter((t) => !!t && enabledSet.has(t));
232
+ if (els.length > 0) {
233
+ const unique = [...new Set(els)];
234
+ patterns.push(`- ${screen.name}: ${unique.join(" → ")}`);
235
+ }
236
+ }
237
+ const patternsSection = patterns.length > 0
238
+ ? "Compose screens from an ordered array of elements. Available screen patterns:\n" +
239
+ patterns.join("\n") +
240
+ "\n\n"
241
+ : "";
242
+ return ("Render branded, interactive UI screens. Outputs styled visual components (charts, tables, grids, forms) " +
243
+ "using the project's brand colors, fonts, and layout — displayed as a rich visual panel.\n\n" +
244
+ patternsSection +
245
+ "For interactivity, add clickQuery with [placeholder] tokens filled from element data on click. " +
246
+ 'Example: clickQuery: "Show details for [title] with full order history"\n\n' +
247
+ `Available elements: ${elementList}`);
248
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../../../src/tools/tool-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAMlD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,SAAS,EACjB,aAAa,EAAE,aAAa,EAC5B,SAAS,CAAC,EAAE,SAAS,GACpB,IAAI,CAuBN"}
1
+ {"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../../../src/tools/tool-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAOlD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,SAAS,EACjB,aAAa,EAAE,aAAa,EAC5B,SAAS,CAAC,EAAE,SAAS,GACpB,IAAI,CAsCN"}
@@ -4,9 +4,10 @@
4
4
  * Uses the high-level McpServer.registerTool() API for composability — customers
5
5
  * can register their own tools alongside BranderUX tools on the same server.
6
6
  */
7
- import { generateScreenInputSchema, GENERATE_SCREEN_DESCRIPTION, } from "./generate-screen-schema.js";
7
+ import { generateScreenInputSchema, buildGenerateScreenDescription, } from "./generate-screen-schema.js";
8
8
  import { createScreenHandler } from "./tool-handler.js";
9
9
  import { RESOURCE_URI } from "../resource/resource-registry.js";
10
+ import { ELEMENT_INFO } from "./element-definitions.js";
10
11
  const TOOL_NAME = "generate_screen";
11
12
  /**
12
13
  * Register the BranderUX generate_screen tool with the MCP server.
@@ -14,8 +15,16 @@ const TOOL_NAME = "generate_screen";
14
15
  */
15
16
  export function registerTools(server, projectConfig, apiConfig) {
16
17
  const handler = createScreenHandler(projectConfig, apiConfig);
18
+ // Build description dynamically from project's element/screen visibility + custom screens
19
+ const description = buildGenerateScreenDescription({
20
+ elementVisibility: projectConfig.settings.elementVisibility,
21
+ customScreens: projectConfig.customScreens,
22
+ });
23
+ // Count enabled elements
24
+ const elementVisibility = projectConfig.settings.elementVisibility ?? {};
25
+ const enabledCount = ELEMENT_INFO.filter((e) => elementVisibility[e.id] !== false).length;
17
26
  server.registerTool(TOOL_NAME, {
18
- description: GENERATE_SCREEN_DESCRIPTION,
27
+ description,
19
28
  inputSchema: generateScreenInputSchema,
20
29
  _meta: {
21
30
  ui: { resourceUri: RESOURCE_URI },
@@ -26,5 +35,6 @@ export function registerTools(server, projectConfig, apiConfig) {
26
35
  // but our handler expects Record<string, unknown>
27
36
  return handler(args);
28
37
  });
29
- console.error(`Registered BranderUX tool: ${TOOL_NAME} ` + `(14 element types, resource: ${RESOURCE_URI})`);
38
+ console.error(`Registered BranderUX tool: ${TOOL_NAME} ` +
39
+ `(${enabledCount} element types, resource: ${RESOURCE_URI})`);
30
40
  }
@@ -19,19 +19,4 @@ export declare enum ElementType {
19
19
  ALERT = "alert",
20
20
  SCREEN = "screen"
21
21
  }
22
- export interface ToolSchema {
23
- name: string;
24
- description: string;
25
- input_schema: {
26
- type: "object";
27
- properties: Record<string, unknown>;
28
- required?: string[];
29
- };
30
- }
31
- export interface ElementDefinition {
32
- id: ElementType;
33
- name: string;
34
- description: string;
35
- toolSchema: ToolSchema;
36
- }
37
22
  //# sourceMappingURL=element-types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"element-types.d.ts","sourceRoot":"","sources":["../../../src/types/element-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,oBAAY,WAAW;IACrB,MAAM,WAAW;IACjB,UAAU,eAAe;IACzB,UAAU,eAAe;IACzB,UAAU,eAAe;IACzB,SAAS,cAAc;IACvB,SAAS,cAAc;IACvB,SAAS,cAAc;IACvB,KAAK,UAAU;IACf,YAAY,iBAAiB;IAC7B,WAAW,gBAAgB;IAC3B,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,SAAS,cAAc;IACvB,KAAK,UAAU;IACf,MAAM,WAAW;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE;QACZ,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,WAAW,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,UAAU,CAAC;CACxB"}
1
+ {"version":3,"file":"element-types.d.ts","sourceRoot":"","sources":["../../../src/types/element-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,oBAAY,WAAW;IACrB,MAAM,WAAW;IACjB,UAAU,eAAe;IACzB,UAAU,eAAe;IACzB,UAAU,eAAe;IACzB,SAAS,cAAc;IACvB,SAAS,cAAc;IACvB,SAAS,cAAc;IACvB,KAAK,UAAU;IACf,YAAY,iBAAiB;IAC7B,WAAW,gBAAgB;IAC3B,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,SAAS,cAAc;IACvB,KAAK,UAAU;IACf,MAAM,WAAW;CAClB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brander/mcp-tools",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "type": "module",
5
5
  "description": "BranderUX MCP Tools — Add branded interactive UI to any MCP server",
6
6
  "main": "dist/server/lib-entry.js",