最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用?Java?開發(fā)?MCP?服務并發(fā)布到?Maven?中央倉庫實踐指南

 更新時間:2026年04月06日 09:12:05   作者:wb04307201  
本文介紹了使用Java開發(fā)MCP服務并發(fā)布到Maven中央倉庫的流程,重點講解了如何通過JBang和stdio將MCP服務集成到大模型中,以及相關最佳實踐和常見問題解決方案,感興趣的朋友跟隨小編一起看看吧

什么是 MCP

Model Context Protocol (MCP) 是一個開放協(xié)議,用于標準化大語言模型與外部數(shù)據(jù)源和工具之間的交互。它允許開發(fā)者將應用程序、數(shù)據(jù)源或 AI 功能無縫集成到任何使用 MCP 的 LLM 客戶端中。

MCP 的核心優(yōu)勢

  • 標準化接口:統(tǒng)一的工具調(diào)用規(guī)范
  • 松耦合架構(gòu):服務與 LLM 客戶端獨立部署
  • 易于擴展:快速添加新的工具和能力
  • 跨平臺支持:支持多種編程語言和運行環(huán)境

MCP 通信模式

MCP 支持多種通信方式:

  • stdio:基于標準輸入輸出的本地進程通信(本文重點)
  • HTTP/SSE:基于 HTTP 的服務器發(fā)送事件
  • WebSocket:雙向?qū)崟r通信

本文將以中國天氣查詢服務為例,詳細介紹如何使用 Java 開發(fā) MCP 服務,并發(fā)布到 Maven 中央倉庫,最終通過 JBang 和 stdio 方式集成到大模型工具中。

項目架構(gòu)與技術選型

技術棧

  • Java 17:LTS 版本,提供優(yōu)秀的性能和新特性
  • Spring Boot 3.5.13:快速應用開發(fā)框架
  • Spring AI MCP:Spring AI 提供的 MCP 服務器支持
  • Maven:項目構(gòu)建和依賴管理
  • JBang:Java 腳本執(zhí)行工具,用于運行 JAR

項目結(jié)構(gòu)

cn-weather-mcp/
├── src/main/java/cn/wubo/cn/weather/mcp/
│   ├── WeatherApplication.java    # 主啟動類
│   └── WeatherService.java        # 天氣服務實現(xiàn)
├── src/main/resources/
│   └── application.yml            # 配置文件
├── pom.xml                        # Maven 配置
└── .github/workflows/
    └── publish.yml                # CI/CD 發(fā)布流程

開發(fā)環(huán)境準備

必需軟件

  • JDK 17+
  • java -version
    
  • Maven 3.6+
  • mvn -version
    
  • Git
  • git --version
    
  • GPG(用于簽名發(fā)布到中央倉庫)
gpg --version

GPG 密鑰生成

發(fā)布到 Maven 中央倉庫需要 GPG 簽名:

# 生成 GPG 密鑰
gpg --full-generate-key
# 查看生成的密鑰
gpg --list-keys
# 將公鑰上傳到密鑰服務器
gpg --keyserver keyserver.ubuntu.com --send-keys YOUR_KEY_ID

創(chuàng)建 Spring Boot 項目

