模块化模型上下文协议服务器

一个基于TypeScript和Express.js构建的模块化、可扩展的模型上下文协议(MCP)服务器实现,提供工具和资源的动态注册与管理,适用于LLM应用与外部数据源的集成。

  • by T-hash06
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 t-hash06/modular-mcp-server

使用说明

MCP服务器-模块化模型上下文协议实现

模块化、可扩展的实现 模型上下文协议(MCP) 使用TypeScript、Express.js和干净的架构设计构建的服务器。该项目为使用自定义工具和资源构建MCP服务器提供了坚实的基础。

目录

概述

模型上下文协议(MCP)是一种开放协议,可实现LLM应用程序与外部数据源和工具之间的无缝集成。该实施提供了:

  • 模块化架构:彻底分离依赖注入的关注点
  • HTTP传输:带会话管理的RESTful API
  • 可扩展设计:易于使用的工具和资源基类
  • 类型安全:完全支持TypeScript,具有全面的类型定义
  • 生产就绪:内置错误处理、日志记录和验证
  • 开发者体验:热重载、linting和格式化工具

主要特点

  • ✅ 工具:AI模型可以执行的自定义函数
  • ✅ 资源:AI模型的上下文和数据源
  • ✅ HTTP传输:标准HTTP/JSON API端点
  • ✅ 会话管理:具有自动清理功能的有状态连接
  • ✅ 注册模式:工具和资源的动态登记
  • ✅ 配置:灵活的服务器配置选项
  • ✅ 验证:使用Zod模式进行输入验证
  • ✅ 错误处理:全面的错误处理和报告
  • ✅ 日志记录:用于调试和监控的结构化日志记录

先决条件

在开始之前,请确保您的系统上安装了以下内容:

  • Node.js:版本20或更高
  • 程序包管理器:npm、yarn或pnpm(建议使用pnpm)
  • TypeScript:建议了解TypeScript
  • Git:用于版本控制和克隆存储库

系统要求

  • 操作系统:Linux、macOS或Windows
  • 记忆:最低512MB RAM
  • 存储:至少100MB可用空间
  • 网络:用于安装依赖项的Internet连接

安装

1.克隆存储库

git clone <repository-url>
cd generic-mcp

2.安装依赖项

使用pnpm(推荐):

pnpm install

使用npm:

npm install

使用纱线:

yarn install

3.建设项目

pnpm build

4.验证安装

pnpm check

此命令运行类型检查和linting,以确保所有设置都正确。

快速开始

1.启动开发服务器

pnpm dev

服务器将于启动 http://localhost:3000 默认情况下。

2.测试健康终点

curl http://localhost:3000/health

您应该看到这样的响应:

{
  "status": "healthy",
  "name": "mcp-server",
  "version": "1.0.0",
  "timestamp": "2025-07-19T12:00:00.000Z",
  "sessions": 0
}

3.启动MCP会话

curl -X POST http://localhost:3000/mcp \
    -H "Content-Type: application/json" \
    -H "Accept: application/json, text/event-stream" \
    -d '{
        "jsonrpc": "2.0",
        "id": 1,
        "method": "initialize",
        "params": {
            "protocolVersion": "2024-11-05",
            "capabilities": {},
            "clientInfo": {
                "name": "test-client",
                "version": "1.0.0"
            }
        }
    }'

4.列出可用工具

curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "MCP-Session-ID: <session-id-from-initialize>" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/list"
  }'

建筑

模块化设计

该项目遵循模块化架构,关注点明确分离:

src/
├── app.ts                    # Main application setup
├── index.ts                  # Entry point
├── config/
│   └── server.config.ts      # Server configuration
├── http/
│   ├── middleware/           # Express middleware
│   ├── routes/              # HTTP route handlers
│   └── utils/               # HTTP utilities
├── resources/
│   ├── base-resource.ts     # Base class for resources
│   ├── registry.ts          # Resource registry
│   └── examples/            # Example implementations
├── server/
│   └── mcp-server.factory.ts # MCP server factory
├── tools/
│   ├── base-tool.ts         # Base class for tools
│   ├── registry.ts          # Tool registry
│   └── examples/            # Example implementations
├── transport/
│   └── session-manager.ts   # Session management
├── types/
│   └── index.ts             # Type definitions
└── utils/
    ├── errors.ts            # Error handling
    └── logger.ts            # Logging utilities

