Skip to main content
Glama
Akakinad

GraphRAG TypeScript MCP Tools

by Akakinad

GraphRAG TypeScript MCP Tools

一个使用 TypeScript、Neo4j 和 MCP TypeScript SDK 构建的 GraphRAG MCP 服务器的完整实现。本项目演示了如何构建生产级 MCP 服务器,公开基于图的工具、资源以及 LLM 采样和补全等高级功能。

本项目是 Neo4j GraphAcademy — Building GraphRAG TypeScript MCP tools 课程的一部分。


什么是 MCP?

模型上下文协议(MCP)是 Anthropic 制定的开放标准,允许 AI 代理(Claude、Cursor、VS Code Copilot)以标准化方式连接到外部工具和数据源。


项目结构

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

构建内容

步骤 1 — 第一个 MCP 服务器 (strawberry/index.ts)

最简单的 MCP 服务器。只有一个工具,没有数据库,stdio 传输。

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),
  }],
}));

测试结果: countLetters("strawberry", "r")3

使用 MCP Inspector 进行测试 — 这是一个基于浏览器的工具,用于探索和测试 MCP 服务器。


步骤 2 — Neo4j 连接 (模块作用域)

与 Python 的 lifespan 上下文管理器不同,TypeScript 使用 模块作用域变量 — 驱动程序在文件顶部创建一次,并由所有工具直接共享。

// 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";

通过 SIGINT 实现优雅关闭:

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

步骤 3 — 工具 1:graphStatistics

统计 Neo4j 中的所有节点和关系。

结果: {"nodes": 28863, "relationships": 332522}


步骤 4 — 工具 2:getMoviesByGenre

按类型搜索电影,并按 IMDB 评分排序。使用 console.error() 进行日志记录 — 在 stdio 服务器中绝不要使用 console.log()(它会破坏 JSON-RPC 通道)。

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 }
  );
  ...
});

步骤 5 — 工具 3:browse_movies_by_genre (分页)

使用 Neo4j 的 SKIPLIMIT 进行基于游标的分页:

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

返回:

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

步骤 6 — 资源:movie://{tmdbId}

使用 ResourceTemplate 通过 TMDB ID 公开完整的电影详情:

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
  }
);

示例: movie://603(《黑客帝国》),movie://13(《阿甘正传》)


步骤 7 — 高级:采样 (explainMovieData)

在执行过程中调用 LLM,将原始 Neo4j 数据转换为自然语言的工具:

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

不使用采样: {'title': 'Toy Story', 'released': '1995', 'actors': [...]}

使用采样(VS Code Copilot): "《玩具总动员》— 一部机智、有趣的动画冒险片,讲述伍迪——一个嫉妒的牛仔玩偶——在巴斯光年成为新宠后感到被冷落……"

注意:需要在底层服务器上设置 capability:

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

步骤 8 — 高级:补全

为类型参数提供实时自动补全建议 — 在用户输入时查询 Neo4j:

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: [] } };
});

与 Python 版本的主要区别

概念

Python (FastMCP)

TypeScript (McpServer)

工具注册

@mcp.tool() 装饰器

server.registerTool() 方法

共享状态

Lifespan 上下文管理器

模块作用域变量

驱动程序访问

ctx.request_context.lifespan_context.driver

driver(直接)

日志记录

await ctx.info()

console.error()

采样

ctx.session.create_message()

server.server.createMessage()

补全

@server.completion()

server.server.setRequestHandler(CompleteRequestSchema)

文件结构

每个功能独立文件

所有内容都在一个 index.ts

数字参数

Python int 类型提示

需要使用 neo4j.int() 包装

提示参数

int, str, float

始终使用 z.string(),手动解析


设置

先决条件

安装

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

配置凭据

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

验证设置

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

运行

使用 MCP Inspector 进行测试(浏览器 UI)

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

打开终端中显示的 URL → 连接 → 工具选项卡 → 列出工具 → 选择工具 → 运行工具。

为 AI 编辑器运行服务器

cd server
npx tsx index.ts

VS Code 配置(.vscode/mcp.json

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

在 VS Code Copilot 中测试

使用 movies-ts MCP 工具解释电影《玩具总动员》 使用 movies-ts MCP 工具搜索动作片 使用 movies-ts MCP 工具获取图统计信息


课程

学习路径: Generative AI & GraphRAG

课程: Building GraphRAG TypeScript MCP tools


Building GraphRAG TypeScript MCP Tools

GraphAcademy 课程 Building GraphRAG TypeScript MCP Tools 的配套仓库。

学员将构建一个 MCP(模型上下文协议)服务器,连接到 Neo4j 图数据库,公开工具和资源以供 AI 助手使用。

开始

  1. .env.example 复制为 .env,并使用你的 Neo4j 连接信息更新其中的值。

  2. 安装依赖:

npm install
  1. 启动服务器:

npm start
  1. 使用 MCP Inspector 检查服务器:

npm run inspect

解决方案

solutions/ 目录包含每个课程检查点的完整代码。

-
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