跳过主要内容
构建并与世界分享您的 MCP 服务器。 一旦您创建了一个出色的 MCP 服务器,请将其提交到 Cline MCP Marketplace,以便数千名开发人员可以发现并一键安装它。

什么是 MCP 服务器?

模型上下文协议 (MCP) 服务器通过赋予 AI 助手(如 Cline)以下能力来扩展它们:
  • 访问外部 API 和服务
  • 检索实时数据
  • 控制应用程序和本地系统
  • 执行仅靠文本提示无法完成的操作
没有 MCP,AI 助手功能强大但处于孤立状态。有了 MCP,它们获得了与几乎所有数字系统交互的能力。

开发协议

有效 MCP 服务器开发的核心是遵循结构化协议。此协议通过一个位于 MCP 工作目录根目录 (/Users/your-name/Documents/Cline/MCP) 的 .clinerules 文件实现。

使用 .clinerules 文件

.clinerules 文件是 Cline 在其所在目录中工作时自动读取的特殊配置。这些文件用于:
  • 配置 Cline 的行为并强制执行最佳实践
  • 将 Cline 切换到专用的 MCP 开发模式
  • 提供构建服务器的逐步协议
  • 实施安全措施,例如防止过早完成
  • 指导您完成规划、实施和测试阶段
以下是应放置在 .clinerules 文件中的完整 MCP 服务器开发协议:
# MCP Server Development Protocol

CRITICAL: DO NOT USE attempt_completion BEFORE TESTING

## Step 1: Planning (PLAN MODE)

-   What problem does this tool solve?
-   What API/service will it use?
-   What are the authentication requirements?
    □ Standard API key
    □ OAuth (requires separate setup script)
    □ Other credentials

## Step 2: Implementation (ACT MODE)

1. Bootstrap

    - For web services, JavaScript integration, or Node.js environments:
        ```bash
        npx @modelcontextprotocol/create-server my-server
        cd my-server
        npm install
        ```
    - For data science, ML workflows, or Python environments:
        ```bash
        pip install mcp
        # Or with uv (recommended)
        uv add "mcp[cli]"
        ```

2. Core Implementation

    - Use MCP SDK
    - Implement comprehensive logging
        - TypeScript (for web/JS projects):
            ```typescript
            console.error("[Setup] Initializing server...")
            console.error("[API] Request to endpoint:", endpoint)
            console.error("[Error] Failed with:", error)
            ```
        - Python (for data science/ML projects):
            ```python
            import logging
            logging.error('[Setup] Initializing server...')
            logging.error(f'[API] Request to endpoint: {endpoint}')
            logging.error(f'[Error] Failed with: {str(error)}')
            ```
    - Add type definitions
    - Handle errors with context
    - Implement rate limiting if needed

3. Configuration

    - Get credentials from user if needed
    - Add to MCP settings:

        - For TypeScript projects:
            ```json
            {
            	"mcpServers": {
            		"my-server": {
            			"command": "node",
            			"args": ["path/to/build/index.js"],
            			"env": {
            				"API_KEY": "key"
            			},
            			"disabled": false,
            			"autoApprove": []
            		}
            	}
            }
            ```
        - For Python projects:

            ```bash
            # Directly with command line
            mcp install server.py -v API_KEY=key

            # Or in settings.json
            {
              "mcpServers": {
                "my-server": {
                  "command": "python",
                  "args": ["server.py"],
                  "env": {
                    "API_KEY": "key"
                  },
                  "disabled": false,
                  "autoApprove": []
                }
              }
            }
            ```

## Step 3: Testing (BLOCKER ⛔️)

<thinking>
BEFORE using attempt_completion, I MUST verify:
□ Have I tested EVERY tool?
□ Have I confirmed success from the user for each test?
□ Have I documented the test results?

If ANY answer is "no", I MUST NOT use attempt_completion.
</thinking>

1. Test Each Tool (REQUIRED)
   □ Test each tool with valid inputs
   □ Verify output format is correct
   DO NOT PROCEED UNTIL ALL TOOLS TESTED

## Step 4: Completion

❗ STOP AND VERIFY:
□ Every tool has been tested with valid inputs
□ Output format is correct for each tool

Only after ALL tools have been tested can attempt_completion be used.

## Key Requirements

-   ✓ Must use MCP SDK
-   ✓ Must have comprehensive logging
-   ✓ Must test each tool individually
-   ✓ Must handle errors gracefully
-   NEVER skip testing before completion
当此 .clinerules 文件存在于您的工作目录中时,Cline 将会:
  1. 计划模式 (PLAN MODE) 开始,在实施前设计您的服务器
  2. 行动模式 (ACT MODE) 中强制执行正确的实施模式
  3. 要求在允许完成之前对所有工具进行测试
  4. 指导您完成整个开发生命周期