核心组件

1. 应用层 (app.ts)

编排所有组件的主要应用程序类:

  • Express.js设置和中间件配置
  • 依赖注入和服务注册
  • 路由配置和错误处理
  • 优雅的停机处理

2. 工具系统 (tools/)

  • BaseTool:用于实现自定义工具的抽象基类
  • 工具注册表:管理工具注册和发现
  • 例子:参考实现(AddTool)

3. 资源系统 (resources/)

  • 基础资源:用于实现自定义资源的抽象基类
  • 资源注册表:管理资源注册和发现
  • 例子:参考实施(GreetingResource)

4. 传输层 (transport/)

  • 会话传输管理器:管理HTTP会话和MCP连接
  • 会话生命周期:创建、管理和清理
  • 协议处理:JSON-RPC消息处理

5. HTTP层 (http/)

  • 中间件:请求日志记录、CORS、验证
  • 路线:MCP端点处理程序
  • 公用事业:请求/响应助手

依赖注入

应用程序使用基于构造函数的依赖注入:

interface ServerDependencies {
  toolRegistry: ToolRegistry;
  resourceRegistry: ResourceRegistry;
  sessionManager: SessionTransportManager;
}

此模式允许:

  • 可测试性:易于模拟和单元测试
  • 灵活性:依赖项的运行时配置
  • 可维护性:明确的依赖关系

注册模式

工具和资源都使用注册表模式进行动态注册:

// Tool registration
const toolRegistry = new ToolRegistryImpl();
toolRegistry.registerToolClass(new AddTool());

// Resource registration
const resourceRegistry = new ResourceRegistryImpl();
resourceRegistry.registerResourceClass(new GreetingResource());

优点:

  • 可扩展性:在不修改核心代码的情况下添加新工具/资源
  • 发现:自动枚举可用功能
  • 验证:使用运行时检查进行类型安全注册

使用示例

创建自定义工具

工具是AI模型可以执行的功能。以下是如何创建自定义工具:

1.创建工具类

// src/tools/examples/weather-tool.ts
import { BaseTool } from "@tools/base-tool.js";
import { ValidationError } from "@types";
import { z } from "zod";

export class WeatherTool extends BaseTool {
  readonly name = "get_weather";
  readonly title = "Weather Information";
  readonly description = "Get current weather for a location";
  readonly inputSchema = {
    location: z.string().describe("City name or coordinates"),
    units: z.enum(["celsius", "fahrenheit"]).optional().describe("Temperature units")
  };

  async execute(params: Record<string, unknown>): Promise<{
    content: Array<{ type: "text"; text: string }>;
  }> {
    this.validateParams(params);

    const { location, units = "celsius" } = params as {
      location: string;
      units?: "celsius" | "fahrenheit";
    };

    // Validate location parameter
    if (!location || location.trim().length === 0) {
      throw new ValidationError("Location parameter is required");
    }

    // Your weather API integration here
    const weatherData = await this.fetchWeatherData(location, units);
    
    const result = `Weather in ${location}: ${weatherData.temperature}°${units === "celsius" ? "C" : "F"}, ${weatherData.description}`;
    
    return this.createTextResponse(result);
  }

  private async fetchWeatherData(location: string, units: string) {
    // Implement your weather API call here
    // This is a mock implementation
    return {
      temperature: 22,
      description: "Sunny"
    };
  }
}

2.注册工具

// In src/app.ts, modify the createDependencies method:
private createDependencies(): ServerDependencies {
  const toolRegistry = new ToolRegistryImpl();
  const resourceRegistry = new ResourceRegistryImpl();

  // Register default tools
  toolRegistry.registerToolClass(new AddTool());
  toolRegistry.registerToolClass(new WeatherTool()); // Add your tool

  // Register default resources
  resourceRegistry.registerResourceClass(new GreetingResource());

  logger.info(
    `Registered ${toolRegistry.getCount()} tools and ${resourceRegistry.getCount()} resources`,
  );

  return {
    toolRegistry,
    resourceRegistry,
    sessionManager: this.sessionManager,
  };
}

创建自定义资源

资源为AI模型提供上下文和数据。以下是如何创建自定义资源:

1.创建资源类

// src/resources/examples/database-resource.ts
import { BaseResource } from "@resources/base-resource.js";
import { ValidationError } from "@types";

