/**
 * MCP server entrypoint for the graph-viewer plugin. Registers one tool,
 * `graph-render`, on the standard stdio transport. Account-scoping is
 * enforced inside the tool handler against the caller-supplied accountId.
 */
import { initStderrTee } from "../../../../lib/mcp-stderr-tee/dist/index.js";
initStderrTee("graph-viewer");
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { eagerTool } from "../../../../lib/mcp-eager/dist/index.js";
import { z } from "zod";
import { graphRender } from "./tools/graph-render.js";
import { closeDriver } from "./lib/neo4j.js";
const server = new McpServer({
    name: "maxy-graph-viewer",
    version: "0.1.0",
});
eagerTool(server, "graph-render", "Render a PNG of an account-scoped Neo4j subgraph rooted at a given nodeId, walking up to hopDepth hops (0-3). Writes the PNG to data/accounts/<accountId>/output/graph-render/ and returns {ok:true, path, nodeCount, edgeCount, width, height, truncated?}. The PNG lands under output/, so it appears in the operator's Artefacts panel (downloadable) and on their file share; callers tell the operator that exact path — MCP image content blocks are not surfaced in the maxy-code chat UI and there is no send-to-chat tool. The image uses the same colour palette and short-label strings as the live /graph page; node positions differ (d3-force, not vis-network) and are auto-fit to the canvas. Subgraphs above 200 nodes are capped and the envelope carries truncated={rendered,total}. Trashed nodes are excluded. Use when the operator asks to see what a subgraph looks like and you want to avoid making them switch to the admin UI on a different device.", {
    accountId: z.string().min(1).describe("Operator account id. The root nodeId must belong to this account or the tool refuses with reason=scope."),
    nodeId: z.string().min(1).describe("elementId of the root node, as returned by memory-search or other graph tools."),
    hopDepth: z.number().int().min(0).max(3).describe("Number of hops to walk from the root (0 = just the root). Max 3."),
}, async (args) => {
    const result = await graphRender(args);
    if (!result.ok) {
        return {
            isError: true,
            content: [
                {
                    type: "text",
                    text: JSON.stringify({ ok: false, reason: result.reason, message: result.message }, null, 2),
                },
            ],
        };
    }
    const envelope = {
        ok: true,
        path: result.path,
        width: result.width,
        height: result.height,
        nodeCount: result.nodeCount,
        edgeCount: result.edgeCount,
    };
    if (result.truncated)
        envelope.truncated = result.truncated;
    return {
        content: [
            {
                type: "text",
                text: JSON.stringify(envelope, null, 2),
            },
        ],
    };
});
async function main() {
    const transport = new StdioServerTransport();
    await server.connect(transport);
}
main().catch((err) => {
    console.error("[graph-viewer] fatal:", err);
    process.exit(1);
});
process.on("SIGINT", async () => {
    await closeDriver();
    process.exit(0);
});
process.on("SIGTERM", async () => {
    await closeDriver();
    process.exit(0);
});
//# sourceMappingURL=index.js.map