mcpField
N
Number Guessing Game MCP Server

Number Guessing Game MCP Server

本地服务
portal.one媒体与设计268 周前更新

关于 Number Guessing Game MCP Server

这是一个用 TypeScript 编写的数字猜谜 MCP 服务示例,面向学习动态、多用户 MCP 应用开发的开发者。它按用户会话隔离游戏状态,并动态管理工具和资源。

主要功能

  1. 01独立的多用户游戏会话
  2. 02按游戏状态启用工具
  3. 03按会话创建和销毁资源
  4. 04Firestore 持久化状态与高分
  5. 05TypeScript 状态模式架构

适用场景

  1. 01学习构建动态 MCP 服务
  2. 02测试按会话变化的工具与资源
  3. 03探索 HTTP 会话生命周期管理

MCP 相关

它向 MCP 客户端提供数字猜谜游戏工具和 game_state 资源。每个用户会话拥有独立且随游戏状态变化的工具与资源。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

数字猜谜游戏 MCP 服务

许可证:MIT

一个使用 TypeScript 实现的示例模型上下文协议(MCP)服务。它展示了动态、基于会话的架构:每位用户都有自己的一组工具和资源,由中央控制器管理。此服务承载一个简单的数字猜谜游戏。

访问地址:https://mcp.number-guessing-game.portal.one/mcp

查看更多远程服务:https://remote-mcp-servers.com/

阅读我们的文章,了解动态 MCP 服务的优势:

https://portal.one/blog/dynamic-mcp-servers-tame-complexity/

以下是手动与服务交互的示例。请注意,工具会根据当前游戏状态发生变化。

https://github.com/user-attachments/assets/8bb15870-2adc-4412-a072-4fc4eb14bbef

以下是 Agent 与服务交互的视频。视频中看不到,但 Agent 可用的工具也会根据游戏状态发生变化。

https://github.com/user-attachments/assets/d7d338a2-8a93-46c3-b4a9-1a6b4caf9dc0

本项目旨在作为学习资源,并为构建动态、多用户 MCP 应用提供实践示例。

目录

  1. 主要功能
  2. 架构概览
  3. 先决条件
  4. 快速开始
  5. 运行服务
  6. 与服务交互
  7. 项目结构
  8. 展示的关键概念
  9. 参与贡献
  10. 许可证

主要功能

  • 真正的多用户会话: 每位连接的用户都有各自隔离的游戏状态和一组 MCP 实体。
  • 动态 MCP 工具: 工具(start_game、guess_number、give_up)会按用户启用或禁用,以反映各自的游戏状态。
  • 动态 MCP 资源: game_state 资源会随用户开始和结束游戏而创建和销毁。
  • 简洁、可扩展的架构:
    • 单个全局 McpServer 处理所有连接。
    • Express.js 控制器管理每个用户会话的生命周期。
    • 按会话划分的实体(工具、资源、游戏逻辑)按需创建。
    • 状态模式: 管理每位用户的游戏流程(大厅、游戏中)。
  • TypeScript 实现: 完整的类型定义,提升可维护性和开发体验。
  • Firestore 集成: 持久化游戏状态和最高分,使服务具备无状态性和可扩展性。

架构概览

该服务采用一种现代且可扩展的模式,由中央控制器管理临时的、特定于会话的资源。

  1. 全局服务配置(src/mcp_setup/index.ts): 应用启动时会创建一个 McpServer 实例。它充当“空白”的连接管理器,本身不包含任何工具或资源。

  2. HTTP 控制器(src/controllers/mcp.controller.ts): 这是应用的核心。

    • 它负责处理发往 /mcp 端点的所有传入 HTTP 请求。
    • 新用户连接时,它会创建一个 StreamableHTTPServerTransport。
    • 它利用传输层的生命周期钩子(onsessioninitialized 和 onclose)管理用户会话。
  3. 会话初始化(onsessioninitialized): 用户的传输层就绪后,控制器会:

    • 调用 src/mcp_setup/tools 和 src/mcp_setup/resources 中的设置函数,为该用户创建一组全新的、唯一的 MCP 实体。
    • 创建一个全新的 GameContext 实例,并将其关联到用户的会话 ID 及其专属 MCP 实体。
    • 通过 GameSessionService 从 Firestore 加载用户状态,并使用状态模式(LobbyState 或 PlayingState)为其会话启用/禁用相应的工具。
  4. 会话销毁(onclose): 用户断开连接时,控制器会:

    • 注销并销毁专为该用户创建的所有工具和资源,以防止内存泄漏。
    • 从活动连接列表中清理该传输层。

此架构可确保每位用户的 UI 状态(例如,启用了哪些工具)都完全隔离、具有状态且可动态管理,同时服务本身仍可扩展。

前置条件

  • Node.js(建议使用 v18.x 或更高版本)
  • npm 或 yarn
  • 可访问已启用 Firestore 的 Google Cloud 项目。

