it-tools-mcp 3.0.0
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/LICENSE +21 -0
- package/README.dockerhub.md +98 -0
- package/README.md +263 -0
- package/build/index.js +75 -0
- package/build/security.js +201 -0
- package/build/tools/color.js +67 -0
- package/build/tools/crypto.js +445 -0
- package/build/tools/dataFormat.js +517 -0
- package/build/tools/development.js +267 -0
- package/build/tools/encoding.js +240 -0
- package/build/tools/idGenerators.js +176 -0
- package/build/tools/math.js +306 -0
- package/build/tools/network.js +578 -0
- package/build/tools/text.js +678 -0
- package/build/tools/utility.js +407 -0
- package/package.json +94 -0
|
@@ -0,0 +1,678 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerTextTools(server) {
|
|
3
|
+
// Text case conversion tools
|
|
4
|
+
server.tool("text-uppercase", "Convert text to uppercase", {
|
|
5
|
+
text: z.string().describe("Text to convert to uppercase"),
|
|
6
|
+
}, async ({ text }) => {
|
|
7
|
+
return {
|
|
8
|
+
content: [
|
|
9
|
+
{
|
|
10
|
+
type: "text",
|
|
11
|
+
text: `Uppercase: ${text.toUpperCase()}`,
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
};
|
|
15
|
+
});
|
|
16
|
+
server.tool("text-lowercase", "Convert text to lowercase", {
|
|
17
|
+
text: z.string().describe("Text to convert to lowercase"),
|
|
18
|
+
}, async ({ text }) => {
|
|
19
|
+
return {
|
|
20
|
+
content: [
|
|
21
|
+
{
|
|
22
|
+
type: "text",
|
|
23
|
+
text: `Lowercase: ${text.toLowerCase()}`,
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
server.tool("text-capitalize", "Capitalize first letter of each word", {
|
|
29
|
+
text: z.string().describe("Text to capitalize"),
|
|
30
|
+
}, async ({ text }) => {
|
|
31
|
+
const capitalized = text.replace(/\b\w/g, l => l.toUpperCase());
|
|
32
|
+
return {
|
|
33
|
+
content: [
|
|
34
|
+
{
|
|
35
|
+
type: "text",
|
|
36
|
+
text: `Capitalized: ${capitalized}`,
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
server.tool("text-camelcase", "Convert text to camelCase", {
|
|
42
|
+
text: z.string().describe("Text to convert to camelCase"),
|
|
43
|
+
}, async ({ text }) => {
|
|
44
|
+
const camelCase = text
|
|
45
|
+
.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => {
|
|
46
|
+
return index === 0 ? word.toLowerCase() : word.toUpperCase();
|
|
47
|
+
})
|
|
48
|
+
.replace(/\s+/g, '');
|
|
49
|
+
return {
|
|
50
|
+
content: [
|
|
51
|
+
{
|
|
52
|
+
type: "text",
|
|
53
|
+
text: `camelCase: ${camelCase}`,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
server.tool("text-pascalcase", "Convert text to PascalCase", {
|
|
59
|
+
text: z.string().describe("Text to convert to PascalCase"),
|
|
60
|
+
}, async ({ text }) => {
|
|
61
|
+
const pascalCase = text
|
|
62
|
+
.replace(/(?:^\w|[A-Z]|\b\w)/g, word => word.toUpperCase())
|
|
63
|
+
.replace(/\s+/g, '');
|
|
64
|
+
return {
|
|
65
|
+
content: [
|
|
66
|
+
{
|
|
67
|
+
type: "text",
|
|
68
|
+
text: `PascalCase: ${pascalCase}`,
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
server.tool("text-kebabcase", "Convert text to kebab-case", {
|
|
74
|
+
text: z.string().describe("Text to convert to kebab-case"),
|
|
75
|
+
}, async ({ text }) => {
|
|
76
|
+
const kebabCase = text
|
|
77
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
78
|
+
.replace(/[^a-zA-Z0-9]+/g, '-')
|
|
79
|
+
.toLowerCase()
|
|
80
|
+
.replace(/^-+|-+$/g, '');
|
|
81
|
+
return {
|
|
82
|
+
content: [
|
|
83
|
+
{
|
|
84
|
+
type: "text",
|
|
85
|
+
text: `kebab-case: ${kebabCase}`,
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
};
|
|
89
|
+
});
|
|
90
|
+
server.tool("text-snakecase", "Convert text to snake_case", {
|
|
91
|
+
text: z.string().describe("Text to convert to snake_case"),
|
|
92
|
+
}, async ({ text }) => {
|
|
93
|
+
const snakeCase = text
|
|
94
|
+
.replace(/([a-z])([A-Z])/g, '$1_$2')
|
|
95
|
+
.replace(/[^a-zA-Z0-9]+/g, '_')
|
|
96
|
+
.toLowerCase()
|
|
97
|
+
.replace(/^_+|_+$/g, '');
|
|
98
|
+
return {
|
|
99
|
+
content: [
|
|
100
|
+
{
|
|
101
|
+
type: "text",
|
|
102
|
+
text: `snake_case: ${snakeCase}`,
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
// Text statistics tool
|
|
108
|
+
server.tool("text-stats", "Get statistics about text (character count, word count, etc.)", {
|
|
109
|
+
text: z.string().describe("Text to analyze"),
|
|
110
|
+
}, async ({ text }) => {
|
|
111
|
+
const lines = text.split('\n');
|
|
112
|
+
const words = text.trim().split(/\s+/).filter(word => word.length > 0);
|
|
113
|
+
const characters = text.length;
|
|
114
|
+
const charactersNoSpaces = text.replace(/\s/g, '').length;
|
|
115
|
+
const paragraphs = text.split(/\n\s*\n/).filter(para => para.trim().length > 0);
|
|
116
|
+
return {
|
|
117
|
+
content: [
|
|
118
|
+
{
|
|
119
|
+
type: "text",
|
|
120
|
+
text: `Text Statistics:
|
|
121
|
+
|
|
122
|
+
Characters: ${characters}
|
|
123
|
+
Characters (no spaces): ${charactersNoSpaces}
|
|
124
|
+
Words: ${words.length}
|
|
125
|
+
Lines: ${lines.length}
|
|
126
|
+
Paragraphs: ${paragraphs.length}
|
|
127
|
+
|
|
128
|
+
Reading time: ~${Math.ceil(words.length / 200)} minutes (200 WPM)
|
|
129
|
+
Speaking time: ~${Math.ceil(words.length / 150)} minutes (150 WPM)`,
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
};
|
|
133
|
+
});
|
|
134
|
+
// Text comparison tool
|
|
135
|
+
server.tool("text-diff", "Compare two texts and show differences", {
|
|
136
|
+
text1: z.string().describe("First text to compare"),
|
|
137
|
+
text2: z.string().describe("Second text to compare"),
|
|
138
|
+
}, async ({ text1, text2 }) => {
|
|
139
|
+
try {
|
|
140
|
+
// Simple diff implementation
|
|
141
|
+
const lines1 = text1.split('\n');
|
|
142
|
+
const lines2 = text2.split('\n');
|
|
143
|
+
const maxLines = Math.max(lines1.length, lines2.length);
|
|
144
|
+
let differences = [];
|
|
145
|
+
let same = true;
|
|
146
|
+
for (let i = 0; i < maxLines; i++) {
|
|
147
|
+
const line1 = lines1[i] || '';
|
|
148
|
+
const line2 = lines2[i] || '';
|
|
149
|
+
if (line1 !== line2) {
|
|
150
|
+
same = false;
|
|
151
|
+
if (line1 && line2) {
|
|
152
|
+
differences.push(`Line ${i + 1}: Changed`);
|
|
153
|
+
differences.push(` - ${line1}`);
|
|
154
|
+
differences.push(` + ${line2}`);
|
|
155
|
+
}
|
|
156
|
+
else if (line1) {
|
|
157
|
+
differences.push(`Line ${i + 1}: Removed`);
|
|
158
|
+
differences.push(` - ${line1}`);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
differences.push(`Line ${i + 1}: Added`);
|
|
162
|
+
differences.push(` + ${line2}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (same) {
|
|
167
|
+
return {
|
|
168
|
+
content: [
|
|
169
|
+
{
|
|
170
|
+
type: "text",
|
|
171
|
+
text: "โ
Texts are identical - no differences found.",
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
return {
|
|
178
|
+
content: [
|
|
179
|
+
{
|
|
180
|
+
type: "text",
|
|
181
|
+
text: `โ Found differences:
|
|
182
|
+
|
|
183
|
+
${differences.join('\n')}
|
|
184
|
+
|
|
185
|
+
Summary:
|
|
186
|
+
Lines in text 1: ${lines1.length}
|
|
187
|
+
Lines in text 2: ${lines2.length}`,
|
|
188
|
+
},
|
|
189
|
+
],
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
return {
|
|
195
|
+
content: [
|
|
196
|
+
{
|
|
197
|
+
type: "text",
|
|
198
|
+
text: `Error comparing texts: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
// ASCII art generator
|
|
205
|
+
server.tool("ascii-art-text", "Generate ASCII art text", {
|
|
206
|
+
text: z.string().describe("Text to convert to ASCII art, or use 'LIST_FONTS' to get all available font names"),
|
|
207
|
+
font: z.string().describe("ASCII art font style. Supports all 295+ figlet fonts. Use 'standard' if unsure.").optional(),
|
|
208
|
+
}, async ({ text, font = "standard" }) => {
|
|
209
|
+
try {
|
|
210
|
+
// Generate ASCII art using figlet
|
|
211
|
+
const figlet = await import('figlet');
|
|
212
|
+
// Get list of available fonts
|
|
213
|
+
const availableFonts = figlet.default.fontsSync();
|
|
214
|
+
// Check if user wants to list all fonts
|
|
215
|
+
if (text.toUpperCase() === 'LIST_FONTS') {
|
|
216
|
+
const sortedFonts = availableFonts.sort();
|
|
217
|
+
const popularFonts = [
|
|
218
|
+
"Standard", "Big", "Small", "Slant", "3-D", "Banner", "Block", "Shadow",
|
|
219
|
+
"Larry 3D", "Doom", "Star Wars", "Gothic", "Graffiti", "Bubble", "Digital"
|
|
220
|
+
];
|
|
221
|
+
// Filter popular fonts that are actually available
|
|
222
|
+
const availablePopularFonts = popularFonts.filter(f => sortedFonts.some(availableFont => availableFont === f));
|
|
223
|
+
return {
|
|
224
|
+
content: [
|
|
225
|
+
{
|
|
226
|
+
type: "text",
|
|
227
|
+
text: `Available ASCII Art Fonts (${sortedFonts.length} total):
|
|
228
|
+
|
|
229
|
+
๐ POPULAR FONTS:
|
|
230
|
+
${availablePopularFonts.join(', ')}
|
|
231
|
+
|
|
232
|
+
๐ ALL AVAILABLE FONTS:
|
|
233
|
+
${sortedFonts.join(', ')}
|
|
234
|
+
|
|
235
|
+
๐ก Usage: Use any font name above as the 'font' parameter.
|
|
236
|
+
Examples: 'Standard', '3-D', 'Larry 3D', 'Banner', 'Block', etc.`,
|
|
237
|
+
},
|
|
238
|
+
],
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
// Find the exact font match (case insensitive and flexible matching)
|
|
242
|
+
let targetFont = "Standard"; // Default fallback
|
|
243
|
+
const inputFont = font.toLowerCase();
|
|
244
|
+
// Direct match
|
|
245
|
+
const exactMatch = availableFonts.find(f => f.toLowerCase() === inputFont);
|
|
246
|
+
if (exactMatch) {
|
|
247
|
+
targetFont = exactMatch;
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
// Fuzzy match - look for fonts that contain the input as substring
|
|
251
|
+
const partialMatch = availableFonts.find(f => f.toLowerCase().includes(inputFont) ||
|
|
252
|
+
inputFont.includes(f.toLowerCase()));
|
|
253
|
+
if (partialMatch) {
|
|
254
|
+
targetFont = partialMatch;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
// Generate ASCII art
|
|
258
|
+
const asciiArt = figlet.default.textSync(text, {
|
|
259
|
+
font: targetFont,
|
|
260
|
+
horizontalLayout: 'default',
|
|
261
|
+
verticalLayout: 'default'
|
|
262
|
+
});
|
|
263
|
+
const fontUsed = targetFont === font ? font : `${font} โ ${targetFont}`;
|
|
264
|
+
return {
|
|
265
|
+
content: [
|
|
266
|
+
{
|
|
267
|
+
type: "text",
|
|
268
|
+
text: `ASCII Art (${fontUsed}):\n\n${asciiArt}`,
|
|
269
|
+
},
|
|
270
|
+
],
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
// Get available fonts for error message
|
|
275
|
+
try {
|
|
276
|
+
const figlet = await import('figlet');
|
|
277
|
+
const availableFonts = figlet.default.fontsSync();
|
|
278
|
+
const popularFonts = [
|
|
279
|
+
"Standard", "Big", "Small", "Slant", "3-D", "Banner", "Block", "Shadow",
|
|
280
|
+
"Larry 3D", "Doom", "Star Wars", "Gothic", "Graffiti", "Bubble", "Digital"
|
|
281
|
+
];
|
|
282
|
+
return {
|
|
283
|
+
content: [
|
|
284
|
+
{
|
|
285
|
+
type: "text",
|
|
286
|
+
text: `Error generating ASCII art: ${error instanceof Error ? error.message : 'Unknown error'}
|
|
287
|
+
|
|
288
|
+
Font '${font}' not found or invalid.
|
|
289
|
+
|
|
290
|
+
Popular fonts to try: ${popularFonts.join(', ')}
|
|
291
|
+
|
|
292
|
+
Total available fonts: ${availableFonts.length}
|
|
293
|
+
Some examples: ${availableFonts.slice(0, 10).join(', ')}...
|
|
294
|
+
|
|
295
|
+
Note: ASCII art generation works best with short text (1-10 characters).`,
|
|
296
|
+
},
|
|
297
|
+
],
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
return {
|
|
302
|
+
content: [
|
|
303
|
+
{
|
|
304
|
+
type: "text",
|
|
305
|
+
text: `Error generating ASCII art: ${error instanceof Error ? error.message : 'Unknown error'}
|
|
306
|
+
|
|
307
|
+
Note: ASCII art generation works best with short text (1-10 characters).`,
|
|
308
|
+
},
|
|
309
|
+
],
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
// NATO phonetic alphabet converter
|
|
315
|
+
server.tool("text-to-nato-alphabet", "Convert text to NATO phonetic alphabet", {
|
|
316
|
+
text: z.string().describe("Text to convert to NATO alphabet"),
|
|
317
|
+
}, async ({ text }) => {
|
|
318
|
+
const natoAlphabet = {
|
|
319
|
+
'A': 'Alfa', 'B': 'Bravo', 'C': 'Charlie', 'D': 'Delta',
|
|
320
|
+
'E': 'Echo', 'F': 'Foxtrot', 'G': 'Golf', 'H': 'Hotel',
|
|
321
|
+
'I': 'India', 'J': 'Juliett', 'K': 'Kilo', 'L': 'Lima',
|
|
322
|
+
'M': 'Mike', 'N': 'November', 'O': 'Oscar', 'P': 'Papa',
|
|
323
|
+
'Q': 'Quebec', 'R': 'Romeo', 'S': 'Sierra', 'T': 'Tango',
|
|
324
|
+
'U': 'Uniform', 'V': 'Victor', 'W': 'Whiskey', 'X': 'X-ray',
|
|
325
|
+
'Y': 'Yankee', 'Z': 'Zulu',
|
|
326
|
+
'0': 'Zero', '1': 'One', '2': 'Two', '3': 'Three',
|
|
327
|
+
'4': 'Four', '5': 'Five', '6': 'Six', '7': 'Seven',
|
|
328
|
+
'8': 'Eight', '9': 'Nine', ' ': '[SPACE]'
|
|
329
|
+
};
|
|
330
|
+
const result = text
|
|
331
|
+
.toUpperCase()
|
|
332
|
+
.split('')
|
|
333
|
+
.map(char => natoAlphabet[char] || `[${char}]`)
|
|
334
|
+
.join(' ');
|
|
335
|
+
return {
|
|
336
|
+
content: [
|
|
337
|
+
{
|
|
338
|
+
type: "text",
|
|
339
|
+
text: `NATO Phonetic Alphabet:
|
|
340
|
+
|
|
341
|
+
Original: ${text}
|
|
342
|
+
NATO: ${result}`,
|
|
343
|
+
},
|
|
344
|
+
],
|
|
345
|
+
};
|
|
346
|
+
});
|
|
347
|
+
// String obfuscator
|
|
348
|
+
server.tool("string-obfuscator", "Obfuscate text by replacing characters with their HTML entities or other representations", {
|
|
349
|
+
text: z.string().describe("Text to obfuscate"),
|
|
350
|
+
method: z.enum(["html-entities", "unicode", "base64"]).describe("Obfuscation method").optional(),
|
|
351
|
+
}, async ({ text, method = "html-entities" }) => {
|
|
352
|
+
try {
|
|
353
|
+
let result = '';
|
|
354
|
+
switch (method) {
|
|
355
|
+
case 'html-entities':
|
|
356
|
+
result = text
|
|
357
|
+
.split('')
|
|
358
|
+
.map(char => `&#${char.charCodeAt(0)};`)
|
|
359
|
+
.join('');
|
|
360
|
+
break;
|
|
361
|
+
case 'unicode':
|
|
362
|
+
result = text
|
|
363
|
+
.split('')
|
|
364
|
+
.map(char => `\\u${char.charCodeAt(0).toString(16).padStart(4, '0')}`)
|
|
365
|
+
.join('');
|
|
366
|
+
break;
|
|
367
|
+
case 'base64':
|
|
368
|
+
result = Buffer.from(text, 'utf-8').toString('base64');
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
371
|
+
return {
|
|
372
|
+
content: [
|
|
373
|
+
{
|
|
374
|
+
type: "text",
|
|
375
|
+
text: `Obfuscated Text (${method}):
|
|
376
|
+
|
|
377
|
+
Original: ${text}
|
|
378
|
+
Obfuscated: ${result}`,
|
|
379
|
+
},
|
|
380
|
+
],
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
catch (error) {
|
|
384
|
+
return {
|
|
385
|
+
content: [
|
|
386
|
+
{
|
|
387
|
+
type: "text",
|
|
388
|
+
text: `Error obfuscating text: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
389
|
+
},
|
|
390
|
+
],
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
// Slugify string
|
|
395
|
+
server.tool("slugify-string", "Convert text to URL-friendly slug format", {
|
|
396
|
+
text: z.string().describe("Text to convert to slug"),
|
|
397
|
+
separator: z.string().describe("Character to use as separator").optional(),
|
|
398
|
+
lowercase: z.boolean().describe("Convert to lowercase").optional(),
|
|
399
|
+
}, async ({ text, separator = "-", lowercase = true }) => {
|
|
400
|
+
try {
|
|
401
|
+
let slug = text
|
|
402
|
+
.normalize('NFD')
|
|
403
|
+
.replace(/[\u0300-\u036f]/g, '') // Remove diacritics
|
|
404
|
+
.replace(/[^\w\s-]/g, '') // Remove special characters
|
|
405
|
+
.trim()
|
|
406
|
+
.replace(/\s+/g, separator) // Replace spaces with separator
|
|
407
|
+
.replace(new RegExp(`${separator}+`, 'g'), separator); // Remove duplicate separators
|
|
408
|
+
if (lowercase) {
|
|
409
|
+
slug = slug.toLowerCase();
|
|
410
|
+
}
|
|
411
|
+
return {
|
|
412
|
+
content: [
|
|
413
|
+
{
|
|
414
|
+
type: "text",
|
|
415
|
+
text: `Original: ${text}
|
|
416
|
+
Slug: ${slug}
|
|
417
|
+
|
|
418
|
+
Settings:
|
|
419
|
+
- Separator: "${separator}"
|
|
420
|
+
- Lowercase: ${lowercase}`,
|
|
421
|
+
},
|
|
422
|
+
],
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
catch (error) {
|
|
426
|
+
return {
|
|
427
|
+
content: [
|
|
428
|
+
{
|
|
429
|
+
type: "text",
|
|
430
|
+
text: `Error creating slug: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
431
|
+
},
|
|
432
|
+
],
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
// Lorem Ipsum generator
|
|
437
|
+
server.tool("lorem-ipsum-generator", "Generate Lorem Ipsum placeholder text", {
|
|
438
|
+
count: z.number().describe("Number of items to generate").optional(),
|
|
439
|
+
type: z.enum(["words", "sentences", "paragraphs"]).describe("Type of content to generate").optional(),
|
|
440
|
+
}, async ({ count = 5, type = "sentences" }) => {
|
|
441
|
+
try {
|
|
442
|
+
if (count < 1 || count > 100) {
|
|
443
|
+
return {
|
|
444
|
+
content: [
|
|
445
|
+
{
|
|
446
|
+
type: "text",
|
|
447
|
+
text: "Count must be between 1 and 100.",
|
|
448
|
+
},
|
|
449
|
+
],
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
const words = [
|
|
453
|
+
"lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit",
|
|
454
|
+
"sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore",
|
|
455
|
+
"magna", "aliqua", "enim", "ad", "minim", "veniam", "quis", "nostrud",
|
|
456
|
+
"exercitation", "ullamco", "laboris", "nisi", "aliquip", "ex", "ea", "commodo",
|
|
457
|
+
"consequat", "duis", "aute", "irure", "in", "reprehenderit", "voluptate",
|
|
458
|
+
"velit", "esse", "cillum", "fugiat", "nulla", "pariatur", "excepteur", "sint",
|
|
459
|
+
"occaecat", "cupidatat", "non", "proident", "sunt", "culpa", "qui", "officia",
|
|
460
|
+
"deserunt", "mollit", "anim", "id", "est", "laborum"
|
|
461
|
+
];
|
|
462
|
+
let result = "";
|
|
463
|
+
if (type === "words") {
|
|
464
|
+
const selectedWords = [];
|
|
465
|
+
for (let i = 0; i < count; i++) {
|
|
466
|
+
selectedWords.push(words[Math.floor(Math.random() * words.length)]);
|
|
467
|
+
}
|
|
468
|
+
result = selectedWords.join(" ");
|
|
469
|
+
}
|
|
470
|
+
else if (type === "sentences") {
|
|
471
|
+
const sentences = [];
|
|
472
|
+
for (let i = 0; i < count; i++) {
|
|
473
|
+
const sentenceLength = Math.floor(Math.random() * 10) + 5;
|
|
474
|
+
const sentenceWords = [];
|
|
475
|
+
for (let j = 0; j < sentenceLength; j++) {
|
|
476
|
+
sentenceWords.push(words[Math.floor(Math.random() * words.length)]);
|
|
477
|
+
}
|
|
478
|
+
sentenceWords[0] = sentenceWords[0].charAt(0).toUpperCase() + sentenceWords[0].slice(1);
|
|
479
|
+
sentences.push(sentenceWords.join(" ") + ".");
|
|
480
|
+
}
|
|
481
|
+
result = sentences.join(" ");
|
|
482
|
+
}
|
|
483
|
+
else if (type === "paragraphs") {
|
|
484
|
+
const paragraphs = [];
|
|
485
|
+
for (let i = 0; i < count; i++) {
|
|
486
|
+
const sentenceCount = Math.floor(Math.random() * 5) + 3;
|
|
487
|
+
const sentences = [];
|
|
488
|
+
for (let j = 0; j < sentenceCount; j++) {
|
|
489
|
+
const sentenceLength = Math.floor(Math.random() * 10) + 5;
|
|
490
|
+
const sentenceWords = [];
|
|
491
|
+
for (let k = 0; k < sentenceLength; k++) {
|
|
492
|
+
sentenceWords.push(words[Math.floor(Math.random() * words.length)]);
|
|
493
|
+
}
|
|
494
|
+
sentenceWords[0] = sentenceWords[0].charAt(0).toUpperCase() + sentenceWords[0].slice(1);
|
|
495
|
+
sentences.push(sentenceWords.join(" ") + ".");
|
|
496
|
+
}
|
|
497
|
+
paragraphs.push(sentences.join(" "));
|
|
498
|
+
}
|
|
499
|
+
result = paragraphs.join("\n\n");
|
|
500
|
+
}
|
|
501
|
+
return {
|
|
502
|
+
content: [
|
|
503
|
+
{
|
|
504
|
+
type: "text",
|
|
505
|
+
text: `Lorem Ipsum (${count} ${type}):\n\n${result}`,
|
|
506
|
+
},
|
|
507
|
+
],
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
catch (error) {
|
|
511
|
+
return {
|
|
512
|
+
content: [
|
|
513
|
+
{
|
|
514
|
+
type: "text",
|
|
515
|
+
text: `Error generating Lorem Ipsum: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
516
|
+
},
|
|
517
|
+
],
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
});
|
|
521
|
+
// Numeronym generator
|
|
522
|
+
server.tool("numeronym-generator", "Generate numeronyms (abbreviations with numbers) from text", {
|
|
523
|
+
text: z.string().describe("Text to convert to numeronym"),
|
|
524
|
+
}, async ({ text }) => {
|
|
525
|
+
try {
|
|
526
|
+
const words = text.trim().split(/\s+/);
|
|
527
|
+
const numeronyms = words.map(word => {
|
|
528
|
+
if (word.length <= 3) {
|
|
529
|
+
return word;
|
|
530
|
+
}
|
|
531
|
+
const firstChar = word[0];
|
|
532
|
+
const lastChar = word[word.length - 1];
|
|
533
|
+
const middleCount = word.length - 2;
|
|
534
|
+
return `${firstChar}${middleCount}${lastChar}`;
|
|
535
|
+
});
|
|
536
|
+
return {
|
|
537
|
+
content: [
|
|
538
|
+
{
|
|
539
|
+
type: "text",
|
|
540
|
+
text: `Original: ${text}\nNumeronym: ${numeronyms.join(' ')}\n\nExamples:\n- internationalization โ i18n\n- localization โ l10n\n- accessibility โ a11y`,
|
|
541
|
+
},
|
|
542
|
+
],
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
catch (error) {
|
|
546
|
+
return {
|
|
547
|
+
content: [
|
|
548
|
+
{
|
|
549
|
+
type: "text",
|
|
550
|
+
text: `Error generating numeronym: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
551
|
+
},
|
|
552
|
+
],
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
});
|
|
556
|
+
// Text to Unicode converter
|
|
557
|
+
server.tool("text-to-unicode", "Convert text to Unicode code points and vice versa", {
|
|
558
|
+
input: z.string().describe("Text to convert to Unicode or Unicode to convert to text"),
|
|
559
|
+
operation: z.enum(["encode", "decode"]).describe("Operation: encode text to Unicode or decode Unicode to text"),
|
|
560
|
+
}, async ({ input, operation }) => {
|
|
561
|
+
try {
|
|
562
|
+
if (operation === "encode") {
|
|
563
|
+
const unicode = input
|
|
564
|
+
.split('')
|
|
565
|
+
.map(char => `U+${char.charCodeAt(0).toString(16).toUpperCase().padStart(4, '0')}`)
|
|
566
|
+
.join(' ');
|
|
567
|
+
return {
|
|
568
|
+
content: [
|
|
569
|
+
{
|
|
570
|
+
type: "text",
|
|
571
|
+
text: `Text: ${input}\nUnicode: ${unicode}`,
|
|
572
|
+
},
|
|
573
|
+
],
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
else {
|
|
577
|
+
// Decode Unicode to text
|
|
578
|
+
const unicodePattern = /U\+([0-9A-Fa-f]{4,6})/g;
|
|
579
|
+
const text = input.replace(unicodePattern, (match, hex) => {
|
|
580
|
+
const decimal = parseInt(hex, 16);
|
|
581
|
+
return String.fromCharCode(decimal);
|
|
582
|
+
});
|
|
583
|
+
return {
|
|
584
|
+
content: [
|
|
585
|
+
{
|
|
586
|
+
type: "text",
|
|
587
|
+
text: `Unicode: ${input}\nText: ${text}`,
|
|
588
|
+
},
|
|
589
|
+
],
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
catch (error) {
|
|
594
|
+
return {
|
|
595
|
+
content: [
|
|
596
|
+
{
|
|
597
|
+
type: "text",
|
|
598
|
+
text: `Error converting text/Unicode: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
599
|
+
},
|
|
600
|
+
],
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
});
|
|
604
|
+
// Emoji search
|
|
605
|
+
server.tool("emoji-search", "Search for emojis by name or category", {
|
|
606
|
+
query: z.string().describe("Search term for emoji (name, category, or keyword)"),
|
|
607
|
+
}, async ({ query }) => {
|
|
608
|
+
try {
|
|
609
|
+
// Basic emoji database (simplified)
|
|
610
|
+
const emojis = {
|
|
611
|
+
// Faces
|
|
612
|
+
"happy": ["๐", "๐", "๐", "๐", "๐", "๐", "๐"],
|
|
613
|
+
"sad": ["๐ข", "๐ญ", "๐", "โน๏ธ", "๐", "๐", "๐"],
|
|
614
|
+
"love": ["๐", "๐ฅฐ", "๐", "๐", "๐", "๐", "โค๏ธ"],
|
|
615
|
+
"angry": ["๐ ", "๐ก", "๐คฌ", "๐ฟ", "๐ข"],
|
|
616
|
+
// Animals
|
|
617
|
+
"cat": ["๐ฑ", "๐", "๐", "๐ธ", "๐น", "๐ป", "๐ผ"],
|
|
618
|
+
"dog": ["๐ถ", "๐", "๐ฆฎ", "๐โ๐ฆบ"],
|
|
619
|
+
"animal": ["๐ถ", "๐ฑ", "๐ญ", "๐น", "๐ฐ", "๐ฆ", "๐ป"],
|
|
620
|
+
// Food
|
|
621
|
+
"food": ["๐", "๐", "๐", "๐ญ", "๐ฅช", "๐ฎ", "๐", "๐"],
|
|
622
|
+
"fruit": ["๐", "๐", "๐", "๐", "๐", "๐", "๐ซ", "๐"],
|
|
623
|
+
// Objects
|
|
624
|
+
"tech": ["๐ป", "๐ฑ", "โ", "๐บ", "๐ท", "๐ฎ", "๐พ", "๐ฟ"],
|
|
625
|
+
"tools": ["๐ง", "๐จ", "โ๏ธ", "๐ ๏ธ", "โ๏ธ", "๐ช", "๐ฉ"],
|
|
626
|
+
// Symbols
|
|
627
|
+
"check": ["โ
", "โ๏ธ", "โ๏ธ"],
|
|
628
|
+
"cross": ["โ", "โ", "โ๏ธ"],
|
|
629
|
+
"star": ["โญ", "๐", "โจ", "๐ซ", "โญ"],
|
|
630
|
+
"heart": ["โค๏ธ", "๐", "๐", "๐", "๐งก", "๐", "๐ค", "๐ค"]
|
|
631
|
+
};
|
|
632
|
+
const searchTerm = query.toLowerCase();
|
|
633
|
+
let results = [];
|
|
634
|
+
for (const [category, emojiList] of Object.entries(emojis)) {
|
|
635
|
+
if (category.includes(searchTerm)) {
|
|
636
|
+
results.push(...emojiList);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
// Remove duplicates
|
|
640
|
+
results = [...new Set(results)];
|
|
641
|
+
if (results.length === 0) {
|
|
642
|
+
return {
|
|
643
|
+
content: [
|
|
644
|
+
{
|
|
645
|
+
type: "text",
|
|
646
|
+
text: `No emojis found for "${query}".
|
|
647
|
+
|
|
648
|
+
Available categories: ${Object.keys(emojis).join(', ')}`,
|
|
649
|
+
},
|
|
650
|
+
],
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
return {
|
|
654
|
+
content: [
|
|
655
|
+
{
|
|
656
|
+
type: "text",
|
|
657
|
+
text: `Emojis for "${query}":
|
|
658
|
+
|
|
659
|
+
${results.join(' ')}
|
|
660
|
+
|
|
661
|
+
Found ${results.length} emoji(s)
|
|
662
|
+
Copy any emoji above to use it!`,
|
|
663
|
+
},
|
|
664
|
+
],
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
catch (error) {
|
|
668
|
+
return {
|
|
669
|
+
content: [
|
|
670
|
+
{
|
|
671
|
+
type: "text",
|
|
672
|
+
text: `Error searching emojis: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
673
|
+
},
|
|
674
|
+
],
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
});
|
|
678
|
+
}
|