chore(hub): remove markdown_to_pdf tool (#3)

Drop markdown_to_pdf MCP surface, implementation, tests, and md-to-pdf dependency.

Roles that still list markdown_to_pdf must be cleaned before startup.

Co-authored-by: Hong Jiarong <me@jrhim.com>
Co-committed-by: Hong Jiarong <me@jrhim.com>
This commit is contained in:
2026-07-18 13:57:27 +08:00
committed by 洪佳荣
parent cc42e6a7c6
commit 97f7972cc5
8 changed files with 5 additions and 2077 deletions
-77
View File
@@ -6,7 +6,6 @@ import { downloadFeishuMessageResource } from "./download.js";
import { readFeishuContext } from "./read.js";
import type { ApprovalManager } from "./approval.js";
import { CPH_HUB_MCP_TOOL_IDS, type CphHubMcpToolId } from "../agent/roleTools.js";
import { MarkdownToPdfError, renderMarkdownToPdf } from "../agent/markdownToPdf.js";
import { WorkspaceFileBoundaryError } from "../security/workspaceFiles.js";
export interface FileDeliveryToolOptions {
@@ -231,76 +230,6 @@ export function createFileDeliveryMcpServer(options: FileDeliveryToolOptions): M
);
}
if (enabledTools.has("markdown_to_pdf")) {
tools.push(
tool(
"markdown_to_pdf",
"Render a Markdown file in the current project workspace to PDF (CommonMark/GFM via md-to-pdf + headless Chrome). Supports external image/CSS URLs, local images relative to the project root, and LaTeX math ($...$ / $$...$$). path is workspace-relative; output defaults to build/<name>.pdf.",
{
path: z.string().describe("Workspace-relative Markdown path (or absolute path inside the workspace)."),
output: z
.string()
.optional()
.describe("Workspace-relative PDF output path. Defaults to build/<markdown-basename>.pdf."),
},
async (args) => {
const workspaceRoot = options.workspaceRoot?.trim();
if (workspaceRoot === undefined || workspaceRoot === "") {
options.rt.logger.error(
{ runId: options.runId, projectId: options.projectId },
"markdown_to_pdf missing configured workspace root",
);
return {
isError: true,
content: [{ type: "text", text: "markdown_to_pdf is unavailable because workspace isolation is not configured." }],
};
}
try {
const result = await renderMarkdownToPdf({
workspaceRoot,
workspaceDir: options.workspaceDir,
markdownPath: args.path,
...(args.output === undefined ? {} : { outputPath: args.output }),
...(options.maxFileBytes === undefined ? {} : { maxMarkdownBytes: options.maxFileBytes }),
});
return {
content: [{
type: "text",
text: JSON.stringify({
ok: true,
path: result.outputPath,
bytes: result.bytes,
}),
}],
};
} catch (error) {
if (error instanceof MarkdownToPdfError) {
const log = error.reason === "compile" || error.reason === "config"
? options.rt.logger.warn.bind(options.rt.logger)
: options.rt.logger.error.bind(options.rt.logger);
log(
{
runId: options.runId,
projectId: options.projectId,
requestedPath: args.path,
reason: error.reason,
err: error,
},
"markdown_to_pdf failed",
);
return {
isError: true,
content: [{ type: "text", text: error.message }],
};
}
throw error;
}
},
{ alwaysLoad: true },
),
);
}
const instructions = mcpInstructions(enabledTools);
return createSdkMcpServer({
name: "cph_hub",
@@ -331,11 +260,5 @@ function mcpInstructions(enabledTools: ReadonlySet<CphHubMcpToolId>): string {
if (enabledTools.has("request_approval")) {
instructions.push("Use request_approval when explicit human approval or confirmation is required before continuing.");
}
if (enabledTools.has("markdown_to_pdf")) {
instructions.push(
"Use markdown_to_pdf to convert a workspace Markdown file into a PDF (GFM + external resources + LaTeX math).",
"After rendering, call send_file with the returned PDF path if the user should receive the file in chat.",
);
}
return instructions.join(" ");
}