1. 創(chuàng)建 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 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.5.13</version>
        <relativePath/>
    </parent>
    
    <groupId>io.github.your-username</groupId>
    <artifactId>cn-weather-mcp</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>cn-weather-mcp</name>
    <description>中國天氣 MCP 服務 - 提供中國城市天氣查詢服務</description>
    
    <!-- 項目元信息 -->
    <url>https://github.com/your-username/cn-weather-mcp</url>
    
    <developers>
        <developer>
            <id>your-id</id>
            <name>Your Name</name>
            <email>your-email@example.com</email>
        </developer>
    </developers>
    
    <licenses>
        <license>
            <name>The Apache Software License, Version 2.0</name>
            <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
        </license>
    </licenses>
    
    <scm>
        <connection>scm:git:https://github.com/your-username/cn-weather-mcp.git</connection>
        <developerConnection>scm:git:git@github.com:your-username/cn-weather-mcp.git</developerConnection>
        <url>https://github.com/your-username/cn-weather-mcp</url>
    </scm>
    
    <properties>
        <java.version>17</java.version>
        <spring-ai.version>1.1.3</spring-ai.version>
    </properties>
    
    <!-- 依賴管理 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>${spring-ai.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
    <dependencies>
        <!-- Spring AI MCP Server -->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-mcp-server</artifactId>
        </dependency>
        
        <!-- Spring Web (用于 HTTP 請求) -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <!-- Spring Boot Maven 插件 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            
            <!-- 源碼插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>3.3.0</version>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar-no-fork</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            
            <!-- Javadoc 插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <version>3.6.0</version>
                <executions>
                    <execution>
                        <id>attach-javadocs</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            
            <!-- GPG 簽名插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-gpg-plugin</artifactId>
                <version>3.1.0</version>
                <executions>
                    <execution>
                        <id>sign-artifacts</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>sign</goal>
                        </goals>
                        <configuration>
                            <gpgArguments>
                                <arg>--pinentry-mode</arg>
                                <arg>loopback</arg>
                            </gpgArguments>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            
            <!-- Central Publishing 插件 -->
            <plugin>
                <groupId>org.sonatype.central</groupId>
                <artifactId>central-publishing-maven-plugin</artifactId>
                <version>0.9.0</version>
                <extensions>true</extensions>
                <configuration>
                    <publishingServerId>central</publishingServerId>
                    <autoPublish>true</autoPublish>
                    <waitUntil>published</waitUntil>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2. 創(chuàng)建配置文件 application.yml

spring:
  main:
    web-application-type: none  # 非 Web 應用
    banner-mode: off            # 關閉啟動橫幅
  ai:
    mcp:
      server:
        name: cn-weather-mcp    # MCP 服務名稱
        version: 1.0.0          # MCP 服務版本
logging:
  file:
    name: ./mcp/cn-weather-mcp.log  # 日志文件路徑

實現(xiàn) MCP 服務核心邏輯

1. 創(chuàng)建服務類 WeatherService

這是 MCP 服務的核心,包含所有工具方法的實現(xiàn):

package cn.wubo.cn.weather.mcp;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestClientException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class WeatherService {
    private static final String BASE_URL = "http://t.weather.itboy.net/api/weather/city/";
    private final RestClient restClient;
    private final ObjectMapper objectMapper;
    private final Map<String, CityCodeInfo> cityCodeMap;
    public WeatherService() {
        this.restClient = RestClient.builder()
                .baseUrl(BASE_URL)
                .build();
        this.objectMapper = new ObjectMapper();
        this.cityCodeMap = loadCityCodes();
    }
    // 加載城市代碼數(shù)據(jù)
    private static Map<String, CityCodeInfo> loadCityCodes() {
        List<CityCodeInfo> cityCodes = Arrays.asList(
            new CityCodeInfo(1, "北京", "北京", "101010100"),
            new CityCodeInfo(23, "天津市", "天津", "101030100"),
            new CityCodeInfo(36, "上海", "上海", "101020100"),
            // ... 更多城市數(shù)據(jù)
        );
        return cityCodes.stream()
            .collect(Collectors.toMap(CityCodeInfo::cityCode, info -> info));
    }
    // 數(shù)據(jù)記錄類
    @JsonIgnoreProperties(ignoreUnknown = true)
    public record WeatherResponse(
            @JsonProperty("status") Integer status,
            @JsonProperty("message") String message,
            @JsonProperty("cityInfo") CityInfo cityInfo,
            @JsonProperty("data") WeatherDataWrapper data
    ) {}
    @JsonIgnoreProperties(ignoreUnknown = true)
    public record CityInfo(
            @JsonProperty("city") String city,
            @JsonProperty("citykey") String cityKey,
            @JsonProperty("parent") String parent,
            @JsonProperty("updateTime") String updateTime
    ) {}
    @JsonIgnoreProperties(ignoreUnknown = true)
    public record WeatherDataWrapper(
            @JsonProperty("shidu") String humidity,
            @JsonProperty("pm25") Double pm25,
            @JsonProperty("pm10") Double pm10,
            @JsonProperty("quality") String quality,
            @JsonProperty("wendu") String temperature,
            @JsonProperty("ganmao") String healthTip,
            @JsonProperty("forecast") List<Forecast> forecast
    ) {}
    @JsonIgnoreProperties(ignoreUnknown = true)
    public record Forecast(
            @JsonProperty("date") String date,
            @JsonProperty("high") String highTemp,
            @JsonProperty("low") String lowTemp,
            @JsonProperty("ymd") String ymd,
            @JsonProperty("week") String week,
            @JsonProperty("fx") String windDirection,
            @JsonProperty("fl") String windLevel,
            @JsonProperty("type") String weatherType,
            @JsonProperty("notice") String notice
    ) {}
    public record CityCodeInfo(
        Integer id,
        String province,
        String city,
        String cityCode
    ) {}
    /**
     * 工具方法 1:獲取當前天氣
     */
    @Tool(description = "Get current weather for a Chinese city. Input is city code (e.g., 101010100 for Beijing)")
    public String getCurrentWeather(
        @ToolParam(description = "City code (e.g., 101010100 for Beijing, 101020100 for Shanghai)") 
        String cityCode
    ) {
        ResponseEntity<byte[]> responseEntity = restClient.get()
                .uri("{cityCode}", cityCode)
                .retrieve()
                .toEntity(byte[].class);
        byte[] body = responseEntity.getBody();
        if (body == null) {
            throw new RuntimeException("Empty response from weather API");
        }
        String response = new String(body, StandardCharsets.UTF_8);
        WeatherResponse weatherResponse;
        try {
            weatherResponse = objectMapper.readValue(response, WeatherResponse.class);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("Failed to parse weather data: " + e.getMessage());
        }
        if (200 != weatherResponse.status()) {
            throw new RuntimeException("Weather API returned error: " + weatherResponse.message());
        }
        WeatherDataWrapper data = weatherResponse.data();
        CityInfo cityInfo = weatherResponse.cityInfo();
        return String.format("""
                        城市:%s (%s)
                        溫度:%s°C
                        濕度:%s
                        空氣質(zhì)量:%s (PM2.5: %s)
                        風向:%s %s
                        溫馨提示:%s
                        更新時間:%s
                        """,
                cityInfo.city(),
                cityInfo.parent(),
                data.temperature(),
                data.humidity(),
                data.quality(),
                data.pm25(),
                data.forecast().get(0).windDirection(),
                data.forecast().get(0).windLevel(),
                data.healthTip(),
                cityInfo.updateTime());
    }
    /**
     * 工具方法 2:搜索城市代碼
     */
    @Tool(description = "Search Chinese city codes by city name. Returns list of cities with their codes for weather queries")
    public String searchCityCode(
        @ToolParam(description = "City name to search (e.g., '北京', '上海', '廣州')") 
        String cityName
    ) {
        if (cityName == null || cityName.trim().isEmpty()) {
            return "請輸入要查詢的城市名稱";
        }
        String searchName = cityName.trim();
        List<CityCodeInfo> results = cityCodeMap.values().stream()
            .filter(info -> info.city().contains(searchName) ||
                    info.province().contains(searchName))
            .limit(20)
            .toList();
        if (results.isEmpty()) {
            return String.format("未找到包含 '%s' 的城市,請檢查輸入后重試", searchName);
        }
        StringBuilder sb = new StringBuilder();
        sb.append(String.format("找到 %d 個匹配的城市:\n\n", results.size()));
        sb.append(String.format("%-4s %-10s %-10s %-12s%n", "編號", "省份", "城市", "城市編碼"));
        sb.append("-".repeat(40)).append("\n");
        for (CityCodeInfo info : results) {
            sb.append(String.format("%-4d %-10s %-10s %-12s%n",
                info.id(), info.province(), info.city(), info.cityCode()));
        }
        sb.append("\n提示:使用城市編碼可以查詢具體天氣");
        return sb.toString();
    }
}

關鍵注解說明

  • @Service:標記為 Spring 服務組件
  • @Tool:Spring AI 的工具注解,標記該方法為 MCP 工具
  • @ToolParam:標注工具方法的參數(shù)及其描述

配置 MCP Server

創(chuàng)建啟動類 WeatherApplication

package cn.wubo.cn.weather.mcp;
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;
@SpringBootApplication
public class WeatherApplication {
    public static void main(String[] args) {
        SpringApplication.run(WeatherApplication.class, args);
    }
    @Bean
    public ToolCallbackProvider weatherTools(WeatherService weatherService) {
        return MethodToolCallbackProvider.builder()
                .toolObjects(weatherService)
                .build();
    }
}

配置說明

  • ToolCallbackProvider:提供工具回調(diào)的 Bean
  • MethodToolCallbackProvider:基于方法注解的工具提供者
  • .toolObjects(weatherService):注冊包含 @Tool 注解的服務對象

發(fā)布到 Maven 中央倉庫

1. 在 Sonatype Central 創(chuàng)建賬戶

訪問 Sonatype Central 注冊賬戶并完成驗證。

2. 配置認證信息

本地測試(~/.m2/settings.xml)

<settings>
  <servers>
    <server>
      <id>central</id>
      <username>your-username</username>
      <password>your-token</password>
    </server>
  </servers>
</settings>

GitHub Secrets 配置

在 GitHub 倉庫設置中添加以下 Secrets:

  • CENTRAL_USERNAME:Sonatype Central 用戶名
  • CENTRAL_TOKEN:Sonatype Central Token
  • GPG_PRIVATE_KEY:GPG 私鑰
  • GPG_PASSPHRASE:GPG 私鑰密碼

3. 創(chuàng)建 GitHub Actions 發(fā)布流程

創(chuàng)建 .github/workflows/publish.yml

name: Publish to Sonatype Central
on:
  release:
    types: [created]
jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'
          cache: maven
      - name: Create Maven settings.xml
        run: |
          mkdir -p ~/.m2
          cat > ~/.m2/settings.xml << EOF
          <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
            <servers>
              <server>
                <id>central</id>
                <username>\${CENTRAL_USERNAME}</username>
                <password>\${CENTRAL_TOKEN}</password>
              </server>
            </servers>
          </settings>
          EOF
        env:
          CENTRAL_USERNAME: \${{ secrets.CENTRAL_USERNAME }}
          CENTRAL_TOKEN: \${{ secrets.CENTRAL_TOKEN }}
      - name: Import GPG Key
        uses: crazy-max/ghaction-import-gpg@v6
        with:
          gpg_private_key: \${{ secrets.GPG_PRIVATE_KEY }}
          passphrase: \${{ secrets.GPG_PASSPHRASE }}
          git_user_signingkey: false
          git_commit_gpgsign: false
      - name: Extract version from tag
        id: version
        run: echo "VERSION=\${GITHUB_REF#refs/tags/v}" >> \$GITHUB_OUTPUT
      - name: Set Version
        run: mvn versions:set -DnewVersion=\${{ steps.version.outputs.VERSION }} -DgenerateBackupPoms=false -B
      - name: Publish to Central
        run: mvn -B clean deploy
        env:
          GPG_PASSPHRASE: \${{ secrets.GPG_PASSPHRASE }}

4. 發(fā)布流程

提交代碼到 Git

git add .
git commit -m "Initial release"
git push origin main

創(chuàng)建 Git Release

# 打標簽
git tag v1.0.0
git push origin v1.0.0
# 或在 GitHub UI 創(chuàng)建 Release
  • 自動發(fā)布
    • 創(chuàng)建 Release 后,GitHub Actions 會自動觸發(fā)
    • 等待 Workflow 完成
    • Sonatype Central 查看發(fā)布狀態(tài)
    • 通常 15-30 分鐘后同步到 Maven Central

5. 驗證發(fā)布

發(fā)布成功后,可以在以下地址查看:

  • Sonatype Central: https://central.sonatype.com/artifact/io.github.wb04307201/cn-weather-mcp
  • Maven Central: https://repo.maven.apache.org/maven2/io/github/wb04307201/cn-weather-mcp/

使用 JBang 通過 stdio 集成到大模型

什么是 JBang

JBang 是一個允許你無需安裝 JDK 或配置項目即可運行 Java 代碼的工具。它非常適合快速原型開發(fā)和腳本編寫。

1. 安裝 JBang

Windows (PowerShell)

iex "& { $(iwr https://ps.jbang.dev) } app setup"

Linux / macOS

curl -Ls https://sh.jbang.dev | bash -s - app setup

2. 驗證安裝

jbang --version

3. MCP Client 配置

以大模型工具的 MCP 配置為例,創(chuàng)建配置文件:

Claude Desktop 配置

編輯 claude_desktop_config.json

{
  "mcpServers": {
    "cn-weather-mcp": {
      "command": "jbang",
      "args": [
        "io.github.wb04307201:cn-weather-mcp:1.0.0"
      ]
    }
  }
}

配置說明

  • command: jbang - 使用 JBang 運行
  • args: Maven 坐標 - JBang 會自動從 Maven Central 下載并運行

4. stdio 工作原理

┌─────────────┐         ┌──────────────┐         ┌─────────────┐
│  LLM Client │?───────?│  JBang       │?───────?│  MCP Server │
│  (Claude)   │  JSON   │  (Runner)    │  stdio  │  (Your Jar) │
└─────────────┘  RPC    └──────────────┘  IO     └─────────────┘

通信流程

  1. LLM Client 發(fā)送 JSON-RPC 請求到 JBang
  2. JBang 啟動 Java 進程,通過 stdin/stdout 與 MCP Server 通信
  3. MCP Server 處理請求并返回結(jié)果
  4. 結(jié)果沿原路返回給 LLM Client

5. 測試 MCP 服務

本地測試

# 直接使用 JBang 運行
jbang io.github.wb04307201:cn-weather-mcp:1.0.0

在 IDE 中測試

運行 WeatherApplication.main() 方法,然后通過 MCP 客戶端工具連接。

6. 在大模型中使用

配置完成后,在大模型對話中可以直接使用:

示例對話

用戶:北京今天天氣怎么樣?

助手:[調(diào)用 MCP 工具 searchCityCode("北京")]
      [獲取城市代碼 101010100]
      [調(diào)用 MCP 工具 getCurrentWeather("101010100")]
      
      北京今天的天氣情況如下:
      - 溫度:25°C
      - 濕度:60%
      - 空氣質(zhì)量:良 (PM2.5: 35)
      - 風向:東南風 2 級
      - 溫馨提示:天氣舒適,適合戶外活動

完整示例代碼清單

項目關鍵文件

  1. pom.xml - Maven 配置(見前文)
  2. application.yml - 應用配置(見前文)
  3. WeatherApplication.java - 啟動類(見前文)
  4. WeatherService.java - 服務實現(xiàn)(見前文)
  5. publish.yml - GitHub Actions(見前文)

運行命令

# 編譯項目
mvn clean package
# 本地測試
mvn spring-boot:run
# 發(fā)布到 Maven Central
mvn clean deploy
# 使用 JBang 運行
jbang io.github.wb04307201:cn-weather-mcp:1.0.0

常見問題與解決方案

Q1: GPG 簽名失敗

錯誤信息gpg: signing failed: No secret key

解決方案

# 確認 GPG 密鑰存在
gpg --list-secret-keys
# 重新生成密鑰
gpg --full-generate-key

Q2: Maven 部署被拒絕

原因:缺少必要的元數(shù)據(jù)或簽名

解決方案

  • 確保 pom.xml 包含所有必需信息(developers, licenses, scm)
  • 確保生成了 source 和 javadoc jars
  • 確保 GPG 簽名正確配置

Q3: JBang 無法下載 JAR

錯誤信息Failed to resolve artifact

解決方案

  • 等待 Maven Central 同步完成(發(fā)布后約 15-30 分鐘)
  • 檢查 Maven 坐標是否正確
  • 清除 JBang 緩存:jbang cache clear

Q4: MCP 工具無法被識別

原因@Tool 注解未正確配置

解決方案

  • 確保方法有 @Tool 注解
  • 確保方法參數(shù)有 @ToolParam 注解
  • 確保 ToolCallbackProvider Bean 正確注冊

最佳實踐建議

1. 代碼規(guī)范

  • 為所有工具方法提供詳細的文檔注釋
  • 使用清晰的參數(shù)命名和描述
  • 提供完善的錯誤處理和異常信息

2. 安全性

  • 避免在代碼中硬編碼敏感信息(API Keys、密碼等)
  • 使用環(huán)境變量或配置中心管理敏感配置
  • 對輸入?yún)?shù)進行驗證和清理

