Skip to content

Latest commit

 

History

History
1378 lines (1076 loc) · 42.1 KB

File metadata and controls

1378 lines (1076 loc) · 42.1 KB

Pagsisimula sa MCP

Maligayang pagdating sa iyong unang hakbang sa Model Context Protocol (MCP)! Kung bago ka sa MCP o nais mong palalimin ang iyong kaalaman, ang gabay na ito ay magbibigay sa iyo ng mga pangunahing hakbang sa pag-set up at proseso ng pag-develop. Matutuklasan mo kung paano nagbibigay ang MCP ng seamless na integrasyon sa pagitan ng mga AI model at mga aplikasyon, at matututunan mo kung paano mabilis na ihanda ang iyong kapaligiran para sa paggawa at pagsubok ng mga solusyong pinapagana ng MCP.

TLDR; Kung gumagawa ka ng mga AI app, alam mo na maaari kang magdagdag ng mga tool at iba pang mga mapagkukunan sa iyong LLM (large language model) upang gawing mas matalino ang LLM. Gayunpaman, kung ilalagay mo ang mga tool at mapagkukunang iyon sa isang server, maaaring magamit ng anumang kliyente, na may o walang LLM, ang app at kakayahan ng server.

Pangkalahatang-ideya

Ang araling ito ay nagbibigay ng praktikal na gabay sa pag-set up ng mga MCP environment at paggawa ng iyong unang MCP application. Matututunan mo kung paano i-set up ang mga kinakailangang tool at framework, gumawa ng mga pangunahing MCP server, lumikha ng mga host application, at subukan ang iyong mga implementasyon.

Ang Model Context Protocol (MCP) ay isang bukas na protocol na nag-i-standardize kung paano nagbibigay ng konteksto ang mga aplikasyon sa LLMs. Isipin ang MCP na parang USB-C port para sa mga AI application - nagbibigay ito ng standardisadong paraan upang ikonekta ang mga AI model sa iba't ibang data source at tool.

Mga Layunin sa Pagkatuto

Sa pagtatapos ng araling ito, magagawa mong:

  • I-set up ang mga development environment para sa MCP gamit ang C#, Java, Python, TypeScript, at Rust
  • Gumawa at mag-deploy ng mga pangunahing MCP server na may custom na mga feature (mga resource, prompt, at tool)
  • Lumikha ng mga host application na kumokonekta sa mga MCP server
  • Subukan at i-debug ang mga implementasyon ng MCP

Pag-set Up ng Iyong MCP Environment

Bago ka magsimula sa MCP, mahalagang ihanda ang iyong development environment at maunawaan ang pangunahing workflow. Ang seksyong ito ay gagabay sa iyo sa mga unang hakbang sa pag-set up upang masigurong maayos ang iyong pagsisimula sa MCP.

Mga Kinakailangan

Bago sumabak sa MCP development, tiyaking mayroon ka ng mga sumusunod:

  • Development Environment: Para sa napili mong wika (C#, Java, Python, TypeScript, o Rust)
  • IDE/Editor: Visual Studio, Visual Studio Code, IntelliJ, Eclipse, PyCharm, o anumang modernong code editor
  • Package Managers: NuGet, Maven/Gradle, pip, npm/yarn, o Cargo
  • API Keys: Para sa anumang AI services na balak mong gamitin sa iyong mga host application

Pangunahing Estruktura ng MCP Server

Karaniwang binubuo ang isang MCP server ng:

  • Server Configuration: Pag-set up ng port, authentication, at iba pang setting
  • Resources: Data at konteksto na ibinibigay sa LLMs
  • Tools: Mga functionality na maaaring tawagin ng mga model
  • Prompts: Mga template para sa pagbuo o pag-istruktura ng teksto

Narito ang isang simpleng halimbawa sa 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);

Sa code sa itaas, ginawa natin ang sumusunod:

  • In-import ang mga kinakailangang klase mula sa MCP TypeScript SDK.
  • Gumawa at nag-configure ng bagong MCP server instance.
  • Nirehistro ang isang custom na tool (calculator) na may handler function.
  • Sinimulan ang server upang makinig sa mga papasok na MCP request.

Pagsubok at Pag-debug