入门

创建 MCP 服务器只需几个简单的步骤即可开始

1. 创建一个 .clinerules 文件(重要)

首先,使用上述协议在 MCP 工作目录的根目录中添加一个 .clinerules 文件。此文件配置 Cline 在此文件夹中工作时使用 MCP 开发协议。

2. 开始一个清晰描述的聊天

通过清晰描述您要构建的内容来开始您的 Cline 聊天。具体说明:
  • 您的 MCP 服务器的目的
  • 您要集成的 API 或服务
  • 您需要的任何特定工具或功能
例如:
I want to build an MCP server for the AlphaAdvantage financial API.
It should allow me to get real-time stock data, perform technical
analysis, and retrieve company financial information.

3. 遵循协议工作

Cline 将自动进入计划模式 (PLAN MODE),指导您完成规划过程:
  • 讨论问题范围
  • 审查 API 文档
  • 规划认证方法
  • 设计工具接口
准备就绪后,使用聊天底部的切换按钮切换到行动模式 (ACT MODE) 以开始实施。

4. 尽早提供 API 文档

帮助 Cline 构建 MCP 服务器最有效的方法之一是在开始时就分享官方 API 文档
Here's the API documentation for the service:
[Paste API documentation here]
提供全面的 API 详细信息(端点、认证、数据结构)将显著提高 Cline 实施有效 MCP 服务器的能力。

理解两种模式

计划模式 (PLAN MODE)

在这个协作阶段,您与 Cline 合作设计您的 MCP 服务器:
  • 定义问题范围
  • 选择适当的 API
  • 规划认证方法
  • 设计工具接口
  • 确定数据格式

行动模式 (ACT MODE)

规划完成后,Cline 帮助实施服务器:
  • 设置项目结构
  • 编写实现代码
  • 配置设置
  • 彻底测试每个组件
  • 最终确定文档

案例研究:AlphaAdvantage 股票分析服务器

让我们逐步了解 AlphaAdvantage MCP 服务器的开发过程,该服务器提供股票数据分析和报告功能。

规划阶段

Planning phase demonstration
在规划阶段,我们:
  1. 定义问题:用户需要通过他们的 AI 助手直接访问金融数据、股票分析和市场洞察
  2. 选择 API:用于金融市场数据的 AlphaAdvantage API
    • 标准 API 密钥认证
    • 速率限制为每分钟 5 个请求(免费套餐)
    • 针对不同金融数据类型的各种端点
  3. 设计所需的工具:
    • 股票概览信息(当前价格、公司详细信息)
    • 带有指标的技术分析(RSI、MACD 等)
    • 基本面分析(财务报表、比率)
    • 财报数据
    • 新闻和情绪分析
  4. 规划数据格式化:
    • 清晰、格式良好的 markdown 输出
    • 结构化数据的表格
    • 趋势的可视化指标 (↑/↓)
    • 财务数字的正确格式化

实施

Building MCP plugin demonstration
我们从引导项目开始:
npx @modelcontextprotocol/create-server alphaadvantage-mcp
cd alphaadvantage-mcp
npm install axios node-cache
接下来,我们使用以下内容构建了项目结构:
src/
  ├── api/
  │   └── alphaAdvantageClient.ts  # API client with rate limiting & caching
  ├── formatters/
  │   └── markdownFormatter.ts     # Output formatters for clean markdown
  └── index.ts                     # Main MCP server implementation

API 客户端实现

API 客户端实现包括:
  • 速率限制:强制执行每分钟 5 个请求的限制
  • 缓存:通过策略性缓存减少 API 调用
  • 错误处理:稳健的错误检测和报告
  • 类型化接口:所有数据的清晰 TypeScript 类型
关键实现细节:
/**
 * Manage rate limiting based on free tier (5 calls per minute)
 */
private async enforceRateLimit() {
  if (this.requestsThisMinute >= 5) {
    console.error("[Rate Limit] Rate limit reached. Waiting for next minute...");
    return new Promise<void>((resolve) => {
      const remainingMs = 60 * 1000 - (Date.now() % (60 * 1000));
      setTimeout(resolve, remainingMs + 100); // Add 100ms buffer
    });
  }

  this.requestsThisMinute++;
  return Promise.resolve();
}

Markdown 格式化

我们实现了格式化程序以精美地显示财务数据:
/**
 * Format company overview into markdown
 */
