diff --git a/package-lock.json b/package-lock.json index 2b9d36f..2c74da8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,8 @@ "version": "0.0.0", "dependencies": { "@modelcontextprotocol/sdk": "^1.11.3", - "node-fetch": "^3.3.2" + "node-fetch": "^3.3.2", + "string-strip-html": "^13.4.12" }, "bin": { "mediawiki-mcp-server": "build/index.js" @@ -322,6 +323,21 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/lodash": { + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.17.tgz", + "integrity": "sha512-RRVJ+J3J+WmyOTqnz3PiBLA501eKwXl2noseKOrNo/6+XEHjTAxO4xHvxQB6QuNm+s4WRbn6rSiap8+EA+ykFQ==", + "license": "MIT" + }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/node": { "version": "22.15.18", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.18.tgz", @@ -1290,6 +1306,18 @@ "node": ">=12" } }, + "node_modules/codsen-utils": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/codsen-utils/-/codsen-utils-1.6.7.tgz", + "integrity": "sha512-M+9D3IhFAk4T8iATX62herVuIx1sp5kskWgxEegKD/JwTTSSGjGQs5Q5J4vVJ4mLcn1uhfxDYv6Yzr8zleHF3w==", + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + }, + "engines": { + "node": ">=14.18.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2930,6 +2958,22 @@ "dev": true, "license": "ISC" }, + "node_modules/html-entities": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", + "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -3261,6 +3305,12 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -3808,6 +3858,56 @@ "node": ">= 0.6" } }, + "node_modules/ranges-apply": { + "version": "7.0.19", + "resolved": "https://registry.npmjs.org/ranges-apply/-/ranges-apply-7.0.19.tgz", + "integrity": "sha512-imA03KuTSuSpQtq9SDhavUz7BtiddCPj+fsYM/XpdypRN/s8vyTayKzni6m5nYs7VMds1kSNK1V3jfwVrPUWBQ==", + "license": "MIT", + "dependencies": { + "ranges-merge": "^9.0.18", + "tiny-invariant": "^1.3.3" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/ranges-merge": { + "version": "9.0.18", + "resolved": "https://registry.npmjs.org/ranges-merge/-/ranges-merge-9.0.18.tgz", + "integrity": "sha512-2+6Eh4yxi5sudUmvCdvxVOSdXIXV+Brfutw8chhZmqkT0REqlzilpyQps1S5n8c7f0+idblqSAHGahTbf/Ar5g==", + "license": "MIT", + "dependencies": { + "ranges-push": "^7.0.18", + "ranges-sort": "^6.0.13" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/ranges-push": { + "version": "7.0.18", + "resolved": "https://registry.npmjs.org/ranges-push/-/ranges-push-7.0.18.tgz", + "integrity": "sha512-wzGHipEklSlY0QloQ88PNt+PkTURIB42PLLcQGY+WyYBlNpnrzps6EYooD3RqNXtdqMQ9kR8IVaF9itRYtuzLA==", + "license": "MIT", + "dependencies": { + "codsen-utils": "^1.6.7", + "ranges-sort": "^6.0.13", + "string-collapse-leading-whitespace": "^7.0.9", + "string-trim-spaces-only": "^5.0.12" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/ranges-sort": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/ranges-sort/-/ranges-sort-6.0.13.tgz", + "integrity": "sha512-M3P0/dUnU3ihLPX2jq0MT2NJA1ls/q6cUAUVPD28xdFFqm3VFarPjTKKhnsBSvYCpZD8HdiElAGAyoPu6uOQjA==", + "license": "MIT", + "engines": { + "node": ">=14.18.0" + } + }, "node_modules/raw-body": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", @@ -4037,6 +4137,12 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -4398,6 +4504,55 @@ "node": ">= 0.8" } }, + "node_modules/string-collapse-leading-whitespace": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/string-collapse-leading-whitespace/-/string-collapse-leading-whitespace-7.0.9.tgz", + "integrity": "sha512-lEuTHlogBT9PWipfk0FOyvoMKX8syiE03QoFk5MDh8oS0AJ2C07IlstR5cGkxz48nKkOIuvkC28w9Rx/cVRNDg==", + "license": "MIT", + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/string-left-right": { + "version": "6.0.20", + "resolved": "https://registry.npmjs.org/string-left-right/-/string-left-right-6.0.20.tgz", + "integrity": "sha512-dz2mUgmsI7m/FMe+BoxZ2+73X1TUoQvjCdnq8vbIAnHlvWfVZleNUR+lw+QgHA2dlJig+hUWC9bFYdNFGGy2bA==", + "license": "MIT", + "dependencies": { + "codsen-utils": "^1.6.7", + "rfdc": "^1.4.1" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/string-strip-html": { + "version": "13.4.12", + "resolved": "https://registry.npmjs.org/string-strip-html/-/string-strip-html-13.4.12.tgz", + "integrity": "sha512-mr1GM1TFcwDkYwLE7TNkHY+Lf3YFEBa19W9KntZoJJSbrKF07W4xmLkPnqf8cypEGyr+dc1H9hsdTw5VSNVGxg==", + "license": "MIT", + "dependencies": { + "@types/lodash-es": "^4.17.12", + "codsen-utils": "^1.6.7", + "html-entities": "^2.5.2", + "lodash-es": "^4.17.21", + "ranges-apply": "^7.0.19", + "ranges-push": "^7.0.18", + "string-left-right": "^6.0.20" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/string-trim-spaces-only": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/string-trim-spaces-only/-/string-trim-spaces-only-5.0.12.tgz", + "integrity": "sha512-Un5nIO1av+hzfnKGmY+bWe0AD4WH37TuDW+jeMPm81rUvU2r3VPRj9vEKdZkPmuhYAMuKlzarm7jDSKwJKOcpQ==", + "license": "MIT", + "engines": { + "node": ">=14.18.0" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -4495,6 +4650,12 @@ "dev": true, "license": "MIT" }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", diff --git a/package.json b/package.json index 08f3d2c..a5146f8 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,8 @@ "license": "", "dependencies": { "@modelcontextprotocol/sdk": "^1.11.3", - "node-fetch": "^3.3.2" + "node-fetch": "^3.3.2", + "string-strip-html": "^13.4.12" }, "devDependencies": { "@types/node": "^22.15.17", diff --git a/src/tools/get-page.ts b/src/tools/get-page.ts index 3ff0575..7f99f5c 100644 --- a/src/tools/get-page.ts +++ b/src/tools/get-page.ts @@ -5,11 +5,13 @@ import type { CallToolResult, TextContent, ToolAnnotations } from '@modelcontext /* eslint-enable n/no-missing-import */ import { makeRestGetRequest } from '../common/utils.js'; import type { MwRestApiPageObject } from '../types/mwRestApi.js'; +import { stripHtml } from 'string-strip-html'; enum ContentFormat { noContent = 'noContent', withSource = 'withSource', - withHtml = 'withHtml' + withHtml = 'withHtml', + withPlainText = 'withPlainText' } export function getPageTool( server: McpServer ): RegisteredTool { @@ -29,9 +31,9 @@ export function getPageTool( server: McpServer ): RegisteredTool { ); } -async function handleGetPageTool( title: string, content: ContentFormat ): Promise { +async function handleGetPageTool( title: string, contentFormat: ContentFormat ): Promise { let subEndpoint: string; - switch ( content ) { + switch ( contentFormat ) { case ContentFormat.noContent: subEndpoint = '/bare'; break; @@ -39,6 +41,7 @@ async function handleGetPageTool( title: string, content: ContentFormat ): Promi subEndpoint = ''; break; case ContentFormat.withHtml: + case ContentFormat.withPlainText: subEndpoint = '/with_html'; break; } @@ -66,11 +69,11 @@ async function handleGetPageTool( title: string, content: ContentFormat ): Promi } return { - content: getPageToolResult( data ) + content: getPageToolResult( data, contentFormat ) }; } -function getPageToolResult( result: MwRestApiPageObject ): TextContent[] { +function getPageToolResult( result: MwRestApiPageObject, contentFormat: ContentFormat ): TextContent[] { const results: TextContent[] = [ { type: 'text', @@ -94,10 +97,17 @@ function getPageToolResult( result: MwRestApiPageObject ): TextContent[] { } if ( result.html !== undefined ) { - results.push( { - type: 'text', - text: `HTML:\n${ result.html }` - } ); + if ( contentFormat === ContentFormat.withHtml ) { + results.push( { + type: 'text', + text: `HTML:\n${ result.html }` + } ); + } else if ( contentFormat === ContentFormat.withPlainText ) { + results.push( { + type: 'text', + text: `Text:\n${ stripHtml( result.html ).result }` + } ); + } } return results;