Skip to main content
Glama

Basic MCP Server

一个小而完整的 MCP(Model Context Protocol)示例项目,基于 TypeScript 和官方 MCP SDK v2。

这个仓库既提供可直接运行的最终服务器,也提供从一个 Tool 开始的渐进课程:

第一次接触 MCP 时,建议从 examples/01-minimal-tool.ts 开始,不要直接阅读完整的 src/server.ts

已实现能力

  • Tools:addechocurrent-timemultiply、进度/取消示例 process_steps,以及持久化 Todo 工具 create_tasklist_taskscomplete_taskdelete_task

  • Resources:示例资源 demo://aboutdemo://greeting/{name},以及任务资源 tasks://boardtasks://items/{id}

  • Subscriptions:任务变化时发布 Resource 内容更新和列表变化通知,支持 stdio 与 Streamable HTTP。

  • Prompts:summarize-textreview-code

  • Completions:为 review-code.language 提供参数候选值。

  • Transports:本地客户端常用的 stdio,以及远程/服务化使用的 Streamable HTTP。

  • HTTP 安全:Bearer Token 身份认证,并按用户隔离 Tool、Resource 和订阅通知。

  • Storage:Node.js 内置 SQLite;默认数据库文件为 data/tasks.db,可通过 MCP_DB_PATH 修改。所有任务查询都带 user_id

  • 工程质量:TypeScript 严格模式、集成测试、健康检查、优雅退出、stdio 日志隔离。

Related MCP server: mcp-project-manager

环境

  • Node.js 24+(当前 WSL 已通过 nvm 安装 Node 24 LTS)

  • npm

新开终端后如果 node --version 仍显示旧版本,请执行:

source ~/.nvm/nvm.sh
nvm use --lts

安装与验证

cd /absolute/path/to/mcp
npm install
npm run check
npm test
npm run build

运行教学客户端,一次观察 Tool、Resource、Prompt、Completion、Progress 和 input_required

npm run demo

生成内置测试覆盖率报告:

npm run test:coverage

运行

开发模式(stdio):

npm run dev

首次启动会自动创建 data/tasks.dbtasks 表。可以指定其他数据库位置:

MCP_DB_PATH=/absolute/path/tasks.db npm run dev

delete_task 会先通过 MCP input_required 请求客户端向用户确认,再执行永久删除。生产环境建议配置一个至少 32 字节的签名密钥:

REQUEST_STATE_SECRET='replace-with-at-least-32-bytes-secret' npm run dev

这个密钥用于给确认流程中的 requestState 签名,防止客户端篡改“正在确认删除哪条任务”。未配置时进程会生成临时随机密钥,适合本地开发,但服务重启后尚未完成的确认会失效;多进程部署必须共享同一个密钥。

编译后运行(stdio):

npm run build
npm start

运行 Streamable HTTP 服务:

MCP_AUTH_TOKENS_JSON='{"alice":"replace-with-a-random-token-of-at-least-32-bytes"}' \
REQUEST_STATE_SECRET='replace-with-at-least-32-bytes-secret' \
npm run start:http
# MCP:    http://127.0.0.1:3000/mcp
# Health: http://127.0.0.1:3000/health

MCP_AUTH_TOKENS_JSON 是“用户 id → Bearer Token”的 JSON 对象,可以配置多个用户:

可以用 openssl rand -hex 32 生成随机 Token,然后配置:

export MCP_AUTH_TOKENS_JSON='{
  "alice":"alice-random-token-with-at-least-32-bytes",
  "bob":"bob-random-token-with-at-least-32-bytes--"
}'

客户端访问 /mcp 时必须发送对应凭据:

Authorization: Bearer alice-random-token-with-at-least-32-bytes

/health 保持公开,方便本地健康检查。stdio 不经过 HTTP 认证,固定使用 local 用户。已有数据库升级时会自动增加 user_id,升级前的任务归入 local 用户;如果希望通过 HTTP 继续访问这些任务,请为 local 配置 Token。

可通过环境变量修改监听地址:

MCP_HOST=127.0.0.1 MCP_PORT=8080 npm run start:http

非回环监听必须同时配置允许的 Host 与 Origin,值为不带 scheme 和端口的逗号分隔 hostname:

MCP_HOST=0.0.0.0 \
MCP_ALLOWED_HOSTS=mcp.example.com \
MCP_ALLOWED_ORIGINS=app.example.com \
npm run start:http

