mcpField
B
Boilerplate MCP Server

Boilerplate MCP Server

本地服务
github.com/aashari开发工具7334 周前更新

关于 Boilerplate MCP Server

Boilerplate MCP Server 是用 TypeScript 编写的 MCP 服务模板,内含 IP 查询的工具、资源和提示词示例。适合希望以 Node.js 创建新 MCP 集成的开发者,其分层结构便于扩展到其他 API。

主要功能

  1. 01分层架构:CLI、工具、资源、控制器、服务与工具函数
  2. 02同时支持 STDIO 与 Streamable HTTP 传输
  3. 03基于 Zod 的类型校验与 registerTool 写法
  4. 04包含 ip-api.com 查询示例及对应命令行
  5. 05内置 MCP Inspector 调试与测试配置

适用场景

  1. 01作为新 TypeScript MCP 服务的起始模板
  2. 02学习工具、资源和提示词在 MCP 中的组织方式
  3. 03通过命令行与 MCP Inspector 测试 IP 查询逻辑

MCP 相关

该项目是 MCP 服务模板,示例中向 MCP 客户端暴露 IP 查询工具、ip:// 资源模板和提示词,并可通过 STDIO 或 HTTP 运行。

配置

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

暂未收录安装方式

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

代码仓库

工具

还没有获取到工具列表

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

详细介绍

Boilerplate MCP Server

用于在 TypeScript 中开发自定义 Model Context Protocol(MCP)服务的生产就绪型基础模板。提供完整的分层架构模式、可运行的示例实现,以及完善的开发者基础设施,以连接 AI 助手与外部 API 和数据源。

NPM Version License: ISC

最新更新(2026 年 2 月):已更新至 MCP SDK 1.26.0 和 Zod 4.3.6,继续采用现代化的 registerTool 模式,并改进了可流式传输的 HTTP。详情请参阅 docs/MODERNIZATION.md。

功能

  • 安全优先:DNS 重绑定防护、仅绑定 localhost、安全错误处理
  • 双传输支持:STDIO 和可流式传输的 HTTP 传输,并支持自动回退
  • 分层架构:清晰划分 CLI、工具、资源、提示词、控制器、服务和实用工具
  • 类型安全:完整的 TypeScript 实现,并使用 Zod v4.3.6 进行模式验证
  • 完整支持所有 MCP 原语:工具、资源和提示词(含示例)
  • ResourceLink 模式:为大型响应提供节省 Token 的资源引用
  • TOON 输出格式:面向 Token 的对象表示法,比 JSON 减少 30-60% 的 Token
  • JMESPath 过滤:从响应中仅提取所需字段,以降低 Token 成本
  • 原始响应日志记录:自动将大型 API 响应记录到 /tmp/mcp/<project>/,并提供截断说明
  • 现代 SDK:使用 MCP SDK v1.26.0 和 registerTool API 模式(已准备好迁移至 v2)
  • 完整的 IP 地址示例:提供用于 IP 地理位置查询的工具、资源、提示词和 CLI 命令
  • 全面测试:包含覆盖率报告的单元测试和集成测试(47 项测试通过)
  • 生产级工具链:集成 ESLint、Prettier、semantic-release 和 MCP Inspector
  • 错误处理:通过 isError 字段和上下文日志记录实现结构化错误处理
  • 安全文档:完整的 SECURITY.md,包含身份验证实现指南

什么是 MCP?

Model Context Protocol(MCP)是一种开放标准,用于安全地将 AI 系统连接到外部工具和数据源。此基础模板采用清晰的分层架构实现 MCP 规范,可扩展用于为任何 API 或数据源构建自定义 MCP 服务。

前提条件

  • Node.js(>=20.x):下载
  • Git:用于版本控制

快速开始

# Clone the repository
git clone https://github.com/aashari/boilerplate-mcp-server.git
cd boilerplate-mcp-server

# Install dependencies
npm install

