跳至主要內容

从零构建 Node.js MCP Server —— 让 AI 读写你的文件系统

布衣云水客大约 3 分钟文章MCPNode.jsTypeScriptAI工具开发

概要

上一篇文章介绍了如何用 Spring AI 构建 Java 版的 MCP Server。但 MCP 远不止 Java——它的官方 SDK 支持 TypeScript/Python/Kotlin,生态非常活跃。

本文将用 Node.js + TypeScript 从零搭建一个 MCP Server,并介绍如何将 AI 对话数据从 Elasticsearch 迁移到 MySQL 的数据管道设计。两个项目结合起来,展示了一条完整的 "AI 工具开发 + AI 数据工程" 链路。

MCP 官方工具:Filesystem Server

MCP 官方提供了开箱即用的文件系统 Server:

{
  "dependencies": {
    "@modelcontextprotocol/create-server": "^0.3.1",
    "@modelcontextprotocol/server-filesystem": "^2025.3.28"
  }
}

只需要在 AI 客户端配置中添加:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"]
    }
  }
}

配置完成后,AI 助手就能在你的指定目录中读文件、写文件、搜索文件——相当于给了 AI 一个受限的文件浏览器。

自定义 MCP Server:Disk Analyzer

官方工具虽然方便,但真实场景下往往需要自定义逻辑。以 "磁盘分析器" 为例:

// 基本结构
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const server = new Server({
  name: "disk-analyzer",
  version: "0.1.0",
}, {
  capabilities: {
    resources: {},   // 暴露数据给 AI 读取
    tools: {},       // 暴露函数给 AI 调用
    prompts: {}      // 暴露提示词模板
  }
});

// TODO: 注册 tools, resources, prompts

const transport = new StdioServerTransport();
await server.connect(transport);

一个 MCP Server 可以暴露三种能力:

能力说明示例
Resources让 AI 读取结构化数据磁盘使用报告、文件大小列表
Tools让 AI 执行操作删除临时文件、扫描大文件
Prompts预定义的提示词模板"分析 C 盘空间并给出清理建议"

开发与调试

MCP Server 通过标准输入输出(stdio)与客户端通信,调试不太直观。官方提供了 MCP Inspector:

npm run inspector
# 或直接使用
npx @modelcontextprotocol/inspector build/index.js

Inspector 会在浏览器中打开一个交互界面,可以:

  • 查看 Server 提供的所有 tools/resources/prompts
  • 手动构造请求测试每个能力
  • 查看完整的请求/响应 JSON

AI 数据管道:ES → MySQL 迁移

另一个实用的场景是:AI 的对话历史存在 Elasticsearch 中,需要迁移到 MySQL 做持久化存储。我写了一个 Python 脚本处理这个迁移:

# 读取 ES 导出的 JSON
with open('input.json', 'r', encoding='utf-8') as f:
    data = json.load(f)

messages = data['hits']['hits']

# 按会话 ID 分组
conversations = defaultdict(list)
for hit in messages:
    conv_id = hit['_source']['metadata']['conversationId']
    conversations[conv_id].append(hit)

# 生成 MySQL INSERT 语句
for conv_id, msgs in conversations.items():
    title = extract_title(msgs)  # 取第一条 USER 消息截断为标题
    timestamps = [get_timestamp(m) for m in msgs]
    sql = f"INSERT INTO chat_conversation (id, title, create_time) VALUES ..."

处理的数据结构:

{
  "_source": {
    "metadata": {
      "conversationId": "1758640633392",
      "messageType": "USER",
      "timestamp": 1767051787364,
      "jiacn": "oH2zD1PUPvspic..."
    },
    "content": "我要做一个水浒传题材的小游戏..."
  }
}

输出两个 SQL 文件:

  • insert_conversations.sql —— 会话记录
  • insert_messages.sql —— 消息记录(含序号、时间戳、metadata JSON)

脚本的关键设计点:

设计实现原因
会话自动提取标题取第一条 USER 消息前 50 字符用户第一句话通常是主题
timestamp 容错metadata.timestampsortnow()ES 字段可能缺失
SQL 注入防护单引号转义 '',反斜杠转义 \\用户输入可能含特殊字符
消息顺序保留message_order 字段保持对话的时间线

小结

这篇文章覆盖了两个方向:

  1. MCP Server 开发——Node.js SDK 让构建自定义 AI 工具变得简单,官方 Filesystem Server 开箱即用,自定义 Tool 只需要继承 SDK 标准接口
  2. AI 数据工程——ES 到 MySQL 的迁移脚本展示了如何用 Python 处理 AI 对话的结构化数据,类似的思路可以用于日志清洗、数据归档、多数据源汇聚

MCP 生态系统正在快速增长,现在入局正是好时机。


Disk Analyzer 源码见 D:\workspace\project\mcp-server\disk-analyzer\,ES 迁移脚本见 D:\workspace\project\python-script\trans_es_to_mysql\