@aiquants/html-to-markdown 0.2.5 → 0.3.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/README.md +10 -8
- package/dist/{core-CFnkfU5N.js → core-CouDTni-.js} +6 -6
- package/dist/index.cjs +1 -1
- package/dist/index.js +3 -3
- package/dist/main.js +1 -1
- package/dist/mcp-server-BAmy7d8r.js +210 -0
- package/dist/mcp-server-CCu0Pcm3.cjs +1 -0
- package/dist/{mcp-server-streamable-BC-Qlr-9.js → mcp-server-streamable-CVDJHcWu.js} +109 -152
- package/dist/mcp-server-streamable-mF26pg3E.cjs +1 -0
- package/dist/mcp-streamable.cjs +1 -1
- package/dist/mcp-streamable.js +1 -1
- package/dist/mcp.cjs +1 -1
- package/dist/mcp.js +1 -1
- package/dist/src/mcp-common.d.ts +107 -0
- package/dist/src/mcp-server-streamable.d.ts +10 -13
- package/dist/src/mcp-server.d.ts +139 -22
- package/dist/{version-BXLLJx3Z.js → version-BF9-U8Ef.js} +156 -9
- package/dist/version-Cg6D6H9g.cjs +1 -0
- package/mcp.json +3 -3
- package/package.json +1 -1
- package/dist/mcp-server-Bo_mCvzz.cjs +0 -1
- package/dist/mcp-server-CueTvF4M.js +0 -364
- package/dist/mcp-server-streamable-Cc4QsZQe.cjs +0 -1
- package/dist/version-DTaUKNBS.cjs +0 -1
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { J as JSONRPCMessageSchema, i as isInitializeRequest,
|
|
2
|
-
import { a as getAugmentedNamespace, c as commonjsGlobal, b as getDefaultExportFromCjs, h as htmlToMarkdown } from "./core-
|
|
1
|
+
import { J as JSONRPCMessageSchema, i as isInitializeRequest, d as isJSONRPCRequest, D as DEFAULT_NEGOTIATED_PROTOCOL_VERSION, e as SUPPORTED_PROTOCOL_VERSIONS, f as isJSONRPCResponse, h as isJSONRPCError, g as getPackageVersion, S as Server, I as InitializeRequestSchema, L as ListToolsRequestSchema, C as CallToolRequestSchema, p as parseHtmlToMarkdownArgs, b as parseSaveContentArgs, s as saveContentToFile } from "./version-BF9-U8Ef.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";
|
|
6
|
-
import { promises } from "fs";
|
|
7
|
-
import { join, resolve, dirname } from "path";
|
|
8
6
|
import yargsParser from "yargs-parser";
|
|
9
7
|
var bytes = { exports: {} };
|
|
10
8
|
/*!
|
|
@@ -6418,10 +6416,10 @@ function requireRawBody() {
|
|
|
6418
6416
|
if (done) {
|
|
6419
6417
|
return readStream(stream, encoding, length, limit, wrap(done));
|
|
6420
6418
|
}
|
|
6421
|
-
return new Promise(function executor(
|
|
6419
|
+
return new Promise(function executor(resolve, reject) {
|
|
6422
6420
|
readStream(stream, encoding, length, limit, function onRead(err, buf) {
|
|
6423
6421
|
if (err) return reject(err);
|
|
6424
|
-
|
|
6422
|
+
resolve(buf);
|
|
6425
6423
|
});
|
|
6426
6424
|
});
|
|
6427
6425
|
}
|
|
@@ -7159,41 +7157,6 @@ class StreamableHTTPServerTransport {
|
|
|
7159
7157
|
}
|
|
7160
7158
|
}
|
|
7161
7159
|
}
|
|
7162
|
-
function generateFilename(url, outputFormat) {
|
|
7163
|
-
if (url && url !== "direct-html-input") {
|
|
7164
|
-
try {
|
|
7165
|
-
const urlObj = new URL(url);
|
|
7166
|
-
let filename = urlObj.pathname.split("/").pop() || "page";
|
|
7167
|
-
filename = filename.replace(/\.[^.]*$/, "");
|
|
7168
|
-
filename = filename.replace(/[<>:"/\\|?*]/g, "_");
|
|
7169
|
-
if (!filename || filename.match(/^\.+$/)) {
|
|
7170
|
-
filename = "page";
|
|
7171
|
-
}
|
|
7172
|
-
return filename;
|
|
7173
|
-
} catch {
|
|
7174
|
-
return "page";
|
|
7175
|
-
}
|
|
7176
|
-
}
|
|
7177
|
-
return "page";
|
|
7178
|
-
}
|
|
7179
|
-
async function saveContentToFile(content, savePath, saveDirectory, url, outputFormat) {
|
|
7180
|
-
if (!savePath && !saveDirectory) {
|
|
7181
|
-
return null;
|
|
7182
|
-
}
|
|
7183
|
-
let finalPath;
|
|
7184
|
-
if (savePath) {
|
|
7185
|
-
finalPath = resolve(savePath);
|
|
7186
|
-
} else if (saveDirectory) {
|
|
7187
|
-
const filename = generateFilename(url);
|
|
7188
|
-
const extension = outputFormat === "html" ? ".html" : ".md";
|
|
7189
|
-
finalPath = resolve(saveDirectory, `${filename}${extension}`);
|
|
7190
|
-
} else {
|
|
7191
|
-
return null;
|
|
7192
|
-
}
|
|
7193
|
-
await promises.mkdir(dirname(finalPath), { recursive: true });
|
|
7194
|
-
await promises.writeFile(finalPath, content, "utf-8");
|
|
7195
|
-
return finalPath;
|
|
7196
|
-
}
|
|
7197
7160
|
class StreamableHtmlToMarkdownMcpServer {
|
|
7198
7161
|
constructor() {
|
|
7199
7162
|
this.version = getPackageVersion();
|
|
@@ -7213,46 +7176,59 @@ class StreamableHtmlToMarkdownMcpServer {
|
|
|
7213
7176
|
sessionIdGenerator: void 0
|
|
7214
7177
|
// Stateless server
|
|
7215
7178
|
});
|
|
7216
|
-
const toolParameters = {
|
|
7217
|
-
type: "object",
|
|
7218
|
-
properties: {
|
|
7219
|
-
url: {
|
|
7220
|
-
type: "string",
|
|
7221
|
-
description: "URL of the web page to convert (e.g., https://example.com). Handles JavaScript-rendered dynamic content effectively."
|
|
7222
|
-
},
|
|
7223
|
-
html_content: {
|
|
7224
|
-
type: "string",
|
|
7225
|
-
description: "HTML string to convert directly. Use instead of URL for local files or API response HTML content."
|
|
7226
|
-
},
|
|
7227
|
-
locale: {
|
|
7228
|
-
type: "string",
|
|
7229
|
-
description: "Browser locale setting. Use 'ja-JP' for Japanese sites, 'en-US' for English sites. Affects content rendering and language detection.",
|
|
7230
|
-
enum: ["en-US", "ja-JP"],
|
|
7231
|
-
default: "en-US"
|
|
7232
|
-
},
|
|
7233
|
-
output_format: {
|
|
7234
|
-
type: "string",
|
|
7235
|
-
description: "Output format: 'markdown' (Markdown only), 'html' (original HTML only), 'both' (returns both formats).",
|
|
7236
|
-
enum: ["markdown", "html", "both"],
|
|
7237
|
-
default: "markdown"
|
|
7238
|
-
},
|
|
7239
|
-
save_path: {
|
|
7240
|
-
type: "string",
|
|
7241
|
-
description: "Complete file path including filename to save converted content (e.g., '/home/user/output.md'). Cannot be used with save_directory."
|
|
7242
|
-
},
|
|
7243
|
-
save_directory: {
|
|
7244
|
-
type: "string",
|
|
7245
|
-
description: "Directory path to save converted content with auto-generated filename (e.g., '/home/user/downloads'). Cannot be used with save_path."
|
|
7246
|
-
}
|
|
7247
|
-
},
|
|
7248
|
-
anyOf: [{ required: ["url"] }, { required: ["html_content"] }]
|
|
7249
|
-
};
|
|
7250
7179
|
this.tools = [
|
|
7251
7180
|
{
|
|
7252
7181
|
name: "html_to_markdown_streamable",
|
|
7253
7182
|
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
|
-
inputSchema:
|
|
7183
|
+
inputSchema: {
|
|
7184
|
+
type: "object",
|
|
7185
|
+
properties: {
|
|
7186
|
+
url: {
|
|
7187
|
+
type: "string",
|
|
7188
|
+
description: "URL of the web page to convert (e.g., https://example.com). Handles JavaScript-rendered dynamic content effectively."
|
|
7189
|
+
},
|
|
7190
|
+
html_content: {
|
|
7191
|
+
type: "string",
|
|
7192
|
+
description: "HTML string to convert directly. Use instead of URL for local files or API response HTML content."
|
|
7193
|
+
},
|
|
7194
|
+
locale: {
|
|
7195
|
+
type: "string",
|
|
7196
|
+
description: "Browser locale setting. Use 'ja-JP' for Japanese sites, 'en-US' for English sites. Affects content rendering and language detection.",
|
|
7197
|
+
enum: ["en-US", "ja-JP"],
|
|
7198
|
+
default: "en-US"
|
|
7199
|
+
}
|
|
7200
|
+
},
|
|
7201
|
+
anyOf: [{ required: ["url"] }, { required: ["html_content"] }]
|
|
7202
|
+
},
|
|
7255
7203
|
handler: (args, context) => this.handleHtmlToMarkdown(args, context)
|
|
7204
|
+
},
|
|
7205
|
+
{
|
|
7206
|
+
name: "save_content_to_file",
|
|
7207
|
+
description: "Save text content to a file with specified path or directory. Supports automatic filename generation. Content will be saved as Markdown format.",
|
|
7208
|
+
inputSchema: {
|
|
7209
|
+
type: "object",
|
|
7210
|
+
properties: {
|
|
7211
|
+
content: {
|
|
7212
|
+
type: "string",
|
|
7213
|
+
description: "Text content to save to file. Will be saved as Markdown format."
|
|
7214
|
+
},
|
|
7215
|
+
save_path: {
|
|
7216
|
+
type: "string",
|
|
7217
|
+
description: "Complete file path including filename to save content (e.g., '/home/user/output.md'). Cannot be used with save_directory."
|
|
7218
|
+
},
|
|
7219
|
+
save_directory: {
|
|
7220
|
+
type: "string",
|
|
7221
|
+
description: "Directory path to save content with auto-generated filename (e.g., '/home/user/downloads'). Cannot be used with save_path."
|
|
7222
|
+
},
|
|
7223
|
+
filename: {
|
|
7224
|
+
type: "string",
|
|
7225
|
+
description: "Base filename to use when save_directory is specified (e.g., 'my-document'). Extension .md will be added automatically."
|
|
7226
|
+
}
|
|
7227
|
+
},
|
|
7228
|
+
required: ["content"],
|
|
7229
|
+
anyOf: [{ required: ["save_path"] }, { required: ["save_directory"] }]
|
|
7230
|
+
},
|
|
7231
|
+
handler: (args, context) => this.handleSaveContentToFile(args, context)
|
|
7256
7232
|
}
|
|
7257
7233
|
];
|
|
7258
7234
|
this.setupRequestHandlers();
|
|
@@ -7339,19 +7315,8 @@ class StreamableHtmlToMarkdownMcpServer {
|
|
|
7339
7315
|
*/
|
|
7340
7316
|
async *handleHtmlToMarkdown(args, _context) {
|
|
7341
7317
|
try {
|
|
7342
|
-
const
|
|
7343
|
-
|
|
7344
|
-
throw new Error("url または html_content のいずれかを提供する必要があります。");
|
|
7345
|
-
}
|
|
7346
|
-
if (save_path && typeof save_path !== "string") {
|
|
7347
|
-
throw new Error("'save_path' must be a string");
|
|
7348
|
-
}
|
|
7349
|
-
if (save_directory && typeof save_directory !== "string") {
|
|
7350
|
-
throw new Error("'save_directory' must be a string");
|
|
7351
|
-
}
|
|
7352
|
-
if (save_path && save_directory) {
|
|
7353
|
-
throw new Error("Cannot specify both 'save_path' and 'save_directory'");
|
|
7354
|
-
}
|
|
7318
|
+
const validatedArgs = parseHtmlToMarkdownArgs(args);
|
|
7319
|
+
const { url, html_content, locale = "en-US" } = validatedArgs;
|
|
7355
7320
|
if (url) {
|
|
7356
7321
|
try {
|
|
7357
7322
|
new URL(url);
|
|
@@ -7370,70 +7335,61 @@ class StreamableHtmlToMarkdownMcpServer {
|
|
|
7370
7335
|
});
|
|
7371
7336
|
yield {
|
|
7372
7337
|
type: "progress",
|
|
7373
|
-
progress:
|
|
7374
|
-
message: "
|
|
7338
|
+
progress: 100,
|
|
7339
|
+
message: "変換が完了しました。"
|
|
7375
7340
|
};
|
|
7376
|
-
const
|
|
7377
|
-
|
|
7378
|
-
|
|
7379
|
-
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
|
|
7385
|
-
|
|
7386
|
-
|
|
7387
|
-
|
|
7388
|
-
|
|
7389
|
-
|
|
7390
|
-
|
|
7391
|
-
if (markdownPath) {
|
|
7392
|
-
const savedMarkdownPath = await saveContentToFile(result.markdown, markdownPath, void 0, url, "markdown");
|
|
7393
|
-
if (savedMarkdownPath) savedPaths.push(savedMarkdownPath);
|
|
7394
|
-
}
|
|
7395
|
-
const htmlPath = save_path ? save_path.endsWith(".html") ? save_path : `${save_path}.html` : save_directory ? join(save_directory, `${generateFilename(url)}.html`) : void 0;
|
|
7396
|
-
if (htmlPath) {
|
|
7397
|
-
const savedHtmlPath = await saveContentToFile(result.html, htmlPath, void 0, url, "html");
|
|
7398
|
-
if (savedHtmlPath) savedPaths.push(savedHtmlPath);
|
|
7341
|
+
const responseText = result.markdown;
|
|
7342
|
+
const content = [{ type: "text", text: responseText }];
|
|
7343
|
+
yield {
|
|
7344
|
+
type: "result",
|
|
7345
|
+
result: { content }
|
|
7346
|
+
};
|
|
7347
|
+
} catch (error) {
|
|
7348
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
7349
|
+
yield {
|
|
7350
|
+
type: "result",
|
|
7351
|
+
result: {
|
|
7352
|
+
content: [
|
|
7353
|
+
{
|
|
7354
|
+
type: "text",
|
|
7355
|
+
text: `エラーが発生しました: ${errorMessage}`
|
|
7399
7356
|
}
|
|
7400
|
-
|
|
7401
|
-
}
|
|
7357
|
+
]
|
|
7402
7358
|
}
|
|
7403
|
-
}
|
|
7359
|
+
};
|
|
7360
|
+
}
|
|
7361
|
+
}
|
|
7362
|
+
/**
|
|
7363
|
+
* Handle save content to file tool call with streamable support.
|
|
7364
|
+
* streamable サポート付きのファイル保存ツール呼び出しを処理
|
|
7365
|
+
*/
|
|
7366
|
+
async *handleSaveContentToFile(args, _context) {
|
|
7367
|
+
try {
|
|
7368
|
+
const validatedArgs = parseSaveContentArgs(args);
|
|
7369
|
+
const { content, save_path, save_directory, filename } = validatedArgs;
|
|
7370
|
+
yield {
|
|
7371
|
+
type: "progress",
|
|
7372
|
+
progress: 20,
|
|
7373
|
+
message: "ファイル保存の準備中..."
|
|
7374
|
+
};
|
|
7375
|
+
const savedPath = await saveContentToFile(content, save_path, save_directory, filename);
|
|
7404
7376
|
yield {
|
|
7405
7377
|
type: "progress",
|
|
7406
7378
|
progress: 100,
|
|
7407
|
-
message: "
|
|
7379
|
+
message: "ファイル保存が完了しました。"
|
|
7408
7380
|
};
|
|
7409
|
-
|
|
7410
|
-
switch (output_format) {
|
|
7411
|
-
case "markdown":
|
|
7412
|
-
responseText = result.markdown;
|
|
7413
|
-
break;
|
|
7414
|
-
case "html":
|
|
7415
|
-
responseText = result.html;
|
|
7416
|
-
break;
|
|
7417
|
-
case "both":
|
|
7418
|
-
responseText = `=== Markdown ===
|
|
7419
|
-
${result.markdown}
|
|
7420
|
-
|
|
7421
|
-
=== HTML ===
|
|
7422
|
-
${result.html}`;
|
|
7423
|
-
break;
|
|
7424
|
-
default:
|
|
7425
|
-
throw new Error(`Invalid output format: ${output_format}`);
|
|
7426
|
-
}
|
|
7427
|
-
if (savedPaths.length > 0) {
|
|
7428
|
-
responseText += `
|
|
7429
|
-
|
|
7430
|
-
=== Files Saved ===
|
|
7431
|
-
${savedPaths.map((path) => `- ${path}`).join("\n")}`;
|
|
7432
|
-
}
|
|
7433
|
-
const content = [{ type: "text", text: responseText }];
|
|
7381
|
+
const responseText = `Content saved successfully to: ${savedPath}`;
|
|
7434
7382
|
yield {
|
|
7435
7383
|
type: "result",
|
|
7436
|
-
result: {
|
|
7384
|
+
result: {
|
|
7385
|
+
content: [
|
|
7386
|
+
{
|
|
7387
|
+
type: "text",
|
|
7388
|
+
text: responseText
|
|
7389
|
+
}
|
|
7390
|
+
],
|
|
7391
|
+
isError: false
|
|
7392
|
+
}
|
|
7437
7393
|
};
|
|
7438
7394
|
} catch (error) {
|
|
7439
7395
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -7445,7 +7401,8 @@ ${savedPaths.map((path) => `- ${path}`).join("\n")}`;
|
|
|
7445
7401
|
type: "text",
|
|
7446
7402
|
text: `エラーが発生しました: ${errorMessage}`
|
|
7447
7403
|
}
|
|
7448
|
-
]
|
|
7404
|
+
],
|
|
7405
|
+
isError: true
|
|
7449
7406
|
}
|
|
7450
7407
|
};
|
|
7451
7408
|
}
|
|
@@ -7466,7 +7423,7 @@ ${savedPaths.map((path) => `- ${path}`).join("\n")}`;
|
|
|
7466
7423
|
app.use(express.json());
|
|
7467
7424
|
await this.server.connect(this.transport);
|
|
7468
7425
|
app.post("/mcp", async (req, res) => {
|
|
7469
|
-
console.
|
|
7426
|
+
console.info("Received MCP request:", req.body);
|
|
7470
7427
|
try {
|
|
7471
7428
|
res.setHeader("Content-Type", "application/json");
|
|
7472
7429
|
const request = req.body;
|
|
@@ -7573,7 +7530,7 @@ ${savedPaths.map((path) => `- ${path}`).join("\n")}`;
|
|
|
7573
7530
|
}
|
|
7574
7531
|
});
|
|
7575
7532
|
app.get("/mcp", async (_req, res) => {
|
|
7576
|
-
console.
|
|
7533
|
+
console.info("Received GET MCP request");
|
|
7577
7534
|
res.writeHead(405).end(
|
|
7578
7535
|
JSON.stringify({
|
|
7579
7536
|
jsonrpc: "2.0",
|
|
@@ -7586,7 +7543,7 @@ ${savedPaths.map((path) => `- ${path}`).join("\n")}`;
|
|
|
7586
7543
|
);
|
|
7587
7544
|
});
|
|
7588
7545
|
app.delete("/mcp", async (_req, res) => {
|
|
7589
|
-
console.
|
|
7546
|
+
console.info("Received DELETE MCP request");
|
|
7590
7547
|
res.writeHead(405).end(
|
|
7591
7548
|
JSON.stringify({
|
|
7592
7549
|
jsonrpc: "2.0",
|
|
@@ -7599,19 +7556,19 @@ ${savedPaths.map((path) => `- ${path}`).join("\n")}`;
|
|
|
7599
7556
|
);
|
|
7600
7557
|
});
|
|
7601
7558
|
const server = app.listen(port, host, () => {
|
|
7602
|
-
console.
|
|
7559
|
+
console.info(`HTML to Markdown Streamable MCP server started on http://${host}:${port}/mcp`);
|
|
7603
7560
|
});
|
|
7604
7561
|
process.on("SIGINT", async () => {
|
|
7605
|
-
console.
|
|
7562
|
+
console.info("Shutting down server...");
|
|
7606
7563
|
try {
|
|
7607
|
-
console.
|
|
7564
|
+
console.info("Closing transport");
|
|
7608
7565
|
await this.transport.close();
|
|
7609
7566
|
} catch (error) {
|
|
7610
7567
|
console.error("Error closing transport:", error);
|
|
7611
7568
|
}
|
|
7612
7569
|
await this.server.close();
|
|
7613
7570
|
server.close(() => {
|
|
7614
|
-
console.
|
|
7571
|
+
console.info("Server shutdown complete");
|
|
7615
7572
|
process.exit(0);
|
|
7616
7573
|
});
|
|
7617
7574
|
});
|