@progress/kendo-jquery-mcp
Version:
Model Context Protocol for KendoJQuery
75 lines (68 loc) • 10.6 kB
JavaScript
var G=Object.defineProperty;var M=(e,t,o)=>t in e?G(e,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[t]=o;var g=(e,t,o)=>M(e,typeof t!="symbol"?t+"":t,o);import{McpServer as Q}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as K}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as x}from"zod";var c="Kendo UI for jQuery",k="jquery",I=["AIPrompt","ActionSheet","AppBar","ArcGauge","AutoComplete","Avatar","Badge","Barcode","BottomNavigation","Breadcrumb","BulletChart","Button","ButtonGroup","Calendar","Captcha","Card","Chart","ChartWizard","Chat","CheckBoxGroup","Checkbox","Chip","ChipList","CircularGauge","CircularProgressBar","Collapsible","ColorGradient","ColorPalette","ColorPicker","ComboBox","ContextMenu","DataSource","DatePicker","DateInput","DateRangePicker","DateTimePicker","Diagram","Dialog","DockManager","DragandDrop","Drawer","DrawingAPI","DropDownButton","DropDownList","DropDownTree","Editor","Effects","ExpansionPanel","FileManager","Filter","FlatColorPicker","FloatingActionButton","Form","Gantt","Globalization","Grid","Heatmap","HierarchicalDataSource","ImageEditor","InlineAIPrompt","Licensing","LinearGauge","ListBox","ListView","Loader","MVVM","Map","MaskedTextBox","MediaPlayer","Menu","MultiColumnComboBox","MultiSelect","MultiViewCalendar","Notification","NumericTextBox","OTP Input","OrgChart","PDFViewer","Pager","PanelBar","PivotGrid","PivotGridV2","Popover","Popup","ProgressBar","PropertyGrid","QRCode","RadialGauge","RadioButton","RadioGroup","RangeSlider","Rating","ResponsivePanel","RippleContainer","SPA","Sankey","Scheduler","ScrollView","Signature","SkeletonContainer","Slider","Sortable","Sparkline","SpeechToTextButton","SplitButton","Splitter","Spreadsheet","Stepper","StockChart","Switch","TabStrip","TaskBoard","Templates","TextArea","TextBox","TileLayout","TimeDurationPicker","TimePicker","Timeline","ToggleButton","Toolbar","Tooltip","Touch","TreeList","TreeMap","TreeView","Upload","VSCodeExtension","Validator","Window","Wizard"];var C=`
- Always use let and const, never use var.
- ALWAYS follow the user's requirements exactly.
- If the user uses font icons, ensure they have called kendo.setDefaults("iconType", "font") before initializing any component, and have included the font icons CSS file.
- Never initialize a component twice on the same element.
- Pay attention when using events. Be careful not to cause an infinite loop by triggering an event that causes the same event to be triggered again.
- Minimize the usage of templates unless the user specifically requests them or if they are essential for the functionality.
`;var T=`
- Always configure the 'pageSize' property through 'dataSource.pageSize'. If no data source is provided, set it through 'pagable.pageSize'.
`;var w=`
- If the user requests CDN links without specifying a version, provide the latest version URLs:
JQuery: https://unpkg.com/jquery@latest/dist/jquery.min.js
JavaScript: https://unpkg.com/@progress/kendo-ui@latest/umd/kendo.all.min.js
CSS: https://unpkg.com/@progress/kendo-theme-bootstrap@latest/dist/bootstrap-main.css
Font Icons: https://unpkg.com/@progress/kendo-font-icons/dist/index.css
- If the user specifies a particular version, use that version in the URLs (replace @latest with @version)
- If the user already has CDN links in their code, only suggest changes if they ask for updates or if there are issues
- If the user is using npm/local installation, do not suggest CDN links unless they specifically ask to switch
`;var P=`
- Look carefully at the user's prompt and data to determine the appropriate chart type.
`;var D=`
- Use either DataSource OR direct shapes/connections arrays, never mix both approaches.
`;var _='\n- The valid BUILT-IN values for the `items.editor` property are:\n```\n"AutoComplete", "DropDownList", "ComboBox", "MultiSelect", "DropDownTree", "MultiColumnComboBox", "DateInput", "DatePicker", "DateTimePicker", "TimePicker",\nTextBox", "TextArea", "NumericTextBox", "MaskedTextBox", "RadioGroup", "CheckBoxGroup", "Switch", "Rating", "Slider", "ColorPicker", "ColorGradient",\n"ColorPalette", "FlatColorPicker", "Signature", "OTPInput", "hidden", "Editor", "Upload"\n```\n';var q={grid:T,chart:P,diagram:D,form:_},A=(e,t)=>{if(!(t.trim().length>0))return"";let n=q[e]?.trim()||"",r=n.length>0;return`
<api_context>
${t}
</api_context>
<global_instructions>
${C}
</global_instructions>
<cdn_instructions>
${w}
</cdn_instructions>
${r?`<component_instructions>
`+n+`
</component_instructions>
`:""}
<component_template_instructions>
Do not use the outdated Kendo UI template syntax (e.g., "#= data.prop #") in your examples.
Always use modern JavaScript template literals or functions for templates.
<example>
Good: template: (data) => \`data.prop\`
Bad: template: "#= data.prop #"
Good: template: function(data) { return \`data.prop\`; }
Bad: template: function(data) { return "#= data.prop #"; }
Good (no external template): function() { if (condition) { console.log(123); } }
Bad (external template): <script type="text/x-kendo-template">#if(condition) {#console.log(123)#}#</script>
</example>
</component_template_instructions>
`.trim()};import{dirname as j,join as J}from"path";import{fileURLToPath as V}from"url";import{readFileSync as O}from"node:fs";import a from"node:fs";import m from"node:path";import $ from"@grpc/proto-loader";import d from"@grpc/grpc-js";var S=["TELERIK_LICENSE","KENDO_UI_LICENSE"],b="TELERIK_LICENSE_PATH",p=(e=>(e[e.UNAUTHENTICATED=16]="UNAUTHENTICATED",e[e.RESOURCE_EXHAUSTED=8]="RESOURCE_EXHAUSTED",e[e.PERMISSION_DENIED=7]="PERMISSION_DENIED",e))(p||{}),E=!1,s=process.env.DEBUG_LOG_FILE,R=!!(s&&typeof s=="string");if(R){let e=m.resolve(s),t=m.dirname(e);if(t!=="."&&t!==process.cwd()&&!a.existsSync(t))try{a.mkdirSync(t,{recursive:!0})}catch(o){console.error("Error creating log directory:",o)}if(!a.existsSync(e))try{a.writeFileSync(e,"")}catch(o){console.error("Error creating log file:",o)}}else E=!1;E=R&&!!s&&a.existsSync(m.resolve(s));function i(...e){if(E&&s){let t=`${new Date().toISOString()}: ${e.join(" ")}
`,o=m.resolve(s);a.appendFile(o,t,n=>{n&&console.error("Error writing to log file:",n)})}}var l=process.env[b],y=process.env[S[0]]||process.env[S[1]],h=class extends Error{constructor(e){super(e),this.name="LicenseError"}};function F(){if(!l&&!y)throw new h(`No license found. Please set one of the following environment variables: ${S.join(", ")} or ${b}`);let e;if(l)try{e=O(l,"utf8"),i("License key read from file: ",l)}catch{throw new h(`Error reading license file: ${l}. Please verify the file exists and is readable.`)}return y&&(e=y,i("License key read from environment variable.")),e}var L=class{constructor(e,t){g(this,"client");g(this,"isDev");this.contextApiUrl=e,this.protoPath=t;let o=$.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"),i("Using ContextApi URl:",this.contextApiUrl);let n=d.loadPackageDefinition(o);this.client=new n.ContextQueryService(this.contextApiUrl||"contextapi.telerik.com:443",this.isDev?d.credentials.createInsecure():d.credentials.createSsl())}async query(e){let t=this.isDev?"fake_license":F(),o=new d.Metadata;if(t&&typeof t=="string"){t=t.replace(/^\uFEFF/,"");try{o.add("x-license-key",t)}catch(n){return i("Error adding license key to metadata:",n),Promise.reject(new Error(`Failed to use license key: ${n.message}`))}}return t&&typeof t=="string"&&o.add("x-license-key",t),new Promise((n,r)=>{this.client.query(e,o,(u,f)=>{u?r(u):n(f)})})}};var z=J(j(V(import.meta.url)),"../proto/service.proto"),H=new L("contextapi.telerik.com:443",z);async function N(e){return H.query(e)}import Y from"fs";import U from"path";import{fileURLToPath as W}from"url";var X=W(import.meta.url),Z=U.dirname(X),ee=U.resolve(Z,"../package.json"),te=JSON.parse(Y.readFileSync(ee,"utf-8")),B=new Q({name:"kendo-and-kendo-resources",version:te.version});B.tool("kendo_jquery_assistant",`Answers questions and retrieves documentation about ${c}.
Use this tool when the user asks about ${c} features, specific components (e.g., Grid, Chart, Editor), implementation details, or general usage.
Provide the user's detailed question as the 'query'. If the question pertains to a specific ${c} component,
specify its name in the 'component' parameter.
If the user's question pertains to or mentions icon usage in any way, such as asking about components that may contain icons (e.g., buttons) or directly about icons, set the 'queryInvolvesIcons' parameter to true.
This tool can be automatically triggered when the following phrases are detected in the user's input/prompt:
- 'kendo';
- '/kendo';
- '/kendojquery';
- '/ask_kendo';
- '/help_kendo';
- '@kendo';
- '@kendojquery';
- '@ask_kendo';
- '@help_kendo'.`,{query:x.string().describe("The query to search for."),component:x.enum(I).describe("The component to search for. If not specified, you can use General."),queryInvolvesIcons:x.boolean().optional().default(!1).describe(`Set to true if the query pertains to or mentions icon usage in any way, such as asking about components that may contain icons (e.g., buttons) or directly about icons.
This influences the allowed types in the API call to include icon-related content.`)},async({query:e,component:t,queryInvolvesIcons:o})=>{i("Calling tool: ",JSON.stringify({query:e,component:t}));let n=t.toLocaleLowerCase();try{let r=await N({query:e,component:n,lib_name:k,text_matches_count:3,code_matches_count:0,allowed_types:o?["documentation","icons"]:["documentation"]}),u=r.values.join(`
`),f=A(n,u);i("Response from context API: ",JSON.stringify(r));let v=[{type:"text",text:f}];return i("Response from tool: ",JSON.stringify(v)),{content:v}}catch(r){throw i("Error calling context API: ",JSON.stringify(r)),r?.code===p.UNAUTHENTICATED?new Error("Error: You are not authenticated. Please verify the Telerik License Key provided is valid."):r?.code===p.RESOURCE_EXHAUSTED?new Error(`Error: You have exceeded the extension quota. Upgrade to subscription licensing in order to unlock full access. Message: ${r.message}.`):r?.code===p.PERMISSION_DENIED?new Error(`Error: You do not have permission to access this resource. Please verify that you have a valid ${c} license key.`):r instanceof h?(i("License error: ",r.message),r):new Error(`Error: An error occurred while calling the service. Please try again later.
Error Message: ${r.message}`)}});async function oe(){let e=new K;i("Starting server..."),await B.connect(e)}oe();