# Build the project
npm run build

# Run in different modes:

# 1. CLI Mode - Execute commands directly
npm run cli -- get-ip-details 8.8.8.8
npm run cli -- get-ip-details                                            # Get your current IP
npm run cli -- get-ip-details 1.1.1.1 -e                                 # With extended data
npm run cli -- get-ip-details 8.8.8.8 --jq "{ip: query, country: country}"  # JMESPath filter
npm run cli -- get-ip-details 8.8.8.8 -o json                            # JSON output

# 2. STDIO Transport - For AI assistant integration (Claude Desktop, Cursor)
npm run mcp:stdio

# 3. HTTP Transport - For web-based integrations
npm run mcp:http

# 4. Development with MCP Inspector
npm run mcp:inspect                         # Auto-opens browser with debugging UI

传输模式

STDIO 传输
  • 通过 stdin/stdout 进行 JSON-RPC 通信
  • 供 Claude Desktop、Cursor AI 和其他本地 AI 助手使用
  • 运行方式:TRANSPORT_MODE=stdio node dist/index.js
可流式传输的 HTTP
  • 基于 HTTP 的传输,使用服务器发送事件(SSE)
  • 支持多个并发连接和 Web 集成
  • 默认运行在端口 3000(可通过 PORT 环境变量配置)
  • MCP 端点:http://localhost:3000/mcp
  • 健康检查:http://localhost:3000/ → 返回服务版本
  • 运行方式:TRANSPORT_MODE=http node dist/index.js

安全 🔒

此基础模板实现了生产就绪的安全措施:

✅ 内置防护
  1. DNS 重绑定防护:验证 Origin 标头,防止恶意网站访问你的 localhost 服务
  2. 仅绑定 localhost:服务明确绑定到 127.0.0.1(无法从网络访问)
  3. 安全错误处理:错误响应包含 isError: true 标志,且不会泄露敏感信息
🔐 安全最佳实践
  • 本地开发:无需身份验证(仅限 localhost + DNS rebinding 防护)
  • 网络部署:必须进行身份验证——实现指南请参阅 SECURITY.md
  • 生产环境:使用 mTLS、OAuth 2.0 或 bearer token(详见 SECURITY.md)

📖 完整安全文档: SECURITY.md

🔍 安全审计报告: docs/AUDIT-2025-01-13.md

输出格式

TOON 格式(默认)

TOON(面向 Token 的对象表示法)是一种针对大模型优化的可读格式,与 JSON 相比可减少 30-60% 的 Token 用量:

status: success
query: 8.8.8.8
country: United States
city: Ashburn
lat: 39.03
lon: -77.5
JSON 格式

指定 --output-format json 时的标准 JSON 输出:

{
  "status": "success",
  "query": "8.8.8.8",
  "country": "United States",
  "city": "Ashburn"
}
JMESPath 筛选

使用 --jq 仅提取所需字段,从而降低 Token 成本:

# Extract specific fields
npm run cli -- get-ip-details 8.8.8.8 --jq "{ip: query, country: country}"

# Output:
# ip: 8.8.8.8
# country: United States

# Nested structure
npm run cli -- get-ip-details 8.8.8.8 --jq "{location: {city: city, coords: {lat: lat, lon: lon}}}"

更多筛选示例请参阅 JMESPath 文档。

架构概览

