@loggi87/mcp-custom-xs 1.0.0 → 1.0.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.
- package/README.md +365 -0
- package/index.js +131 -43
- package/package.json +7 -3
package/README.md
ADDED
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
# mcp-custom-xs
|
|
2
|
+
|
|
3
|
+
**MCP Server con reglas de código compartidas para proyectos React + TypeScript.**
|
|
4
|
+
|
|
5
|
+
Un paquete de reglas y estándares que puedes usar en tus proyectos para mantener calidad, consistencia y arquitectura limpia.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 📋 ¿Qué incluye?
|
|
10
|
+
|
|
11
|
+
- ✅ **Max 80 líneas por archivo** - Mantén archivos pequeños y legibles
|
|
12
|
+
- ✅ **Atomic Design** - Estructura de componentes: atoms → molecules → organisms
|
|
13
|
+
- ✅ **Feature-based** - Organiza por features, no por tipo
|
|
14
|
+
- ✅ **TypeScript Strict** - Type safety total
|
|
15
|
+
- ✅ **Validación automática** - Valida tus archivos contra las reglas
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 🚀 Instalación
|
|
20
|
+
|
|
21
|
+
### 1. Instalar el paquete
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @loggi87/mcp-custom-xs
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### 2. Opción A: Usar en Claude.ai (recomendado para desarrollo)
|
|
28
|
+
|
|
29
|
+
Agrega las reglas a tus **Custom Instructions** en Claude.ai:
|
|
30
|
+
|
|
31
|
+
**Settings → Custom Instructions → Instructions**
|
|
32
|
+
|
|
33
|
+
````
|
|
34
|
+
# MCP Code Rules (@loggi87/mcp-custom-xs)
|
|
35
|
+
|
|
36
|
+
## Reglas obligatorias para TODOS los features:
|
|
37
|
+
|
|
38
|
+
1. **Max 80 líneas por archivo**
|
|
39
|
+
- Si necesitas más, divide en múltiples archivos
|
|
40
|
+
- Excepciones documentadas requieren comentario // LONG_FILE
|
|
41
|
+
|
|
42
|
+
2. **Atomic Design para componentes**
|
|
43
|
+
```
|
|
44
|
+
src/components/
|
|
45
|
+
├── atoms/ (botones, inputs, etiquetas)
|
|
46
|
+
├── molecules/ (formularios simples, tarjetas)
|
|
47
|
+
└── organisms/ (modales, headers complejos)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
3. **Feature-based structure**
|
|
51
|
+
```
|
|
52
|
+
src/features/{featureName}/
|
|
53
|
+
├── components/ (atoms, molecules, organisms)
|
|
54
|
+
├── hooks/
|
|
55
|
+
├── services/
|
|
56
|
+
├── types/
|
|
57
|
+
└── index.ts
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
4. **TypeScript Strict Mode**
|
|
61
|
+
- \`tsconfig.json\`: \`"strict": true\`
|
|
62
|
+
- No usar \`any\`
|
|
63
|
+
- Tipear siempre argumentos y retornos
|
|
64
|
+
|
|
65
|
+
5. **Validar con tsc ANTES de terminar**
|
|
66
|
+
```bash
|
|
67
|
+
tsc --noEmit
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Cuando generes código:
|
|
71
|
+
1. Crea los archivos respetando estas reglas
|
|
72
|
+
2. Muestra la estructura antes del código
|
|
73
|
+
3. Al final, ejecuta \`tsc --noEmit\`
|
|
74
|
+
4. Si hay errores de tipos, arréglalos
|
|
75
|
+
5. Reporta: ✅ Validado o ❌ Errores encontrados
|
|
76
|
+
|
|
77
|
+
## Ejemplo de request:
|
|
78
|
+
"Crea el feature de AuthModal usando @loggi87/mcp-custom-xs"
|
|
79
|
+
````
|
|
80
|
+
|
|
81
|
+
**Listo.** Desde ese momento, cada código que te genere seguirá estas reglas automáticamente.
|
|
82
|
+
|
|
83
|
+
### 3. Opción B: Usar en tu proyecto (para validación programática)
|
|
84
|
+
|
|
85
|
+
```javascript
|
|
86
|
+
// En tu proyecto
|
|
87
|
+
const rules = require('@loggi87/mcp-custom-xs');
|
|
88
|
+
|
|
89
|
+
// Validar un archivo
|
|
90
|
+
const validation = rules.validateFile('./src/components/Button.tsx');
|
|
91
|
+
|
|
92
|
+
console.log(validation);
|
|
93
|
+
// {
|
|
94
|
+
// valid: true,
|
|
95
|
+
// errors: [],
|
|
96
|
+
// file: './src/components/Button.tsx',
|
|
97
|
+
// lineCount: 31
|
|
98
|
+
// }
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## 📂 Estructura recomendada
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
proyecto/
|
|
107
|
+
├── src/
|
|
108
|
+
│ ├── components/
|
|
109
|
+
│ │ ├── atoms/
|
|
110
|
+
│ │ │ ├── Button.tsx (30 líneas)
|
|
111
|
+
│ │ │ └── Input.tsx (28 líneas)
|
|
112
|
+
│ │ ├── molecules/
|
|
113
|
+
│ │ │ └── LoginForm.tsx (65 líneas)
|
|
114
|
+
│ │ └── organisms/
|
|
115
|
+
│ │ └── AuthModal.tsx (72 líneas)
|
|
116
|
+
│ ├── features/
|
|
117
|
+
│ │ ├── Auth/
|
|
118
|
+
│ │ │ ├── components/
|
|
119
|
+
│ │ │ ├── hooks/
|
|
120
|
+
│ │ │ ├── services/
|
|
121
|
+
│ │ │ ├── types/
|
|
122
|
+
│ │ │ └── index.ts
|
|
123
|
+
│ │ └── Dashboard/
|
|
124
|
+
│ │ └── ...
|
|
125
|
+
│ ├── hooks/
|
|
126
|
+
│ ├── services/
|
|
127
|
+
│ ├── types/
|
|
128
|
+
│ └── index.ts
|
|
129
|
+
├── tsconfig.json
|
|
130
|
+
├── .eslintrc.json
|
|
131
|
+
└── package.json
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 🔧 Configuración recomendada
|
|
137
|
+
|
|
138
|
+
### tsconfig.json
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"compilerOptions": {
|
|
143
|
+
"strict": true,
|
|
144
|
+
"esModuleInterop": true,
|
|
145
|
+
"skipLibCheck": true,
|
|
146
|
+
"forceConsistentCasingInFileNames": true,
|
|
147
|
+
"resolveJsonModule": true,
|
|
148
|
+
"moduleResolution": "node",
|
|
149
|
+
"target": "ES2020",
|
|
150
|
+
"module": "ESNext",
|
|
151
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"]
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### .eslintrc.json
|
|
157
|
+
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
|
161
|
+
"parser": "@typescript-eslint/parser",
|
|
162
|
+
"rules": {
|
|
163
|
+
"max-lines": ["error", { "max": 80 }],
|
|
164
|
+
"@typescript-eslint/no-explicit-any": "error",
|
|
165
|
+
"no-unused-vars": "warn"
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## 💡 Ejemplos
|
|
173
|
+
|
|
174
|
+
### ✅ Buen componente (respeta las reglas)
|
|
175
|
+
|
|
176
|
+
**src/components/atoms/Button.tsx**
|
|
177
|
+
```typescript
|
|
178
|
+
import React from 'react';
|
|
179
|
+
|
|
180
|
+
interface ButtonProps {
|
|
181
|
+
label: string;
|
|
182
|
+
onClick: () => void;
|
|
183
|
+
variant?: 'primary' | 'secondary';
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export const Button: React.FC<ButtonProps> = ({
|
|
187
|
+
label,
|
|
188
|
+
onClick,
|
|
189
|
+
variant = 'primary',
|
|
190
|
+
}) => {
|
|
191
|
+
const baseStyle = 'px-4 py-2 rounded font-semibold';
|
|
192
|
+
const variantStyle =
|
|
193
|
+
variant === 'primary'
|
|
194
|
+
? 'bg-blue-500 text-white'
|
|
195
|
+
: 'bg-gray-200 text-black';
|
|
196
|
+
|
|
197
|
+
return (
|
|
198
|
+
<button
|
|
199
|
+
className={\`\${baseStyle} \${variantStyle}\`}
|
|
200
|
+
onClick={onClick}
|
|
201
|
+
>
|
|
202
|
+
{label}
|
|
203
|
+
</button>
|
|
204
|
+
);
|
|
205
|
+
};
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Cumple:**
|
|
209
|
+
- ✅ 31 líneas (< 80)
|
|
210
|
+
- ✅ En \`atoms/\` (Atomic Design)
|
|
211
|
+
- ✅ TypeScript tipado correctamente
|
|
212
|
+
- ✅ Componente simple y reutilizable
|
|
213
|
+
|
|
214
|
+
### ❌ Mal componente (no respeta reglas)
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
// ❌ 120 líneas (> 80)
|
|
218
|
+
// ❌ Lógica compleja + UI mezcladas
|
|
219
|
+
// ❌ No está en estructura atómica
|
|
220
|
+
// ❌ any types
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## 🤝 Mejoras y contribuciones
|
|
226
|
+
|
|
227
|
+
¿Querés mejorar las reglas? ¡Excelente!
|
|
228
|
+
|
|
229
|
+
1. **Fork el repo**
|
|
230
|
+
2. **Crea una rama** (\`git checkout -b feature/nueva-regla\`)
|
|
231
|
+
3. **Modifica \`index.js\`**
|
|
232
|
+
4. **Testea** (\`npm test\`)
|
|
233
|
+
5. **Haz PR** con descripción clara
|
|
234
|
+
|
|
235
|
+
### Cambios comunes que podrías hacer:
|
|
236
|
+
|
|
237
|
+
```javascript
|
|
238
|
+
// En index.js, puedes agregar:
|
|
239
|
+
|
|
240
|
+
// - Cambiar límite de líneas
|
|
241
|
+
max_lines_per_file: 100, // Era 80
|
|
242
|
+
|
|
243
|
+
// - Agregar nuevas validaciones
|
|
244
|
+
no_console_logs: true,
|
|
245
|
+
|
|
246
|
+
// - Permitir excepciones
|
|
247
|
+
exceptions: {
|
|
248
|
+
"src/utils/constants.ts": { max_lines: 200 }
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## 📦 Cómo se usa en un proyecto real
|
|
255
|
+
|
|
256
|
+
### Paso 1: Instalar
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
npm install @loggi87/mcp-custom-xs
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Paso 2: Agregar a Claude Custom Instructions
|
|
263
|
+
|
|
264
|
+
Copia el contenido arriba y pégalo en Claude.ai Settings.
|
|
265
|
+
|
|
266
|
+
### Paso 3: Pedir features
|
|
267
|
+
|
|
268
|
+
```
|
|
269
|
+
"Crea el feature de LoginForm con:
|
|
270
|
+
- Validación de email
|
|
271
|
+
- Password con toggle visibility
|
|
272
|
+
- Remember me checkbox
|
|
273
|
+
|
|
274
|
+
Usa @loggi87/mcp-custom-xs"
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Claude automáticamente:
|
|
278
|
+
- ✅ Divide en atoms/molecules si es necesario
|
|
279
|
+
- ✅ Mantiene archivos < 80 líneas
|
|
280
|
+
- ✅ Usa TypeScript strict
|
|
281
|
+
- ✅ Corre \`tsc --noEmit\`
|
|
282
|
+
- ✅ Reporta si todo está ✅
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## 📋 API
|
|
287
|
+
|
|
288
|
+
### \`rules\`
|
|
289
|
+
|
|
290
|
+
Objeto con todas las reglas definidas:
|
|
291
|
+
|
|
292
|
+
```javascript
|
|
293
|
+
const { rules } = require('@loggi87/mcp-custom-xs');
|
|
294
|
+
|
|
295
|
+
console.log(rules);
|
|
296
|
+
// {
|
|
297
|
+
// max_lines_per_file: 80,
|
|
298
|
+
// architecture: 'atomic',
|
|
299
|
+
// project_structure: 'feature-based',
|
|
300
|
+
// typescript_strict: true,
|
|
301
|
+
// run_tsc_before_finish: true
|
|
302
|
+
// }
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### \`validateFile(filePath)\`
|
|
306
|
+
|
|
307
|
+
Valida un archivo contra las reglas:
|
|
308
|
+
|
|
309
|
+
```javascript
|
|
310
|
+
const { validateFile } = require('@loggi87/mcp-custom-xs');
|
|
311
|
+
|
|
312
|
+
const result = validateFile('./src/components/atoms/Button.tsx');
|
|
313
|
+
|
|
314
|
+
console.log(result);
|
|
315
|
+
// {
|
|
316
|
+
// valid: true,
|
|
317
|
+
// errors: [],
|
|
318
|
+
// file: './src/components/atoms/Button.tsx',
|
|
319
|
+
// lineCount: 31
|
|
320
|
+
// }
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## 🐛 Troubleshooting
|
|
326
|
+
|
|
327
|
+
### "Cannot find module '@loggi87/mcp-custom-xs'"
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
npm install @loggi87/mcp-custom-xs
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### "TypeScript errors después de instalar"
|
|
334
|
+
|
|
335
|
+
Verifica que \`tsconfig.json\` tiene \`"strict": true\`
|
|
336
|
+
|
|
337
|
+
### "Claude no sigue las reglas"
|
|
338
|
+
|
|
339
|
+
1. Verifica que copiaste las Custom Instructions correctamente
|
|
340
|
+
2. Pide explícitamente: "usa @loggi87/mcp-custom-xs"
|
|
341
|
+
3. Si no funciona, menciona las reglas en el mensaje
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## 📞 Contacto
|
|
346
|
+
|
|
347
|
+
¿Preguntas, bugs, o mejoras?
|
|
348
|
+
|
|
349
|
+
- **Issues**: Abre un issue en GitHub
|
|
350
|
+
- **Mejoras**: Haz un PR
|
|
351
|
+
- **Contacto directo**: [@loggi87](https://github.com/loggi87)
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## 📄 Licencia
|
|
356
|
+
|
|
357
|
+
MIT - Úsalo libremente en tus proyectos
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## Versión
|
|
362
|
+
|
|
363
|
+
**@loggi87/mcp-custom-xs@1.0.0**
|
|
364
|
+
|
|
365
|
+
Última actualización: Marzo 2026
|
package/index.js
CHANGED
|
@@ -1,56 +1,144 @@
|
|
|
1
|
-
// index.js - MCP Server
|
|
1
|
+
// index.js - MCP Server (@loggi87/mcp-custom-xs)
|
|
2
|
+
const { McpServer } = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
3
|
+
const { StdioServerTransport } = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
4
|
+
const { z } = require("zod");
|
|
2
5
|
const fs = require("fs");
|
|
6
|
+
const path = require("path");
|
|
3
7
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
const RULES = {
|
|
9
|
+
max_lines_per_file: 80,
|
|
10
|
+
architecture: "atomic",
|
|
11
|
+
project_structure: "feature-based",
|
|
12
|
+
typescript_strict: true,
|
|
13
|
+
run_tsc_before_finish: true
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
function validateFile(filePath) {
|
|
17
|
+
try {
|
|
18
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
19
|
+
const lines = content.split("\n").length;
|
|
20
|
+
const errors = [];
|
|
21
|
+
|
|
22
|
+
if (lines > RULES.max_lines_per_file) {
|
|
23
|
+
errors.push({
|
|
24
|
+
type: "TOO_MANY_LINES",
|
|
25
|
+
message: `❌ ${lines} líneas (máx ${RULES.max_lines_per_file})`,
|
|
26
|
+
severity: "error"
|
|
27
|
+
});
|
|
13
28
|
}
|
|
14
29
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
30
|
+
if (filePath.endsWith(".ts") || filePath.endsWith(".tsx")) {
|
|
31
|
+
if (!content.includes("// @ts-check") && !content.includes("strict")) {
|
|
32
|
+
errors.push({
|
|
33
|
+
type: "NO_TYPESCRIPT_STRICT",
|
|
34
|
+
message: "❌ Falta TypeScript strict mode",
|
|
35
|
+
severity: "warn",
|
|
36
|
+
suggestion: "Agrega 'strict': true en tsconfig.json"
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
19
40
|
|
|
20
|
-
|
|
41
|
+
if (filePath.includes("components")) {
|
|
42
|
+
const validDirs = ["/atoms/", "/molecules/", "/organisms/"];
|
|
43
|
+
if (!validDirs.some((dir) => filePath.includes(dir))) {
|
|
44
|
+
errors.push({
|
|
45
|
+
type: "WRONG_COMPONENT_STRUCTURE",
|
|
46
|
+
message: "❌ Componente no está en atoms/molecules/organisms",
|
|
47
|
+
severity: "error",
|
|
48
|
+
suggestion: "Estructura correcta: src/components/{atoms|molecules|organisms}/"
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
21
52
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
53
|
+
return {
|
|
54
|
+
valid: errors.length === 0,
|
|
55
|
+
file: filePath,
|
|
56
|
+
lineCount: lines,
|
|
57
|
+
errors,
|
|
58
|
+
summary: errors.length === 0
|
|
59
|
+
? "✅ Archivo válido"
|
|
60
|
+
: `❌ ${errors.length} error(es) encontrado(s)`
|
|
61
|
+
};
|
|
62
|
+
} catch (error) {
|
|
63
|
+
return {
|
|
64
|
+
valid: false,
|
|
65
|
+
file: filePath,
|
|
66
|
+
errors: [{ type: "FILE_READ_ERROR", message: error.message, severity: "error" }]
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
26
70
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
errors.push("❌ Falta // @ts-check para TypeScript strict");
|
|
30
|
-
}
|
|
71
|
+
function validateFeature(featureDir) {
|
|
72
|
+
const results = [];
|
|
31
73
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
74
|
+
const walkDir = (dir) => {
|
|
75
|
+
try {
|
|
76
|
+
fs.readdirSync(dir).forEach((file) => {
|
|
77
|
+
const filePath = path.join(dir, file);
|
|
78
|
+
const stat = fs.statSync(filePath);
|
|
79
|
+
if (stat.isDirectory() && !file.startsWith(".")) {
|
|
80
|
+
walkDir(filePath);
|
|
81
|
+
} else if (/\.(ts|tsx|js)$/.test(file)) {
|
|
82
|
+
results.push(validateFile(filePath));
|
|
38
83
|
}
|
|
84
|
+
});
|
|
85
|
+
} catch (e) {}
|
|
86
|
+
};
|
|
39
87
|
|
|
40
|
-
|
|
41
|
-
valid: errors.length === 0,
|
|
42
|
-
errors,
|
|
43
|
-
suggestions: this.getSuggestions(errors)
|
|
44
|
-
};
|
|
45
|
-
}
|
|
88
|
+
walkDir(featureDir);
|
|
46
89
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
90
|
+
const totalErrors = results.reduce((sum, r) => sum + r.errors.length, 0);
|
|
91
|
+
return {
|
|
92
|
+
valid: totalErrors === 0,
|
|
93
|
+
featureDir,
|
|
94
|
+
filesValidated: results.length,
|
|
95
|
+
totalErrors,
|
|
96
|
+
files: results,
|
|
97
|
+
summary: totalErrors === 0
|
|
98
|
+
? `✅ Feature válido (${results.length} archivos)`
|
|
99
|
+
: `❌ ${totalErrors} error(es) en ${results.length} archivo(s)`
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function getFormattedRules() {
|
|
104
|
+
return `# Reglas del proyecto (@loggi87/mcp-custom-xs)
|
|
105
|
+
|
|
106
|
+
1. **Max ${RULES.max_lines_per_file} líneas por archivo**
|
|
107
|
+
2. **Atomic Design** para componentes (atoms / molecules / organisms)
|
|
108
|
+
3. **Feature-based** project structure
|
|
109
|
+
4. **TypeScript Strict Mode**
|
|
110
|
+
5. **Ejecutar tsc** antes de terminar cualquier tarea`;
|
|
54
111
|
}
|
|
55
112
|
|
|
56
|
-
|
|
113
|
+
// Servidor MCP
|
|
114
|
+
const server = new McpServer({ name: "mcp-custom-xs", version: "1.0.3" });
|
|
115
|
+
|
|
116
|
+
server.tool(
|
|
117
|
+
"validate_file",
|
|
118
|
+
"Valida un archivo contra las reglas del proyecto (líneas, atomic design, TypeScript)",
|
|
119
|
+
{ filePath: z.string().describe("Ruta absoluta o relativa al archivo a validar") },
|
|
120
|
+
async ({ filePath }) => ({
|
|
121
|
+
content: [{ type: "text", text: JSON.stringify(validateFile(filePath), null, 2) }]
|
|
122
|
+
})
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
server.tool(
|
|
126
|
+
"validate_feature",
|
|
127
|
+
"Valida todos los archivos de un directorio/feature contra las reglas del proyecto",
|
|
128
|
+
{ featureDir: z.string().describe("Ruta al directorio del feature a validar") },
|
|
129
|
+
async ({ featureDir }) => ({
|
|
130
|
+
content: [{ type: "text", text: JSON.stringify(validateFeature(featureDir), null, 2) }]
|
|
131
|
+
})
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
server.tool(
|
|
135
|
+
"get_rules",
|
|
136
|
+
"Devuelve las reglas de código del proyecto",
|
|
137
|
+
{},
|
|
138
|
+
async () => ({
|
|
139
|
+
content: [{ type: "text", text: getFormattedRules() }]
|
|
140
|
+
})
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
const transport = new StdioServerTransport();
|
|
144
|
+
server.connect(transport);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loggi87/mcp-custom-xs",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -10,5 +10,9 @@
|
|
|
10
10
|
"mcp",
|
|
11
11
|
"rules",
|
|
12
12
|
"atomic-design"
|
|
13
|
-
]
|
|
14
|
-
|
|
13
|
+
],
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@modelcontextprotocol/sdk": "^1.28.0",
|
|
16
|
+
"zod": "^4.3.6"
|
|
17
|
+
}
|
|
18
|
+
}
|