3. 性能優(yōu)化

  • 使用連接池管理 HTTP 連接
  • 實現(xiàn)適當?shù)木彺娌呗詼p少重復請求
  • 異步處理耗時操作

4. 可維護性

  • 保持單一職責原則,每個工具方法功能明確
  • 編寫單元測試覆蓋核心邏輯
  • 使用日志記錄關鍵操作和錯誤信息

總結(jié)

本文詳細介紹了如何使用 Java 開發(fā) MCP 服務并發(fā)布到 Maven 中央倉庫的完整流程:

核心步驟回顧

  1. ? 環(huán)境準備:安裝 JDK、Maven、GPG
  2. ? 項目搭建:創(chuàng)建 Spring Boot 項目,配置 Maven POM
  3. ? 服務開發(fā):實現(xiàn) @Tool 注解的業(yè)務方法
  4. ? MCP 配置:配置 ToolCallbackProvider Bean
  5. ? 發(fā)布準備:配置 GPG 簽名和 Sonatype Central
  6. ? 自動化發(fā)布:使用 GitHub Actions 自動發(fā)布
  7. ? 集成使用:通過 JBang 和 stdio 集成到大模型

技術優(yōu)勢

  • 快速開發(fā):基于 Spring AI,幾行代碼即可暴露 MCP 工具
  • 標準化:遵循 MCP 協(xié)議,兼容所有 MCP 客戶端
  • 易部署:通過 JBang 無需安裝,直接運行 JAR
  • 可擴展:輕松添加新的工具和方法

