bostrom-mcp/src/tools/graph.ts

import { z } from "zod";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { ok, safe, paginationHint, READ_ONLY_ANNOTATIONS } from "../util.js";
import * as svc from "../services/graph.js";

export function registerGraphTools(server: McpServer) {
  server.registerTool(
    "graph_search",
    {
      description: "Search cyberlinks by particle CID or neuron address. Returns linked particles and their creators.",
      inputSchema: {
        particle: z.string().optional().describe("CID of a particle to find links from/to"),
        neuron: z.string().optional().describe("Neuron address (bostrom1...) to find their links"),
        limit: z.number().min(1).max(100).default(20).describe("Max results"),
        offset: z.number().min(0).default(0).describe("Pagination offset"),
      },
      annotations: READ_ONLY_ANNOTATIONS,
    },
    safe(async ({ particle, neuron, limit, offset }) => {
      const result = await svc.searchCyberlinks({ particle, neuron, limit, offset });
      const pagination = paginationHint("graph_search", offset, limit, result.links);
      return ok({ ...result, ...(pagination && { pagination }) });
    }),
  );

  server.registerTool(
    "graph_rank",
    {
      description: "Get the cyberank score for a particle (CID). Higher rank = more important in the knowledge graph.",
      inputSchema: {
        particle: z.string().describe("CID of the particle"),
      },
      annotations: READ_ONLY_ANNOTATIONS,
    },
    safe(async ({ particle }) => ok(await svc.getRank(particle))),
  );

  server.registerTool(
    "graph_neuron",
    {
      description: "Get neuron profile: number of cyberlinks created",
      inputSchema: {
        address: z.string().describe("Neuron address (bostrom1...)"),
      },
      annotations: READ_ONLY_ANNOTATIONS,
    },
    safe(async ({ address }) => ok(await svc.getNeuron(address))),
  );

  server.registerTool(
    "graph_particle",
    {
      description: "Fetch particle content by CID from IPFS. Returns text content (truncated at 50KB).",
      inputSchema: {
        cid: z.string().describe("IPFS CID of the particle"),
      },
      annotations: READ_ONLY_ANNOTATIONS,
    },
    safe(async ({ cid }) => {
      const content = await svc.getParticle(cid);
      return { content: [{ type: "text" as const, text: content }] };
    }),
  );

  server.registerTool(
    "graph_recent_links",
    {
      description: "Get the most recent cyberlinks created on Bostrom",
      inputSchema: {
        limit: z.number().min(1).max(100).default(20).describe("Max results"),
      },
      annotations: READ_ONLY_ANNOTATIONS,
    },
    safe(async ({ limit }) => {
      const links = await svc.getRecentLinks(limit);
      return ok(links);
    }),
  );

  server.registerTool(
    "graph_stats",
    {
      description: "Get knowledge graph statistics: total cyberlinks and active neurons",
      annotations: READ_ONLY_ANNOTATIONS,
    },
    safe(async () => ok(await svc.getGraphStats())),
  );
}

Synonyms

bostrom-mcp/src/services/graph.ts
soft3.js/src/queries/graph.ts

Neighbours