Skip to main content
Glama
libra850
by libra850

find_broken_links

Detect and fix broken links in Obsidian vaults to maintain note connectivity and improve content organization.

Instructions

壊れたリンクの検出と修復支援を行います

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • Primary tool handler that implements the logic to find broken links in Obsidian vault by scanning all MD files for wiki and markdown links, verifying targets, and providing similarity-based suggestions.
    async findBrokenLinks(): Promise<{ brokenLinks: Array<{ sourceFile: string; linkText: string; targetPath: string; lineNumber: number; suggestions: string[]; }>; totalCount: number; }> { const vaultPath = this.config.vaultPath; const brokenLinks: Array<{ sourceFile: string; linkText: string; targetPath: string; lineNumber: number; suggestions: string[]; }> = []; // すべてのMarkdownファイルを取得 const allMdFiles = await this.getAllMdFiles(vaultPath); const allFileBasenames = allMdFiles.map(file => path.basename(file, '.md')); const processFile = async (filePath: string) => { try { const content = await fs.readFile(filePath, 'utf-8'); const lines = content.split('\n'); const relativeFilePath = path.relative(vaultPath, filePath); for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) { const line = lines[lineIndex]; // ウィキリンク [[]] の検出 const wikiLinkMatches = line.matchAll(/\[\[([^\]|]+)(\|[^\]]+)?\]\]/g); for (const match of wikiLinkMatches) { const targetPath = match[1]; const linkText = match[2] ? match[2].substring(1) : targetPath; // ターゲットファイルの存在確認 const possiblePaths = [ path.join(vaultPath, `${targetPath}.md`), path.join(vaultPath, targetPath), ]; let exists = false; for (const possiblePath of possiblePaths) { if (await FileUtils.fileExists(possiblePath)) { exists = true; break; } } if (!exists) { // 修復候補を検索 const suggestions = this.findSimilarFiles(targetPath, allFileBasenames); brokenLinks.push({ sourceFile: relativeFilePath, linkText, targetPath, lineNumber: lineIndex + 1, suggestions, }); } } // Markdownリンク []() の検出 const mdLinkMatches = line.matchAll(/\[([^\]]+)\]\(([^)]+)\)/g); for (const match of mdLinkMatches) { const linkText = match[1]; const targetPath = match[2]; // 内部リンク(.mdファイル)のみチェック if (targetPath.endsWith('.md') || !targetPath.includes('://')) { const fullTargetPath = path.resolve(path.dirname(filePath), targetPath); if (!(await FileUtils.fileExists(fullTargetPath))) { const suggestions = this.findSimilarFiles(path.basename(targetPath, '.md'), allFileBasenames); brokenLinks.push({ sourceFile: relativeFilePath, linkText, targetPath, lineNumber: lineIndex + 1, suggestions, }); } } } } } catch (error) { // ファイル読み込みエラーは無視 } }; // すべてのMarkdownファイルを処理 for (const filePath of allMdFiles) { await processFile(filePath); } return { brokenLinks, totalCount: brokenLinks.length, }; }
  • src/server.ts:192-199 (registration)
    MCP tool registration defining the name, description, and input schema for find_broken_links.
    { name: 'find_broken_links', description: '壊れたリンクの検出と修復支援を行います', inputSchema: { type: 'object', properties: {}, }, },
  • Server-side dispatch handler that invokes the ObsidianHandler's findBrokenLinks method and formats the response as MCP content.
    case 'find_broken_links': const brokenLinksResult = await this.obsidianHandler.findBrokenLinks(); return { content: [ { type: 'text', text: JSON.stringify(brokenLinksResult, null, 2), }, ], };
  • Helper utility to generate file name suggestions for broken links using similarity scoring.
    private findSimilarFiles(targetName: string, allFileBasenames: string[]): string[] { const target = targetName.toLowerCase(); const suggestions: { name: string; score: number }[] = []; for (const filename of allFileBasenames) { const score = this.calculateSimilarity(target, filename.toLowerCase()); if (score > 0.3) { // 30%以上の類似度 suggestions.push({ name: filename, score }); } } return suggestions .sort((a, b) => b.score - a.score) .slice(0, 5) .map(s => s.name); }
  • Helper to recursively collect all Markdown files in the vault.
    private async getAllMdFiles(dirPath: string): Promise<string[]> { const files: string[] = []; const processDirectory = async (currentPath: string) => { try { const entries = await fs.readdir(currentPath, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(currentPath, entry.name); if (entry.isDirectory()) { await processDirectory(fullPath); } else if (entry.isFile() && entry.name.endsWith('.md')) { files.push(fullPath); } } } catch (error) { // ディレクトリ読み込みエラーは無視 } }; await processDirectory(dirPath); return files; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/libra850/obsidian-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server