@aiquants/html-to-markdown 0.2.4 → 0.2.6

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.
@@ -61,12 +61,12 @@ const getMessage = (locale, key2, replacements) => {
61
61
  const getHtmlWithPlaywright = async (url, locale) => {
62
62
  let browser;
63
63
  try {
64
- console.error(getMessage(locale, "playwright_launch"));
64
+ console.info(getMessage(locale, "playwright_launch"));
65
65
  browser = await chromium.launch();
66
66
  const page = await browser.newPage({ locale });
67
- console.error(getMessage(locale, "playwright_goto", { url, locale }));
67
+ console.info(getMessage(locale, "playwright_goto", { url, locale }));
68
68
  await page.goto(url, { waitUntil: "networkidle" });
69
- console.error(getMessage(locale, "playwright_get_content"));
69
+ console.info(getMessage(locale, "playwright_get_content"));
70
70
  const html2 = await page.content();
71
71
  return html2;
72
72
  } catch (error) {
@@ -75,7 +75,7 @@ const getHtmlWithPlaywright = async (url, locale) => {
75
75
  } finally {
76
76
  if (browser) {
77
77
  await browser.close();
78
- console.error(getMessage(locale, "playwright_close"));
78
+ console.info(getMessage(locale, "playwright_close"));
79
79
  }
80
80
  }
81
81
  };
@@ -20681,7 +20681,7 @@ const handleTableCell = (_state, node2, _parent) => {
20681
20681
  return { type: "tableCell", children: [{ type: "html", value }] };
20682
20682
  };
20683
20683
  const convertHtmlToMarkdown = async (html2, baseUrl, locale) => {
20684
- console.error(getMessage(locale, "convert_start"));
20684
+ console.info(getMessage(locale, "convert_start"));
20685
20685
  const slugger2 = new BananaSlug();
20686
20686
  const file = await unified().use(rehypeParse, { fragment: true }).use(rehypeRaw).use(rehypeSanitizeHtml).use(rehypeWikipediaFootnotes).use(rehypeNamedAnchors).use(rehypeSlug).use(rehypeParagraphWrapper).use(rehypeAbsoluteLinks, { baseUrl }).use(rehypeRemark, {
20687
20687
  handlers: {
@@ -20783,7 +20783,7 @@ const convertHtmlToMarkdown = async (html2, baseUrl, locale) => {
20783
20783
  }).process(html2);
20784
20784
  const unescapedMarkdown = String(file).replace(/\\\[\^(.+?)\\?\](?!\s*:)/g, "[^$1]").replace(/\]\(\\#/g, "](#");
20785
20785
  const correctedMarkdown = unescapedMarkdown.replace(/(\s*)- - /g, "$1- ").replace(/(\s*)\* \* /g, "$1* ");
20786
- console.error(getMessage(locale, "convert_success"));
20786
+ console.info(getMessage(locale, "convert_success"));
20787
20787
  return correctedMarkdown;
20788
20788
  };
20789
20789
  const htmlToMarkdown = async (urlOrHtml, options = {}) => {
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 r=require("./core-D2dlEt1l.cjs"),t=require("./mcp-server-B5lrAMe3.cjs"),c=require("./mcp-server-streamable-B3R3qi85.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;
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-Bo_mCvzz.cjs"),c=require("./mcp-server-streamable-Cc4QsZQe.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,9 +5,9 @@ Object.assign(global, {
5
5
  window,
6
6
  self: window
7
7
  });
8
- import { g, h } from "./core-CFnkfU5N.js";
9
- import { c, r } from "./mcp-server-BEggrdWH.js";
10
- import { c as c2, r as r2 } from "./mcp-server-streamable-CuBJeQTj.js";
8
+ import { g, h } from "./core-CouDTni-.js";
9
+ import { c, r } from "./mcp-server-B8hz3lXI.js";
10
+ import { c as c2, r as r2 } from "./mcp-server-streamable-3B3B1fuS.js";
11
11
  export {
12
12
  c as createMcpServer,
13
13
  c2 as createStreamableMcpServer,
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-CFnkfU5N.js";
9
+ import { g as getMessage, h as htmlToMarkdown } from "./core-CouDTni-.js";
10
10
  const runCli = async () => {
11
11
  const yargsParser = (await import("yargs-parser")).default;
12
12
  const fs = await import("node:fs");
@@ -5,11 +5,11 @@ Object.assign(global, {
5
5
  window,
6
6
  self: window
7
7
  });
8
- import { J as JSONRPCMessageSchema, g as getPackageVersion, S as Server, L as ListToolsRequestSchema, C as CallToolRequestSchema } from "./version-BXLLJx3Z.js";
8
+ import { J as JSONRPCMessageSchema, g as getPackageVersion, S as Server, L as ListToolsRequestSchema, C as CallToolRequestSchema } from "./version-PCzxchJe.js";
9
9
  import process from "node:process";
10
10
  import { promises } from "fs";
11
11
  import { join, resolve, dirname } from "path";
12
- import { h as htmlToMarkdown } from "./core-CFnkfU5N.js";
12
+ import { h as htmlToMarkdown } from "./core-CouDTni-.js";
13
13
  class ReadBuffer {
14
14
  append(chunk) {
15
15
  this._buffer = this._buffer ? Buffer.concat([this._buffer, chunk]) : chunk;
@@ -178,7 +178,7 @@ class HtmlToMarkdownMcpServer {
178
178
  {
179
179
  name: "@aiquants/html-to-markdown",
180
180
  version: this.version,
181
- description: "A tool to dynamically fetch a web page from a given URL and convert it to Markdown."
181
+ description: "Convert web pages and HTML to Markdown with JavaScript dynamic content support, table structure preservation, and file saving capabilities."
182
182
  },
183
183
  {
184
184
  capabilities: {
@@ -198,37 +198,37 @@ class HtmlToMarkdownMcpServer {
198
198
  tools: [
199
199
  {
200
200
  name: "html_to_markdown",
201
- description: "Convert HTML content from a URL or HTML string to Markdown format. Supports dynamic content loading and preserves table structures.",
201
+ description: "Convert web pages or HTML strings to Markdown format. Handles JavaScript-rendered dynamic content and preserves table structures with file saving capabilities.",
202
202
  inputSchema: {
203
203
  type: "object",
204
204
  properties: {
205
205
  url: {
206
206
  type: "string",
207
- description: "The URL of the web page to convert to Markdown"
207
+ description: "URL of the web page to convert (e.g., https://example.com). Handles JavaScript-rendered dynamic content effectively."
208
208
  },
209
209
  html_content: {
210
210
  type: "string",
211
- description: "HTML content as a string to convert to Markdown (alternative to URL)"
211
+ description: "HTML string to convert directly. Use instead of URL for local files or API response HTML content."
212
212
  },
213
213
  locale: {
214
214
  type: "string",
215
- description: "The locale to use for browser context (en-US or ja-JP)",
215
+ description: "Browser locale setting. Use 'ja-JP' for Japanese sites, 'en-US' for English sites. Affects content rendering and language detection.",
216
216
  enum: ["en-US", "ja-JP"],
217
217
  default: "en-US"
218
218
  },
219
219
  output_format: {
220
220
  type: "string",
221
- description: "Output format: 'markdown' (default), 'html', or 'both'",
221
+ description: "Output format: 'markdown' (Markdown only), 'html' (original HTML only), 'both' (returns both formats).",
222
222
  enum: ["markdown", "html", "both"],
223
223
  default: "markdown"
224
224
  },
225
225
  save_path: {
226
226
  type: "string",
227
- description: "Full path (including filename) where to save the converted content. Cannot be used with save_directory."
227
+ description: "Complete file path including filename to save converted content (e.g., '/home/user/output.md'). Cannot be used with save_directory."
228
228
  },
229
229
  save_directory: {
230
230
  type: "string",
231
- description: "Directory path where to save the converted content with auto-generated filename. Cannot be used with save_path."
231
+ description: "Directory path to save converted content with auto-generated filename (e.g., '/home/user/downloads'). Cannot be used with save_path."
232
232
  }
233
233
  },
234
234
  anyOf: [{ required: ["url"] }, { required: ["html_content"] }]
@@ -348,7 +348,7 @@ ${savedPaths.map((path) => `- ${path}`).join("\n")}`;
348
348
  async start() {
349
349
  const transport = new StdioServerTransport();
350
350
  await this.server.connect(transport);
351
- console.error("HTML to Markdown MCP server started");
351
+ console.info("HTML to Markdown MCP server started");
352
352
  }
353
353
  }
354
354
  const createMcpServer = () => {
@@ -0,0 +1 @@
1
+ const t=new(require("happy-dom").Window);Object.assign(global,{document:t.document,window:t,self:t});const e=require("./version-DTaUKNBS.cjs"),r=require("node:process"),n=require("fs"),o=require("path"),s=require("./core-D2dlEt1l.cjs");class a{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 r=this._buffer.toString("utf8",0,t).replace(/\r$/,"");return this._buffer=this._buffer.subarray(t+1),function(t){return e.JSONRPCMessageSchema.parse(JSON.parse(t))}(r)}clear(){this._buffer=void 0}}class i{constructor(t=r.stdin,e=r.stdout){this._stdin=t,this._stdout=e,this._readBuffer=new a,this._started=!1,this._ondata=t=>{this._readBuffer.append(t),this.processReadBuffer()},this._onerror=t=>{var e;null===(e=this.onerror)||void 0===e||e.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,e;;)try{const e=this._readBuffer.readMessage();if(null===e)break;null===(t=this.onmessage)||void 0===t||t.call(this,e)}catch(r){null===(e=this.onerror)||void 0===e||e.call(this,r)}}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(e=>{const r=function(t){return JSON.stringify(t)+"\n"}(t);this._stdout.write(r)?e():this._stdout.once("drain",e)})}}function c(t,e){if(t&&"direct-html-input"!==t)try{let e=new URL(t).pathname.split("/").pop()||"page";return e=e.replace(/\.[^.]*$/,""),e=e.replace(/[<>:"/\\|?*]/g,"_"),e&&!e.match(/^\.+$/)||(e="page"),e}catch{return"page"}return"page"}async function l(t,e,r,s,a){if(!e&&!r)return null;let i;if(e)i=o.resolve(e);else{if(!r)return null;{const t=c(s),e="html"===a?".html":".md";i=o.resolve(r,`${t}${e}`)}}return await n.promises.mkdir(o.dirname(i),{recursive:!0}),await n.promises.writeFile(i,t,"utf-8"),i}class d{constructor(){this.version=e.getPackageVersion(),this.server=new e.Server({name:"@aiquants/html-to-markdown",version:this.version,description:"Convert web pages and HTML to Markdown with JavaScript dynamic content support, table structure preservation, and file saving capabilities."},{capabilities:{tools:{}}}),this.setupToolHandlers()}setupToolHandlers(){this.server.setRequestHandler(e.ListToolsRequestSchema,async()=>({tools:[{name:"html_to_markdown",description:"Convert web pages or HTML strings to Markdown format. Handles JavaScript-rendered dynamic content and preserves table structures with file saving capabilities.",inputSchema:{type:"object",properties:{url:{type:"string",description:"URL of the web page to convert (e.g., https://example.com). Handles JavaScript-rendered dynamic content effectively."},html_content:{type:"string",description:"HTML string to convert directly. Use instead of URL for local files or API response HTML content."},locale:{type:"string",description:"Browser locale setting. Use 'ja-JP' for Japanese sites, 'en-US' for English sites. Affects content rendering and language detection.",enum:["en-US","ja-JP"],default:"en-US"},output_format:{type:"string",description:"Output format: 'markdown' (Markdown only), 'html' (original HTML only), 'both' (returns both formats).",enum:["markdown","html","both"],default:"markdown"},save_path:{type:"string",description:"Complete file path including filename to save converted content (e.g., '/home/user/output.md'). Cannot be used with save_directory."},save_directory:{type:"string",description:"Directory path to save converted content with auto-generated filename (e.g., '/home/user/downloads'). Cannot be used with save_path."}},anyOf:[{required:["url"]},{required:["html_content"]}]}}]})),this.server.setRequestHandler(e.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 e=function(t){if(!t||"object"!=typeof t)throw new Error("Arguments are required");const{url:e,html_content:r,locale:n="en-US",output_format:o="markdown",save_path:s,save_directory:a}=t;if(!e&&!r)throw new Error("Either 'url' or 'html_content' is required");if(e&&"string"!=typeof e)throw new Error("'url' must be a string");if(r&&"string"!=typeof r)throw new Error("'html_content' must be a string");if(n&&!["en-US","ja-JP"].includes(n))throw new Error("'locale' must be 'en-US' or 'ja-JP'");if(o&&!["markdown","html","both"].includes(o))throw new Error("'output_format' must be 'markdown', 'html', or 'both'");if(s&&"string"!=typeof s)throw new Error("'save_path' must be a string");if(a&&"string"!=typeof a)throw new Error("'save_directory' must be a string");if(s&&a)throw new Error("Cannot specify both 'save_path' and 'save_directory'");return{url:e,html_content:r,locale:n,output_format:o,save_path:s,save_directory:a}}(t),{url:r,html_content:n,locale:a="en-US",output_format:i="markdown",save_path:d,save_directory:h}=e;if(r)try{new URL(r)}catch{throw new Error(`Invalid URL: ${r}`)}const u=await s.htmlToMarkdown(r||"direct-html-input",{locale:a,htmlContent:n}),m=[];if(d||h)switch(i){case"markdown":{const t=await l(u.markdown,d,h,r,"markdown");t&&m.push(t);break}case"html":{const t=await l(u.html,d,h,r,"html");t&&m.push(t);break}case"both":{const t=d?d.endsWith(".md")?d:`${d}.md`:h?o.join(h,`${c(r)}.md`):void 0;if(t){const e=await l(u.markdown,t,void 0,r,"markdown");e&&m.push(e)}const e=d?d.endsWith(".html")?d:`${d}.html`:h?o.join(h,`${c(r)}.html`):void 0;if(e){const t=await l(u.html,e,void 0,r,"html");t&&m.push(t)}break}}let f="";switch(i){case"markdown":f=u.markdown;break;case"html":f=u.html;break;case"both":f=`=== Markdown ===\n${u.markdown}\n\n=== HTML ===\n${u.html}`;break;default:throw new Error(`Invalid output format: ${i}`)}m.length>0&&(f+=`\n\n=== Files Saved ===\n${m.map(t=>`- ${t}`).join("\n")}`);return{content:[{type:"text",text:f}],isError:!1}}catch(e){return{content:[{type:"text",text:`Error: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}}async start(){const t=new i;await this.server.connect(t)}}const h=()=>new d;exports.createMcpServer=h,exports.runMcpServer=async()=>{const t=h();await t.start()};
@@ -1,5 +1,5 @@
1
- import { J as JSONRPCMessageSchema, i as isInitializeRequest, a as isJSONRPCRequest, D as DEFAULT_NEGOTIATED_PROTOCOL_VERSION, b as SUPPORTED_PROTOCOL_VERSIONS, c as isJSONRPCResponse, d as isJSONRPCError, g as getPackageVersion, S as Server, I as InitializeRequestSchema, L as ListToolsRequestSchema, C as CallToolRequestSchema } from "./version-BXLLJx3Z.js";
2
- import { a as getAugmentedNamespace, c as commonjsGlobal, b as getDefaultExportFromCjs, h as htmlToMarkdown } from "./core-CFnkfU5N.js";
1
+ import { J as JSONRPCMessageSchema, i as isInitializeRequest, a as isJSONRPCRequest, D as DEFAULT_NEGOTIATED_PROTOCOL_VERSION, b as SUPPORTED_PROTOCOL_VERSIONS, c as isJSONRPCResponse, d as isJSONRPCError, g as getPackageVersion, S as Server, I as InitializeRequestSchema, L as ListToolsRequestSchema, C as CallToolRequestSchema } from "./version-PCzxchJe.js";
2
+ import { a as getAugmentedNamespace, c as commonjsGlobal, b as getDefaultExportFromCjs, h as htmlToMarkdown } from "./core-CouDTni-.js";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import cors from "cors";
5
5
  import express from "express";
@@ -7201,7 +7201,7 @@ class StreamableHtmlToMarkdownMcpServer {
7201
7201
  {
7202
7202
  name: "@aiquants/html-to-markdown-streamable",
7203
7203
  version: this.version,
7204
- description: "A streamable tool to dynamically fetch a web page from a given URL and convert it to Markdown."
7204
+ description: "Streamable HTML to Markdown converter with real-time progress updates and JavaScript dynamic content support."
7205
7205
  },
7206
7206
  {
7207
7207
  capabilities: {
@@ -7218,31 +7218,31 @@ class StreamableHtmlToMarkdownMcpServer {
7218
7218
  properties: {
7219
7219
  url: {
7220
7220
  type: "string",
7221
- description: "The URL of the web page to convert to Markdown"
7221
+ description: "URL of the web page to convert (e.g., https://example.com). Handles JavaScript-rendered dynamic content effectively."
7222
7222
  },
7223
7223
  html_content: {
7224
7224
  type: "string",
7225
- description: "HTML content as a string to convert to Markdown (alternative to URL)"
7225
+ description: "HTML string to convert directly. Use instead of URL for local files or API response HTML content."
7226
7226
  },
7227
7227
  locale: {
7228
7228
  type: "string",
7229
- description: "The locale to use for browser context (en-US or ja-JP)",
7229
+ description: "Browser locale setting. Use 'ja-JP' for Japanese sites, 'en-US' for English sites. Affects content rendering and language detection.",
7230
7230
  enum: ["en-US", "ja-JP"],
7231
7231
  default: "en-US"
7232
7232
  },
7233
7233
  output_format: {
7234
7234
  type: "string",
7235
- description: "Output format: 'markdown' (default), 'html', or 'both'",
7235
+ description: "Output format: 'markdown' (Markdown only), 'html' (original HTML only), 'both' (returns both formats).",
7236
7236
  enum: ["markdown", "html", "both"],
7237
7237
  default: "markdown"
7238
7238
  },
7239
7239
  save_path: {
7240
7240
  type: "string",
7241
- description: "Full path (including filename) where to save the converted content. Cannot be used with save_directory."
7241
+ description: "Complete file path including filename to save converted content (e.g., '/home/user/output.md'). Cannot be used with save_directory."
7242
7242
  },
7243
7243
  save_directory: {
7244
7244
  type: "string",
7245
- description: "Directory path where to save the converted content with auto-generated filename. Cannot be used with save_path."
7245
+ description: "Directory path to save converted content with auto-generated filename (e.g., '/home/user/downloads'). Cannot be used with save_path."
7246
7246
  }
7247
7247
  },
7248
7248
  anyOf: [{ required: ["url"] }, { required: ["html_content"] }]
@@ -7250,7 +7250,7 @@ class StreamableHtmlToMarkdownMcpServer {
7250
7250
  this.tools = [
7251
7251
  {
7252
7252
  name: "html_to_markdown_streamable",
7253
- description: "Convert HTML content from a URL or HTML string to Markdown format with streamable support. Supports dynamic content loading and preserves table structures.",
7253
+ description: "Streamable HTML to Markdown converter with real-time progress updates. Ideal for large pages and time-consuming conversions with JavaScript dynamic content support.",
7254
7254
  inputSchema: toolParameters,
7255
7255
  handler: (args, context) => this.handleHtmlToMarkdown(args, context)
7256
7256
  }
@@ -7466,7 +7466,7 @@ ${savedPaths.map((path) => `- ${path}`).join("\n")}`;
7466
7466
  app.use(express.json());
7467
7467
  await this.server.connect(this.transport);
7468
7468
  app.post("/mcp", async (req, res) => {
7469
- console.error("Received MCP request:", req.body);
7469
+ console.info("Received MCP request:", req.body);
7470
7470
  try {
7471
7471
  res.setHeader("Content-Type", "application/json");
7472
7472
  const request = req.body;
@@ -7573,7 +7573,7 @@ ${savedPaths.map((path) => `- ${path}`).join("\n")}`;
7573
7573
  }
7574
7574
  });
7575
7575
  app.get("/mcp", async (_req, res) => {
7576
- console.error("Received GET MCP request");
7576
+ console.info("Received GET MCP request");
7577
7577
  res.writeHead(405).end(
7578
7578
  JSON.stringify({
7579
7579
  jsonrpc: "2.0",
@@ -7586,7 +7586,7 @@ ${savedPaths.map((path) => `- ${path}`).join("\n")}`;
7586
7586
  );
7587
7587
  });
7588
7588
  app.delete("/mcp", async (_req, res) => {
7589
- console.error("Received DELETE MCP request");
7589
+ console.info("Received DELETE MCP request");
7590
7590
  res.writeHead(405).end(
7591
7591
  JSON.stringify({
7592
7592
  jsonrpc: "2.0",
@@ -7599,19 +7599,19 @@ ${savedPaths.map((path) => `- ${path}`).join("\n")}`;
7599
7599
  );
7600
7600
  });
7601
7601
  const server = app.listen(port, host, () => {
7602
- console.error(`HTML to Markdown Streamable MCP server started on http://${host}:${port}/mcp`);
7602
+ console.info(`HTML to Markdown Streamable MCP server started on http://${host}:${port}/mcp`);
7603
7603
  });
7604
7604
  process.on("SIGINT", async () => {
7605
- console.error("Shutting down server...");
7605
+ console.info("Shutting down server...");
7606
7606
  try {
7607
- console.error("Closing transport");
7607
+ console.info("Closing transport");
7608
7608
  await this.transport.close();
7609
7609
  } catch (error) {
7610
7610
  console.error("Error closing transport:", error);
7611
7611
  }
7612
7612
  await this.server.close();
7613
7613
  server.close(() => {
7614
- console.error("Server shutdown complete");
7614
+ console.info("Server shutdown complete");
7615
7615
  process.exit(0);
7616
7616
  });
7617
7617
  });