export class DatabaseResource extends BaseResource {
  readonly name = "database";
  readonly title = "Database Query Resource";
  readonly description = "Execute database queries";
  readonly uriTemplate = "database://{table}/{id?}";
  readonly mimeType = "application/json";

  async read(
    uri: URL,
    params: Record<string, string>,
  ): Promise<{
    contents: Array<{ uri: string; text: string }>;
  }> {
    this.validateParams(params, ["table"]);

    const { table, id } = params;

    // Basic validation
    if (!table || table.trim().length === 0) {
      throw new ValidationError("Table parameter is required");
    }

    // Sanitize table name (basic SQL injection prevention)
    const sanitizedTable = table.replace(/[^a-zA-Z0-9_]/g, "");
    
    let result: any;
    
    if (id) {
      // Fetch specific record
      result = await this.fetchRecord(sanitizedTable, id);
    } else {
      // Fetch all records
      result = await this.fetchTable(sanitizedTable);
    }

    return this.createContentResponse(
      uri.href,
      JSON.stringify(result, null, 2)
    );
  }

  private async fetchRecord(table: string, id: string) {
    // Implement your database query here
    // This is a mock implementation
    return {
      id: id,
      table: table,
      data: { name: "Sample Record" }
    };
  }

  private async fetchTable(table: string) {
    // Implement your database query here
    // This is a mock implementation
    return [
      { id: "1", name: "Record 1" },
      { id: "2", name: "Record 2" }
    ];
  }
}

2.注册资源

// In src/app.ts, modify the createDependencies method:
private createDependencies(): ServerDependencies {
  const toolRegistry = new ToolRegistryImpl();
  const resourceRegistry = new ResourceRegistryImpl();

  // Register default tools
  toolRegistry.registerToolClass(new AddTool());

  // Register default resources
  resourceRegistry.registerResourceClass(new GreetingResource());
  resourceRegistry.registerResourceClass(new DatabaseResource()); // Add your resource

  logger.info(
    `Registered ${toolRegistry.getCount()} tools and ${resourceRegistry.getCount()} resources`,
  );

  return {
    toolRegistry,
    resourceRegistry,
    sessionManager: this.sessionManager,
  };
}

工具和资源注册流程

注册过程遵循以下步骤:

  1. 实例化:创建工具/资源类的实例
  2. 注册:将它们添加到适当的注册表中
  3. 发现:MCP服务器通过协议自动公开它们
  4. 验证:使用Zod模式验证输入参数
  5. 执行:根据客户端请求执行工具或读取资源

动态注册

您还可以在运行时动态注册工具和资源:

// During application startup or based on configuration
const toolRegistry = app.getDependencies().toolRegistry;
const resourceRegistry = app.getDependencies().resourceRegistry;

// Conditionally register tools based on environment
if (process.env.ENABLE_WEATHER_TOOL === 'true') {
  toolRegistry.registerToolClass(new WeatherTool());
}

// Register resources based on database availability
if (isDatabaseAvailable()) {
  resourceRegistry.registerResourceClass(new DatabaseResource());
}

API文档

MCP服务器公开以下HTTP端点:

健康检查

获取 /health

返回服务器运行状况和基本信息。

答复:

{
  "status": "healthy",
  "name": "mcp-server",
  "version": "1.0.0",
  "timestamp": "2025-07-19T12:00:00.000Z",
  "sessions": 0
}

MCP协议端点

所有MCP协议通信都通过这些端点进行:

初始化会话

发布 /mcp

初始化新的MCP会话。

请求:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {},
    "clientInfo": {
      "name": "client-name",
      "version": "1.0.0"
    }
  }
}

答复:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "tools": {},
      "resources": {}
    },
    "serverInfo": {
      "name": "mcp-server",
      "version": "1.0.0"
    }
  }
}

列出工具

发布 /mcp

列出当前会话中可用的工具。

标题:

  • X-MCP-Session-ID:初始化响应中的会话ID

请求:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/list"
}

答复:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "tools": [
      {
        "name": "add",
        "description": "Add two numbers",
        "inputSchema": {
          "type": "object",
          "properties": {
            "a": { "type": "string", "description": "First number" },
            "b": { "type": "string", "description": "Second number" }
          },
          "required": ["a", "b"]
        }
      }
    ]
  }
}

呼叫工具

发布 /mcp

执行特定工具。

标题:

  • X-MCP-Session-ID:初始化响应中的会话ID