Bago ka magsimula sa pagsubok ng iyong MCP server, mahalagang maunawaan ang mga available na tool at pinakamahusay na mga kasanayan para sa pag-debug. Ang epektibong pagsubok ay nagsisiguro na ang iyong server ay gumagana ayon sa inaasahan at tumutulong sa mabilis na pagtukoy at paglutas ng mga isyu. Ang sumusunod na seksyon ay naglalahad ng mga inirerekomendang paraan para sa pag-validate ng iyong MCP implementation.

Nagbibigay ang MCP ng mga tool upang matulungan kang subukan at i-debug ang iyong mga server:

  • Inspector tool, isang graphical interface na nagbibigay-daan sa iyong kumonekta sa iyong server at subukan ang iyong mga tool, prompt, at resource.
  • curl, maaari ka ring kumonekta sa iyong server gamit ang isang command line tool tulad ng curl o iba pang mga kliyente na maaaring lumikha at magpatakbo ng mga HTTP command.

Paggamit ng MCP Inspector

Ang MCP Inspector ay isang visual testing tool na tumutulong sa iyo na:

  1. Tuklasin ang Kakayahan ng Server: Awtomatikong matukoy ang mga available na resource, tool, at prompt
  2. Subukan ang Tool Execution: Subukan ang iba't ibang parameter at makita ang mga tugon sa real-time
  3. Tingnan ang Metadata ng Server: Suriin ang impormasyon ng server, mga schema, at mga configuration
# ex TypeScript, installing and running MCP Inspector
npx @modelcontextprotocol/inspector node build/index.js

Kapag pinatakbo mo ang mga command sa itaas, ilulunsad ng MCP Inspector ang isang lokal na web interface sa iyong browser. Maaari mong asahan na makakita ng isang dashboard na nagpapakita ng iyong mga nakarehistrong MCP server, ang kanilang mga available na tool, resource, at prompt. Ang interface ay nagbibigay-daan sa iyong interactive na subukan ang tool execution, suriin ang metadata ng server, at tingnan ang mga tugon sa real-time, na nagpapadali sa pag-validate at pag-debug ng iyong mga implementasyon ng MCP server.

Narito ang isang screenshot kung ano ang maaaring hitsura nito:

MCP Inspector server connection

Karaniwang Mga Isyu sa Setup at Mga Solusyon

Isyu Posibleng Solusyon
Connection refused Suriin kung tumatakbo ang server at tama ang port
Tool execution errors Suriin ang validation ng parameter at error handling
Authentication failures Siguraduhing tama ang API keys at mga pahintulot
Schema validation errors Siguraduhing tumutugma ang mga parameter sa itinakdang schema
Server not starting Suriin ang port conflicts o nawawalang dependencies
CORS errors I-configure ang tamang CORS headers para sa cross-origin requests
Authentication issues Siguraduhing valid ang token at may tamang pahintulot

Lokal na Pag-develop

Para sa lokal na pag-develop at pagsubok, maaari mong patakbuhin ang mga MCP server nang direkta sa iyong makina:

  1. Simulan ang proseso ng server: Patakbuhin ang iyong MCP server application
  2. I-configure ang networking: Siguraduhing accessible ang server sa inaasahang port
  3. Ikonekta ang mga kliyente: Gumamit ng mga lokal na koneksyon tulad ng http://localhost:3000
# Example: Running a TypeScript MCP server locally
npm run start
# Server running at http://localhost:3000

Paggawa ng Iyong Unang MCP Server

Tinalakay na natin ang Mga Pangunahing Konsepto sa nakaraang aralin, ngayon ay oras na upang gamitin ang kaalamang iyon.

Ano ang Kayang Gawin ng Isang Server

Bago tayo magsimulang magsulat ng code, balikan natin kung ano ang kayang gawin ng isang server:

Ang isang MCP server ay maaaring, halimbawa:

  • Mag-access ng mga lokal na file at database
  • Kumonekta sa mga remote API
  • Magsagawa ng mga kalkulasyon
  • Mag-integrate sa iba pang mga tool at serbisyo
  • Magbigay ng user interface para sa interaksyon

Mahusay, ngayong alam na natin kung ano ang kaya nitong gawin, magsimula na tayong mag-code.

Ehersisyo: Paglikha ng Server

Upang makagawa ng server, sundin ang mga hakbang na ito:

  • I-install ang MCP SDK.
  • Gumawa ng proyekto at i-set up ang estruktura ng proyekto.
  • Isulat ang server code.
  • Subukan ang server.

-1- Gumawa ng Proyekto

