数字猜谜游戏MCP服务器

用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
以及一个代理与服务器交互的视频。你在视频中看不到,但代理可用的工具也在根据游戏状态而变化。
https://github.com/user-attachments/assets/d7d338a2-8a93-46c3-b4a9-1a6b4caf9dc0
本项目旨在作为构建动态多用户MCP应用程序的学习资源和实例。
目录
主要特点
- 真正的多用户会话: 每个连接的用户都有自己的独立游戏状态和一组MCP实体。
- 动态MCP工具: 工具(
start_game,guess_number,give_up)根据每个用户的情况启用或禁用,反映他们的个人游戏状态。 - 动态MCP资源: 这
game_state每个用户在开始和结束游戏时都会创建和销毁资源。 - 干净、可扩展的架构:
- A. 单一全球 McpServer 处理所有连接。 - 一 Express.js控制器 管理每个用户会话的生命周期。 - 会话范围实体 (工具、资源、游戏逻辑)是按需创建的。 - 状态模式: 管理每个用户的游戏流程(大厅、游戏)。
- TypeScript实现: 完全打字,以获得更好的可维护性和开发人员体验。
- Firestore集成: 保持游戏状态和高分,使服务器无状态且可扩展。
结构概述
服务器遵循一种现代的、可扩展的模式,其中中央控制器管理临时的、特定于会话的资源。
- 全局服务器配置(
src/mcp_setup/index.ts): A. McpServer 实例是在应用程序启动时创建的。它充当“白板”连接管理器,本身不包含任何工具或资源。
- HTTP控制器(
src/controllers/mcp.controller.ts): 这是应用程序的大脑。
- 它处理所有传入的HTTP请求 /mcp 终点。 - 当新用户连接时,它会创建一个 StreamableHTTPServerTransport. - 它使用运输的生命周期挂钩(onsessioninitialized 和 onclose)以管理用户的会话。
- 会话初始化(
onsessioninitialized): 当用户的运输工具准备就绪时,控制器:
- 创建一个 一组新的、独特的MCP实体 对于该用户,可以调用中的setup函数 src/mcp_setup/tools 和 src/mcp_setup/resources. - 创建一个 新 GameContext 例如,将其链接到用户的会话ID及其唯一的MCP实体。 - 从Firestore加载用户状态(通过 GameSessionService)并使用状态模式(LobbyState 或 PlayingState)为他们的会话启用/禁用正确的工具。
- 会话销毁(
onclose): 当用户断开连接时,控制器:
- 注销并销毁 为特定用户创建的所有工具和资源,防止内存泄漏。 - 从活动连接列表中清除传输。
这种架构确保每个用户的UI状态(例如,启用了哪些工具)是完全隔离的、有状态的和动态管理的,而服务器本身保持可扩展性。
先决条件
- Node.js(建议使用v18.x或更高版本)
- npm或纱线
- 在启用Firestore的情况下访问Google Cloud项目。
入门指南
安装
- 克隆存储库:
git clone https://github.com/portal-labs-infrastructure/number-guessing-game-mcp-server
cd number-guessing-game-mcp-server- 安装依赖项:
npm install
# or
yarn install配置
- 设置谷歌云身份验证: 确保您的环境已通过Google Cloud项目的身份验证。对于本地开发,您可以使用gcloud CLI:
gcloud auth application-default login- 创建一个
.env文件: 复制示例文件。
cp .env.example .env- 编辑
.env: 填写所需的环境变量。
- PORT:服务器运行的端口(例如。, 8083). - GCP_PROJECT_ID:您的谷歌云项目ID。 - BASE_URL:您服务器的面向公众的URL(例如。, http://localhost:8083). - OAUTH_ISSUER_URL:OAuth提供者的基本URL。 - DOCS_URL:指向您的服务文档的链接。
运行服务器
开发模式(用于热重载开发):
npm run dev生产模式:
编译TypeScript:
npm run build启动服务器:
npm start您应该看到输出,指示服务器正在运行并已连接到Firestore。
与服务器交互
Live服务器
您需要一个支持以下功能的MCP客户端:
- OAuth2(具有动态客户端注册)
- 工具通知
- 资源通知
您可以使用 MCP检查员,但它没有工具和资源通知,因此您必须手动刷新工具和资源。
你使用 门户一 web客户端,在可用MCP服务器列表中找到服务器,然后单击“连接”。
请参阅中支持动态MCP工具和资源(发现)的其他客户端 MCP SDK示例客户端.
本地
确保客户端可以访问服务器。如果您在本地运行服务器,并使用基于web的客户端,则可以使用以下工具 吸烟 将服务器暴露于互联网:
ngrok http http://localhost:8083如果您在本地主机上使用客户端,则可以直接连接到 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上的状态服务: 通过无状态协议实现持久、隔离的用户会话。
- 状态模式: 管理每个用户游戏流程的复杂状态转换。
- 状态持久化消防仓库: 将服务器的运行时与游戏状态解耦,允许横向扩展和弹性。
- TypeScript最佳实践: 在真实世界、可扩展的应用程序结构中使用类型来编写健壮的代码。
贡献
欢迎投稿!如果您有改进、新功能或发现任何错误的想法,请随时打开问题或拉取请求。
许可证
此项目根据MIT许可证获得许可-请参阅 许可证 文件以获取详细信息。