请求:

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "add",
    "arguments": {
      "a": "5",
      "b": "3"
    }
  }
}

答复:

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "8"
      }
    ]
  }
}

列出资源

发布 /mcp

列出当前会话中的可用资源。

标题:

  • X-MCP-Session-ID:初始化响应中的会话ID

请求:

{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "resources/list"
}

答复:

{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "resources": [
      {
        "name": "greeting",
        "description": "Dynamic greeting generator",
        "uri": "greeting://{name}",
        "mimeType": "text/plain"
      }
    ]
  }
}

读取资源

发布 /mcp

阅读特定资源。

标题:

  • X-MCP-Session-ID:初始化响应中的会话ID

请求:

{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "resources/read",
  "params": {
    "uri": "greeting://Alice"
  }
}

答复:

{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "contents": [
      {
        "uri": "greeting://Alice",
        "mimeType": "text/plain",
        "text": "Hello, Alice!"
      }
    ]
  }
}

关闭会话

删除 /mcp

关闭MCP会话并清理资源。

标题:

  • X-MCP-Session-ID:要关闭的会话ID

答复:

{
  "jsonrpc": "2.0",
  "result": {
    "message": "Session closed successfully"
  }
}

错误响应

服务器返回标准JSON-RPC错误响应:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32600,
    "message": "Invalid Request",
    "data": "Additional error details"
  }
}

常见错误代码:

  • -32700:分析错误
  • -32600:无效请求
  • -32601:未找到方法
  • -32602:无效参数
  • -32603:内部错误

发展

可用脚本

该项目包括几个用于开发的npm/pnpm脚本:

# Development
pnpm dev          # Start development server with hot reload
pnpm build        # Build the project for production
pnpm start        # Start the production server

# Code Quality
pnpm check        # Run type checking and linting
pnpm lint         # Run Biome linting
pnpm format       # Format code with Biome
pnpm type-check   # Run TypeScript type checking

# Git Hooks
pnpm prepare      # Install git hooks (Husky)

开发环境设置

  1. 再进行

    pnpm install
    
  2. 设置Git挂钩

    pnpm prepare
    
  3. 启动开发服务器

    pnpm dev
    
  4. 运行质量检查

    pnpm check
    

代码质量工具

该项目使用多种工具来维护代码质量:

生物群系

生物群系 提供快速的换行和格式化:

  • 配置: biome.json
  • 特性:ESLint类linting,Prettier类格式化
  • 速度:性能极快
  • 整合:VS代码扩展可用

TypeScript

