场景二:开发全新的领域 MCP 服务

示例:开发一个“地理编码”服务,允许用户配置不同的POI数据源来发布多个地理编码实例。因为涉及新增MCP服务,所以在此需完整实现提供者层、组件层、MCP工具层三层,按以下步骤操作。开始前请先完成开发准备中的示例工程获取与 Maven 项目配置。

步骤 1:实现提供者 (Provider) 层

这一层负责对接数据源,地理编码服务需要两个类:

  • 配置类GeocodingProviderSetting.java:定义需要从配置文件中读取的参数(比如 POI 数据路径)

package com.supermap.mcp.extension.provider;
public class GeocodingProviderSetting {
public String dataPath; // POI数据文件路径
}

  • 实现类GeocodingProvider.java:实现ProviderContextAware接口,加载数据并提供查询方法

package com.supermap.mcp.extension.provider;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.supermap.services.components.spi.ProviderContext;
import com.supermap.services.components.spi.ProviderContextAware;

// Provider实现,负责加载和查询数据
public class GeocodingProvider implements ProviderContextAware {
private Map<String, String> mockData = new ConcurrentHashMap<>();
// 模拟查询
public String findCoordinate(String address) {
return mockData.getOrDefault(address, "未找到地址");
}
@Override
public void setProviderContext(ProviderContext context) {
GeocodingProviderSetting providerSetting = context.getConfig(GeocodingProviderSetting.class);
System.out.println("正在从路径加载地理编码数据: " + providerSetting.dataPath);
// 模拟加载数据
mockData.put("超图软件", "116.4,39.9");
mockData.put("故宫", "116.39,39.91");
}
}

注意:

Provider 实现中必须实现 com.supermap.services.components.spi.ProviderContextAware 接口。这是从用户 mcp-services.xml 配置中动态获取 <config> 参数的唯一途径。

步骤 2:实现组件 (Component) 层

这一层负责组织业务逻辑,创建GeocodingImpl.java类,实现ComponentContextAware接口

package com.supermap.mcp.extension.component;

import java.util.List;
import org.apache.commons.collections4.CollectionUtils;
import com.supermap.mcp.extension.provider.GeocodingProvider;
import com.supermap.services.components.Component;
import com.supermap.services.components.ComponentContext;
import com.supermap.services.components.ComponentContextAware;

// 服务组件,封装核心业务逻辑
@Component(providerTypes = {GeocodingProvider.class}, optional = false, type = "Geocoding")
public class GeocodingImpl implements ComponentContextAware {
GeocodingProvider provider = null;
public String geocode(String address) {
if (provider != null) {
return provider.findCoordinate(address);
}
return "Provider未找到";
}
@Override
public void setComponentContext(ComponentContext context) {
List<GeocodingProvider> providers = context.getProviders(GeocodingProvider.class);
if (CollectionUtils.isNotEmpty(providers)) {
provider = providers.get(0);
}
}
}

注意:

Component 实现中必须实现 com.supermap.services.components.ComponentContextAware 接口。通过此接口的 setComponentContext 方法,您可以在运行时获取到XML中为其配置的Provider实例。

步骤 3:实现 MCP 工具层

创建GeocodingTools.java类,实现McpToolMaterial接口,把组件方法适配成 AI 可调用的工具

package com.supermap.mcp.extension.tool;

import java.util.List;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import com.supermap.mcp.extension.component.GeocodingImpl;
import com.supermap.services.mcp.McpContext;
import com.supermap.services.mcp.material.McpToolMaterial;

// MCP工具类,将业务方法暴露给AI
public class GeocodingTools implements McpToolMaterial {
private GeocodingImpl geocodingComponent;

@Override
public boolean init(McpContext context) {
List<?> bizComponents = context.getBizComponents();
bizComponents.stream()
.filter(c -> c instanceof GeocodingImpl)
.findFirst()
.ifPresent(c -> this.geocodingComponent = (GeocodingImpl) c);
return this.geocodingComponent != null;
}

@Override
public String mcpModuleName() {
return "mcp-geocoding";
}

@Tool(description = "geocode.description")
public String geocode(@ToolParam(description = "geocode.params.address") String address) {
return geocodingComponent.geocode(address);
}
}

