index.ts•2.73 kB
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
export function registerEncodeHtmlEntities(server: McpServer) {
server.registerTool("encode_html_entities", {
description: "Extended HTML entity encoding/decoding",
inputSchema: {
text: z.string().describe("Text to encode or decode"),
operation: z.enum(["encode", "decode"]).describe("Operation to perform"),
},
// VS Code compliance annotations
annotations: {
title: "Encode Html Entities",
description: "Extended HTML entity encoding/decoding",
readOnlyHint: false
}
}, async ({ text, operation }) => {
try {
if (operation === "encode") {
const encoded = text
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/©/g, '©')
.replace(/®/g, '®')
.replace(/™/g, '™')
.replace(/€/g, '€')
.replace(/£/g, '£')
.replace(/¥/g, '¥')
.replace(/§/g, '§')
.replace(/¶/g, '¶')
.replace(/†/g, '†')
.replace(/‡/g, '‡');
return {
content: [
{
type: "text",
text: `HTML entities encoded: ${encoded}`,
},
],
};
} else {
// Proper HTML decoding order: decode & LAST to prevent double-unescaping
const decoded = text
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, "'")
.replace(/©/g, '©')
.replace(/®/g, '®')
.replace(/™/g, '™')
.replace(/€/g, '€')
.replace(/£/g, '£')
.replace(/¥/g, '¥')
.replace(/§/g, '§')
.replace(/¶/g, '¶')
.replace(/†/g, '†')
.replace(/‡/g, '‡')
.replace(/&/g, '&'); // Decode ampersand LAST
return {
content: [
{
type: "text",
text: `HTML entities decoded: ${decoded}`,
},
],
};
}
} catch (error) {
return {
content: [
{
type: "text",
text: `Error processing HTML entities: ${error instanceof Error ? error.message : 'Unknown error'}`,
},
],
};
}
}
);
}