项目结构(点击展开)
src/
├── cli/                    # Command-line interfaces
│   ├── index.ts            # CLI entry point with Commander setup
│   └── ipaddress.cli.ts    # IP address CLI commands
├── controllers/            # Business logic orchestration  
│   ├── ipaddress.controller.ts    # IP lookup business logic
│   └── ipaddress.formatter.ts     # Response formatting
├── services/               # External API interactions
│   ├── vendor.ip-api.com.service.ts  # ip-api.com service
│   └── vendor.ip-api.com.types.ts    # Service type definitions
├── tools/                  # MCP tool definitions (AI interface)
│   ├── ipaddress.tool.ts   # IP lookup tool (inline content)
│   ├── ipaddress-link.tool.ts  # IP lookup with ResourceLink pattern
│   └── ipaddress.types.ts  # Tool argument schemas
├── resources/              # MCP resource definitions
│   └── ipaddress.resource.ts # IP lookup resource (URI: ip://address)
├── prompts/                # MCP prompt definitions
│   └── analysis.prompt.ts  # IP analysis prompt templates
├── types/                  # Global type definitions
│   └── common.types.ts     # Shared interfaces (ControllerResponse, etc.)
├── utils/                  # Shared utilities
│   ├── logger.util.ts      # Contextual logging system
│   ├── error.util.ts       # MCP-specific error formatting
│   ├── error-handler.util.ts # Error handling utilities
│   ├── config.util.ts      # Environment configuration
│   ├── constants.util.ts   # Version and package constants
│   ├── formatter.util.ts   # Markdown formatting and response truncation
│   ├── toon.util.ts        # TOON format encoding
│   ├── jq.util.ts          # JMESPath filtering
│   ├── response.util.ts    # Raw API response logging
│   └── transport.util.ts   # HTTP transport utilities
└── index.ts                # Server entry point (dual transport)

分层架构

该样板遵循清晰的分层架构,包含 6 个不同的层,有助于提升可维护性并清晰分离各项职责:

1. CLI 层(src/cli/)
  • 用途:用于直接使用和测试工具的命令行接口
  • 实现:基于 Commander 的参数解析,并进行上下文相关的错误处理
  • 示例:get-ip-details [ipAddress] --include-extended-data --no-use-https
  • 模式:注册命令 → 解析参数 → 调用控制器 → 处理错误
2. 工具层(src/tools/)
  • 用途:AI 助手可调用的 MCP 工具定义
  • 实现:使用 Zod 进行架构验证,并返回结构化响应
  • 示例:ip_get_details 工具,支持可选的 IP 地址和配置选项
  • 模式:定义架构 → 验证参数 → 调用控制器 → 格式化 MCP 响应
3. 资源层(src/resources/)
  • 用途:MCP 资源,通过 URI 提供可访问的上下文数据
  • 实现:使用 registerResource API 和 ResourceTemplate 创建参数化 URI
  • 示例:ip://{ipAddress} 资源模板,提供 IP 地理定位数据
  • 模式:注册 URI 模板 → 提取变量 → 返回格式化内容
4. 控制器层(src/controllers/)
  • 用途:业务逻辑编排,并进行全面的错误处理
  • 实现:选项验证、回退逻辑、响应格式化
  • 示例:IP 查询,包括 HTTPS 回退、测试环境检测和 API Token 验证
  • 模式:验证输入 → 应用默认值 → 调用服务 → 格式化响应
5. 服务层(src/services/)
  • 用途:直接与外部 API 交互,尽量减少业务逻辑
  • 实现:HTTP 传输工具,并进行结构化错误处理
  • 示例:调用 ip-api.com API,并进行身份验证和字段选择
  • 模式:构建请求 → 发起 API 调用 → 验证响应 → 返回原始数据
6. 工具函数层(src/utils/)
  • 用途:在所有层之间共享功能
  • 主要组件:
    • logger.util.ts:上下文日志记录(文件:方法上下文)
    • error.util.ts:MCP 专用错误格式化
    • error-handler.util.ts:错误处理和上下文构建
    • transport.util.ts:支持重试逻辑的 HTTP/API 工具
    • config.util.ts:环境配置管理
    • constants.util.ts:版本和软件包常量
    • formatter.util.ts:Markdown 格式化和响应截断
    • toon.util.ts:TOON 格式编码(节省 Token 的输出)
    • jq.util.ts:使用 JMESPath 筛选并转换响应
    • response.util.ts:将原始 API 响应记录到 /tmp/mcp/<project>/