步骤 4:声明新服务模块

在src/main/resources/META-INF/services/mcp/目录下,创建mcp-geocoding.properties文件,来声明新服务模块

# 模块唯一名称
mcp.moduleName=mcp-geocoding

# 关键!使用 mcp.bizComponentType 定义这是一个新的服务组件类型。
# 框架会根据这个声明,将 GeocodingImpl 识别为一个可被实例化的服务类别。
mcp.bizComponentType=com.supermap.mcp.extension.component.GeocodingImpl

# 声明此服务类型对应的MCP工具实现
mcp.tool.impls=com.supermap.mcp.extension.tool.GeocodingTools

步骤 5:添加国际化描述

为了让 AI 理解工具功能,需要提供中英文描述的YAML文件,该文件名称必须遵循特定格式:{模块名}_{语言}.yaml。

  • {模块名}:即您在 .properties 文件中定义的 mcp.bizComponentType。
  • {语言}:zh 代表中文,en 代表英文。

在src/main/resources/META-INF/services/mcp/tools/目录下,创建mcp-geocoding_zh.yaml

geocode:
description: 获取指定地点的地理编码
params:
address: 地址

同理创建mcp-geocoding_en.yaml,替换对应文字即可。

步骤 6:打包扩展成果

  • 在项目根目录下执行 mvn clean install,这将在 target/ 目录下生成扩展的核心JAR包(例如 mcp-service-extension-1.0-SNAPSHOT.jar)。
  • 如果您的项目引入了 third-party-dependencies.txt 中不存在的第三方依赖,请执行 mvn dependency:copy-dependencies -DincludeScope=runtime,这会将这些依赖JAR包复制到 target/dependency/ 目录下。

步骤 7:部署、集成与测试

1、部署扩展包:

  • 将 mcp-service-extension-1.0-SNAPSHOT.jar 及其所有第三方依赖(如果存在于 target/dependency/ 目录)复制到 AgentX Server 的 cfg/iserver_mcp/extensions 目录下。

2、配置服务实例:

  • 在 AgentX Server 的 cfg/iserver_mcp/config 目录下,创建或编辑 mcp-services.xml 文件。
  • 在此文件中,您可以根据需要,利用您开发的 GeocodingImpl 组件和 GeocodingProvider 提供者,发布一个或多个地理编码服务实例。

<?xml version="1.0" encoding="UTF-8"?>
<application>
<components>
<!-- 实例一:北京地理编码服务 -->
<component name="beijing-geocoder"
class="com.supermap.mcp.extension.component.GeocodingImpl"
interfaceNames="mcp"
enabled="true"
providers="beijing-geocoder-provider"/>

<!-- 实例二:上海地理编码服务 -->
<component name="shanghai-geocoder"
class="com.supermap.mcp.extension.component.GeocodingImpl"
interfaceNames="mcp"
enabled="true"
providers="shanghai-geocoder-provider"/>
</components>

<providers>
<!-- 北京实例的Provider,指向北京的数据 -->
<provider name="beijing-geocoder-provider"
enabled="true"
class="com.supermap.mcp.extension.provider.GeocodingProvider">
<config class="com.supermap.mcp.extension.provider.GeocodingProviderSetting">
<dataPath>/data/gis/beijing_poi.udb</dataPath>
</config>
</provider>

<!-- 上海实例的Provider,指向上海的数据 -->
<provider name="shanghai-geocoder-provider"
enabled="true"
class="com.supermap.mcp.extension.provider.GeocodingProvider">
<config class="com.supermap.mcp.extension.provider.GeocodingProviderSetting">
<dataPath>/data/gis/shanghai_poi.udb</dataPath>
</config>
</provider>
</providers>
</application>

3、重启服务节点:

重启 iserver-mcp-server Docker 节点。

4、访问新服务:

重启后,mcp-services.xml 中配置的两个全新MCP服务将自动发布并可用,其访问地址分别为:

.../agentx/services/beijing-geocoder/mcp

.../agentx/services/shanghai-geocoder/mcp