public
anord
read
Ledger
Why work hard when you can work easier?
Languages
Repository composition by tracked source files.
TypeScript
86%
CSS
10%
SQL
3%
Shell
1%
HTML
0%
import { Router } from "express";
import { z } from "zod";
import { createOrUpdatePage, getPageBySlug, getPageMetadata, listSpaces } from "../../services/pages.js";
import { searchPages } from "../../services/search.js";
import { canEditPage } from "@ledger/shared";
const toolsCallSchema = z.object({
method: z.string(),
params: z.record(z.any()).optional(),
id: z.union([z.string(), z.number()]).optional()
});
export const mcpRouter = Router();
mcpRouter.post("/", async (req, res) => {
const body = toolsCallSchema.parse(req.body);
if (body.method === "tools/list") {
return res.json({
id: body.id,
result: {
tools: [
{ name: "search_knowledge_base", description: "Search knowledge base pages visible to the current auth context and return structured page summaries." },
{ name: "read_page", description: "Read a page by slug when the current auth context is allowed to access it." },
{ name: "list_spaces", description: "List spaces visible to the current auth context." },
{ name: "get_page_metadata", description: "Return non-sensitive page metadata for a visible page id." },
{ name: "create_draft_page", description: "Create a draft page in a space when the current auth context can edit content." }
]
}
});
}
if (body.method === "tools/call") {
const name = String(body.params?.name ?? "");
const args = body.params?.arguments ?? {};
if (name === "search_knowledge_base") {
const result = await searchPages(String(args.query ?? ""), req.user ?? null);
return res.json({ id: body.id, result: { pages: result } });
}
if (name === "read_page") {
const result = await getPageBySlug(String(args.slug ?? ""), req.user ?? null);
return res.json({ id: body.id, result: result ? { page: result } : null });
}
if (name === "list_spaces") {
const result = await listSpaces(req.user ?? null);
return res.json({ id: body.id, result: { spaces: result } });
}
if (name === "get_page_metadata") {
const result = await getPageMetadata(String(args.pageId ?? ""), req.user ?? null);
return res.json({ id: body.id, result: result ? { page: result } : null });
}
if (name === "create_draft_page") {
if (!canEditPage(req.user ?? null)) {
return res.status(403).json({ error: "Editor access required" });
}
const result = await createOrUpdatePage(
null,
{
spaceId: String(args.spaceId),
title: String(args.title),
bodyMarkdown: String(args.bodyMarkdown),
visibility: "internal",
state: "draft"
},
req.user!.id
);
return res.json({ id: body.id, result: { page: result } });
}
}
return res.status(400).json({ error: "Unsupported MCP method" });
});