开发者指南

开发脚本
# Build and Clean
npm run build               # Build TypeScript to dist/
npm run clean               # Remove dist/ and coverage/
npm run prepare             # Build + ensure executable permissions (for npm publish)

# CLI Testing
npm run cli -- get-ip-details 8.8.8.8                    # Test specific IP
npm run cli -- get-ip-details --include-extended-data    # Test with extended data
npm run cli -- get-ip-details --no-use-https             # Test with HTTP

# MCP Server Modes
npm run mcp:stdio           # STDIO transport for AI assistants
npm run mcp:http            # HTTP transport on port 3000
npm run mcp:inspect         # HTTP + auto-open MCP Inspector

# Testing
npm test                    # Run all tests (Jest)
npm run test:coverage       # Generate coverage report
npm run test:cli            # Run CLI-specific tests

# Code Quality
npm run lint                # ESLint with TypeScript rules
npm run format              # Prettier formatting
环境变量
核心配置
  • TRANSPORT_MODE:传输模式(stdio | http,默认值:stdio)
  • PORT:HTTP 服务端口(默认值:3000)
  • DEBUG:启用调试日志(true | false,默认值:false)
  • NODE_ENV:Node 环境(development | production,默认值:development)
IP API 配置
  • IPAPI_API_TOKEN:用于获取 ip-api.com 扩展数据的 API 令牌(可选,提供免费套餐)
.env 文件示例
# Core configuration
TRANSPORT_MODE=http
PORT=3000
DEBUG=true
NODE_ENV=development

# External API Keys
IPAPI_API_TOKEN=your_token_here
调试工具
  • MCP Inspector:用于测试 MCP 工具的可视化工具

    • 使用 npm run mcp:inspect 运行服务
    • 打开终端中显示的 URL
    • 交互式测试工具
  • 调试日志:通过 DEBUG=true 环境变量启用

  • 原始响应日志:大型 API 响应(>40,000 个字符)会自动记录

    • 响应保存在 /tmp/mcp/<project-name>/ 目录中
    • 文件名格式:<timestamp>-<random>.txt
    • 包含请求详情、响应数据和性能指标
    • 被截断的响应会提供访问完整原始文件的指引
配置(点击展开)

创建 ~/.mcp/configs.json:

{
  "boilerplate": {
    "environments": {
      "DEBUG": "true",
      "TRANSPORT_MODE": "http",
      "PORT": "3000"
    }
  }
}

构建自定义工具

分步工具实现指南(点击展开)
1. 定义服务层

在 src/services/ 中创建一个新服务,并遵循特定供应商的命名模式:

// src/services/vendor.example-api.service.ts
import { Logger } from '../utils/logger.util.js';
import { fetchApi } from '../utils/transport.util.js';
import { ExampleApiResponse, ExampleApiRequestOptions } from './vendor.example-api.types.js';
import { createApiError, McpError } from '../utils/error.util.js';

const serviceLogger = Logger.forContext('services/vendor.example-api.service.ts');

async function get(
	param?: string,
	options: ExampleApiRequestOptions = {}
): Promise<ExampleApiResponse> {
	const methodLogger = serviceLogger.forMethod('get');
	methodLogger.debug(`Calling Example API with param: ${param}`);

	try {
		const url = `https://api.example.com/${param || 'default'}`;
		const rawData = await fetchApi<ExampleApiResponse>(url, {
			headers: options.apiKey ? { 'Authorization': `Bearer ${options.apiKey}` } : {}
		});

		methodLogger.debug('Received successful response from Example API');
		return rawData;
	} catch (error) {
		methodLogger.error('Service error fetching data', error);
		
		if (error instanceof McpError) {
			throw error;
		}
		
		throw createApiError(
			'Unexpected service error while fetching data',
			undefined,
			error
		);
	}
}

export default { get };
2. 创建控制器

在 src/controllers/ 中添加一个控制器,用于处理业务逻辑并提供错误上下文:

// src/controllers/example.controller.ts
import { Logger } from '../utils/logger.util.js';
import exampleService from '../services/vendor.example-api.service.js';
import { formatExample } from './example.formatter.js';
import { handleControllerError, buildErrorContext } from '../utils/error-handler.util.js';
import { ControllerResponse } from '../types/common.types.js';
import { config } from '../utils/config.util.js';

const logger = Logger.forContext('controllers/example.controller.ts');

export interface GetDataOptions {
	param?: string;
	includeMetadata?: boolean;
}

async function getData(
	options: GetDataOptions = {}
): Promise<ControllerResponse> {
	const methodLogger = logger.forMethod('getData');
	methodLogger.debug(`Getting data for param: ${options.param || 'default'}`, options);

	try {
		// Apply business logic and defaults
		const apiKey = config.get('EXAMPLE_API_TOKEN');
		
		// Call service layer
		const data = await exampleService.get(options.param, {
			apiKey,
			includeMetadata: options.includeMetadata ?? false
		});
		
		// Format response
		const formattedContent = formatExample(data);
		return { content: formattedContent };
		
	} catch (error) {
		throw handleControllerError(
			error,
			buildErrorContext(
				'ExampleData',
				'getData',
				'controllers/example.controller.ts@getData',
				options.param || 'default',
				{ options }
			)
		);
	}
}

export default { getData };
3. 实现 MCP 工具

在 src/tools/ 中创建工具定义,并遵循注册模式:

// src/tools/example.tool.ts
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
import { Logger } from '../utils/logger.util.js';
import { formatErrorForMcpTool } from '../utils/error.util.js';
import exampleController from '../controllers/example.controller.js';

const logger = Logger.forContext('tools/example.tool.ts');

// Define Zod schema for tool arguments
const GetDataSchema = z.object({
	param: z.string().optional().describe('Optional parameter for the API call'),
	includeMetadata: z.boolean().optional().default(false)
		.describe('Whether to include additional metadata in the response')
});

async function handleGetData(args: Record<string, unknown>) {
	const methodLogger = logger.forMethod('handleGetData');
	
	try {
		methodLogger.debug('Tool example_get_data called', args);

		// Validate arguments with Zod
		const validatedArgs = GetDataSchema.parse(args);

		// Call controller
		const result = await exampleController.getData({
			param: validatedArgs.param,
			includeMetadata: validatedArgs.includeMetadata
		});

		// Return MCP-formatted response
		return {
			content: [
				{
					type: 'text' as const,
					text: result.content
				}
			]
		};
	} catch (error) {
		methodLogger.error('Tool example_get_data failed', error);
		return formatErrorForMcpTool(error);
	}
}

// Registration function using the modern registerTool API (SDK v1.23.0)
function registerTools(server: McpServer) {
	const registerLogger = logger.forMethod('registerTools');
	registerLogger.debug('Registering example tools...');

	// SDK best practices: 'title' for UI display name, 'description' for detailed info
	server.registerTool(
		'example_get_data',
		{
			title: 'Get Example Data',  // Display name for UI (e.g., 'Get Example Data')
			description: `Gets data from the Example API with optional parameter.
Use this tool to fetch example data. Returns formatted data as Markdown.`,
			inputSchema: GetDataSchema,
		},
		handleGetData
	);

	registerLogger.debug('Example tools registered successfully');
}

export default { registerTools };
4. 添加 CLI 支持

在 src/cli/ 中创建 CLI 命令,并遵循 Commander 模式:

// src/cli/example.cli.ts
import { Command } from 'commander';
import { Logger } from '../utils/logger.util.js';
import exampleController from '../controllers/example.controller.js';
import { handleCliError } from '../utils/error.util.js';

const logger = Logger.forContext('cli/example.cli.ts');

