We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Midhun-edv/magento-coding-standard-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
/**
* Luma/Blank Theme Coding Standards Preset
* Technology: jQuery + RequireJS/AMD + KnockoutJS + LESS
* This is the default Magento 2 frontend stack.
* Reference: https://devdocs.magento.com/guides/v2.4/frontend-dev-guide/
*/
import { ThemeStandard } from '../types.js';
export const LUMA_THEME: ThemeStandard = {
id: 'luma',
name: 'Luma/Blank Theme',
version: '1.0.0',
description: 'Standards for the default Magento 2 Luma/Blank theme using jQuery, RequireJS, KnockoutJS, and LESS. This is the standard Magento frontend stack.',
technologies: {
use: [
'RequireJS (define(), require()) for module loading',
'jQuery and jQuery UI widgets ($.widget())',
'KnockoutJS (data-bind, ko.observable, uiComponent)',
'LESS preprocessor with Magento UI Library',
'data-mage-init for JS initialization',
'x-magento-init for deferred JS initialization',
'Magento UI Components (uiComponent, uiElement, uiCollection)',
'Magento_Ui/js/model/* and Magento_Ui/js/view/*',
'text! and domReady! RequireJS plugins',
'$block->getData("viewModel") for ViewModel access',
],
avoid: [
'Global variables (window.myVar)',
'Inline <script> tags without data-mage-init or x-magento-init',
'ES modules (import/export) in frontend JS',
'Direct DOM manipulation without jQuery',
'Alpine.js directives (x-data, x-show, x-on)',
'TailwindCSS utility classes',
'Modifying core Magento JS files directly',
],
},
validationRules: [
{
pattern: '\\bwindow\\.\\w+\\s*=',
fileTypes: ['js'],
severity: 7,
type: 'warning',
message: 'Global variable assignment detected. In Luma, use RequireJS modules to avoid polluting the global scope.',
rule: 'Luma.JS.NoGlobalVars',
suggestion: 'Wrap code in a define() or require() block. Return values from define() modules instead of assigning to window.',
mode: 'discourage',
},
{
pattern: '<script(?!\\s+type=["\']text/x-magento)',
fileTypes: ['phtml'],
severity: 7,
type: 'warning',
message: 'Inline <script> tag detected. In Luma, use data-mage-init or x-magento-init for JavaScript initialization.',
rule: 'Luma.Template.NoInlineScript',
suggestion: 'Use data-mage-init=\'{"Component": {"config": "value"}}\' on elements, or <script type="text/x-magento-init"> for deferred init.',
mode: 'discourage',
},
{
pattern: '\\bimport\\s+.*\\bfrom\\s+["\']|\\bexport\\s+(default|const|function|class)',
fileTypes: ['js'],
severity: 7,
type: 'warning',
message: 'ES module syntax detected. Luma uses RequireJS (AMD) for module loading, not ES modules.',
rule: 'Luma.JS.NoESModules',
suggestion: 'Use define([\'deps\'], function(deps) { ... }) for modules and require([\'deps\'], function(deps) { ... }) for entry points.',
mode: 'discourage',
},
{
pattern: 'x-data\\s*=|x-show\\s*=|x-on:|@click\\s*=',
fileTypes: ['phtml'],
severity: 6,
type: 'warning',
message: 'Alpine.js directives detected. Luma does not include Alpine.js. Use KnockoutJS data-bind or jQuery for interactivity.',
rule: 'Luma.Template.NoAlpineJS',
suggestion: 'Use data-bind="visible: isVisible" for show/hide, data-bind="click: handleClick" for events, or $.widget() for complex interactions.',
mode: 'discourage',
},
],
patternOverrides: [
{
taskKeyword: 'requirejs module',
correctPattern: 'Use define() with dependency array (AMD format)',
example: `// Luma: RequireJS AMD module
// File: app/code/Vendor/Module/view/frontend/web/js/my-component.js
define([
'jquery',
'mage/translate',
'domReady!'
], function ($, $t) {
'use strict';
return function (config, element) {
var $element = $(element);
$element.on('click', '.action-button', function () {
// Handle click
$(this).text($t('Clicked!'));
});
};
});
// Usage in phtml template:
// <div data-mage-init='{"Vendor_Module/js/my-component": {"option": "value"}}'>`,
avoidPatterns: [
{ pattern: 'import/export (ES modules)', reason: 'Luma uses RequireJS AMD format, not ES modules' },
{ pattern: 'window.myFunction()', reason: 'Never use global variables; use RequireJS modules' },
],
explanation: 'Luma uses RequireJS for all JavaScript module loading. Modules use the AMD define() format with dependency arrays. Initialize components using data-mage-init or x-magento-init.',
},
{
taskKeyword: 'jquery widget',
correctPattern: 'Use $.widget() factory with _create, _init, and _destroy methods',
example: `// Luma: jQuery Widget
// File: app/code/Vendor/Module/view/frontend/web/js/my-widget.js
define([
'jquery',
'jquery-ui-modules/widget',
'mage/translate'
], function ($, widget, $t) {
'use strict';
$.widget('vendor.myWidget', {
options: {
selector: '.item',
activeClass: 'active',
url: null
},
_create: function () {
this._bind();
},
_bind: function () {
this._on({
'click [data-action="toggle"]': '_onToggle',
'keydown [data-action="toggle"]': '_onKeyDown'
});
},
_onToggle: function (event) {
event.preventDefault();
$(event.currentTarget)
.closest(this.options.selector)
.toggleClass(this.options.activeClass);
},
_onKeyDown: function (event) {
if (event.keyCode === 13 || event.keyCode === 32) {
this._onToggle(event);
}
},
_destroy: function () {
this.element.find(this.options.selector)
.removeClass(this.options.activeClass);
}
});
return $.vendor.myWidget;
});
// Usage in phtml:
// <div data-mage-init='{"Vendor_Module/js/my-widget": {"selector": ".item"}}'>`,
avoidPatterns: [
{ pattern: 'Alpine.data()', reason: 'Alpine.js is not available in Luma' },
{ pattern: 'Vanilla JS class', reason: 'Luma convention uses $.widget() factory for reusable components' },
],
explanation: 'Luma uses the jQuery Widget Factory for reusable, configurable, and destroyable components. Widgets extend $.Widget and use options, _create(), _bind(), and event delegation via _on().',
},
{
taskKeyword: 'ui component',
correctPattern: 'Extend uiComponent with KnockoutJS observables and templates',
example: `// Luma: Magento UI Component
// File: app/code/Vendor/Module/view/frontend/web/js/view/my-component.js
define([
'uiComponent',
'ko',
'mage/translate'
], function (Component, ko, $t) {
'use strict';
return Component.extend({
defaults: {
template: 'Vendor_Module/my-component',
items: [],
isLoading: true
},
initialize: function () {
this._super();
this.items = ko.observableArray([]);
this.isLoading = ko.observable(true);
this.loadItems();
return this;
},
loadItems: function () {
// Use Magento's storage or AJAX
var self = this;
$.ajax({
url: this.apiUrl,
type: 'GET',
dataType: 'json'
}).done(function (response) {
self.items(response);
self.isLoading(false);
});
},
getItemCount: function () {
return this.items().length;
}
});
});
// KnockoutJS HTML template:
// File: app/code/Vendor/Module/view/frontend/web/template/my-component.html
// <div class="my-component" data-bind="visible: !isLoading()">
// <ul data-bind="foreach: items">
// <li data-bind="text: name"></li>
// </ul>
// </div>`,
avoidPatterns: [
{ pattern: 'React/Vue/Alpine components', reason: 'Luma uses KnockoutJS + uiComponent framework' },
],
explanation: 'Magento UI Components extend uiComponent (Magento_Ui/js/lib/core/element/element). They use KnockoutJS observables for reactivity and .html template files for rendering. Configure via layout XML with <item name="component" .../>.',
},
{
taskKeyword: 'template structure',
correctPattern: 'Use $block, $escaper, data-mage-init, LESS for styling',
example: `<?php
declare(strict_types=1);
use Magento\\Framework\\Escaper;
use Magento\\Framework\\View\\Element\\Template;
/** @var Template $block */
/** @var Escaper $escaper */
$viewModel = $block->getData('viewModel');
?>
<div class="my-component" data-mage-init='{"Vendor_Module/js/my-component": {}}'>
<h2 class="my-component-title">
<?= $escaper->escapeHtml($viewModel->getTitle()) ?>
</h2>
<?php if ($viewModel->hasItems()): ?>
<ul class="my-component-list">
<?php foreach ($viewModel->getItems() as $item): ?>
<li class="my-component-item">
<a href="<?= $escaper->escapeUrl($item->getUrl()) ?>"
class="my-component-link">
<?= $escaper->escapeHtml($item->getName()) ?>
</a>
</li>
<?php endforeach; ?>
</ul>
<?php else: ?>
<p class="my-component-empty">
<?= $escaper->escapeHtml(__('No items found.')) ?>
</p>
<?php endif; ?>
</div>`,
avoidPatterns: [
{ pattern: 'TailwindCSS classes (p-4, flex, etc.)', reason: 'Luma uses LESS with BEM-style class names' },
{ pattern: '$viewModels->require()', reason: 'Luma uses $block->getData("viewModel") for ViewModel access' },
],
explanation: 'Luma templates use $block and $escaper for data and security, data-mage-init for JS initialization, and BEM-style CSS class names styled via LESS. ViewModels are accessed through $block->getData("viewModel") after being configured in layout XML.',
},
{
taskKeyword: 'less css',
correctPattern: 'Use LESS with Magento UI Library variables and mixins',
example: `// Luma: LESS Styling
// File: app/code/Vendor/Module/view/frontend/web/css/source/_module.less
// Import Magento UI Library variables
@import 'source/_variables.less';
// Use Magento UI Library variables
.my-component {
.lib-css(background-color, @color-white);
.lib-css(padding, @indent__base);
.lib-css(margin-bottom, @indent__l);
&-title {
.lib-font-size(20);
.lib-css(color, @text__color);
.lib-css(font-weight, @font-weight__bold);
.lib-css(margin-bottom, @indent__s);
}
&-list {
.lib-list-reset-styles();
}
&-item {
.lib-css(padding, @indent__xs 0);
border-bottom: 1px solid @border-color__base;
&:last-child {
border-bottom: none;
}
}
&-link {
.lib-link();
}
&-empty {
.lib-css(color, @color-gray60);
.lib-css(font-style, italic);
}
}
// Responsive
.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) {
.my-component {
.lib-css(padding, @indent__s);
}
}`,
avoidPatterns: [
{ pattern: 'Inline styles', reason: 'Use LESS with Magento UI Library' },
{ pattern: '@apply (TailwindCSS)', reason: 'Luma uses LESS, not TailwindCSS' },
],
explanation: 'Luma uses LESS with the Magento UI Library. Use .lib-css() mixins for theme-aware properties, @variables for consistent spacing/colors, and the responsive .media-width() mixin for breakpoints.',
},
],
bestPractices: [
'Always use declare(strict_types=1) at the top of phtml files',
'Use RequireJS define() for all JS modules — never use global variables',
'Use $.widget() for reusable interactive components',
'Initialize JS via data-mage-init or x-magento-init, never inline <script> tags',
'Use KnockoutJS data-bind for dynamic UI bindings in templates',
'Extend uiComponent for complex components with templates',
'Use LESS with Magento UI Library variables (@indent__base, @color-white, etc.)',
'Follow BEM naming convention for CSS classes (block__element--modifier)',
'Use .lib-css() mixins for theme-aware CSS properties',
'Access ViewModels via $block->getData("viewModel") configured in layout XML',
'Use $escaper->escapeHtml(), escapeUrl(), escapeJs() for all output',
'Use mage/translate ($t()) for all translatable strings in JS',
'Prefer jQuery event delegation via _on() in widgets over direct binding',
'Use requirejs-config.js for module aliases and mixins',
],
};