validate_documentation_links
Identify and fix broken internal links in documentation files to ensure accuracy and accessibility. Supports recursive checks and customizable paths.
Instructions
Check for broken internal links in documentation files.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| basePath | No | ||
| path | No | ||
| recursive | No |
Implementation Reference
- src/handlers/documents.ts:795-879 (handler)The core handler method that implements the validate_documentation_links tool. It scans all markdown files in the specified base path (recursively by default), extracts internal markdown links, resolves them relative to the linking file, and checks if the target files exist. Reports broken links with file, link, and line number.async validateLinks(basePath = "", recursive = true): Promise<ToolResponse> { try { const validBasePath = await this.validatePath(basePath || this.docsDir); // Find all markdown files const pattern = recursive ? "**/*.md" : "*.md"; const files = await glob(pattern, { cwd: validBasePath }); const brokenLinks: Array<{ file: string; link: string; lineNumber: number; }> = []; // Check each file for links for (const file of files) { const filePath = path.join(validBasePath, file); const content = await fs.readFile(filePath, "utf-8"); const lines = content.split("\n"); // Find markdown links: [text](path) const linkRegex = /\[([^\]]+)\]\(([^)]+)\)/g; for (let i = 0; i < lines.length; i++) { const line = lines[i]; let match; while ((match = linkRegex.exec(line)) !== null) { const [, , linkPath] = match; // Skip external links and anchors if ( linkPath.startsWith("http://") || linkPath.startsWith("https://") || linkPath.startsWith("#") || linkPath.startsWith("mailto:") ) { continue; } // Resolve the link path relative to the current file const fileDir = path.dirname(filePath); const resolvedPath = path.resolve(fileDir, linkPath); // Check if the link target exists try { await fs.access(resolvedPath); } catch { brokenLinks.push({ file: path.relative(this.docsDir, filePath), link: linkPath, lineNumber: i + 1, }); } } } } return { content: [ { type: "text", text: brokenLinks.length > 0 ? `Found ${brokenLinks.length} broken links in ${files.length} files` : `No broken links found in ${files.length} files`, }, ], metadata: { brokenLinks, filesChecked: files.length, basePath: path.relative(this.docsDir, validBasePath), }, }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); return { content: [ { type: "text", text: `Error validating links: ${errorMessage}` }, ], isError: true, }; } }
- src/schemas/tools.ts:93-96 (schema)Zod schema defining the input parameters for the validate_documentation_links tool: optional basePath (defaults to root) and recursive flag (defaults to true).export const ValidateLinksSchema = ToolInputSchema.extend({ basePath: z.string().optional().default(""), recursive: z.boolean().default(true), });
- src/index.ts:285-289 (registration)Tool registration in the ListToolsRequestSchema handler, defining the tool's name, description, and input schema for discovery.name: "validate_documentation_links", description: "Check for broken internal links in documentation files.", inputSchema: zodToJsonSchema(ValidateLinksSchema) as any, },
- src/index.ts:470-481 (registration)Dispatch logic in the CallToolRequestSchema switch statement that validates input using ValidateLinksSchema and invokes the documentHandler.validateLinks method.case "validate_documentation_links": { const parsed = ValidateLinksSchema.safeParse(args); if (!parsed.success) { throw new Error( `Invalid arguments for validate_links: ${parsed.error}` ); } return await documentHandler.validateLinks( parsed.data.basePath, parsed.data.recursive ); }