开始使用

安装
  1. 克隆代码仓库:
    git clone https://github.com/portal-labs-infrastructure/number-guessing-game-mcp-server
    cd number-guessing-game-mcp-server
    
  2. 安装依赖项:
    npm install
    # or
    yarn install
    
配置
  1. 设置 Google Cloud 身份验证: 确保你的环境已通过身份验证,可访问 Google Cloud 项目。本地开发时,可以使用 gcloud CLI:
    gcloud auth application-default login
    
  2. 创建 .env 文件: 复制示例文件。
    cp .env.example .env
    
  3. 编辑 .env: 填写所需的环境变量。
    • PORT:服务运行的端口(例如,8083)。
    • GCP_PROJECT_ID:你的 Google Cloud 项目 ID。
    • BASE_URL:服务的公网 URL(例如,http://localhost:8083)。
    • OAUTH_ISSUER_URL:OAuth 提供方的基础 URL。
    • DOCS_URL:服务文档链接。

运行服务

开发模式(用于支持热重载的开发):
npm run dev
生产模式:

编译 TypeScript:

npm run build

启动服务:

npm start

你应该会看到表明服务正在运行并已连接到 Firestore 的输出。

与服务交互

在线服务

你需要使用支持以下功能的 MCP 客户端:

  • OAuth2(支持动态客户端注册)
  • 工具通知
  • 资源通知

你可以使用 MCP Inspector,但它不支持工具和资源通知,因此你必须手动刷新工具和资源。

使用 Portal One Web 客户端,在可用 MCP 服务列表中找到该服务,然后点击“连接”。

如需查看其他支持动态 MCP 工具和资源(发现)的客户端,请参阅 MCP SDK 示例客户端。

本地

确保客户端可以访问服务。如果你在本地运行服务,并使用基于 Web 的客户端,可以使用 ngrok 等工具将服务暴露到互联网:

ngrok http http://localhost:8083

如果你使用的是 localhost 上的客户端,可以直接连接到 http://localhost:8083/mcp。

项目结构

src/
├── config/
│   └── index.ts                # Loads and exports environment variables
├── controllers/
│   └── mcp.controller.ts       # Manages session lifecycles and creates entities on-demand
├── game/
│   ├── commands/               # Command Pattern: Encapsulates user actions
│   │   ├── command.interface.ts
│   │   ├── give-up.command.ts
│   │   ├── guess-number.command.ts
│   │   └── start-game.command.ts
│   ├── core/
│   │   ├── game-context.ts       # Central game logic coordinator for a SINGLE session
│   │   ├── game-session-service.ts # Handles all Firestore interactions (get/set state)
│   │   ├── game-types.ts       # Core TypeScript interfaces for the game
│   │   ├── resource-factory.ts # (Not used in current setup, but available)
│   │   └── tool-factory.ts     # (Not used in current setup, but available)
│   ├── states/                 # State Pattern: Manages game flow (Lobby, Playing)
│   │   ├── game-state.interface.ts
│   │   ├── lobby.state.ts
│   │   └── playing.state.ts
│   └── utils/
│       └── game-constants.ts   # Shared game constants
├── index.ts                    # Main application entry point (Express server setup)
├── mcp_setup/
│   ├── index.ts                # Creates the single, global McpServer instance
│   ├── resources/              # Factory functions for creating MCP resources
│   │   ├── index.ts            # Barrel file for exporting all resource setups
│   │   └── ... (setup-banner-image-resource.ts, etc.)
│   └── tools/                  # Factory functions for creating MCP tools
│       ├── index.ts            # Barrel file for exporting all tool setups
│       └── ... (setup-guess-number-tool.ts, etc.)
├── routes/
│   └── mcp.routes.ts           # Defines the Express routes for /mcp
└── services/
    └── firestore.service.ts    # Initializes the global Firestore client

展示的核心概念

  • 动态的、会话级的 MCP: 这是此架构的核心。工具和资源不是全局的;它们会针对每个用户会话创建和销毁。
  • 生命周期管理: 使用传输钩子(onsessioninitialized、onclose)管理会话资源的设置和拆除。
  • 基于 HTTP 的有状态服务: 通过无状态协议实现持久且相互隔离的用户会话。
  • 状态模式: 管理每个用户游戏流程中的复杂状态转换。
  • 使用 Firestore 持久化状态: 将服务的运行时与游戏状态解耦,从而支持水平扩展和提升弹性。
  • TypeScript 最佳实践: 在真实且可扩展的应用结构中使用类型,以编写稳健的代码。

贡献

欢迎贡献!如果你有改进建议、新功能想法或发现了 Bug,欢迎提交 issue 或 pull request。

许可证

本项目采用 MIT 许可证授权,详情请参阅 LICENSE 文件。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。