默认仅监听回环地址。目前的静态 Token 方案用于学习和受控环境,它不是完整的 MCP OAuth 实现。若要暴露到公网,还应使用 TLS、真正的 OAuth/OIDC 身份提供方、密钥管理、限流、审计,并配置正确的 Host/Origin 白名单。可复制 .env.example 查看所有环境变量。

任务 Tool 与 Resource

  • create_taskcomplete_taskdelete_task 修改 SQLite 中的任务。

  • list_tasks 让模型主动调用工具查询任务。

  • tasks://board 把整个任务板作为只读 JSON 上下文提供给客户端。

  • tasks://items/{id} 通过稳定 URI 读取单个任务,例如 tasks://items/1

delete_task 的调用是两轮完成的:

  1. 客户端第一次调用时,服务器返回 input_required,其中包含确认表单和已签名的 requestState,此时数据库还没有变化。

  2. 客户端取得用户选择后,MCP SDK 自动带着 inputResponses 和原样的 requestState 重试同一个 Tool。

  3. 服务器验证签名、任务 id、任务标题和确认结果;只有明确接受且 confirm: true 时才删除。

这不是服务器私自弹窗:显示确认界面的是支持 Elicitation 的 MCP 客户端。客户端若不支持该能力,就不能完成这项交互式删除。

Tool 和 Resource 共享同一个 TaskStore,所以 Tool 修改任务后,再次读取 Resource 会立即得到最新数据。

HTTP 模式会从已验证 Token 中取得 userId,并把它注入 MCP Server。任务的创建、读取、完成和删除都使用 user_id 作为 SQL 条件;每个用户还有独立的 MCP handler,因此 Resource 订阅通知也不会广播给其他用户。

客户端订阅后,服务器会发布以下通知:

  • create_tasktasks://board 和新任务 URI 的内容更新,同时通知 Resource 列表发生变化。

  • complete_tasktasks://board 和对应任务 URI 的内容更新。

  • delete_tasktasks://board 和被删除任务 URI 的内容更新,同时通知 Resource 列表发生变化。

通知只表示某个 URI 已变化,不携带完整任务数据。客户端收到通知后,可以立即重新读取 Resource,也可以只把本地缓存标记为过期。

使用 MCP Inspector

先编译,再启动官方检查器:

npm run build
npm run inspect

运行单独课程示例:

npx @modelcontextprotocol/inspector npx tsx examples/01-minimal-tool.ts

客户端配置示例

Codex/Claude Desktop/Cursor 等支持 stdio 的 MCP Host 可使用等价配置:

{
  "mcpServers": {
    "basic-mcp": {
      "command": "/absolute/path/to/node",
      "args": ["/absolute/path/to/mcp/dist/src/stdio.js"],
      "env": {
        "MCP_DB_PATH": "/absolute/path/to/mcp/data/tasks.db"
      }
    }
  }
}

建议先执行 npm run build。把占位路径替换为 which node 和项目目录返回的绝对路径;也可以写一个固定启动脚本,由它加载 nvm。

如果 MCP Host 运行在 Windows(而服务器代码位于 WSL),可使用:

{
  "mcpServers": {
    "basic-mcp": {
      "command": "wsl.exe",
      "args": [
        "-d",
        "Ubuntu-24.04",
        "--",
        "env",
        "MCP_DB_PATH=/absolute/wsl/path/to/mcp/data/tasks.db",
        "/absolute/wsl/path/to/node",
        "/absolute/wsl/path/to/mcp/dist/src/stdio.js"
      ]
    }
  }
}

项目结构

src/server.ts      # MCP 能力注册和服务器工厂
src/auth.ts        # 静态 Bearer Token 配置与验证
src/task-store.ts  # SQLite 任务存储层
src/stdio.ts       # stdio 入口
src/http.ts        # Streamable HTTP 入口
src/http-server.ts # HTTP 认证、用户路由与服务器装配
test/              # 真实 MCP Client 驱动的集成测试
examples/          # 从最小 Tool 到教学 Client 的渐进示例
docs/              # 学习路径、架构和练习

扩展时通常只需要在 src/server.ts 中增加 registerToolregisterResourceregisterPrompt

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables local-first LLM orchestration with persistent memory, knowledge management, routing, swarm patterns, API probing, tests, automation planning, and plugin discovery via a stdio MCP server, using SQLite for offline storage.
    191 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables task management through natural language: create tasks, list and filter them, and update their status. It uses SQLite for persistence and supports both local stdio and remote SSE transports.
    11 npm
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables task state management for AI agents with secure credential handling and optional client-side encryption via a local stdio proxy.
    MIT