歡迎踏出 Model Context Protocol (MCP) 的第一步!無論您是 MCP 的新手,還是希望加深理解,本指南將引導您完成基本的設置和開發過程。您將了解 MCP 如何實現 AI 模型與應用程式之間的無縫整合,並學習如何快速準備環境以構建和測試基於 MCP 的解決方案。
簡而言之:如果您開發 AI 應用程式,您可能知道可以為大型語言模型 (LLM) 添加工具和其他資源,以使其更具知識性。然而,如果您將這些工具和資源放置在伺服器上,任何有或沒有 LLM 的客戶端都可以使用該應用程式和伺服器的功能。
本課程提供有關設置 MCP 環境和構建第一個 MCP 應用程式的實用指導。您將學習如何設置必要的工具和框架,構建基本的 MCP 伺服器,創建主機應用程式,並測試您的實現。
Model Context Protocol (MCP) 是一種開放協議,標準化了應用程式如何向 LLM 提供上下文。可以將 MCP 想像成 AI 應用程式的 USB-C 接口——它提供了一種標準化的方式來連接 AI 模型與不同的數據來源和工具。
完成本課程後,您將能夠:
- 為 C#、Java、Python、TypeScript 和 Rust 設置 MCP 的開發環境
- 構建和部署具有自定義功能(資源、提示和工具)的基本 MCP 伺服器
- 創建連接到 MCP 伺服器的主機應用程式
- 測試和調試 MCP 的實現
在開始使用 MCP 之前,準備開發環境並了解基本工作流程非常重要。本節將引導您完成初始設置步驟,以確保順利開始使用 MCP。
在進入 MCP 開發之前,請確保您已具備以下條件:
- 開發環境:適用於您選擇的語言(C#、Java、Python、TypeScript 或 Rust)
- IDE/編輯器:Visual Studio、Visual Studio Code、IntelliJ、Eclipse、PyCharm 或任何現代代碼編輯器
- 套件管理器:NuGet、Maven/Gradle、pip、npm/yarn 或 Cargo
- API 金鑰:用於您計劃在主機應用程式中使用的任何 AI 服務
一個 MCP 伺服器通常包括:
- 伺服器配置:設置端口、身份驗證和其他設置
- 資源:提供給 LLM 的數據和上下文
- 工具:模型可以調用的功能
- 提示:用於生成或結構化文本的模板
以下是 TypeScript 的簡化範例:
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// Create an MCP server
const server = new McpServer({
name: "Demo",
version: "1.0.0"
});
// Add an addition tool
server.tool("add",
{ a: z.number(), b: z.number() },
async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }]
})
);
// Add a dynamic greeting resource
server.resource(
"file",
// The 'list' parameter controls how the resource lists available files. Setting it to undefined disables listing for this resource.
new ResourceTemplate("file://{path}", { list: undefined }),
async (uri, { path }) => ({
contents: [{
uri: uri.href,
text: `File, ${path}!`
}]
// Add a file resource that reads the file contents
server.resource(
"file",
new ResourceTemplate("file://{path}", { list: undefined }),
async (uri, { path }) => {
let text;
try {
text = await fs.readFile(path, "utf8");
} catch (err) {
text = `Error reading file: ${err.message}`;
}
return {
contents: [{
uri: uri.href,
text
}]
};
}
);
server.prompt(
"review-code",
{ code: z.string() },
({ code }) => ({
messages: [{
role: "user",
content: {
type: "text",
text: `Please review this code:\n\n${code}`
}
}]
})
);
// Start receiving messages on stdin and sending messages on stdout
const transport = new StdioServerTransport();
await server.connect(transport);在上述代碼中,我們:
- 從 MCP TypeScript SDK 中導入必要的類。
- 創建並配置一個新的 MCP 伺服器實例。
- 註冊一個帶有處理函數的自定義工具(
calculator)。 - 啟動伺服器以監聽傳入的 MCP 請求。
在開始測試 MCP 伺服器之前,了解可用的工具和調試的最佳實踐非常重要。有效的測試可以確保您的伺服器按預期運行,並幫助您快速識別和解決問題。以下部分概述了驗證 MCP 實現的推薦方法。
MCP 提供了一些工具來幫助您測試和調試伺服器:
- Inspector 工具:這是一個圖形界面,允許您連接到伺服器並測試工具、提示和資源。
- curl:您也可以使用命令行工具如 curl 或其他能創建和運行 HTTP 命令的客戶端連接到伺服器。
MCP Inspector 是一個視覺化測試工具,幫助您:
- 發現伺服器功能:自動檢測可用的資源、工具和提示
- 測試工具執行:嘗試不同的參數並即時查看響應
- 查看伺服器元數據:檢查伺服器信息、架構和配置
# ex TypeScript, installing and running MCP Inspector
npx @modelcontextprotocol/inspector node build/index.js運行上述命令後,MCP Inspector 將在您的瀏覽器中啟動一個本地網頁界面。您可以看到一個儀表板,顯示已註冊的 MCP 伺服器及其可用的工具、資源和提示。該界面允許您交互式測試工具執行、檢查伺服器元數據並查看即時響應,從而更輕鬆地驗證和調試 MCP 伺服器的實現。
以下是界面可能的樣子:
| 問題 | 可能的解決方案 |
|---|---|
| 連接被拒絕 | 檢查伺服器是否正在運行以及端口是否正確 |
| 工具執行錯誤 | 檢查參數驗證和錯誤處理 |
| 身份驗證失敗 | 驗證 API 金鑰和權限 |
| 架構驗證錯誤 | 確保參數與定義的架構匹配 |
| 伺服器無法啟動 | 檢查端口衝突或缺少的依賴項 |
| CORS 錯誤 | 為跨域請求配置正確的 CORS 標頭 |
| 身份驗證問題 | 驗證令牌的有效性和權限 |
在本地開發和測試中,您可以直接在機器上運行 MCP 伺服器:
- 啟動伺服器進程:運行您的 MCP 伺服器應用程式
- 配置網絡:確保伺服器可通過預期的端口訪問
- 連接客戶端:使用本地連接 URL,例如
http://localhost:3000
# Example: Running a TypeScript MCP server locally
npm run start
# Server running at http://localhost:3000我們在之前的課程中已經介紹了核心概念,現在是時候將這些知識付諸實踐了。
在開始編寫代碼之前,讓我們回顧一下伺服器可以做什麼:
一個 MCP 伺服器可以:
- 訪問本地文件和數據庫
- 連接到遠程 API
- 執行計算
- 與其他工具和服務集成
- 提供用戶交互界面
很好,現在我們知道它的功能了,讓我們開始編碼吧。
要創建伺服器,您需要按照以下步驟進行:
- 安裝 MCP SDK。
- 創建一個項目並設置項目結構。
- 編寫伺服器代碼。
- 測試伺服器。
# Create project directory and initialize npm project
mkdir calculator-server
cd calculator-server
npm init -y# Create project dir
mkdir calculator-server
cd calculator-server
# Open the folder in Visual Studio Code - Skip this if you are using a different IDE
code .dotnet new console -n McpCalculatorServer
cd McpCalculatorServer對於 Java,創建一個 Spring Boot 項目:
curl https://start.spring.io/starter.zip \
-d dependencies=web \
-d javaVersion=21 \
-d type=maven-project \
-d groupId=com.example \
-d artifactId=calculator-server \
-d name=McpServer \
-d packageName=com.microsoft.mcp.sample.server \
-o calculator-server.zip解壓 zip 文件:
unzip calculator-server.zip -d calculator-server
cd calculator-server
# optional remove the unused test
rm -rf src/test/java將以下完整配置添加到您的 pom.xml 文件中:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- Spring Boot parent for dependency management -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.0</version>
<relativePath />
</parent>
<!-- Project coordinates -->
<groupId>com.example</groupId>
<artifactId>calculator-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Calculator Server</name>
<description>Basic calculator MCP service for beginners</description>
<!-- Properties -->
<properties>
<java.version>21</java.version>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<!-- Spring AI BOM for version management -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- Dependencies -->
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!-- Build configuration -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>21</release>
</configuration>
</plugin>
</plugins>
</build>
<!-- Repositories for Spring AI snapshots -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
</project>mkdir calculator-server
cd calculator-server
cargo init現在您已創建項目,接下來讓我們添加依賴項:
# If not already installed, install TypeScript globally
npm install typescript -g
# Install the MCP SDK and Zod for schema validation
npm install @modelcontextprotocol/sdk zod
npm install -D @types/node typescript# Create a virtual env and install dependencies
python -m venv venv
venv\Scripts\activate
pip install "mcp[cli]"cd calculator-server
./mvnw clean install -DskipTestscargo add rmcp --features server,transport-io
cargo add serde
cargo add tokio --features rt-multi-thread打開 package.json 文件,並將內容替換為以下內容以確保您可以構建和運行伺服器:
{
"name": "calculator-server",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"scripts": {
"start": "tsc && node ./build/index.js",
"build": "tsc && node ./build/index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "A simple calculator server using Model Context Protocol",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.16.0",
"zod": "^3.25.76"
},
"devDependencies": {
"@types/node": "^24.0.14",
"typescript": "^5.8.3"
}
}創建一個 tsconfig.json 文件,內容如下:
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}創建一個源代碼目錄:
mkdir src
touch src/index.ts創建一個文件 server.py
touch server.py安裝所需的 NuGet 套件:
dotnet add package ModelContextProtocol --prerelease
dotnet add package Microsoft.Extensions.Hosting對於 Java Spring Boot 項目,項目結構會自動創建。
對於 Rust,當您運行 cargo init 時,會默認創建一個 src/main.rs 文件。打開該文件並刪除默認代碼。
創建一個文件 index.ts 並添加以下代碼:
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// Create an MCP server
const server = new McpServer({
name: "Calculator MCP Server",
version: "1.0.0"
});現在您有了一個伺服器,但它功能有限,讓我們來改進它。
# server.py
from mcp.server.fastmcp import FastMCP
# Create an MCP server
mcp = FastMCP("Demo")using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ModelContextProtocol.Server;
using System.ComponentModel;
var builder = Host.CreateApplicationBuilder(args);
builder.Logging.AddConsole(consoleLogOptions =>
{
// Configure all logs to go to stderr
consoleLogOptions.LogToStandardErrorThreshold = LogLevel.Trace;
});
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithToolsFromAssembly();
await builder.Build().RunAsync();
// add features對於 Java,創建核心伺服器組件。首先,修改主應用程式類:
src/main/java/com/microsoft/mcp/sample/server/McpServerApplication.java:
package com.microsoft.mcp.sample.server;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import com.microsoft.mcp.sample.server.service.CalculatorService;
@SpringBootApplication
public class McpServerApplication {
public static void main(String[] args) {
SpringApplication.run(McpServerApplication.class, args);
}
@Bean
public ToolCallbackProvider calculatorTools(CalculatorService calculator) {
return MethodToolCallbackProvider.builder().toolObjects(calculator).build();
}
}創建計算器服務 src/main/java/com/microsoft/mcp/sample/server/service/CalculatorService.java:
package com.microsoft.mcp.sample.server.service;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.stereotype.Service;
/**
* Service for basic calculator operations.
* This service provides simple calculator functionality through MCP.
*/
@Service
public class CalculatorService {
/**
* Add two numbers
* @param a The first number
* @param b The second number
* @return The sum of the two numbers
*/
@Tool(description = "Add two numbers together")
public String add(double a, double b) {
double result = a + b;
return formatResult(a, "+", b, result);
}
/**
* Subtract one number from another
* @param a The number to subtract from
* @param b The number to subtract
* @return The result of the subtraction
*/
@Tool(description = "Subtract the second number from the first number")
public String subtract(double a, double b) {
double result = a - b;
return formatResult(a, "-", b, result);
}
/**
* Multiply two numbers
* @param a The first number
* @param b The second number
* @return The product of the two numbers
*/
@Tool(description = "Multiply two numbers together")
public String multiply(double a, double b) {
double result = a * b;
return formatResult(a, "*", b, result);
}
/**
* Divide one number by another
* @param a The numerator
* @param b The denominator
* @return The result of the division
*/
@Tool(description = "Divide the first number by the second number")
public String divide(double a, double b) {
if (b == 0) {
return "Error: Cannot divide by zero";
}
double result = a / b;
return formatResult(a, "/", b, result);
}
/**
* Calculate the power of a number
* @param base The base number
* @param exponent The exponent
* @return The result of raising the base to the exponent
*/
@Tool(description = "Calculate the power of a number (base raised to an exponent)")
public String power(double base, double exponent) {
double result = Math.pow(base, exponent);
return formatResult(base, "^", exponent, result);
}
/**
* Calculate the square root of a number
* @param number The number to find the square root of
* @return The square root of the number
*/
@Tool(description = "Calculate the square root of a number")
public String squareRoot(double number) {
if (number < 0) {
return "Error: Cannot calculate square root of a negative number";
}
double result = Math.sqrt(number);
return String.format("√%.2f = %.2f", number, result);
}
/**
* Calculate the modulus (remainder) of division
* @param a The dividend
* @param b The divisor
* @return The remainder of the division
*/
@Tool(description = "Calculate the remainder when one number is divided by another")
public String modulus(double a, double b) {
if (b == 0) {
return "Error: Cannot divide by zero";
}
double result = a % b;
return formatResult(a, "%", b, result);
}
/**
* Calculate the absolute value of a number
* @param number The number to find the absolute value of
* @return The absolute value of the number
*/
@Tool(description = "Calculate the absolute value of a number")
public String absolute(double number) {
double result = Math.abs(number);
return String.format("|%.2f| = %.2f", number, result);
}
/**
* Get help about available calculator operations
* @return Information about available operations
*/
@Tool(description = "Get help about available calculator operations")
public String help() {
return "Basic Calculator MCP Service\n\n" +
"Available operations:\n" +
"1. add(a, b) - Adds two numbers\n" +
"2. subtract(a, b) - Subtracts the second number from the first\n" +
"3. multiply(a, b) - Multiplies two numbers\n" +
"4. divide(a, b) - Divides the first number by the second\n" +
"5. power(base, exponent) - Raises a number to a power\n" +
"6. squareRoot(number) - Calculates the square root\n" +
"7. modulus(a, b) - Calculates the remainder of division\n" +
"8. absolute(number) - Calculates the absolute value\n\n" +
"Example usage: add(5, 3) will return 5 + 3 = 8";
}
/**
* Format the result of a calculation
*/
private String formatResult(double a, String operator, double b, double result) {
return String.format("%.2f %s %.2f = %.2f", a, operator, b, result);
}
}生產環境服務的可選組件:
創建啟動配置 src/main/java/com/microsoft/mcp/sample/server/config/StartupConfig.java:
package com.microsoft.mcp.sample.server.config;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class StartupConfig {
@Bean
public CommandLineRunner startupInfo() {
return args -> {
System.out.println("\n" + "=".repeat(60));
System.out.println("Calculator MCP Server is starting...");
System.out.println("SSE endpoint: http://localhost:8080/sse");
System.out.println("Health check: http://localhost:8080/actuator/health");
System.out.println("=".repeat(60) + "\n");
};
}
}創建健康檢查控制器 src/main/java/com/microsoft/mcp/sample/server/controller/HealthController.java:
package com.microsoft.mcp.sample.server.controller;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
@RestController
public class HealthController {
@GetMapping("/health")
public ResponseEntity<Map<String, Object>> healthCheck() {
Map<String, Object> response = new HashMap<>();
response.put("status", "UP");
response.put("timestamp", LocalDateTime.now().toString());
response.put("service", "Calculator MCP Server");
return ResponseEntity.ok(response);
}
}創建異常處理器 src/main/java/com/microsoft/mcp/sample/server/exception/GlobalExceptionHandler.java:
package com.microsoft.mcp.sample.server.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<ErrorResponse> handleIllegalArgumentException(IllegalArgumentException ex) {
ErrorResponse error = new ErrorResponse(
"Invalid_Input",
"Invalid input parameter: " + ex.getMessage());
return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}
public static class ErrorResponse {
private String code;
private String message;
public ErrorResponse(String code, String message) {
this.code = code;
this.message = message;
}
// Getters
public String getCode() { return code; }
public String getMessage() { return message; }
}
}創建自定義橫幅 src/main/resources/banner.txt:
_____ _ _ _
/ ____| | | | | | |
| | __ _| | ___ _ _| | __ _| |_ ___ _ __
| | / _` | |/ __| | | | |/ _` | __/ _ \| '__|
| |___| (_| | | (__| |_| | | (_| | || (_) | |
\_____\__,_|_|\___|\__,_|_|\__,_|\__\___/|_|
Calculator MCP Server v1.0
Spring Boot MCP Application
在 src/main.rs 文件的頂部添加以下代碼。這將導入 MCP 伺服器所需的庫和模組。
use rmcp::{
handler::server::{router::tool::ToolRouter, tool::Parameters},
model::{ServerCapabilities, ServerInfo},
schemars, tool, tool_handler, tool_router,
transport::stdio,
ServerHandler, ServiceExt,
};
use std::error::Error;計算器伺服器將是一個簡單的伺服器,可以將兩個數字相加。讓我們創建一個結構來表示計算器請求。
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
pub struct CalculatorRequest {
pub a: f64,
pub b: f64,
}接下來,創建一個結構來表示計算器伺服器。此結構將保存工具路由器,用於註冊工具。
#[derive(Debug, Clone)]
pub struct Calculator {
tool_router: ToolRouter<Self>,
}現在,我們可以實現 Calculator 結構來創建伺服器的新實例,並實現伺服器處理程序以提供伺服器信息。
#[tool_router]
impl Calculator {
pub fn new() -> Self {
Self {
tool_router: Self::tool_router(),
}
}
}
#[tool_handler]
impl ServerHandler for Calculator {
fn get_info(&self) -> ServerInfo {
ServerInfo {
instructions: Some("A simple calculator tool".into()),
capabilities: ServerCapabilities::builder().enable_tools().build(),
..Default::default()
}
}
}最後,我們需要實現主函數來啟動伺服器。此函數將創建 Calculator 結構的實例並通過標準輸入/輸出提供服務。
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let service = Calculator::new().serve(stdio()).await?;
service.waiting().await?;
Ok(())
}伺服器現在已設置為提供有關自身的基本信息。接下來,我們將添加一個工具來執行加法。
通過添加以下代碼來添加工具和資源:
server.tool(
"add",
{ a: z.number(), b: z.number() },
async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }]
})
);
server.resource(
"greeting",
new ResourceTemplate("greeting://{name}", { list: undefined }),
async (uri, { name }) => ({
contents: [{
uri: uri.href,
text: `Hello, ${name}!`
}]
})
);您的工具接受參數 a 和 b,並運行一個函數,生成以下形式的響應:
{
contents: [{
type: "text", content: "some content"
}]
}您的資源通過字符串 "greeting" 訪問,接受參數 name,並生成類似於工具的響應:
{
uri: "<href>",
text: "a text"
}# Add an addition tool
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers"""
return a + b
# Add a dynamic greeting resource
@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
"""Get a personalized greeting"""
return f"Hello, {name}!"在上述代碼中,我們:
- 定義了一個工具
add,接受參數a和p,兩者均為整數。 - 創建了一個名為
greeting的資源,接受參數name。
將以下內容添加到您的 Program.cs 文件中:
[McpServerToolType]
public static class CalculatorTool
{
[McpServerTool, Description("Adds two numbers")]
public static string Add(int a, int b) => $"Sum {a + b}";
}工具已在前一步中創建。
在 impl Calculator 區塊內添加一個新工具:
#[tool(description = "Adds a and b")]
async fn add(
&self,
Parameters(CalculatorRequest { a, b }): Parameters<CalculatorRequest>,
) -> String {
(a + b).to_string()
}讓我們添加最後的代碼,使伺服器可以啟動:
// Start receiving messages on stdin and sending messages on stdout
const transport = new StdioServerTransport();
await server.connect(transport);完整代碼如下:
// index.ts
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// Create an MCP server
const server = new McpServer({
name: "Calculator MCP Server",
version: "1.0.0"
});
// Add an addition tool
server.tool(
"add",
{ a: z.number(), b: z.number() },
async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }]
})
);
// Add a dynamic greeting resource
server.resource(
"greeting",
new ResourceTemplate("greeting://{name}", { list: undefined }),
async (uri, { name }) => ({
contents: [{
uri: uri.href,
text: `Hello, ${name}!`
}]
})
);
// Start receiving messages on stdin and sending messages on stdout
const transport = new StdioServerTransport();
server.connect(transport);# server.py
from mcp.server.fastmcp import FastMCP
# Create an MCP server
mcp = FastMCP("Demo")
# Add an addition tool
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers"""
return a + b
# Add a dynamic greeting resource
@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
"""Get a personalized greeting"""
return f"Hello, {name}!"
# Main execution block - this is required to run the server
if __name__ == "__main__":
mcp.run()創建一個 Program.cs 文件,內容如下:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ModelContextProtocol.Server;
using System.ComponentModel;
var builder = Host.CreateApplicationBuilder(args);
builder.Logging.AddConsole(consoleLogOptions =>
{
// Configure all logs to go to stderr
consoleLogOptions.LogToStandardErrorThreshold = LogLevel.Trace;
});
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithToolsFromAssembly();
await builder.Build().RunAsync();
[McpServerToolType]
public static class CalculatorTool
{
[McpServerTool, Description("Adds two numbers")]
public static string Add(int a, int b) => $"Sum {a + b}";
}您的完整主應用程式類應如下所示:
// McpServerApplication.java
package com.microsoft.mcp.sample.server;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import com.microsoft.mcp.sample.server.service.CalculatorService;
@SpringBootApplication
public class McpServerApplication {
public static void main(String[] args) {
SpringApplication.run(McpServerApplication.class, args);
}
@Bean
public ToolCallbackProvider calculatorTools(CalculatorService calculator) {
return MethodToolCallbackProvider.builder().toolObjects(calculator).build();
}
}Rust 伺服器的最終代碼應如下所示:
use rmcp::{
ServerHandler, ServiceExt,
handler::server::{router::tool::ToolRouter, tool::Parameters},
model::{ServerCapabilities, ServerInfo},
schemars, tool, tool_handler, tool_router,
transport::stdio,
};
use std::error::Error;
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
pub struct CalculatorRequest {
pub a: f64,
pub b: f64,
}
#[derive(Debug, Clone)]
pub struct Calculator {
tool_router: ToolRouter<Self>,
}
#[tool_router]
impl Calculator {
pub fn new() -> Self {
Self {
tool_router: Self::tool_router(),
}
}
#[tool(description = "Adds a and b")]
async fn add(
&self,
Parameters(CalculatorRequest { a, b }): Parameters<CalculatorRequest>,
) -> String {
(a + b).to_string()
}
}
#[tool_handler]
impl ServerHandler for Calculator {
fn get_info(&self) -> ServerInfo {
ServerInfo {
instructions: Some("A simple calculator tool".into()),
capabilities: ServerCapabilities::builder().enable_tools().build(),
..Default::default()
}
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let service = Calculator::new().serve(stdio()).await?;
service.waiting().await?;
Ok(())
}使用以下命令啟動伺服器:
npm run buildmcp run server.py若要使用 MCP Inspector,請使用
mcp dev server.py,該命令會自動啟動 Inspector 並提供所需的代理會話令牌。如果使用mcp run server.py,您需要手動啟動 Inspector 並配置連接。
確保您位於項目目錄中:
cd McpCalculatorServer
dotnet run./mvnw clean install -DskipTests
java -jar target/calculator-server-0.0.1-SNAPSHOT.jar運行以下命令以格式化並運行伺服器:
cargo fmt
cargo runInspector 是一個很棒的工具,可以啟動您的伺服器並讓您與之交互,以測試其是否正常運行。讓我們啟動它:
Note
在 "command" 欄位中可能會顯示不同的內容,因為它包含了針對您的特定運行時運行伺服器的命令。
npx @modelcontextprotocol/inspector node build/index.js或者將其添加到您的 package.json 中,例如:"inspector": "npx @modelcontextprotocol/inspector node build/index.js",然後運行 npm run inspector
Python 包裝了一個名為 Inspector 的 Node.js 工具。可以像下面這樣調用該工具:
mcp dev server.py然而,它並未實現工具中的所有方法,因此建議直接運行以下 Node.js 工具:
npx @modelcontextprotocol/inspector mcp run server.py如果您使用的工具或 IDE 允許您配置運行腳本的命令和參數,請確保在 Command 欄位中設置 python,並將 server.py 設為 Arguments。這樣可以確保腳本正確運行。
確保您位於項目目錄中:
cd McpCalculatorServer
npx @modelcontextprotocol/inspector dotnet run確保您的計算器伺服器正在運行,然後運行 Inspector:
npx @modelcontextprotocol/inspector在 Inspector 網頁界面中:
您現在已成功連接到伺服器
Java 伺服器測試部分已完成
接下來的部分是與伺服器進行互動。
您應該會看到以下的使用者介面:
-
點選「連接」按鈕以連接到伺服器
當您成功連接到伺服器後,應該會看到以下畫面: -
選擇「工具」並點選「listTools」,您應該會看到「Add」出現,點選「Add」並填寫參數值。
您應該會看到以下的回應,也就是來自「add」工具的結果:
恭喜您,您已成功建立並執行了您的第一個伺服器!
要使用 MCP Inspector CLI 執行 Rust 伺服器,請使用以下指令:
npx @modelcontextprotocol/inspector cargo run --cli --method tools/call --tool-name add --tool-arg a=1 b=2MCP 提供多種語言的官方 SDK:
- C# SDK - 與 Microsoft 合作維護
- Java SDK - 與 Spring AI 合作維護
- TypeScript SDK - 官方 TypeScript 實作
- Python SDK - 官方 Python 實作
- Kotlin SDK - 官方 Kotlin 實作
- Swift SDK - 與 Loopwork AI 合作維護
- Rust SDK - 官方 Rust 實作
- 使用語言專屬的 SDK 設置 MCP 開發環境非常簡單
- 建立 MCP 伺服器需要創建並註冊具有清晰結構的工具
- 測試和除錯對於可靠的 MCP 實作至關重要
建立一個包含您選擇工具的簡單 MCP 伺服器:
- 使用您偏好的語言(.NET、Java、Python、TypeScript 或 Rust)實作該工具。
- 定義輸入參數和返回值。
- 執行檢查工具以確保伺服器正常運作。
- 使用多種輸入測試該實作。
- 在 Azure 上使用 Model Context Protocol 建立代理
- 使用 Azure 容器應用程式進行遠端 MCP(Node.js/TypeScript/JavaScript)
- .NET OpenAI MCP 代理
下一步:開始使用 MCP 客戶端
免責聲明:
本文件已使用 AI 翻譯服務 Co-op Translator 進行翻譯。雖然我們致力於提供準確的翻譯,但請注意,自動翻譯可能包含錯誤或不準確之處。原始文件的母語版本應被視為權威來源。對於關鍵資訊,建議使用專業人工翻譯。我們對因使用此翻譯而引起的任何誤解或錯誤解釋不承擔責任。



