-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathget-doc.js
More file actions
79 lines (72 loc) · 2.41 KB
/
get-doc.js
File metadata and controls
79 lines (72 loc) · 2.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// @ts-expect-error: fred needs to expose types
import { renderSimplified } from "@mdn/fred/out/static/ssr/index.js";
import TurndownService from "turndown";
// @ts-expect-error
import turndownPluginGfm from "turndown-plugin-gfm";
import z from "zod";
import { NonSentryError } from "../sentry/error.js";
const turndownService = new TurndownService({
headingStyle: "atx",
codeBlockStyle: "fenced",
});
turndownService.use(turndownPluginGfm.gfm);
/** @param {InstanceType<import("../server.js").ExtendedServer>} server */
export function registerGetDocTool(server) {
server.registerTool(
"get-doc",
{
title: "Get documentation",
description: "Retrieve a page of MDN documentation as markdown.",
inputSchema: {
path: z
.string()
.describe("path or full URL: e.g. '/en-US/docs/Web/API/Headers'"),
},
},
async ({ path }) => {
const url = new URL(path, "https://developer.mozilla.org");
if (url.host !== "developer.mozilla.org") {
throw new NonSentryError(`Error: ${url} doesn't look like an MDN url`);
}
if (!/^\/?([a-z-]+?\/)?docs\//i.test(url.pathname)) {
throw new NonSentryError(
`Error: ${path} doesn't look like the path to a piece of MDN documentation`,
);
}
if (!url.pathname.endsWith("/index.json")) {
url.pathname += "/index.json";
}
const res = await fetch(url);
if (!res.ok) {
if (res.status === 404) {
throw new NonSentryError(`Error: We couldn't find ${path}`);
}
throw new Error(`${res.status}: ${res.statusText} for ${path}`);
}
/** @type {import("@mdn/rari").DocPage} */
const context = await res.json();
const renderedHtml = await renderSimplified(context.url, context);
const markdown = turndownService.turndown(renderedHtml);
let frontmatter = "";
const { browserCompat } = context.doc;
if (browserCompat) {
frontmatter += "---\n";
if (browserCompat.length > 1) {
frontmatter += "compat-keys:\n";
frontmatter += browserCompat.map((key) => ` - ${key}\n`).join("");
} else {
frontmatter += `compat-key: ${browserCompat[0]}\n`;
}
frontmatter += "---\n";
}
return {
content: [
{
type: "text",
text: frontmatter + markdown,
},
],
};
},
);
}