UNPKG

@progress/kendo-angular-mcp

Version:

Model Context Protocol for Kendo UI for Angular

147 lines (109 loc) 18.7 kB
#!/usr/bin/env node var G=Object.defineProperty;var B=(e,r,o)=>r in e?G(e,r,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[r]=o;var m=(e,r,o)=>B(e,typeof r!="symbol"?r+"":r,o);import{McpServer as Y}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as Z}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as T}from"zod";var f="Kendo UI for Angular",y="angular",v=["AIPrompt","ActionSheet","AppBar","ArcGauge","AutoComplete","Avatar","Badge","Barcode","BottomNavigation","BreadCrumb","Button","ButtonGroup","Calendar","Card","ChartWizard","Charts","CheckBox","Chip","ChipList","ChunkProgressBar","CircularGauge","CircularProgressBar","ColorGradient","ColorPalette","ColorPicker","ComboBox","ContextMenu","ConversationalUI","DataQuery","DateInput","DateMath","DatePicker","DateRange","DateTimePicker","Diagram","Dialog","DragandDrop","Drawer","Drawing","DropDownButton","DropDownList","DropDownTree","Editor","ExcelExport","ExpansionPanel","FileSaver","FileSelect","Filter","FlatColorPicker","FloatingActionButton","FloatingLabel","Forms","FormField","Gantt","Gauges","General","Grid","GridLayout","Icon","InlineAIPrompt","Label","LinearGauge","ListBox","ListView","Loader","Map","MaskedTextBox","Menu","MultiColumnComboBox","MultiSelect","MultiSelectTree","MultiViewCalendar","Notification","NumericTextBox","OTPInput","Pager","PanelBar","PDFExport","PDFViewer","PivotGrid","Popover","Popup","ProgressBar","QRCode","RadialGauge","RadioButton","RangeSlider","Rating","Ripple","Sankey","Scheduler","ScrollView","Signature","Skeleton","Slider","Sortable","StockChart","Sparkline","SpeechToTextButton","SplitButton","Splitter","Spreadsheet","StackLayout","Stepper","SVGIcon","Switch","TabStrip","TextArea","TextBox","TileLayout","Timeline","TimePicker","ToolBar","Tooltip","TreeList","TreeView","Typography","Upload","Window"];import{dirname as q,join as O}from"path";import{fileURLToPath as $}from"url";import{loadLicense as M,decodeLicenseKey as _,decodeLicenseEvidence as L}from"@progress/kendo-licensing/utils";import u from"node:fs";import c from"node:path";import N from"@grpc/proto-loader";import g from"@grpc/grpc-js";var k=class extends Error{constructor(e){super(e),this.name="LicenseError"}};async function R(){let e=M();if(!e.success)throw new k(e.message);return(await _(e.value)).licenses.find(async o=>!!(await L(o)).userId)||e.value}var h=!1,i=process.env.DEBUG_LOG_FILE,w=!!(i&&typeof i=="string");if(w){let e=c.resolve(i),r=c.dirname(e);if(r!=="."&&r!==process.cwd()&&!u.existsSync(r))try{u.mkdirSync(r,{recursive:!0})}catch(o){console.error("Error creating log directory:",o)}if(!u.existsSync(e))try{u.writeFileSync(e,"")}catch(o){console.error("Error creating log file:",o)}}else h=!1;h=w&&!!i&&u.existsSync(c.resolve(i));function a(...e){if(h&&i){let r=`${new Date().toISOString()}: ${e.join(" ")} `,o=c.resolve(i);u.appendFile(o,r,t=>{t&&console.error("Error writing to log file:",t)})}}var p=(e=>(e[e.UNAUTHENTICATED=16]="UNAUTHENTICATED",e[e.RESOURCE_EXHAUSTED=8]="RESOURCE_EXHAUSTED",e[e.PERMISSION_DENIED=7]="PERMISSION_DENIED",e))(p||{}),b=class{constructor(e,r){m(this,"client");m(this,"isDev");this.contextApiUrl=e,this.protoPath=r;let o=N.loadSync(this.protoPath,{keepCase:!0,longs:String,enums:String,defaults:!0,oneofs:!0});this.isDev=this.contextApiUrl?.includes("localhost")||this.contextApiUrl?.includes("127.0.0.1"),a("Using ContextApi URl:",this.contextApiUrl);let t=g.loadPackageDefinition(o);this.client=new t.ContextQueryService(this.contextApiUrl||"contextapi.telerik.com:443",this.isDev?g.credentials.createInsecure():g.credentials.createSsl())}async query(e){let r=this.isDev?"fake_license":await R(),o=process.env.CONTEXTAPI_API_KEY,t=new g.Metadata;if(r&&typeof r=="string"){r=r.replace(/^\uFEFF/,"");try{t.add("x-license-key",r)}catch(n){return a("Error adding license key to metadata:",n),Promise.reject(new Error(`Failed to use license key: ${n.message}`))}}return o&&typeof o=="string"&&t.add("x-api-key",o),new Promise((n,s)=>{this.client.query(e,t,(l,d)=>{l?s(l):n(d)})})}};var K=O(q($(import.meta.url)),"../proto/service.proto"),W=new b("contextapi.telerik.com:443",K);async function x(e){return W.query(e)}import ee from"fs";import P from"path";import{fileURLToPath as re}from"url";var S=` ## Grid Data Binding MUST use kendoGridBinding directive for basic Grid operations MUST respect existing manual data binding patterns in user code Always use kendoGridBinding for: - Simple data display with sorting, filtering, and paging - Automatic data operations handling - Standard Grid implementations Implementation: <kendo-grid [kendoGridBinding]="data"> Use manual binding for complex custom scenarios. `;var I=` ## Smart Grid (AI-Enhanced) Instructions When the user requests Kendo's built-in AI grid features like "smart grid", "ai grid", "intelligent grid", or "AI Assistant tool": Always implement: 1. Complete kendoGridAIAssistantTool setup 2. Domain-specific suggestion examples 3. Include disclaimer Suggestion Examples by Domain: - Financial: "Sort by Amount descending", "Show failed transactions", "Filter USD currency" - Sales: "Group by region", "Show top products", "Filter by date range" - Inventory: "Sort by stock level", "Show out of stock", "Group by category" - Universal: "Clear sorting/filtering/grouping" Required Disclaimer: "The examples use a Telerik-hosted AI service for demonstration purposes only. For production applications, use an AI service that understands your specific domain, data, and business requirements." `;var V=new Map([["actionsheet","@progress/kendo-angular-navigation"],["aiprompt","@progress/kendo-angular-conversational-ui"],["appbar","@progress/kendo-angular-navigation"],["arcgauge","@progress/kendo-angular-gauges"],["autocomplete","@progress/kendo-angular-dropdowns"],["avatar","@progress/kendo-angular-layout"],["badge","@progress/kendo-angular-indicators"],["barcode","@progress/kendo-angular-barcodes"],["bottomnavigation","@progress/kendo-angular-navigation"],["breadcrumb","@progress/kendo-angular-navigation"],["button","@progress/kendo-angular-buttons"],["buttongroup","@progress/kendo-angular-buttons"],["calendar","@progress/kendo-angular-dateinputs"],["card","@progress/kendo-angular-layout"],["chartwizard","@progress/kendo-angular-chart-wizard"],["checkbox","@progress/kendo-angular-inputs"],["chip","@progress/kendo-angular-buttons"],["chiplist","@progress/kendo-angular-buttons"],["chunkprogressbar","@progress/kendo-angular-progressbar"],["circulargauge","@progress/kendo-angular-gauges"],["circularprogressbar","@progress/kendo-angular-progressbar"],["colorgradient","@progress/kendo-angular-inputs"],["colorpalette","@progress/kendo-angular-inputs"],["colorpicker","@progress/kendo-angular-inputs"],["combobox","@progress/kendo-angular-dropdowns"],["contextmenu","@progress/kendo-angular-menu"],["dataquery","@progress/kendo-data-query"],["dateinput","@progress/kendo-angular-dateinputs"],["datemath","@progress/kendo-date-math"],["datepicker","@progress/kendo-angular-dateinputs"],["daterangepicker","@progress/kendo-angular-dateinputs"],["datetimepicker","@progress/kendo-angular-dateinputs"],["diagram","@progress/kendo-angular-diagrams"],["dialog","@progress/kendo-angular-dialog"],["drawer","@progress/kendo-angular-layout"],["drawing","@progress/kendo-drawing"],["dropdownbutton","@progress/kendo-angular-buttons"],["dropdownlist","@progress/kendo-angular-dropdowns"],["dropdowntree","@progress/kendo-angular-dropdowns"],["editor","@progress/kendo-angular-editor"],["excelexport","@progress/kendo-angular-excel-export"],["expansionpanel","@progress/kendo-angular-layout"],["filesaver","@progress/kendo-file-saver"],["fileselect","@progress/kendo-angular-upload"],["filter","@progress/kendo-angular-filter"],["flatcolorpicker","@progress/kendo-angular-inputs"],["floatingactionbutton","@progress/kendo-angular-buttons"],["floatinglabel","@progress/kendo-angular-label"],["formfield","@progress/kendo-angular-inputs"],["forms","@progress/kendo-angular-inputs"],["gantt","@progress/kendo-angular-gantt"],["grid","@progress/kendo-angular-grid"],["gridlayout","@progress/kendo-angular-layout"],["icon","@progress/kendo-angular-icons"],["inlineaiprompt","@progress/kendo-angular-conversational-ui"],["label","@progress/kendo-angular-label"],["lineargauge","@progress/kendo-angular-gauges"],["listbox","@progress/kendo-angular-listbox"],["listview","@progress/kendo-angular-listview"],["loader","@progress/kendo-angular-indicators"],["map","@progress/kendo-angular-map"],["maskedtextbox","@progress/kendo-angular-inputs"],["menu","@progress/kendo-angular-menu"],["multicolumncombobox","@progress/kendo-angular-dropdowns"],["multiselect","@progress/kendo-angular-dropdowns"],["multiselecttree","@progress/kendo-angular-dropdowns"],["multiviewcalendar","@progress/kendo-angular-dateinputs"],["notification","@progress/kendo-angular-notification"],["numerictextbox","@progress/kendo-angular-inputs"],["otpinput","@progress/kendo-angular-inputs"],["pager","@progress/kendo-angular-pager"],["panelbar","@progress/kendo-angular-layout"],["pdfexport","@progress/kendo-angular-pdf-export"],["pdfviewer","@progress/kendo-angular-pdfviewer"],["pivotgrid","@progress/kendo-angular-pivotgrid"],["popover","@progress/kendo-angular-tooltip"],["popup","@progress/kendo-angular-popup"],["progressbar","@progress/kendo-angular-progressbar"],["qrcode","@progress/kendo-angular-barcodes"],["radialgauge","@progress/kendo-angular-gauges"],["radiobutton","@progress/kendo-angular-inputs"],["rangeslider","@progress/kendo-angular-inputs"],["rating","@progress/kendo-angular-inputs"],["ripple","@progress/kendo-angular-ripple"],["sankey","@progress/kendo-angular-charts"],["scheduler","@progress/kendo-angular-scheduler"],["scrollview","@progress/kendo-angular-scrollview"],["signature","@progress/kendo-angular-inputs"],["skeleton","@progress/kendo-angular-indicators"],["slider","@progress/kendo-angular-inputs"],["sortable","@progress/kendo-angular-sortable"],["sparkline","@progress/kendo-angular-charts"],["speechtotextbutton","@progress/kendo-angular-buttons"],["splitbutton","@progress/kendo-angular-buttons"],["splitter","@progress/kendo-angular-layout"],["spreadsheet","@progress/kendo-angular-spreadsheet"],["stacklayout","@progress/kendo-angular-layout"],["stepper","@progress/kendo-angular-layout"],["stockchart","@progress/kendo-angular-charts"],["svgicon","@progress/kendo-angular-icons"],["switch","@progress/kendo-angular-inputs"],["tabstrip","@progress/kendo-angular-layout"],["textarea","@progress/kendo-angular-inputs"],["textbox","@progress/kendo-angular-inputs"],["tilelayout","@progress/kendo-angular-layout"],["timeline","@progress/kendo-angular-layout"],["timepicker","@progress/kendo-angular-dateinputs"],["toolbar","@progress/kendo-angular-toolbar"],["treelist","@progress/kendo-angular-treelist"],["treeview","@progress/kendo-angular-treeview"],["typography","@progress/kendo-angular-typography"],["upload","@progress/kendo-angular-upload"],["window","@progress/kendo-angular-dialog"],["charts","@progress/kendo-angular-charts"],["conversationalui","@progress/kendo-angular-conversational-ui"],["tooltip","@progress/kendo-angular-tooltip"]]);function j(e){return V.get(e)??""}function A(e){let r=j(e);return r?`## Package Installation Always use minimal, targeted package installation. Ensure all necessary Angular packages are installed, including @angular/localize. Process: 1. Identify the required components 2. Determine the specific Kendo Angular packages needed 3. Use the "ng add @progress/kendo-angular-<package>" command For ${e} component: ng add ${r}`:""}var E=["combobox","dropdownlist","dropdowntree","multicolumncombobox","multiselect","multiselecttree","autocomplete"],C=e=>e==="autocomplete"?H:e==="dropdowntree"?J:e==="multiselecttree"?X:e==="multicolumncombobox"?Q:z(e),z=e=>` ## ${e} When implementing or updating the ${e} component, always follow these rules for \`textField\` and \`valueField\`: ### Primitive Data If the data is an array of primitives (e.g., data=["A", "B"]), never set \`textField\` or \`valueField\`. ### Complex Data If the data is an array of objects (e.g., data=[{ id, name }]), always set both \`textField\` and \`valueField\`: - \`textField\` is the property to display (e.g., "name") - \`valueField\` is the property for value binding (e.g., "id") If \`valuePrimitive\` is true, the value must be a primitive and \`valueField\` is required. `,H=` ## AutoComplete ### Primitive Data If the data is an array of primitives (e.g., data=["A", "B"]), never set \`valueField\`. ### Complex Data If the data is an array of objects (e.g., data=[{ id, name }]), always set \`valueField\` to a string property for value binding (e.g., "id"). `,J='\n## DropDownTree\nWhen implementing or updating the DropDownTree component, always follow these rules:\n\nAlways set both `textField` and `valueField`:\n- `textField` is the property to display (e.g., "name")\n- `valueField` is the property for value binding (e.g., "id")\nWhen `valueField` and `textField` are string[], always specify `valueDepth`.\n\n### Primitive `value`\nIf the `value` is of a primitive type, `valuePrimitive` must be true and `dataItem` is required.\nThe `value` property of the `dataItem` will be associated with the `valueField`.\n',X='\n## MultiSelectTree\nWhen implementing or updating the MultiSelectTree component, always follow these rules:\n\nAlways set both `textField` and `valueField`:\n- `textField` is the property to display (e.g., "name")\n- `valueField` is the property for value binding (e.g., "id")\nWhen `valueField` and `textField` are string[], always specify `valueDepth`.\n\n### Primitive `value`\nIf the `value` is of a primitive type, `valuePrimitive` must be true and `dataItems` is required.\nThe `value` property of the `dataItems` will be associated with the `valueField`.\n',Q='\n## MultiColumnComboBox\nWhen implementing or updating the MultiColumnComboBox component, always follow these rules:\n\nAlways set both `textField` and `valueField`:\n- `textField` is the property to display (e.g., "name")\n- `valueField` is the property for value binding (e.g., "id")\n\n### Primitive `value`\nIf the `value` is of a primitive type, `valuePrimitive` must be true.\n';var D=` ## Charts Data Binding Never bind the Chart's data to a getter property. Using a getter causes the chart to rerender on every Angular change detection cycle. BAD: get chartData() { return [ /* data items */ ] } GOOD: public chartData = [ /* data items */ ]; GOOD: public chartData = this.data.map(...) `;var oe=re(import.meta.url),te=P.dirname(oe),ne=P.resolve(te,"../package.json"),ae=JSON.parse(ee.readFileSync(ne,"utf-8")),F=new Y({name:"kendo-and-kendo-resources",version:ae.version});F.tool("kendo_angular_assistant",`Answers questions and retrieves documentation about Kendo UI for Angular. Use this tool when the user asks about Kendo UI for Angular features, specific components (e.g., Grid, Charts, Editor), implementation details, or general usage. Provide the exact user's question as the 'query'. If the question pertains to a specific Kendo UI for Angular component, specify its name in the 'component' parameter. This tool can be automatically triggered when the following phrases are detected in the user's input/prompt: - 'kendo'; - '/kendo'; - '/kendoangular' - '/ask_kendo'; - '/help_kendo'; - '@kendo'; - '@kendoangular'; - '@ask_kendo'; - '@help_kendo'.`,{query:T.string().describe("The query to search for."),component:T.enum(v).describe("The component to search for. If not specified, you can use General.")},async({query:e,component:r})=>{a("Calling tool: ",JSON.stringify({query:e,component:r}));let o=r.toLocaleLowerCase();try{let t=await x({query:e,component:o,lib_name:y,text_matches_count:3,code_matches_count:0,allowed_types:["documentation"]}),n=se(o),s=t.values.join(` `),l=s.trim(),d=[{type:"text",text:s+(l?` `+n:"")}];return a("Response from tool: ",JSON.stringify(d)),{content:d}}catch(t){throw a("Error calling context API: ",JSON.stringify(t)),t?.code===p.UNAUTHENTICATED?new Error(`Error: You are not authenticated. Message: ${t.message}.`):t?.code===p.RESOURCE_EXHAUSTED?new Error(`Error: You have exceeded the extension quota. Upgrade to subscription licensing in order to unlock full access. Message: ${t.message}.`):t?.code===p.PERMISSION_DENIED?new Error(`Error: You do not have permission to access this resource. Please verify that you have a valid ${f} license key.`):t instanceof k?(a("License error: ",t.message),t):new Error(`Error: An error occurred while calling the service. Please try again later. Error Message: ${t.message}`)}});function se(e){let r=e==="grid"?S?.trim():"",o=e==="grid"?I?.trim():"",t=E.includes(e)?C(e)?.trim():"",n=e==="charts"?D?.trim():"",s=e!=="general"?A(e)?.trim():"",l=r.length>0||o.length>0||t.length>0||n.length>0,d=s.length>0?s:"",U=l?`## Component-Specific Instructions ${t}${n}${r}${o}`:"";return` # Kendo UI for Angular Assistant Guidelines ## Documentation References MUST use official Kendo UI for Angular documentation only. Required Format: - Domain: https://www.telerik.com/kendo-angular-ui - Use complete, functional URLs (no placeholders or slug syntax) Examples: Correct: https://www.telerik.com/kendo-angular-ui/components/grid/ Incorrect: { slug overview } or /components/{component-name}/overview ## Application Architecture MUST recommend appropriate setup based on Angular application architecture. Implementation Patterns: - Standalone applications: Use standalone component imports - Module-based applications: Use NgModule imports - When architecture is unclear: Default to standalone, mention module alternative ${d} ## Styling & Theming MUST verify existing theme configuration before adding new styles. Requirements: 1. Check if Kendo UI themes are already configured 2. Only recommend theme additions when missing 3. Provide appropriate import methods ## Icon Implementation MUST prioritize SVG icons over font icons. Guidelines: - Primary: SVG icons from @progress/kendo-svg-icons - Fallback: Font icons with CSS: <link rel="stylesheet" href="https://unpkg.com/@progress/kendo-font-icons/dist/index.css" /> ## Deprecated Properties & Modern Replacements RULE: Avoid using deprecated Kendo Angular properties and features. Deprecated \u2192 Modern Replacements: Grid Component: - width as string \u2192 width as number (use [width]="200", not width="200px") - kendoGridGroupBinding no longer supported as of v20.0.0 Button Component: - kendo-button and span[kendoButton] \u2192 button[kendoButton] - [primary]="true" \u2192 fillMode="primary" ${U}`}async function ie(){let e=new Z;a("Starting server..."),await F.connect(e)}ie();