@aiquants/html-to-markdown 0.1.4 → 0.1.5
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 +101 -18
- package/dist/{core-CVMYjtlI.cjs → core-D2dlEt1l.cjs} +1 -1
- package/dist/{core-DOzMLPij.js → core-DU_246Q7.js} +52 -14
- package/dist/index.cjs +1 -1
- package/dist/index.js +8 -2
- package/dist/main.cjs +1 -1
- package/dist/main.js +1 -1
- package/dist/mcp-server-CpmnW1p8.js +283 -0
- package/dist/mcp-server-D4Mj1IQ9.cjs +1 -0
- package/dist/mcp-server-streamable-Bu7QAr3W.cjs +1 -0
- package/dist/mcp-server-streamable-CQD5zK30.js +7538 -0
- package/dist/mcp-streamable.cjs +2 -0
- package/dist/mcp-streamable.js +6 -0
- package/dist/mcp.cjs +2 -0
- package/dist/mcp.js +13 -0
- package/dist/src/core.d.ts +4 -4
- package/dist/src/index.d.ts +2 -0
- package/dist/src/mcp-server-streamable.d.ts +74 -0
- package/dist/src/mcp-server.d.ts +57 -0
- package/dist/src/mcp-streamable.d.ts +6 -0
- package/dist/src/mcp.d.ts +6 -0
- package/dist/src/types.d.ts +5 -0
- package/dist/src/version.d.ts +9 -0
- package/dist/tests/core-unified.test.d.ts +5 -0
- package/dist/tests/coverage-complete.test.d.ts +5 -0
- package/dist/tests/mcp-unified.test.d.ts +5 -0
- package/dist/tests/plugins-unified.test.d.ts +5 -0
- package/dist/tests/test-client.d.ts +4 -0
- package/dist/version-BRVBmpor.js +11318 -0
- package/dist/version-DTaUKNBS.cjs +1 -0
- package/mcp.json +14 -0
- package/package.json +26 -10
- package/dist/tests/100-percent-final.test.d.ts +0 -1
- package/dist/tests/absolute-final-coverage.test.d.ts +0 -1
- package/dist/tests/browser-100.test.d.ts +0 -1
- package/dist/tests/browser-coverage.test.d.ts +0 -1
- package/dist/tests/browser.test.d.ts +0 -1
- package/dist/tests/cli.test.d.ts +0 -1
- package/dist/tests/converter-coverage.test.d.ts +0 -1
- package/dist/tests/converter.test.d.ts +0 -1
- package/dist/tests/core.test.d.ts +0 -1
- package/dist/tests/coverage-edge-cases.test.d.ts +0 -1
- package/dist/tests/direct-coverage.test.d.ts +0 -1
- package/dist/tests/final-100-percent.test.d.ts +0 -1
- package/dist/tests/final-coverage.test.d.ts +0 -1
- package/dist/tests/i18n.test.d.ts +0 -1
- package/dist/tests/index.test.d.ts +0 -1
- package/dist/tests/line-70-coverage.test.d.ts +0 -1
- package/dist/tests/main.test.d.ts +0 -1
- package/dist/tests/plugins.test.d.ts +0 -1
- package/dist/tests/readme-usage.test.d.ts +0 -1
- package/dist/tests/rehype-absolute-links-coverage.test.d.ts +0 -1
- package/dist/tests/rehype-absolute-links.test.d.ts +0 -1
- package/dist/tests/rehype-named-anchors.test.d.ts +0 -1
- package/dist/tests/rehype-sanitize-html-coverage.test.d.ts +0 -1
- package/dist/tests/rehype-sanitize-html.test.d.ts +0 -1
- package/dist/tests/rehype-wikipedia-footnotes.test.d.ts +0 -1
- package/dist/tests/types.test.d.ts +0 -1
- package/dist/tests/ultimate-coverage.test.d.ts +0 -1
- /package/dist/tests/{100-percent-coverage.test.d.ts → entry-points-error.test.d.ts} +0 -0
|
@@ -19494,9 +19494,39 @@ function bail(error) {
|
|
|
19494
19494
|
throw error;
|
|
19495
19495
|
}
|
|
19496
19496
|
}
|
|
19497
|
+
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
|
|
19497
19498
|
function getDefaultExportFromCjs(x) {
|
|
19498
19499
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
19499
19500
|
}
|
|
19501
|
+
function getAugmentedNamespace(n) {
|
|
19502
|
+
if (Object.prototype.hasOwnProperty.call(n, "__esModule")) return n;
|
|
19503
|
+
var f = n.default;
|
|
19504
|
+
if (typeof f == "function") {
|
|
19505
|
+
var a2 = function a3() {
|
|
19506
|
+
var isInstance = false;
|
|
19507
|
+
try {
|
|
19508
|
+
isInstance = this instanceof a3;
|
|
19509
|
+
} catch {
|
|
19510
|
+
}
|
|
19511
|
+
if (isInstance) {
|
|
19512
|
+
return Reflect.construct(f, arguments, this.constructor);
|
|
19513
|
+
}
|
|
19514
|
+
return f.apply(this, arguments);
|
|
19515
|
+
};
|
|
19516
|
+
a2.prototype = f.prototype;
|
|
19517
|
+
} else a2 = {};
|
|
19518
|
+
Object.defineProperty(a2, "__esModule", { value: true });
|
|
19519
|
+
Object.keys(n).forEach(function(k) {
|
|
19520
|
+
var d = Object.getOwnPropertyDescriptor(n, k);
|
|
19521
|
+
Object.defineProperty(a2, k, d.get ? d : {
|
|
19522
|
+
enumerable: true,
|
|
19523
|
+
get: function() {
|
|
19524
|
+
return n[k];
|
|
19525
|
+
}
|
|
19526
|
+
});
|
|
19527
|
+
});
|
|
19528
|
+
return a2;
|
|
19529
|
+
}
|
|
19500
19530
|
var extend$1;
|
|
19501
19531
|
var hasRequiredExtend;
|
|
19502
19532
|
function requireExtend() {
|
|
@@ -20662,11 +20692,7 @@ const convertHtmlToMarkdown = async (html2, baseUrl, locale) => {
|
|
|
20662
20692
|
if (children.length === 0) {
|
|
20663
20693
|
return { type: "html", value: `<span id="${String(id)}"></span>` };
|
|
20664
20694
|
}
|
|
20665
|
-
return [
|
|
20666
|
-
{ type: "html", value: `<span id="${String(id)}">` },
|
|
20667
|
-
...children,
|
|
20668
|
-
{ type: "html", value: "</span>" }
|
|
20669
|
-
];
|
|
20695
|
+
return [{ type: "html", value: `<span id="${String(id)}">` }, ...children, { type: "html", value: "</span>" }];
|
|
20670
20696
|
}
|
|
20671
20697
|
return state.all(node2);
|
|
20672
20698
|
},
|
|
@@ -20760,23 +20786,35 @@ const convertHtmlToMarkdown = async (html2, baseUrl, locale) => {
|
|
|
20760
20786
|
console.log(getMessage(locale, "convert_success"));
|
|
20761
20787
|
return correctedMarkdown;
|
|
20762
20788
|
};
|
|
20763
|
-
const htmlToMarkdown = async (
|
|
20764
|
-
const { locale = "en-US" } = options;
|
|
20789
|
+
const htmlToMarkdown = async (urlOrHtml, options = {}) => {
|
|
20790
|
+
const { locale = "en-US", htmlContent } = options;
|
|
20765
20791
|
try {
|
|
20766
|
-
|
|
20767
|
-
|
|
20768
|
-
if (
|
|
20769
|
-
|
|
20792
|
+
let htmlContentToProcess;
|
|
20793
|
+
let sourceUrl;
|
|
20794
|
+
if (htmlContent) {
|
|
20795
|
+
htmlContentToProcess = htmlContent;
|
|
20796
|
+
sourceUrl = urlOrHtml || "direct-html-input";
|
|
20797
|
+
} else {
|
|
20798
|
+
new URL(urlOrHtml);
|
|
20799
|
+
htmlContentToProcess = await getHtmlWithPlaywright(urlOrHtml, locale);
|
|
20800
|
+
sourceUrl = urlOrHtml;
|
|
20801
|
+
}
|
|
20802
|
+
if (!htmlContentToProcess) {
|
|
20803
|
+
console.error(`No HTML content found for source: ${sourceUrl}`);
|
|
20770
20804
|
return { html: "", markdown: "" };
|
|
20771
20805
|
}
|
|
20772
|
-
const markdown = await convertHtmlToMarkdown(
|
|
20773
|
-
return { html:
|
|
20806
|
+
const markdown = await convertHtmlToMarkdown(htmlContentToProcess, sourceUrl, locale);
|
|
20807
|
+
return { html: htmlContentToProcess, markdown };
|
|
20774
20808
|
} catch (error) {
|
|
20775
|
-
|
|
20809
|
+
const source = htmlContent ? "HTML string" : `URL: ${urlOrHtml}`;
|
|
20810
|
+
console.error(`An error occurred during the conversion process for ${source}`, error);
|
|
20776
20811
|
return { html: "", markdown: "" };
|
|
20777
20812
|
}
|
|
20778
20813
|
};
|
|
20779
20814
|
export {
|
|
20815
|
+
getAugmentedNamespace as a,
|
|
20816
|
+
getDefaultExportFromCjs as b,
|
|
20817
|
+
commonjsGlobal as c,
|
|
20780
20818
|
getMessage as g,
|
|
20781
20819
|
htmlToMarkdown as h
|
|
20782
20820
|
};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=new(require("happy-dom").Window);Object.assign(global,{document:e.document,window:e,self:e}),Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
const e=new(require("happy-dom").Window);Object.assign(global,{document:e.document,window:e,self:e}),Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./core-D2dlEt1l.cjs"),t=require("./mcp-server-D4Mj1IQ9.cjs"),c=require("./mcp-server-streamable-Bu7QAr3W.cjs");exports.getMessage=r.getMessage,exports.htmlToMarkdown=r.htmlToMarkdown,exports.createMcpServer=t.createMcpServer,exports.runMcpServer=t.runMcpServer,exports.createStreamableMcpServer=c.createStreamableMcpServer,exports.runStreamableMcpServer=c.runStreamableMcpServer;
|
package/dist/index.js
CHANGED
|
@@ -5,8 +5,14 @@ Object.assign(global, {
|
|
|
5
5
|
window,
|
|
6
6
|
self: window
|
|
7
7
|
});
|
|
8
|
-
import { g, h } from "./core-
|
|
8
|
+
import { g, h } from "./core-DU_246Q7.js";
|
|
9
|
+
import { c, r } from "./mcp-server-CpmnW1p8.js";
|
|
10
|
+
import { c as c2, r as r2 } from "./mcp-server-streamable-CQD5zK30.js";
|
|
9
11
|
export {
|
|
12
|
+
c as createMcpServer,
|
|
13
|
+
c2 as createStreamableMcpServer,
|
|
10
14
|
g as getMessage,
|
|
11
|
-
h as htmlToMarkdown
|
|
15
|
+
h as htmlToMarkdown,
|
|
16
|
+
r as runMcpServer,
|
|
17
|
+
r2 as runStreamableMcpServer
|
|
12
18
|
};
|
package/dist/main.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
Object.create,Object.defineProperty,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.prototype.hasOwnProperty;const e=new(require("happy-dom").Window);Object.assign(global,{document:e.document,window:e,self:e});const t=require("./core-
|
|
2
|
+
Object.create,Object.defineProperty,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.prototype.hasOwnProperty;const e=new(require("happy-dom").Window);Object.assign(global,{document:e.document,window:e,self:e});const t=require("./core-D2dlEt1l.cjs");var r="undefined"!=typeof document?document.currentScript:null;(async()=>{(("undefined"==typeof document?require("url").pathToFileURL(__filename).href:r&&"SCRIPT"===r.tagName.toUpperCase()&&r.src||new URL("main.cjs",document.baseURI).href).endsWith(process.argv[1])||process.argv[1]&&process.argv[1].includes("vite-node"))&&(async()=>{const e=(await import("yargs-parser")).default,r=await import("node:fs"),o=await import("node:path"),c=e(process.argv.slice(2),{string:["locale","output"],alias:{output:["o"]},default:{locale:"en-US"}}),s=c._[0],n=c.locale,a=c.output;s||process.exit(1);try{new URL(s)}catch(i){process.exit(1)}try{const{markdown:e,html:c}=await t.htmlToMarkdown(s,{locale:n});let i;if(a){i=o.resolve(process.cwd(),a);const e=o.dirname(i);r.existsSync(e)||r.mkdirSync(e,{recursive:!0})}else{const e=`${s.replace(/https?:\/\//,"").replace(/[^a-zA-Z0-9]/g,"_")}_${Date.now()}.md`,t=o.join(process.cwd(),".outputs","raw");r.existsSync(t)||r.mkdirSync(t,{recursive:!0}),i=o.join(t,e)}r.writeFileSync(i,e);const p=o.parse(i),l=o.join(p.dir,`${p.name}.html`);r.writeFileSync(l,c)}catch(i){process.exit(1)}})()})();
|
package/dist/main.js
CHANGED
|
@@ -6,7 +6,7 @@ Object.assign(global, {
|
|
|
6
6
|
window,
|
|
7
7
|
self: window
|
|
8
8
|
});
|
|
9
|
-
import { g as getMessage, h as htmlToMarkdown } from "./core-
|
|
9
|
+
import { g as getMessage, h as htmlToMarkdown } from "./core-DU_246Q7.js";
|
|
10
10
|
const runCli = async () => {
|
|
11
11
|
const yargsParser = (await import("yargs-parser")).default;
|
|
12
12
|
const fs = await import("node:fs");
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { Window } from "happy-dom";
|
|
2
|
+
const window = new Window();
|
|
3
|
+
Object.assign(global, {
|
|
4
|
+
document: window.document,
|
|
5
|
+
window,
|
|
6
|
+
self: window
|
|
7
|
+
});
|
|
8
|
+
import { J as JSONRPCMessageSchema, g as getPackageVersion, S as Server, L as ListToolsRequestSchema, C as CallToolRequestSchema } from "./version-BRVBmpor.js";
|
|
9
|
+
import process from "node:process";
|
|
10
|
+
import { h as htmlToMarkdown } from "./core-DU_246Q7.js";
|
|
11
|
+
class ReadBuffer {
|
|
12
|
+
append(chunk) {
|
|
13
|
+
this._buffer = this._buffer ? Buffer.concat([this._buffer, chunk]) : chunk;
|
|
14
|
+
}
|
|
15
|
+
readMessage() {
|
|
16
|
+
if (!this._buffer) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const index = this._buffer.indexOf("\n");
|
|
20
|
+
if (index === -1) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
const line = this._buffer.toString("utf8", 0, index).replace(/\r$/, "");
|
|
24
|
+
this._buffer = this._buffer.subarray(index + 1);
|
|
25
|
+
return deserializeMessage(line);
|
|
26
|
+
}
|
|
27
|
+
clear() {
|
|
28
|
+
this._buffer = void 0;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function deserializeMessage(line) {
|
|
32
|
+
return JSONRPCMessageSchema.parse(JSON.parse(line));
|
|
33
|
+
}
|
|
34
|
+
function serializeMessage(message) {
|
|
35
|
+
return JSON.stringify(message) + "\n";
|
|
36
|
+
}
|
|
37
|
+
class StdioServerTransport {
|
|
38
|
+
constructor(_stdin = process.stdin, _stdout = process.stdout) {
|
|
39
|
+
this._stdin = _stdin;
|
|
40
|
+
this._stdout = _stdout;
|
|
41
|
+
this._readBuffer = new ReadBuffer();
|
|
42
|
+
this._started = false;
|
|
43
|
+
this._ondata = (chunk) => {
|
|
44
|
+
this._readBuffer.append(chunk);
|
|
45
|
+
this.processReadBuffer();
|
|
46
|
+
};
|
|
47
|
+
this._onerror = (error) => {
|
|
48
|
+
var _a;
|
|
49
|
+
(_a = this.onerror) === null || _a === void 0 ? void 0 : _a.call(this, error);
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Starts listening for messages on stdin.
|
|
54
|
+
*/
|
|
55
|
+
async start() {
|
|
56
|
+
if (this._started) {
|
|
57
|
+
throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");
|
|
58
|
+
}
|
|
59
|
+
this._started = true;
|
|
60
|
+
this._stdin.on("data", this._ondata);
|
|
61
|
+
this._stdin.on("error", this._onerror);
|
|
62
|
+
}
|
|
63
|
+
processReadBuffer() {
|
|
64
|
+
var _a, _b;
|
|
65
|
+
while (true) {
|
|
66
|
+
try {
|
|
67
|
+
const message = this._readBuffer.readMessage();
|
|
68
|
+
if (message === null) {
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
(_a = this.onmessage) === null || _a === void 0 ? void 0 : _a.call(this, message);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
(_b = this.onerror) === null || _b === void 0 ? void 0 : _b.call(this, error);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async close() {
|
|
78
|
+
var _a;
|
|
79
|
+
this._stdin.off("data", this._ondata);
|
|
80
|
+
this._stdin.off("error", this._onerror);
|
|
81
|
+
const remainingDataListeners = this._stdin.listenerCount("data");
|
|
82
|
+
if (remainingDataListeners === 0) {
|
|
83
|
+
this._stdin.pause();
|
|
84
|
+
}
|
|
85
|
+
this._readBuffer.clear();
|
|
86
|
+
(_a = this.onclose) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
87
|
+
}
|
|
88
|
+
send(message) {
|
|
89
|
+
return new Promise((resolve) => {
|
|
90
|
+
const json = serializeMessage(message);
|
|
91
|
+
if (this._stdout.write(json)) {
|
|
92
|
+
resolve();
|
|
93
|
+
} else {
|
|
94
|
+
this._stdout.once("drain", resolve);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function parseHtmlToMarkdownArgs(args) {
|
|
100
|
+
if (!args || typeof args !== "object") {
|
|
101
|
+
throw new Error("Arguments are required");
|
|
102
|
+
}
|
|
103
|
+
const { url, html_content, locale = "en-US", output_format = "markdown" } = args;
|
|
104
|
+
if (!url && !html_content) {
|
|
105
|
+
throw new Error("Either 'url' or 'html_content' is required");
|
|
106
|
+
}
|
|
107
|
+
if (url && typeof url !== "string") {
|
|
108
|
+
throw new Error("'url' must be a string");
|
|
109
|
+
}
|
|
110
|
+
if (html_content && typeof html_content !== "string") {
|
|
111
|
+
throw new Error("'html_content' must be a string");
|
|
112
|
+
}
|
|
113
|
+
if (locale && !["en-US", "ja-JP"].includes(locale)) {
|
|
114
|
+
throw new Error("'locale' must be 'en-US' or 'ja-JP'");
|
|
115
|
+
}
|
|
116
|
+
if (output_format && !["markdown", "html", "both"].includes(output_format)) {
|
|
117
|
+
throw new Error("'output_format' must be 'markdown', 'html', or 'both'");
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
url,
|
|
121
|
+
html_content,
|
|
122
|
+
locale,
|
|
123
|
+
output_format
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
class HtmlToMarkdownMcpServer {
|
|
127
|
+
constructor() {
|
|
128
|
+
this.version = getPackageVersion();
|
|
129
|
+
this.server = new Server(
|
|
130
|
+
{
|
|
131
|
+
name: "@aiquants/html-to-markdown",
|
|
132
|
+
version: this.version,
|
|
133
|
+
description: "A tool to dynamically fetch a web page from a given URL and convert it to Markdown."
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
capabilities: {
|
|
137
|
+
tools: {}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
);
|
|
141
|
+
this.setupToolHandlers();
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Setup tool handlers for the MCP server.
|
|
145
|
+
* MCP サーバーのツールハンドラーを設定
|
|
146
|
+
*/
|
|
147
|
+
setupToolHandlers() {
|
|
148
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
149
|
+
return {
|
|
150
|
+
tools: [
|
|
151
|
+
{
|
|
152
|
+
name: "html_to_markdown",
|
|
153
|
+
description: "Convert HTML content from a URL or HTML string to Markdown format. Supports dynamic content loading and preserves table structures.",
|
|
154
|
+
inputSchema: {
|
|
155
|
+
type: "object",
|
|
156
|
+
properties: {
|
|
157
|
+
url: {
|
|
158
|
+
type: "string",
|
|
159
|
+
description: "The URL of the web page to convert to Markdown"
|
|
160
|
+
},
|
|
161
|
+
html_content: {
|
|
162
|
+
type: "string",
|
|
163
|
+
description: "HTML content as a string to convert to Markdown (alternative to URL)"
|
|
164
|
+
},
|
|
165
|
+
locale: {
|
|
166
|
+
type: "string",
|
|
167
|
+
description: "The locale to use for browser context (en-US or ja-JP)",
|
|
168
|
+
enum: ["en-US", "ja-JP"],
|
|
169
|
+
default: "en-US"
|
|
170
|
+
},
|
|
171
|
+
output_format: {
|
|
172
|
+
type: "string",
|
|
173
|
+
description: "Output format: 'markdown' (default), 'html', or 'both'",
|
|
174
|
+
enum: ["markdown", "html", "both"],
|
|
175
|
+
default: "markdown"
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
anyOf: [{ required: ["url"] }, { required: ["html_content"] }]
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
]
|
|
182
|
+
};
|
|
183
|
+
});
|
|
184
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
185
|
+
switch (request.params.name) {
|
|
186
|
+
case "html_to_markdown": {
|
|
187
|
+
return await this.handleHtmlToMarkdown(request.params.arguments);
|
|
188
|
+
}
|
|
189
|
+
default:
|
|
190
|
+
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Handle HTML to Markdown conversion tool call.
|
|
196
|
+
* HTML から Markdown への変換ツール呼び出しを処理
|
|
197
|
+
*/
|
|
198
|
+
async handleHtmlToMarkdown(args) {
|
|
199
|
+
try {
|
|
200
|
+
const validatedArgs = parseHtmlToMarkdownArgs(args);
|
|
201
|
+
const { url, html_content, locale = "en-US", output_format = "markdown" } = validatedArgs;
|
|
202
|
+
if (url) {
|
|
203
|
+
try {
|
|
204
|
+
new URL(url);
|
|
205
|
+
} catch {
|
|
206
|
+
throw new Error(`Invalid URL: ${url}`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
const result = await htmlToMarkdown(url || "direct-html-input", {
|
|
210
|
+
locale,
|
|
211
|
+
htmlContent: html_content
|
|
212
|
+
});
|
|
213
|
+
let content;
|
|
214
|
+
switch (output_format) {
|
|
215
|
+
case "markdown":
|
|
216
|
+
content = [
|
|
217
|
+
{
|
|
218
|
+
type: "text",
|
|
219
|
+
text: result.markdown
|
|
220
|
+
}
|
|
221
|
+
];
|
|
222
|
+
break;
|
|
223
|
+
case "html":
|
|
224
|
+
content = [
|
|
225
|
+
{
|
|
226
|
+
type: "text",
|
|
227
|
+
text: result.html
|
|
228
|
+
}
|
|
229
|
+
];
|
|
230
|
+
break;
|
|
231
|
+
case "both":
|
|
232
|
+
content = [
|
|
233
|
+
{
|
|
234
|
+
type: "text",
|
|
235
|
+
text: result.markdown
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
type: "text",
|
|
239
|
+
text: result.html
|
|
240
|
+
}
|
|
241
|
+
];
|
|
242
|
+
break;
|
|
243
|
+
default:
|
|
244
|
+
throw new Error(`Invalid output format: ${output_format}`);
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
content,
|
|
248
|
+
isError: false
|
|
249
|
+
};
|
|
250
|
+
} catch (error) {
|
|
251
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
252
|
+
return {
|
|
253
|
+
content: [
|
|
254
|
+
{
|
|
255
|
+
type: "text",
|
|
256
|
+
text: `Error: ${errorMessage}`
|
|
257
|
+
}
|
|
258
|
+
],
|
|
259
|
+
isError: true
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Start the MCP server.
|
|
265
|
+
* MCP サーバーを開始
|
|
266
|
+
*/
|
|
267
|
+
async start() {
|
|
268
|
+
const transport = new StdioServerTransport();
|
|
269
|
+
await this.server.connect(transport);
|
|
270
|
+
console.error("HTML to Markdown MCP server started");
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
const createMcpServer = () => {
|
|
274
|
+
return new HtmlToMarkdownMcpServer();
|
|
275
|
+
};
|
|
276
|
+
const runMcpServer = async () => {
|
|
277
|
+
const server = createMcpServer();
|
|
278
|
+
await server.start();
|
|
279
|
+
};
|
|
280
|
+
export {
|
|
281
|
+
createMcpServer as c,
|
|
282
|
+
runMcpServer as r
|
|
283
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const t=new(require("happy-dom").Window);Object.assign(global,{document:t.document,window:t,self:t});const r=require("./version-DTaUKNBS.cjs"),e=require("node:process"),o=require("./core-D2dlEt1l.cjs");class n{append(t){this._buffer=this._buffer?Buffer.concat([this._buffer,t]):t}readMessage(){if(!this._buffer)return null;const t=this._buffer.indexOf("\n");if(-1===t)return null;const e=this._buffer.toString("utf8",0,t).replace(/\r$/,"");return this._buffer=this._buffer.subarray(t+1),function(t){return r.JSONRPCMessageSchema.parse(JSON.parse(t))}(e)}clear(){this._buffer=void 0}}class s{constructor(t=e.stdin,r=e.stdout){this._stdin=t,this._stdout=r,this._readBuffer=new n,this._started=!1,this._ondata=t=>{this._readBuffer.append(t),this.processReadBuffer()},this._onerror=t=>{var r;null===(r=this.onerror)||void 0===r||r.call(this,t)}}async start(){if(this._started)throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");this._started=!0,this._stdin.on("data",this._ondata),this._stdin.on("error",this._onerror)}processReadBuffer(){for(var t,r;;)try{const r=this._readBuffer.readMessage();if(null===r)break;null===(t=this.onmessage)||void 0===t||t.call(this,r)}catch(e){null===(r=this.onerror)||void 0===r||r.call(this,e)}}async close(){var t;this._stdin.off("data",this._ondata),this._stdin.off("error",this._onerror);0===this._stdin.listenerCount("data")&&this._stdin.pause(),this._readBuffer.clear(),null===(t=this.onclose)||void 0===t||t.call(this)}send(t){return new Promise(r=>{const e=function(t){return JSON.stringify(t)+"\n"}(t);this._stdout.write(e)?r():this._stdout.once("drain",r)})}}class a{constructor(){this.version=r.getPackageVersion(),this.server=new r.Server({name:"@aiquants/html-to-markdown",version:this.version,description:"A tool to dynamically fetch a web page from a given URL and convert it to Markdown."},{capabilities:{tools:{}}}),this.setupToolHandlers()}setupToolHandlers(){this.server.setRequestHandler(r.ListToolsRequestSchema,async()=>({tools:[{name:"html_to_markdown",description:"Convert HTML content from a URL or HTML string to Markdown format. Supports dynamic content loading and preserves table structures.",inputSchema:{type:"object",properties:{url:{type:"string",description:"The URL of the web page to convert to Markdown"},html_content:{type:"string",description:"HTML content as a string to convert to Markdown (alternative to URL)"},locale:{type:"string",description:"The locale to use for browser context (en-US or ja-JP)",enum:["en-US","ja-JP"],default:"en-US"},output_format:{type:"string",description:"Output format: 'markdown' (default), 'html', or 'both'",enum:["markdown","html","both"],default:"markdown"}},anyOf:[{required:["url"]},{required:["html_content"]}]}}]})),this.server.setRequestHandler(r.CallToolRequestSchema,async t=>{if("html_to_markdown"===t.params.name)return await this.handleHtmlToMarkdown(t.params.arguments);throw new Error(`Unknown tool: ${t.params.name}`)})}async handleHtmlToMarkdown(t){try{const r=function(t){if(!t||"object"!=typeof t)throw new Error("Arguments are required");const{url:r,html_content:e,locale:o="en-US",output_format:n="markdown"}=t;if(!r&&!e)throw new Error("Either 'url' or 'html_content' is required");if(r&&"string"!=typeof r)throw new Error("'url' must be a string");if(e&&"string"!=typeof e)throw new Error("'html_content' must be a string");if(o&&!["en-US","ja-JP"].includes(o))throw new Error("'locale' must be 'en-US' or 'ja-JP'");if(n&&!["markdown","html","both"].includes(n))throw new Error("'output_format' must be 'markdown', 'html', or 'both'");return{url:r,html_content:e,locale:o,output_format:n}}(t),{url:e,html_content:n,locale:s="en-US",output_format:a="markdown"}=r;if(e)try{new URL(e)}catch{throw new Error(`Invalid URL: ${e}`)}const i=await o.htmlToMarkdown(e||"direct-html-input",{locale:s,htmlContent:n});let c;switch(a){case"markdown":c=[{type:"text",text:i.markdown}];break;case"html":c=[{type:"text",text:i.html}];break;case"both":c=[{type:"text",text:i.markdown},{type:"text",text:i.html}];break;default:throw new Error(`Invalid output format: ${a}`)}return{content:c,isError:!1}}catch(r){return{content:[{type:"text",text:`Error: ${r instanceof Error?r.message:String(r)}`}],isError:!0}}}async start(){const t=new s;await this.server.connect(t)}}const i=()=>new a;exports.createMcpServer=i,exports.runMcpServer=async()=>{const t=i();await t.start()};
|