完全支持TypeScript,具有严格的类型检查:

  • 配置: tsconfig.json
  • 路径别名:方便的进口(例如。, @tools/*, @resources/*)
  • 构建输出: dist/ 包含声明文件的目录
  • 源地图:已启用调试

承诺

强制执行常规提交消息:

  • 配置: commitlint.config.js
  • 格式: type(scope): description
  • 例子:
    • feat: add weather tool
    • fix: resolve session cleanup issue
    • docs: update README installation section

哈士奇

Git挂钩用于自动质量检查:

  • 预承诺:运行linting和格式化
  • 提交消息:验证提交消息格式

测试和验证

运行测试

该项目使用统一 check 验证命令:

pnpm check

此命令:

  1. 运行TypeScript类型检查(tsc --noEmit)
  2. 在 src 目录
  3. 报告任何错误或警告

手动测试

对于MCP服务器的手动测试:

  1. 启动服务器:

    pnpm dev
    
  2. 测试健康终点:

    curl http://localhost:3000/health
    
  3. 测试MCP会话:

    # Initialize session
    curl -X POST http://localhost:3000/mcp \
      -H "Content-Type: application/json" \
      -d '{
        "jsonrpc": "2.0",
        "id": 1,
        "method": "initialize",
        "params": {
          "protocolVersion": "2024-11-05",
          "capabilities": {},
          "clientInfo": {"name": "test", "version": "1.0.0"}
        }
      }'
    

调试

该项目包括综合测井:

import { logger } from "@utils/logger.js";

// Log levels: debug, info, warn, error
logger.info("Server started successfully");
logger.error("Failed to process request", { error });

要启用调试日志记录,请执行以下操作:

DEBUG=* pnpm dev

配置

服务器配置

服务器可以通过以下方式配置 ServerConfig 接口:

// src/config/server.config.ts
export interface ServerConfig {
  name: string;                              // Server name for MCP identification
  version: string;                           // Server version
  port: number;                             // HTTP port to listen on
  enableDnsRebindingProtection: boolean;    // DNS rebinding protection
  allowedHosts: string[];                   // Allowed hosts for DNS protection
  sessionIdGenerator: () => string;         // Session ID generator function
}

默认配置

export const defaultServerConfig: ServerConfig = {
  name: "mcp-server",
  version: "1.0.0",
  port: Number(process.env.PORT) || 3000,
  enableDnsRebindingProtection: false,
  allowedHosts: ["127.0.0.1"],
  sessionIdGenerator: () => randomUUID(),
};

环境变量

您可以使用环境变量自定义配置:

# Server configuration
PORT=8080                                 # Server port (default: 3000)

# Development
DEBUG=*                                   # Enable debug logging
NODE_ENV=production                       # Environment mode

自定义配置

要使用自定义配置,请执行以下操作:

// Custom configuration
const customConfig: ServerConfig = {
  name: "my-mcp-server",
  version: "2.0.0",
  port: 8080,
  enableDnsRebindingProtection: true,
  allowedHosts: ["localhost", "127.0.0.1", "example.com"],
  sessionIdGenerator: () => `session-${Date.now()}`,
};

// Create application with custom config
const app = new McpApplication(customConfig);

路径别名

该项目使用TypeScript路径别名进行干净导入:

// Instead of relative imports
import { BaseTool } from "../../tools/base-tool.js";

// Use clean aliases
import { BaseTool } from "@tools/base-tool.js";

可用别名:

  • @config/* → ./src/config/*
  • @http/* → ./src/http/*
  • @resources/* → ./src/resources/*
  • @server/* → ./src/server/*
  • @tools/* → ./src/tools/*
  • @transport/* → ./src/transport/*
  • @types/* → ./src/types/*
  • @types → ./src/types/index.ts
  • @utils/* → ./src/utils/*

故障排除

常见问题

1.端口已在使用中

错误: EADDRINUSE: address already in use :::3000

解决方案:

  • 更改端口: PORT=8080 pnpm dev
  • 使用端口终止进程: kill -9 $(lsof -ti:3000)
  • 在配置中使用其他端口

2.找不到模块错误

错误: Cannot find module '@tools/base-tool.js'

解决方案:

  • 确保您已经构建了项目: pnpm build
  • 检查中的TypeScript路径别名 tsconfig.json
  • 验证文件扩展名是否为 .js 在进口报表中

3.TypeScript编译错误

错误:期间出现各种TypeScript错误 pnpm check

解决方案:

  • 检查是否缺少类型定义: pnpm install @types/node
  • 验证中的TypeScript配置 tsconfig.json
  • 确保所有导入使用正确的文件扩展名

4.会话管理问题

错误: Session not found 或会话相关错误

解决方案:

  • 确保您正在发送 X-MCP-Session-ID 头球
  • 检查会话ID是否来自最近的 initialize 呼叫
  • 验证会话超时设置

5.JSON-RPC协议错误

错误:JSON-RPC请求无效

解决方案:

  • 确保请求包括 jsonrpc: "2.0"
  • 包括一个独特的 id 每个请求的字段
  • 使用正确 method 名称(例如。, tools/list, resources/read)

调试模式

启用调试日志以排除问题:

DEBUG=* pnpm dev

这将显示以下内容的详细日志:

  • HTTP请求和响应
  • 会话创建和管理
  • 工具和资源执行
  • 错误处理

检查服务器运行状况

始终通过检查运行状况端点开始故障排除:

curl http://localhost:3000/health

健康的反应应该是这样的:

{
  "status": "healthy",
  "name": "mcp-server",
  "version": "1.0.0",
  "timestamp": "2025-07-19T12:00:00.000Z",
  "sessions": 0
}

验证错误

在创建自定义工具或资源时,常见的验证问题包括:

  • 缺少必要参数:确保提供所有必填字段
  • 参数类型无效:检查Zod模式定义
  • 空值或无效值:在你的类中实现适当的验证

性能问题

如果您遇到性能问题:

  1. 检查会话计数:通过健康端点监视活动会话
  2. 审查工具复杂性:确保工具不会执行长时间运行的操作
  3. 监控内存使用情况:使用Node.js分析工具
  4. 优化资源查询:缓存频繁访问的数据

部署

生产建设

  1. 构建项目:

    pnpm build
    
  2. 启动生产服务器:

    pnpm start
    

Docker部署

创建一个 Dockerfile:

FROM node:20-alpine

WORKDIR /app

# Copy package files
COPY package.json pnpm-lock.yaml ./

# Install dependencies
RUN npm install -g pnpm && pnpm install --frozen-lockfile

# Copy source code
COPY . .

# Build the application
RUN pnpm build

# Expose port
EXPOSE 3000

# Start the server
CMD ["pnpm", "start"]

构建并运行:

docker build -t mcp-server .
docker run -p 3000:3000 mcp-server

生产环境变量

# Required
NODE_ENV=production
PORT=3000

# Optional
DEBUG=                                    # Disable debug logging
LOG_LEVEL=info                           # Set log level

性能和扩展指南

内存管理

  • 会话清理:服务器会自动清理非活动会话
  • 资源池:考虑为数据库资源实施连接池
  • 内存监控:使用以下工具 clinic.js 用于内存分析

水平缩放

  • 无状态设计:服务器设计为无状态(会话在内存中)
  • 负载平衡:为多个实例使用粘性会话或外部会话存储
  • 健康检查:The /health 端点支持负载平衡器健康检查

性能优化

  • 工具执行:将工具执行时间控制在30秒以内
  • 资源缓存:对频繁访问的资源实施缓存
  • 异步操作:对所有I/O操作使用async/await

监控

设置监控:

  • 响应时间:跟踪端点性能
  • 错误率:监视失败的请求
  • 会话计数:注意会话泄漏
  • 资源使用:CPU和内存消耗

安全考虑

DNS重新绑定保护

在生产环境中启用DNS重新绑定保护:

const config: ServerConfig = {
  enableDnsRebindingProtection: true,
  allowedHosts: ["your-domain.com", "api.your-domain.com"],
  // ... other config
};

输入验证

  • 所有工具和资源输入都使用Zod模式进行验证
  • 对数据库查询实施额外的清理
  • 使用参数化查询来防止SQL注入

HTTPS在生产中

使用反向代理(nginx、Cloudflare)终止SSL:

server {
    listen 443 ssl;
    server_name your-domain.com;
    
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    
    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

贡献

我们欢迎为改进MCP服务器实施做出贡献!

开发工作流程

  1. 分叉存储库

  2. 创建要素分支:

    git checkout -b feature/new-tool
    
  3. 进行更改:

    • 遵循现有代码样式
    • 添加新功能的测试
    • 根据需要更新文档
  4. 进行质量检查:

    pnpm check
    
  5. 提交您的更改:

    git commit -m "feat: add weather tool"
    
  6. 推送并创建拉取请求

代码规范

TypeScript指南

  • 使用严格的TypeScript设置
  • 对于对象形状,更喜欢接口而不是类型
  • 在Promises上使用async/await
  • 实施适当的错误处理

命名约定

  • 类:PascalCase(例如。, WeatherTool, DatabaseResource)
  • 文件:烤肉串盒(例如。, weather-tool.ts, database-resource.ts)
  • 变量:camelCase(例如。, sessionId, toolRegistry)
  • 常量:UPPER_SNAKE_CASE(例如。, DEFAULT_PORT, MAX_SESSIONS)

代码组织

  • 将文件集中于单一职责
  • 使用已建立的目录结构
  • 为常见模式实现基类
  • 使用依赖注入实现可测试性

文档

  • 为公共方法添加JSDoc注释
  • 在复杂代码中包含使用示例
  • 更新README以获取新功能
  • 文档配置选项

拉取请求指南

  • 包括对变更的清晰描述
  • 参考文献相关问题
  • 确保所有检查均已通过
  • 添加新功能的测试
  • 更新文档

报告问题

在报告问题时,请包括:

  • Node.js和包管理器版本
  • 重现问题的步骤
  • 预期行为与实际行为
  • 相关错误消息或日志
  • 配置详细信息(如适用)

资源

模型上下文协议

技术栈

开发工具

相关项目


许可证

该项目根据MIT许可证获得许可。请参阅 许可证 文件以获取详细信息。

致谢

  • 创建MCP规范的模型上下文协议团队
  • TypeScript和Node.js社区提供优秀的工具
  • 本项目中使用的开源软件包的贡献者

有关更多信息、问题或支持,请在GitHub存储库上打开问题。