function register(program: Command) {
	const methodLogger = logger.forMethod('register');
	methodLogger.debug('Registering example CLI commands...');

	program
		.command('get-data')
		.description('Gets data from the Example API')
		.argument('[param]', 'Optional parameter for the API call')
		.option('-m, --include-metadata', 'Include additional metadata in response')
		.action(async (param, options) => {
			const actionLogger = logger.forMethod('action:get-data');
			
			try {
				actionLogger.debug('CLI get-data called', { param, options });

				const result = await exampleController.getData({
					param,
					includeMetadata: options.includeMetadata || false
				});

				console.log(result.content);
			} catch (error) {
				handleCliError(error);
			}
		});

	methodLogger.debug('Example CLI commands registered successfully');
}

export default { register };
5. 注册组件

更新入口点,以注册新组件:

// 1. Register CLI in src/cli/index.ts
import exampleCli from './example.cli.js';

export async function runCli(args: string[]) {
	// ... existing setup code ...
	
	// Register CLI commands
	exampleCli.register(program);  // Add this line
	
	// ... rest of function
}

// 2. Register Tools in src/index.ts
import exampleTools from './tools/example.tool.js';

// In the startServer function, after existing registrations:
exampleTools.registerTools(serverInstance);
6. 添加 MCP 资源(可选)

在 src/resources/ 中使用新版 registerResource API 创建资源:

// src/resources/example.resource.ts
import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
import { Logger } from '../utils/logger.util.js';
import exampleController from '../controllers/example.controller.js';
import { formatErrorForMcpResource } from '../utils/error.util.js';

const logger = Logger.forContext('resources/example.resource.ts');

function registerResources(server: McpServer) {
	const registerLogger = logger.forMethod('registerResources');
	registerLogger.debug('Registering example resources...');

	// Use registerResource with ResourceTemplate for parameterized URIs (SDK v1.23.0)
	server.registerResource(
		'example-data',
		new ResourceTemplate('example://{param}', { list: undefined }),
		{
			title: 'Example Data',  // Display name for UI
			description: 'Retrieve example data by parameter'
		},
		async (uri, variables) => {
			const methodLogger = logger.forMethod('exampleResource');
			try {
				// Extract parameter from template variables
				const param = variables.param as string | undefined;

				methodLogger.debug('Example resource called', { uri: uri.href, param });

				const result = await exampleController.getData({ param });

				return {
					contents: [
						{
							uri: uri.href,
							text: result.content,
							mimeType: 'text/markdown'
						}
					]
				};
			} catch (error) {
				methodLogger.error('Resource error', error);
				return formatErrorForMcpResource(error, uri.href);
			}
		}
	);

	registerLogger.debug('Example resources registered successfully');
}

export default { registerResources };

IP 地址示例实现

该样板包含一个完整的 IP 地址地理定位示例,展示了所有层:

可用工具和命令

CLI 命令:

npm run cli -- get-ip-details                                            # Get current public IP (TOON format)
npm run cli -- get-ip-details 8.8.8.8                                    # Get details for specific IP
npm run cli -- get-ip-details 1.1.1.1 -e                                 # Short form with extended data
npm run cli -- get-ip-details 1.1.1.1 --include-extended-data           # Long form with extended data
npm run cli -- get-ip-details 8.8.8.8 --no-use-https                    # Force HTTP (for free tier)
npm run cli -- get-ip-details 8.8.8.8 -o json                            # JSON output (short form)
npm run cli -- get-ip-details 8.8.8.8 --output-format json              # JSON output (long form)
npm run cli -- get-ip-details 8.8.8.8 --jq "{ip: query, country: country}"  # JMESPath filtered output

MCP 工具:

  • ip_get_details - 为 AI 助手提供 IP 地理定位查询
  • ip_get_details_link - 同样的查询,并输出资源链接,供支持资源的客户端使用