應用場景

  • 企業(yè)工具集成:將內(nèi)部系統(tǒng)封裝為 MCP 工具供 AI 調(diào)用
  • SaaS 服務封裝:將第三方 API 包裝為標準化工具
  • 個人項目分享:發(fā)布開源工具到 Maven Central
  • 微服務治理:統(tǒng)一管理 AI 可調(diào)用的服務接口

后續(xù)學習資源

  • Spring AI 官方文檔:https://docs.spring.io/spring-ai/reference/
  • MCP 協(xié)議規(guī)范:https://modelcontextprotocol.io/
  • Sonatype Central 發(fā)布指南:https://central.sonatype.org/publish/
  • JBang 使用手冊:https://www.jbang.dev/documentation/

通過本文的學習,你已經(jīng)掌握了從零開始開發(fā)、發(fā)布和使用 MCP 服務的完整技能樹?,F(xiàn)在就開始創(chuàng)建你自己的 MCP 服務,讓大模型能夠調(diào)用你的代碼吧!

項目源碼參考:https://github.com/wb04307201/cn-weather-mcp

到此這篇關于使用 Java 開發(fā) MCP 服務并發(fā)布到 Maven 中央倉庫完整指南的文章就介紹到這了,更多相關java mcp服務發(fā)布maven 中央倉庫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 詳解servlet的url-pattern匹配規(guī)則

    詳解servlet的url-pattern匹配規(guī)則

    本篇文章主要介紹了=servlet的url-pattern匹配規(guī)則,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • SpringBoot SSMP 整合案例分享

    SpringBoot SSMP 整合案例分享

    這篇文章主要介紹了SpringBoot SSMP 整合案例分享,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-08-08
  • Java中StopWatch的使用示例詳解

    Java中StopWatch的使用示例詳解

    stopWatch 是org.springframework.util 包下的一個工具類,使用它可直觀的輸出代碼執(zhí)行耗時,以及執(zhí)行時間百分比,這篇文章主要介紹了Java中StopWatch的使用詳解,需要的朋友可以參考下
    2025-04-04
  • java獲取文件路徑所有方式的詳細介紹

    java獲取文件路徑所有方式的詳細介紹

    在Java編程中我們經(jīng)常需要獲取文件的路徑,以便對文件進行讀取、寫入或其他操作,這篇文章主要介紹了java獲取文件路徑所有方式的相關資料,需要的朋友可以參考下
    2025-08-08
  • MyBatis在mapper中傳遞參數(shù)的四種方式

    MyBatis在mapper中傳遞參數(shù)的四種方式

    MyBatis是一個持久層框架,它提供了一種將數(shù)據(jù)庫操作與Java對象之間的映射關系進行配置的方式,在MyBatis中,Mapper是用于定義數(shù)據(jù)庫操作的接口,而參數(shù)傳遞則是通過Mapper接口的方法來實現(xiàn)的,本文給大家介紹了MyBatis在mapper中傳遞參數(shù)的四種方式,需要的朋友可以參考下
    2024-03-03
  • java實現(xiàn)圖書館管理系統(tǒng)

    java實現(xiàn)圖書館管理系統(tǒng)

    這篇文章主要為大家詳細介紹了java實現(xiàn)圖書館管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • java+selenium實現(xiàn)滑塊驗證

    java+selenium實現(xiàn)滑塊驗證

    現(xiàn)在越來越多的網(wǎng)站都使用采用滑塊驗證來作為驗證機制,用于判斷用戶是否為人類而不是機器人,本文就將利用java和selenium實現(xiàn)滑塊驗證,希望對大家有所幫助
    2023-12-12
  • Spring Boot 應用程序中配置使用consul的方法

    Spring Boot 應用程序中配置使用consul的方法

    配置是 Spring Boot 應用程序中的一部分,主要用于配置服務端口、應用名稱、Consul 服務發(fā)現(xiàn)以及健康檢查等功能,下面給大家介紹Spring Boot 應用程序中配置使用consul,感興趣的朋友一起看看吧
    2025-04-04
  • 深入淺析Spring 的aop實現(xiàn)原理

    深入淺析Spring 的aop實現(xiàn)原理

    AOP(Aspect-OrientedProgramming,面向方面編程),可以說是OOP(Object-Oriented Programing,面向?qū)ο缶幊蹋┑难a充和完善。本文給大家介紹Spring 的aop實現(xiàn)原理,感興趣的朋友一起學習吧
    2016-03-03
  • springmvc接收參數(shù)為日期類型詳解

    springmvc接收參數(shù)為日期類型詳解

    這篇文章主要介紹了springmvc接收參數(shù)為日期類型,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-09-09

最新評論

峡江县| 青田县| 建湖县| 新巴尔虎左旗| 衡南县| 永仁县| 平原县| 云南省| 临湘市| 肇庆市| 永和县| 兴业县| 墨竹工卡县| 富源县| 正安县| 汽车| 沁阳市| 兴化市| 嘉善县| 怀来县| 南充市| 鸡西市| 宜兰市| 渭南市| 蕉岭县| 彭泽县| 临潭县| 垫江县| 南木林县| 柳河县| 乌拉特后旗| 太白县| 西充县| 沁阳市| 驻马店市| 彝良县| 明溪县| 土默特左旗| 丹凤县| 汉沽区| 南投县|