TypeScript

# Create project directory and initialize npm project
mkdir calculator-server
cd calculator-server
npm init -y

Python

# 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 .

.NET

dotnet new console -n McpCalculatorServer
cd McpCalculatorServer

Java

Para sa Java, gumawa ng Spring Boot project:

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

I-extract ang zip file:

unzip calculator-server.zip -d calculator-server
cd calculator-server
# optional remove the unused test
rm -rf src/test/java

Idagdag ang sumusunod na kumpletong configuration sa iyong pom.xml file:

<?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>

Rust

mkdir calculator-server
cd calculator-server
cargo init

-2- Magdagdag ng Dependencies

Ngayon na mayroon ka nang proyekto, magdagdag tayo ng mga dependencies:

TypeScript

# 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

Python

# Create a virtual env and install dependencies
python -m venv venv
venv\Scripts\activate
pip install "mcp[cli]"

Java

cd calculator-server
./mvnw clean install -DskipTests

Rust

cargo add rmcp --features server,transport-io
cargo add serde
cargo add tokio --features rt-multi-thread

-3- Gumawa ng Mga File ng Proyekto

TypeScript

Buksan ang package.json file at palitan ang nilalaman ng sumusunod upang masigurong maaari mong i-build at patakbuhin ang server:

{
  "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"
  }
}

Gumawa ng tsconfig.json na may sumusunod na nilalaman:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "./build",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

Gumawa ng direktoryo para sa iyong source code:

mkdir src
touch src/index.ts

Python

Gumawa ng file na server.py

touch server.py

.NET

I-install ang mga kinakailangang NuGet packages:

dotnet add package ModelContextProtocol --prerelease
dotnet add package Microsoft.Extensions.Hosting

Java

Para sa mga Java Spring Boot project, awtomatikong nalilikha ang estruktura ng proyekto.

Rust

Para sa Rust, ang src/main.rs file ay awtomatikong nalilikha kapag pinatakbo mo ang cargo init. Buksan ang file at tanggalin ang default na code.

-4- Gumawa ng Server Code

TypeScript

Gumawa ng file na index.ts at idagdag ang sumusunod na code:

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"
});

Ngayon ay mayroon ka nang server, ngunit hindi pa ito gumagawa ng marami. Ayusin natin iyon.

Python

# server.py
from mcp.server.fastmcp import FastMCP

# Create an MCP server
mcp = FastMCP("Demo")

.NET

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

Para sa Java, gumawa ng mga pangunahing bahagi ng server. Una, i-modify ang pangunahing application class:

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();
    }
}

Gumawa ng calculator service 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);
    }
}

Opsyonal na mga bahagi para sa isang production-ready na serbisyo:

Gumawa ng startup configuration 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");
        };
    }
}

Gumawa ng health controller 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);
    }
}

Gumawa ng exception handler 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; }
    }
}

Gumawa ng custom banner src/main/resources/banner.txt:

_____      _            _       _             
 / ____|    | |          | |     | |            
| |     __ _| | ___ _   _| | __ _| |_ ___  _ __ 
| |    / _` | |/ __| | | | |/ _` | __/ _ \| '__|
| |___| (_| | | (__| |_| | | (_| | || (_) | |   
 \_____\__,_|_|\___|\__,_|_|\__,_|\__\___/|_|   
                                                
Calculator MCP Server v1.0
Spring Boot MCP Application

Rust

Idagdag ang sumusunod na code sa itaas ng src/main.rs file. Inilalagay nito ang mga kinakailangang library at module para sa iyong MCP server.

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;

Ang calculator server ay magiging simple lamang na maaaring magdagdag ng dalawang numero. Gumawa tayo ng struct para kumatawan sa calculator request.

#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
pub struct CalculatorRequest {
    pub a: f64,
    pub b: f64,
}

Susunod, gumawa ng struct para kumatawan sa calculator server. Ang struct na ito ay maglalaman ng tool router, na ginagamit upang magrehistro ng mga tool.

#[derive(Debug, Clone)]
pub struct Calculator {
    tool_router: ToolRouter<Self>,
}

Ngayon, maaari nating i-implement ang Calculator struct upang gumawa ng bagong instance ng server at i-implement ang server handler upang magbigay ng impormasyon tungkol sa server.

#[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()
        }
    }
}