这两个工具使用相同的参数:

  • ipAddress(可选):要查询的 IP 地址(省略时使用当前设备的公网 IP)
  • includeExtendedData(可选,默认值:false):包含 ASN、主机和组织数据(需要 API 令牌)
  • useHttps(可选,默认值:true):API 调用时使用 HTTPS
  • jq(可选):用于筛选或转换响应的 JMESPath 表达式
  • outputFormat(可选,默认值:"toon"):输出格式——“toon”或“json”

输出行为:

  • ip_get_details:返回一个 text 内容块
  • ip_get_details_link:返回相同的第一个 text 块,以及一个 resource_link 块(ip://<resolved-ip>)

MCP 资源:

  • ip://{ipAddress} - IP 详情资源模板(例如,ip://8.8.8.8、ip://1.1.1.1)
    • 以 Markdown 格式返回 IP 地理定位数据
    • 默认使用 TOON 格式以节省令牌
展示的功能
  • TOON 输出:节省令牌的格式(比 JSON 少用 30%–60% 的令牌)
  • JMESPath 筛选:仅提取所需字段以降低成本
  • 回退逻辑:免费套餐用户在 HTTPS 失败时回退至 HTTP
  • 环境检测:测试环境和生产环境中的行为不同
  • API 令牌支持:可选令牌,用于获取扩展数据(ASN、移动网络检测等)
  • 错误处理:针对私有或保留 IP 地址返回结构化错误
配置选项
# Optional - for extended data features
IPAPI_API_TOKEN=your_token_from_ip-api.com

# Development
DEBUG=true                    # Enable detailed logging
TRANSPORT_MODE=http          # Use HTTP transport
PORT=3001                    # Custom port

发布你的 MCP 服务

  1. 自定义包详情:

    {
      "name": "your-mcp-server-name",
      "version": "1.0.0", 
      "description": "Your custom MCP server",
      "author": "Your Name",
      "keywords": ["mcp", "your-domain", "ai-integration"]
    }
    
  2. 更新文档: 将 IP 地址示例替换为适合你使用场景的示例

  3. 全面测试:

    npm run build && npm test
    npm run cli -- your-command
    npm run mcp:stdio    # Test with MCP Inspector
    
  4. 发布: 将符合 Conventional Commits 规范的提交推送到 main,然后通过 GitHub Actions(OIDC 可信发布)自动发布 semantic-release。

测试策略

此样板包含全面的测试基础设施:

测试结构
tests/               # Not present - tests are in src/
src/
├── **/*.test.ts     # Co-located with source files
├── utils/           # Utility function tests
├── controllers/     # Business logic tests  
├── services/        # API integration tests
└── cli/             # CLI command tests
测试最佳实践
  • 单元测试:测试实用工具和纯函数(*.util.test.ts)
  • 控制器测试:使用模拟的服务调用测试业务逻辑
  • 服务测试:使用真实或模拟的 HTTP 调用测试 API 集成
  • CLI 测试:测试命令解析和执行
  • 测试环境检测:在控制器中自动处理测试模式
运行测试
npm test                    # Run all tests
npm run test:coverage       # Generate coverage report  
npm run test:cli           # CLI-specific tests only
覆盖率目标
  • 目标:测试覆盖率 >80%
  • 重点关注业务逻辑(控制器)和实用工具
  • 适当地模拟外部服务

许可证

ISC 许可证

MCP SDK v2 准备情况

⚠️ 注意:MCP SDK v2 正在开发中(预计于 2026 年第 1 季度稳定)。此样板已做好迁移准备,只需进行少量更改。

v2 主要变更:

  • 拆分软件包:@modelcontextprotocol/server 和 @modelcontextprotocol/client
  • 提供用于 Express、Hono 和 Node.js HTTP 的可选中间件包
  • 核心 API 模式保持不变(此样板已采用现代 API)

详细的迁移指南和时间线请参阅 MODERNIZATION.md。

资源和文档

MCP 协议资源
实现参考
你的 MCP 服务生态

评论

支持 Markdown

第一次接触 MCP?

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

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