MCP 怎么用

November 21, 2025

什么是MCP?

首先我们先明白,在没有MCP之前,我们想结合LLM和自己的知识进行回答,一般是通过 FunctionCall 或者代码层 if else,亦或者是插件、LangChain等。

在这里不是说这些解决方案不够好,而是相比 MCP 他们越来越定制化且不可拆分。这样一来、其他的 LLM客户端想调取你的能力就非常难。

所以 MCP 的出现是将能力进行模块化,给模型调用。

MCP 是 C/S 架构。可以理解为 Client 端会结合AI 应用决定和调取哪些 MCP Server。

此篇我们只开发 Server 服务。

MCP Server 和 Client 的通信可以是,本地Stdio,Http,也就是说 MCP Server可以是本地的、也可以是远程的。

通过 JSON 形式(JSON-RPC)进行数据传输约定。

从最简单的 Demo 开始。

让Cursor 列出我桌面的文件夹

JAVASCRIPT
import { readdir, stat } from 'fs/promises'
import { join } from 'path'
import { homedir } from 'os'
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'

// 创建 MCP 服务器实例
// name 和 version 用于标识服务器
const server = new McpServer({
  name: 'desktop_folders',
  version: '1.0.0',
})

/**
 * 注册工具:list_desktop_folders
 *
 * server.tool() 方法用于注册一个可被 AI 调用的工具
 * 参数说明:
 *   - 第一个参数:工具名称(AI 通过这个名称调用工具)
 *   - 第二个参数:工具的参数定义(这里为空对象,表示不需要参数)
 *   - 第三个参数:工具的执行函数(异步函数,返回工具执行结果)
 */
server.tool(
  'list_desktop_folders',
  {}, // 工具参数定义(空对象表示无参数)
  async () => {
    try {
      // 获取桌面路径(跨平台兼容)
      const desktopPath = join(homedir(), 'Desktop')

      // 读取桌面目录下的所有文件和文件夹
      const items = await readdir(desktopPath)

      // 并行检查每个项目是否为文件夹(提高性能)
      const folderChecks = await Promise.all(
        items.map(async (item) => {
          const itemPath = join(desktopPath, item)
          const stats = await stat(itemPath)
          return stats.isDirectory() ? item : null
        })
      )

      // 过滤出文件夹名称(移除 null 值)
      const folders = folderChecks.filter(Boolean)

      // 格式化返回结果
      // MCP 工具必须返回特定格式:content 数组包含文本内容
      return {
        content: [
          {
            type: 'text',
            text:
              folders.length > 0
                ? `桌面上的文件夹:\n${folders.join('\n')}\n\n共 ${folders.length} 个文件夹`
                : '桌面上没有文件夹',
          },
        ],
      }
    } catch (error) {
      // 错误处理:返回错误信息并标记为错误
      return {
        content: [
          {
            type: 'text',
            text: `错误:${error.message}`,
          },
        ],
        isError: true,
      }
    }
  }
)

/**
 * 启动服务器
 *
 * StdioServerTransport 使用标准输入输出进行通信
 * 这是 MCP 服务器最常见的通信方式
 */
const transport = new StdioServerTransport()
await server.connect(transport)

import { readdir, stat } from 'fs/promises'
import { join } from 'path'
import { homedir } from 'os'
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'

// 创建 MCP 服务器实例
// name 和 version 用于标识服务器
const server = new McpServer({
  name: 'desktop_folders',
  version: '1.0.0',
})

/**
 * 注册工具:list_desktop_folders
 *
 * server.tool() 方法用于注册一个可被 AI 调用的工具
 * 参数说明:
 *   - 第一个参数:工具名称(AI 通过这个名称调用工具)
 *   - 第二个参数:工具的参数定义(这里为空对象,表示不需要参数)
 *   - 第三个参数:工具的执行函数(异步函数,返回工具执行结果)
 */
server.tool(
  'list_desktop_folders',
  {}, // 工具参数定义(空对象表示无参数)
  async () => {
    try {
      // 获取桌面路径(跨平台兼容)
      const desktopPath = join(homedir(), 'Desktop')

      // 读取桌面目录下的所有文件和文件夹
      const items = await readdir(desktopPath)

      // 并行检查每个项目是否为文件夹(提高性能)
      const folderChecks = await Promise.all(
        items.map(async (item) => {
          const itemPath = join(desktopPath, item)
          const stats = await stat(itemPath)
          return stats.isDirectory() ? item : null
        })
      )

      // 过滤出文件夹名称(移除 null 值)
      const folders = folderChecks.filter(Boolean)

      // 格式化返回结果
      // MCP 工具必须返回特定格式:content 数组包含文本内容
      return {
        content: [
          {
            type: 'text',
            text:
              folders.length > 0
                ? `桌面上的文件夹:\n${folders.join('\n')}\n\n共 ${folders.length} 个文件夹`
                : '桌面上没有文件夹',
          },
        ],
      }
    } catch (error) {
      // 错误处理:返回错误信息并标记为错误
      return {
        content: [
          {
            type: 'text',
            text: `错误:${error.message}`,
          },
        ],
        isError: true,
      }
    }
  }
)

/**
 * 启动服务器
 *
 * StdioServerTransport 使用标准输入输出进行通信
 * 这是 MCP 服务器最常见的通信方式
 */
const transport = new StdioServerTransport()
await server.connect(transport)

延展阅读

https://modelcontextprotocol.io/docs/develop/build-server