export function formatStockOverview(overviewData: any, quoteData: any): string {
	// Extract data
	const overview = overviewData
	const quote = quoteData["Global Quote"]

	// Calculate price change
	const currentPrice = parseFloat(quote["05. price"] || "0")
	const priceChange = parseFloat(quote["09. change"] || "0")
	const changePercent = parseFloat(quote["10. change percent"]?.replace("%", "") || "0")

	// Format markdown
	let markdown = `# ${overview.Symbol} (${overview.Name}) - ${formatCurrency(currentPrice)} ${addTrendIndicator(priceChange)}${changePercent > 0 ? "+" : ""}${changePercent.toFixed(2)}%\n\n`

	// Add more details...

	return markdown
}

工具实现

我们定义了五个具有清晰接口的工具:
server.setRequestHandler(ListToolsRequestSchema, async () => {
	console.error("[Setup] Listing available tools")

	return {
		tools: [
			{
				name: "get_stock_overview",
				description: "Get basic company info and current quote for a stock symbol",
				inputSchema: {
					type: "object",
					properties: {
						symbol: {
							type: "string",
							description: "Stock symbol (e.g., 'AAPL')",
						},
						market: {
							type: "string",
							description: "Optional market (e.g., 'US')",
							default: "US",
						},
					},
					required: ["symbol"],
				},
			},
			// Additional tools defined here...
		],
	}
})
每个工具的处理程序都包含:
  • 输入验证
  • 带错误处理的 API 客户端调用
  • 响应的 Markdown 格式化
  • 全面的日志记录

测试阶段

这个关键阶段涉及系统地测试每个工具:
  1. 首先,我们在设置中配置了 MCP 服务器:
{
	"mcpServers": {
		"alphaadvantage-mcp": {
			"command": "node",
			"args": ["/path/to/alphaadvantage-mcp/build/index.js"],
			"env": {
				"ALPHAVANTAGE_API_KEY": "YOUR_API_KEY"
			},
			"disabled": false,
			"autoApprove": []
		}
	}
}
  1. 然后我们单独测试了每个工具:
  • get_stock_overview:检索 AAPL 股票概览信息
    # AAPL (Apple Inc) - $241.84 ↑+1.91%
    
    **Sector:** TECHNOLOGY
    **Industry:** ELECTRONIC COMPUTERS
    **Market Cap:** 3.63T
    **P/E Ratio:** 38.26
    ...
    
  • get_technical_analysis:获取价格走势和 RSI 数据
    # Technical Analysis: AAPL
    
    ## Daily Price Action
    
    Current Price: $241.84 (↑$4.54, +1.91%)
    
    ### Recent Daily Prices
    
    | Date       | Open    | High    | Low     | Close   | Volume |
    | ---------- | ------- | ------- | ------- | ------- | ------ |
    | 2025-02-28 | $236.95 | $242.09 | $230.20 | $241.84 | 56.83M |
    
    ...
    
  • get_earnings_report:检索 MSFT 盈利历史并格式化报告
    # Earnings Report: MSFT (Microsoft Corporation)
    
    **Sector:** TECHNOLOGY
    **Industry:** SERVICES-PREPACKAGED SOFTWARE
    **Current EPS:** $12.43
    
    ## Recent Quarterly Earnings
    
    | Quarter    | Date       | EPS Estimate | EPS Actual | Surprise % |
    | ---------- | ---------- | ------------ | ---------- | ---------- |
    | 2024-12-31 | 2025-01-29 | $3.11        | $3.23      | ↑4.01%     |
    
    ...
    

挑战与解决方案

在开发过程中,我们遇到了几个挑战:
  1. API 速率限制:
    • 挑战:免费套餐限制为每分钟 5 次调用
    • 解决方案:实施队列,强制执行速率限制,并添加全面缓存
  2. 数据格式化:
    • 挑战:原始 API 数据对用户不友好
    • 解决方案:创建格式化实用程序以一致地显示财务数据
  3. 超时问题:
    • 挑战:进行多次 API 调用的复杂工具可能会超时
    • 解决方案:建议将复杂工具拆分为更小的部分,优化缓存

经验教训

我们的 AlphaAdvantage 实现教会了我们几个关键经验教训:
  1. 规划 API 限制:从一开始就了解并围绕 API 速率限制进行设计
  2. 策略性缓存:识别高价值缓存机会以提高性能
  3. 为可读性格式化:投入精力进行良好的数据格式化以改善用户体验
  4. 测试每条路径:在完成前单独测试所有工具
  5. 处理 API 复杂性:对于需要多次调用的 API,设计范围更简单的工具

核心实现最佳实践

全面的日志记录

有效的日志记录对于调试 MCP 服务器至关重要
// Start-up logging
console.error("[Setup] Initializing AlphaAdvantage MCP server...")

// API request logging
console.error(`[API] Getting stock overview for ${symbol}`)

// Error handling with context
console.error(`[Error] Tool execution failed: ${error.message}`)

// Cache operations
console.error(`[Cache] Using cached data for: ${cacheKey}`)