Sa wakas, kailangan nating i-implement ang pangunahing function upang simulan ang server. Ang function na ito ay gagawa ng instance ng Calculator struct at ise-serve ito sa pamamagitan ng standard input/output.

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let service = Calculator::new().serve(stdio()).await?;
    service.waiting().await?;
    Ok(())
}

Ang server ay handa na upang magbigay ng pangunahing impormasyon tungkol sa sarili nito. Susunod, magdadagdag tayo ng tool upang magsagawa ng addition.

-5- Pagdaragdag ng Tool at Resource

Magdagdag ng tool at resource sa pamamagitan ng pagdaragdag ng sumusunod na code:

TypeScript

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}!`
    }]
  })
);

Ang iyong tool ay tumatanggap ng mga parameter na a at b at nagpapatakbo ng isang function na gumagawa ng tugon sa anyo ng:

{
  contents: [{
    type: "text", content: "some content"
  }]
}

Ang iyong resource ay naa-access sa pamamagitan ng string na "greeting" at tumatanggap ng parameter na name at gumagawa ng katulad na tugon sa tool:

{
  uri: "<href>",
  text: "a text"
}

Python

# 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}!"

Sa code sa itaas, ginawa natin ang sumusunod:

  • Tinukoy ang tool na add na tumatanggap ng mga parameter na a at p, parehong integer.
  • Gumawa ng resource na tinatawag na greeting na tumatanggap ng parameter na name.

.NET

Idagdag ito sa iyong Program.cs file:

[McpServerToolType]
public static class CalculatorTool
{
    [McpServerTool, Description("Adds two numbers")]
    public static string Add(int a, int b) => $"Sum {a + b}";
}

Java

Ang mga tool ay nagawa na sa nakaraang hakbang.

Rust

Magdagdag ng bagong tool sa loob ng impl Calculator block:

#[tool(description = "Adds a and b")]
async fn add(
    &self,
    Parameters(CalculatorRequest { a, b }): Parameters<CalculatorRequest>,
) -> String {
    (a + b).to_string()
}

-6- Panghuling Code

Idagdag ang huling code na kailangan upang masimulan ang server:

TypeScript

// Start receiving messages on stdin and sending messages on stdout
const transport = new StdioServerTransport();
await server.connect(transport);

Narito ang buong code:

// 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);

Python

# 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()

.NET

Gumawa ng Program.cs file na may sumusunod na nilalaman:

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}";
}

Java

Ang iyong kumpletong pangunahing application class ay dapat magmukhang ganito:

// 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

Ang panghuling code para sa Rust server ay dapat magmukhang ganito:

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(())
}

-7- Subukan ang Server

Simulan ang server gamit ang sumusunod na command:

TypeScript

npm run build

Python

mcp run server.py

Upang gamitin ang MCP Inspector, gamitin ang mcp dev server.py na awtomatikong naglulunsad ng Inspector at nagbibigay ng kinakailangang proxy session token. Kung gumagamit ng mcp run server.py, kakailanganin mong manu-manong simulan ang Inspector at i-configure ang koneksyon.

.NET

Siguraduhing nasa iyong project directory ka:

cd McpCalculatorServer
dotnet run

Java

./mvnw clean install -DskipTests
java -jar target/calculator-server-0.0.1-SNAPSHOT.jar

Rust

Patakbuhin ang sumusunod na mga command upang i-format at patakbuhin ang server:

cargo fmt
cargo run

-8- Patakbuhin gamit ang Inspector

Ang inspector ay isang mahusay na tool na maaaring magsimula ng iyong server at nagbibigay-daan sa iyong makipag-ugnayan dito upang masubukan kung gumagana ito. Simulan natin ito:

Note

Maaaring magmukhang iba ang "command" field dahil naglalaman ito ng command para sa pagpapatakbo ng server gamit ang iyong partikular na runtime.

TypeScript

npx @modelcontextprotocol/inspector node build/index.js

o idagdag ito sa iyong package.json tulad nito: "inspector": "npx @modelcontextprotocol/inspector node build/index.js" at pagkatapos ay patakbuhin ang npm run inspector

Ang Python ay gumagamit ng Node.js tool na tinatawag na inspector. Posibleng tawagin ang tool na iyon tulad nito:

mcp dev server.py

Gayunpaman, hindi nito na-implement ang lahat ng mga method na available sa tool kaya inirerekomendang patakbuhin ang Node.js tool nang direkta tulad ng nasa ibaba:

npx @modelcontextprotocol/inspector mcp run server.py

Kung gumagamit ka ng tool o IDE na nagbibigay-daan sa iyong i-configure ang mga command at argument para sa pagpapatakbo ng mga script, tiyaking itakda ang python sa Command field at server.py bilang Arguments. Tinitiyak nito na maayos na tatakbo ang script.

.NET

Siguraduhing nasa iyong project directory ka:

cd McpCalculatorServer
npx @modelcontextprotocol/inspector dotnet run

Java

Siguraduhing tumatakbo ang iyong calculator server. Pagkatapos, patakbuhin ang inspector:

npx @modelcontextprotocol/inspector

Sa web interface ng inspector:

  1. Piliin ang "SSE" bilang uri ng transportasyon
  2. Itakda ang URL sa: http://localhost:8080/sse
  3. I-click ang "Connect" Kumonekta

Nakakonekta ka na ngayon sa server
Tapos na ang seksyon ng pagsubok sa Java server

Ang susunod na seksyon ay tungkol sa pakikipag-ugnayan sa server.

Makikita mo ang sumusunod na user interface:

Kumonekta

  1. Kumonekta sa server sa pamamagitan ng pagpili sa button na "Connect".
    Kapag nakakonekta ka na sa server, makikita mo ang sumusunod:

    Nakakonekta

  2. Piliin ang "Tools" at "listTools", makikita mo ang "Add" na lilitaw. Piliin ang "Add" at punan ang mga halaga ng parameter.

    Makikita mo ang sumusunod na tugon, ibig sabihin, ang resulta mula sa "add" na tool:

    Resulta ng pagpapatakbo ng add

Binabati kita, nagawa mong lumikha at patakbuhin ang iyong unang server!

Rust

Upang patakbuhin ang Rust server gamit ang MCP Inspector CLI, gamitin ang sumusunod na command:

npx @modelcontextprotocol/inspector cargo run --cli --method tools/call --tool-name add --tool-arg a=1 b=2

Opisyal na SDKs

Nagbibigay ang MCP ng mga opisyal na SDK para sa iba't ibang wika:

  • C# SDK - Pinapanatili sa pakikipagtulungan sa Microsoft
  • Java SDK - Pinapanatili sa pakikipagtulungan sa Spring AI
  • TypeScript SDK - Ang opisyal na implementasyon ng TypeScript
  • Python SDK - Ang opisyal na implementasyon ng Python
  • Kotlin SDK - Ang opisyal na implementasyon ng Kotlin
  • Swift SDK - Pinapanatili sa pakikipagtulungan sa Loopwork AI
  • Rust SDK - Ang opisyal na implementasyon ng Rust

Mahahalagang Punto

  • Ang pag-set up ng MCP development environment ay madali gamit ang mga language-specific SDK.
  • Ang paggawa ng MCP servers ay nangangailangan ng paglikha at pagrerehistro ng mga tool na may malinaw na mga schema.
  • Ang pagsubok at pag-debug ay mahalaga para sa maaasahang mga implementasyon ng MCP.

Mga Halimbawa

Gawain

Lumikha ng isang simpleng MCP server gamit ang tool na gusto mo:

  1. Ipatupad ang tool sa wika na iyong pinili (.NET, Java, Python, TypeScript, o Rust).
  2. Tukuyin ang mga input parameter at mga return value.
  3. Patakbuhin ang inspector tool upang matiyak na gumagana nang maayos ang server.
  4. Subukan ang implementasyon gamit ang iba't ibang input.

Solusyon

Solusyon

Karagdagang Mga Mapagkukunan

Ano ang susunod

Susunod: Pagsisimula sa MCP Clients

Paunawa:
Ang dokumentong ito ay isinalin gamit ang AI translation service na Co-op Translator. Bagama't sinisikap naming maging tumpak, pakitandaan na ang mga awtomatikong pagsasalin ay maaaring maglaman ng mga pagkakamali o hindi pagkakatugma. Ang orihinal na dokumento sa kanyang katutubong wika ang dapat ituring na opisyal na sanggunian. Para sa mahalagang impormasyon, inirerekomenda ang propesyonal na pagsasalin ng tao. Hindi kami mananagot sa anumang hindi pagkakaunawaan o maling interpretasyon na maaaring magmula sa paggamit ng pagsasaling ito.