Skip to main content
Glama
Akakinad

GraphRAG TypeScript MCP Tools

by Akakinad

GraphRAG TypeScript MCP Tools

Eine vollständige Implementierung eines GraphRAG-MCP-Servers, erstellt mit TypeScript, Neo4j und dem MCP-TypeScript-SDK. Dieses Projekt zeigt, wie man produktionsreife MCP-Server baut, die graphgestützte Tools, Ressourcen und erweiterte Funktionen wie LLM-Sampling und Completions bereitstellen.

Erstellt im Rahmen des Kurses Neo4j GraphAcademy — Building GraphRAG TypeScript MCP tools.


Was ist MCP?

Das Model Context Protocol (MCP) ist ein offener Standard von Anthropic, der es KI-Agenten (Claude, Cursor, VS Code Copilot) ermöglicht, auf standardisierte Weise eine Verbindung zu externen Tools und Datenquellen herzustellen.


Projektstruktur

genai-mcp-build-custom-tools-typescript/
├── server/
│ └── index.ts ← Main MCP server: 4 tools + 1 resource + sampling + completions
├── strawberry/
│ └── index.ts ← First MCP server: simple countLetters tool
├── solutions/ ← Course reference solutions
├── .vscode/
│ └── mcp.json ← VS Code MCP configuration
└── README.md

Was gebaut wurde

Schritt 1 — Erster MCP-Server (strawberry/index.ts)

Der einfachste mögliche MCP-Server. Ein Tool, keine Datenbank, stdio-Transport.

server.registerTool("countLetters", {
  description: "Count occurrences of a letter in the text",
  inputSchema: {
    text: z.string().describe("The text to search in"),
    search: z.string().describe("The letter to count"),
  },
}, async ({ text, search }) => ({
  content: [{
    type: "text",
    text: String(text.toLowerCase().split(search.toLowerCase()).length - 1),
  }],
}));

Testergebnis: countLetters("strawberry", "r")3

Getestet mit dem MCP Inspector — einem browserbasierten Tool zum Erkunden und Testen von MCP-Servern.

Schritt 2 — Neo4j-Verbindung (Modulbereich)

Im Gegensatz zum Lifespan-Kontextmanager von Python verwendet TypeScript Variablen im Modulbereich – der Treiber wird einmal am Anfang der Datei erstellt und direkt von allen Tools gemeinsam genutzt.

// Created ONCE when file loads — shared by all tools
const driver: Driver = neo4j.driver(
  process.env["NEO4J_URI"] ?? "neo4j://localhost:7687",
  neo4j.auth.basic(
    process.env["NEO4J_USERNAME"] ?? "neo4j",
    process.env["NEO4J_PASSWORD"] ?? "password"
  )
);
const database = process.env["NEO4J_DATABASE"] ?? "neo4j";

Sanftes Herunterfahren per SIGINT:

process.on("SIGINT", async () => {
  await driver.close();
  await server.close();
  process.exit(0);
});

Schritt 3 — Tool 1: graphStatistics

Zählt alle Knoten und Beziehungen in Neo4j.

Ergebnis: {"nodes": 28863, "relationships": 332522}

Schritt 4 — Tool 2: getMoviesByGenre

Sucht Filme nach Genre, sortiert nach IMDB-Bewertung. Verwendet console.error() für die Protokollierung – niemals console.log() in stdio-Servern (dies korrumpiert den JSON-RPC-Kanal).

server.registerTool("getMoviesByGenre", {
  description: "Get movies by genre from the Neo4j database",
  inputSchema: {
    genre: z.string().describe("The genre to search for (e.g., Action, Comedy, Drama)"),
    limit: z.number().default(10).describe("Maximum number of movies to return"),
  },
}, async ({ genre, limit }) => {
  const { records } = await driver.executeQuery(query,
    { genre, limit: neo4j.int(limit) },  // neo4j.int() for 64-bit integer compatibility
    { database }
  );
  ...
});

Schritt 5 — Tool 3: browse_movies_by_genre (paginiert)

Cursor-basierte Paginierung mit Neo4js SKIP und LIMIT:

const skip = parseInt(cursor, 10) || 0;
// Cypher: SKIP $skip LIMIT $limit
const nextCursor = movies.length === pageSize ? String(skip + pageSize) : null;

Rückgabe:

{
  "genre": "Action",
  "movies": [...],
  "nextCursor": "2",
  "page": 1,
  "pageSize": 2,
  "hasMore": true,
  "count": 2
}

Schritt 6 — Resource: movie://{tmdbId}

Stellt vollständige Filmdaten anhand der TMDB-ID mithilfe von ResourceTemplate bereit:

server.registerResource(
  "movie",
  new ResourceTemplate("movie://{tmdbId}", { list: undefined }),
  { description: "Get detailed information about a specific movie", mimeType: "application/json" },
  async (uri, { tmdbId }) => {
    // uri.href = "movie://603"
    // returns: contents array with JSON movie data
  }
);

Beispiele: movie://603 (The Matrix), movie://13 (Forrest Gump)

Schritt 7 — Fortgeschritten: Sampling (explainMovieData)

Tools, die während der Ausführung das LLM aufrufen, um rohe Neo4j-Daten in natürliche Sprache umzuwandeln:

const result = await server.server.createMessage({
  messages: [{
    role: "user",
    content: {
      type: "text",
      text: `Describe '${movieData.title}' (${movieData.released})...`,
    },
  }],
  maxTokens: 200,
});

Ohne Sampling: {'title': 'Toy Story', 'released': '1995', 'actors': [...]}

Mit Sampling (VS Code Copilot): „Toy Story – Ein kluges, lustiges Animationsabenteuer über Woody, eine eifersüchtige Cowboy-Puppe, die sich verdrängt fühlt, als Buzz Lightyear zum neuen Liebling wird …“

Hinweis: Erfordert das Setzen der Fähigkeit auf dem Low-Level-Server:

server.server["_capabilities"] = { ...server.server["_capabilities"], completions: {} };

Schritt 8 — Fortgeschritten: Completions

Echtzeit-Autovervollständigungsvorschläge für Genreparameter – fragt Neo4j ab, während der Benutzer tippt:

import { CompleteRequestSchema } from "@modelcontextprotocol/sdk/types.js";

server.server.setRequestHandler(CompleteRequestSchema, async (request) => {
  if (request.params.argument.name === "genre") {
    const { records } = await driver.executeQuery(
      `MATCH (g:Genre)
       WHERE g.name STARTS WITH $prefix
       RETURN g.name AS name
       ORDER BY name ASC LIMIT 10`,
      { prefix: request.params.argument.value },
      { database }
    );
    return { completion: { values: records.map(r => r.get("name")) } };
  }
  return { completion: { values: [] } };
});

Hauptunterschiede zur Python-Version

Konzept

Python (FastMCP)

TypeScript (McpServer)

Tool-Registrierung

@mcp.tool()-Dekorator

server.registerTool()-Methode

Gemeinsamer Zustand

Lifespan-Kontextmanager

Variablen im Modulbereich

Treiberzugriff

ctx.request_context.lifespan_context.driver

driver (direkt)

Protokollierung

await ctx.info()

console.error()

Sampling

ctx.session.create_message()

server.server.createMessage()

Completions

@server.completion()

server.server.setRequestHandler(CompleteRequestSchema)

Dateistruktur

Separate Dateien pro Feature

Alles in einer index.ts

Zahlenparameter

Python-int-Typhinweise

neo4j.int()-Wrapper erforderlich

Prompt-Parameter

int, str, float

Immer z.string(), manuell parsen

Einrichtung

Voraussetzungen

Installation

git clone https://github.com/Akakinad/genai-mcp-build-custom-tools-typescript
cd genai-mcp-build-custom-tools-typescript
npm install

Anmeldedaten konfigurieren

cat > server/.env << EOF
NEO4J_URI=bolt://your-sandbox-ip:7687
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=your-password
NEO4J_DATABASE=neo4j
EOF

Einrichtung überprüfen

npx tsx client/test_environment.ts
# Expected: All checks passed!

Ausführen

Testen mit dem MCP Inspector (Browser-Oberfläche)

cd server
npx @modelcontextprotocol/inspector npx tsx index.ts

Öffnen Sie die im Terminal angezeigte URL → Connect → Registerkarte „Tools“ → List Tools → wählen Sie ein Tool → Run Tool.

Server für die Verwendung mit KI-Editoren ausführen

cd server
npx tsx index.ts

VS Code-Konfiguration (.vscode/mcp.json)

{
  "servers": {
    "movies-ts": {
      "type": "stdio",
      "command": "npx",
      "args": ["tsx", "/absolute/path/to/server/index.ts"]
    }
  }
}

Testen in VS Code Copilot

  • Erklären Sie den Film „Toy Story“ mit dem MCP-Tool movies-ts.

  • Suchen Sie Actionfilme mit dem MCP-Tool movies-ts.

  • Rufen Sie Graphenstatistiken mit dem MCP-Tool movies-ts ab.

Kurs

Lernpfad: Generative AI & GraphRAG

Kurs: Building GraphRAG TypeScript MCP tools


Building GraphRAG TypeScript MCP Tools

Begleit-Repository zum GraphAcademy-Kurs Building GraphRAG TypeScript MCP Tools.

Die Teilnehmenden bauen einen MCP-Server (Model Context Protocol), der eine Verbindung zu einer Neo4j-Graphdatenbank herstellt und Tools sowie Ressourcen für die Verwendung mit KI-Assistenten bereitstellt.

Erste Schritte

  1. Kopieren Sie .env.example in .env und aktualisieren Sie die Werte mit Ihren Neo4j-Verbindungsdetails.

  2. Installieren Sie die Abhängigkeiten:

npm install
  1. Starten Sie den Server:

npm start
  1. Inspizieren Sie den Server mit dem MCP Inspector:

npm run inspect

Lösungen

Das Verzeichnis solutions/ enthält den vollständigen Code für jeden Lektions-Checkpoint.

-
license - not tested
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • MCP server for AI dialogue using various LLM models via AceDataCloud

  • MCP server for Argo RPG Platform — connects AI assistants to campaign data via OAuth2

  • Self-hosted MCP gateway: turn any API, database or MCP server into AI connectors — no code.

View all MCP Connectors

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/Akakinad/genai-mcp-build-custom-tools-typescript'

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