import Link from "next/link"; import { listDocuments } from "@mcpedia/core"; import { SECTIONS } from "@mcpedia/config/sections"; export const dynamic = "force-dynamic"; /** * Build a hierarchical folder tree from a flat list of document paths. * Each tree node is either a folder (has children) or a leaf doc. */ interface TreeNode { name: string; slug: string; title: string; children: TreeNode[]; isLeaf: boolean; } function buildFolderTree(paths: string[], section: string): TreeNode[] { const tree: TreeNode[] = []; const base = `${section}/`; const addPath = (cleanPath: string) => { const parts = cleanPath.split("/"); let current = tree; let currentPath = section; for (let i = 0; i < parts.length; i++) { const part = parts[i]; const isLeaf = i === parts.length - 1; currentPath = `${currentPath}/${part}`; let node = current.find((n) => n.name === part); if (!node) { node = { name: part, slug: currentPath, title: "", children: [], isLeaf: false, }; current.push(node); } if (isLeaf) { node.isLeaf = true; node.title = part .split(/[-_]/) .map((w) => w.charAt(0).toUpperCase() + w.slice(1)) .join(" "); } else if (!node.title) { node.title = part .split(/[-_]/) .map((w) => w.charAt(0).toUpperCase() + w.slice(1)) .join(" "); } current = node.children; } }; for (const docPath of paths) { const rel = docPath.startsWith(base) ? docPath.slice(base.length) : docPath; const cleanPath = rel.replace(/\.md$/, ""); addPath(cleanPath); } return tree; } function renderTree(nodes: TreeNode[], pathname: string) { return (
No documents
)}A content-first knowledge base for humans and AI agents. Browse the hierarchical folder structure below, search all documents, or connect via the MCP server.
{s.desc}
{/* Inline folder tree */}
MCP server at{" "}
mcp.asepharyana.my.id/mcp
. All tools available via Streamable HTTP transport.