GraphRAG TypeScript MCP Tools
GraphRAG TypeScript MCP Tools
Полная реализация MCP-сервера GraphRAG, созданного с использованием TypeScript, Neo4j и MCP TypeScript SDK. Этот проект демонстрирует, как создавать MCP-серверы производственного уровня, которые предоставляют инструменты и ресурсы на основе графов, а также расширенные возможности, такие как семплирование LLM и автодополнение.
Создан в рамках курса Neo4j GraphAcademy — Building GraphRAG TypeScript MCP tools.
Что такое MCP?
Model Context Protocol (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 (на уровне модуля)
В отличие от lifespan-менеджера контекста в Python, 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() — никогда не используйте console.log() в stdio-серверах (это нарушает 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 SKIP и LIMIT:
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}
Предоставляет полные сведения о фильме по TMDB ID с использованием ResourceTemplate:
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 (The Matrix), movie://13 (Forrest Gump)
Шаг 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) |
Регистрация инструмента | декоратор | метод |
Общее состояние | Менеджер контекста lifespan | Переменные уровня модуля |
Доступ к драйверу |
|
|
Логирование |
|
|
Семплирование |
|
|
Автодополнение |
|
|
Структура файлов | Отдельные файлы для каждой функции | Всё в одном |
Числовые параметры | Подсказки типов Python int | требуется обёртка |
Параметры промпта |
| Всегда |
Настройка
Предварительные требования
Node.js 20+
npm
Neo4j Sandbox — набор данных Recommendations от sandbox.neo4j.com
Установка
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 (браузерный интерфейс)
cd server
npx @modelcontextprotocol/inspector npx tsx index.tsОткройте URL, показанный в терминале → Connect → вкладка Tools → List Tools → выберите инструмент → Run Tool.
Запуск сервера для использования в 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
Объясните фильм «История игрушек» с помощью MCP-инструмента movies-ts Найдите боевики с помощью MCP-инструмента movies-ts Получите статистику графа с помощью MCP-инструмента movies-ts
Курс
Учебный путь: Generative AI & GraphRAG
Курс: Building GraphRAG TypeScript MCP tools
Building GraphRAG TypeScript MCP Tools
Сопутствующий репозиторий для курса GraphAcademy Building GraphRAG TypeScript MCP Tools.
Студенты создают MCP-сервер (Model Context Protocol), который подключается к графовой базе данных Neo4j и предоставляет инструменты и ресурсы для использования с AI-ассистентами.
Начало работы
Скопируйте
.env.exampleв.envи обновите значения, указав данные подключения к Neo4j.Установите зависимости:
npm installЗапустите сервер:
npm startПроверьте сервер с помощью MCP Inspector:
npm run inspectРешения
Каталог solutions/ содержит готовый код для каждой контрольной точки урока.
This server cannot be installed
Maintenance
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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