强类型

类型定义可防止错误并提高可维护性
export interface AlphaAdvantageConfig {
	apiKey: string
	cacheTTL?: Partial<typeof DEFAULT_CACHE_TTL>
	baseURL?: string
}

/**
 * Validate that a stock symbol is provided and looks valid
 */
function validateSymbol(symbol: unknown): asserts symbol is string {
	if (typeof symbol !== "string" || symbol.trim() === "") {
		throw new McpError(ErrorCode.InvalidParams, "A valid stock symbol is required")
	}

	// Basic symbol validation (letters, numbers, dots)
	const symbolRegex = /^[A-Za-z0-9.]+$/
	if (!symbolRegex.test(symbol)) {
		throw new McpError(ErrorCode.InvalidParams, `Invalid stock symbol: ${symbol}`)
	}
}

智能缓存

减少 API 调用并提高性能
// Default cache TTL in seconds
const DEFAULT_CACHE_TTL = {
	STOCK_OVERVIEW: 60 * 60, // 1 hour
	TECHNICAL_ANALYSIS: 60 * 30, // 30 minutes
	FUNDAMENTAL_ANALYSIS: 60 * 60 * 24, // 24 hours
	EARNINGS_REPORT: 60 * 60 * 24, // 24 hours
	NEWS: 60 * 15, // 15 minutes
}

// Check cache first
const cachedData = this.cache.get<T>(cacheKey)
if (cachedData) {
	console.error(`[Cache] Using cached data for: ${cacheKey}`)
	return cachedData
}

// Cache successful responses
this.cache.set(cacheKey, response.data, cacheTTL)

优雅的错误处理

实施健壮的错误处理,以保持良好的用户体验
try {
	switch (request.params.name) {
		case "get_stock_overview": {
			// Implementation...
		}

		// Other cases...

		default:
			throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`)
	}
} catch (error) {
	console.error(`[Error] Tool execution failed: ${error instanceof Error ? error.message : String(error)}`)

	if (error instanceof McpError) {
		throw error
	}

	return {
		content: [
			{
				type: "text",
				text: `Error: ${error instanceof Error ? error.message : String(error)}`,
			},
		],
		isError: true,
	}
}

MCP 资源

资源允许您的 MCP 服务器向 Cline 暴露数据,而无需执行代码。它们非常适合提供上下文,例如 Cline 可以在对话中引用的文件、API 响应或数据库记录。

将资源添加到 MCP 服务器

  1. 定义资源您的服务器将暴露的内容
server.setRequestHandler(ListResourcesRequestSchema, async () => {
	return {
		resources: [
			{
				uri: "file:///project/readme.md",
				name: "Project README",
				mimeType: "text/markdown",
			},
		],
	}
})
  1. 实施读取处理程序以提供内容
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
	if (request.params.uri === "file:///project/readme.md") {
		const content = await fs.promises.readFile("/path/to/readme.md", "utf-8")
		return {
			contents: [
				{
					uri: request.params.uri,
					mimeType: "text/markdown",
					text: content,
				},
			],
		}
	}

	throw new Error("Resource not found")
})
资源使您的 MCP 服务器更具上下文感知能力,允许 Cline 访问特定信息而无需您复制/粘贴。有关更多信息,请参阅 官方文档

常见挑战与解决方案

API 认证复杂性

挑战:API 通常有不同的认证方法。 解决方案
  • 对于 API 密钥,在 MCP 配置中使用环境变量
  • 对于 OAuth,创建单独的脚本来获取刷新令牌
  • 安全地存储敏感令牌
// Authenticate using API key from environment
const API_KEY = process.env.ALPHAVANTAGE_API_KEY
if (!API_KEY) {
	console.error("[Error] Missing ALPHAVANTAGE_API_KEY environment variable")
	process.exit(1)
}

// Initialize API client
const apiClient = new AlphaAdvantageClient({
	apiKey: API_KEY,
})

API 功能缺失或受限

挑战:API 可能无法提供您需要的所有功能。 解决方案
  • 使用可用的端点实现回退
  • 在必要时创建模拟功能
  • 转换 API 数据以匹配您的需求

API 速率限制

挑战:大多数 API 都有速率限制,可能导致失败。 解决方案
  • 实施适当的速率限制
  • 添加智能缓存
  • 提供优雅的降级
  • 提供关于速率限制的透明错误
if (this.requestsThisMinute >= 5) {
	console.error("[Rate Limit] Rate limit reached. Waiting for next minute...")
	return new Promise<void>((resolve) => {
		const remainingMs = 60 * 1000 - (Date.now() % (60 * 1000))
		setTimeout(resolve, remainingMs + 100) // Add 100ms buffer
	})
}

额外资源