使用说明
🌤️ Spring AI MCP服务器-天气服务
实施模型上下文协议(MCP)协议的天气信息提供服务器。 通过Claude Desktop和stdio通信连接,利用韩国气象厅官方API提供实时天气信息。
🎯 真正的MCP服务器是?
这个项目(真正的MCP)
Claude (AI) ──stdio/JSON-RPC 2.0──► MCP 서버 ──► 실제 로직 (날씨 API, 계산 등)
↑ │
└─── AI가 도구 선택/호출 ─────────────┘
- 通信方式:stdio(标准I/O)
- 协议:JSON-RPC 2.0
- AI位置:客户端(Claude Desktop)
- 服务器角色:仅提供工具(无AI)
通用AI聊天机器人后端(假MCP)
사용자 ──HTTP──► Spring 서버 ──► OpenAI API
│
└── 서버가 AI 호출
- 通信方式:REST API(HTTP)
- AI位置:服务器端(调用OpenAI)
- MCP协议:未使用
🚀 快速入门
1.要求事项
- Java 17或更高版本
- Gradle 8.5或更高版本
- Claude Desktop(MCP客户端)
- 气象厅API密钥(公共数据门户由颁发)
2.设置API密钥
2.1.API密钥发放
- 公共数据门户 连接
- 注册和登录会员
- 搜索“气象厅_短期预报查询服务”
- 单击申请使用
- 复制已颁发的验证密钥
2.2.注册API密钥
src/main/resources/application.yml 打开文件 service-key 更改值:
weather:
api:
service-key: YOUR_API_KEY_HERE
或设置为环境变量:
# Windows
set WEATHER_API_SERVICE_KEY=YOUR_API_KEY_HERE
# macOS/Linux
export WEATHER_API_SERVICE_KEY=YOUR_API_KEY_HERE
3.构建项目
# Windows
.\gradlew clean build
# macOS/Linux
./gradlew clean build
4.Claude桌面设置
视窗: %APPDATA%\Claude\claude_desktop_config.json 添加到文件:
{
"mcpServers": {
"weather": {
"command": "java",
"args": [
"-jar",
"-Dfile.encoding=UTF-8",
"C:\\workspace\\intellij\\mcp\\build\\libs\\mcp-0.0.1-SNAPSHOT.jar"
]
}
}
}
macOS/Linux: ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"weather": {
"command": "java",
"args": [
"-jar",
"-Dfile.encoding=UTF-8",
"/absolute/path/to/mcp/build/libs/mcp-0.0.1-SNAPSHOT.jar"
]
}
}
}
5.重新启动Claude Desktop
要应用设置,请完全退出并重新启动Claude Desktop。
6.使用
在Claude Desktop中,提出以下问题:
서울의 날씨를 알려줘
부산 날씨가 궁금해
위도 37.5665, 경도 126.9780의 초단기 예보를 알려줘
Claude自动调用MCP服务器上的工具,提供实时天气信息!
📦 项目结构
mcp/
├── src/
│ ├── main/
│ │ ├── java/dev/wony/mcp/
│ │ │ ├── McpApplication.java # Spring Boot 메인 클래스
│ │ │ └── tool/
│ │ │ ├── WeatherService.java # 날씨 조회 서비스
│ │ │ └── dto/
│ │ │ ├── GridCoordinate.java # 격자 좌표 변환
│ │ │ ├── WeatherApiResponse.java # API 응답 DTO
│ │ │ ├── WeatherCategory.java # 날씨 카테고리 enum
│ │ │ ├── WeatherInfo.java # 날씨 정보 DTO
│ │ │ └── KmaApiResponse.java # 기상청 API 응답
│ │ └── resources/
│ │ └── application.yml # 서버 설정 및 API 키
│ └── test/
│ └── java/dev/wony/mcp/tool/
│ ├── WeatherServiceTest.java # 단위 테스트
│ ├── WeatherServiceIntegrationTest.java # 통합 테스트
│ └── dto/
│ ├── GridCoordinateTest.java # 격자 변환 테스트
│ └── WeatherCategoryTest.java # 카테고리 테스트
├── docs/
│ ├── KMA_API_GUIDE.md # 기상청 API 가이드
│ └── WEATHER_API.md # 날씨 API 상세 문서
├── build.gradle # Gradle 빌드 설정
├── CLAUDE_SETUP.md # Claude Desktop 연동 가이드
└── README.md # 이 파일
🛠️ 提供的工具
1.超短期实况查询(getUltraStrtNcst)
提供以当前时间为基准的实况信息。
输入:
latitude(double):纬度(例如37.5665)longitude(double):硬度(例如126.9780)
输出:
=== 초단기실황 (위도: 37.5665, 경도: 126.9780) ===
발표시각: 20241126 1400
기온: 15.2℃
1시간 강수량: 0mm
습도: 65%
강수형태: 없음
풍향: N
풍속: 2.3m/s
发布时间:每小时准时(00:00,01:00,…,23:00)+10分钟后提供
2.超短期预报查询(getUltraStrtFcst)
提供6小时内的预报信息。
输入:
latitude(double):纬度longitude(double):硬度
输出:各时段预报(气温、降水、天空状态、风向、风速等)
发布时间:每小时30分钟(00:30,01:30,…,23:30)+15分钟后提供
3.短期预报查询(getVilageFcst)
提供3天预报信息。
输入:
latitude(double):纬度longitude(double):硬度
输出:3天时间段详细预报(气温、降水率、降水量、积雪、风向、风速、湿度等)
发布时间:每天8次(02、05、08、11、14、17、20、23时)+10分钟后提供
4.主要城市天气查询(getCurrentWeather)
使用城市名称轻松查询当前天气。
输入:
city(String):城市名(首尔、釜山、大邱、仁川、光州、大田、蔚山、世宗、济州之一)
输出:
📍 서울 현재 날씨 (기준시각: 11월 26일 14시)
🌡️ 기온: 15.2°C
🌧️ 1시간 강수량: 없음
💧 습도: 65%
💨 풍속: 2.3m/s
☔ 강수형태: 없음
5.查询支持城市列表(getSupportedCities)
返回可查询天气的城市列表。
输出:
날씨 조회 가능한 도시:
서울, 부산, 대구, 인천, 광주, 대전, 울산, 세종, 제주
主要城市坐标:
- 首尔:(37.5665,126.9780)
- 釜山:(35.1796,129.0756)
- 济州:(33.4996,126.5312)
- 大田:(36.3504,127.3845)
- 大邱:(35.8714,128.6014)
参考:纬度将自动转换为气象站网格坐标(nx,ny)。使用Lambert Conformal Conic Projection算法。
🔧 开发指南
添加新工具
src/main/java/dev/wony/mcp/tool/在目录中创建新的服务类@Service使用注释- 方法
@Tool添加注释 McpApplication.java在中注册Bean
示例:
package dev.wony.mcp.tool;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Service;
@Service
public class TranslationService {
@Tool(description = "Translate text to another language")
public String translate(
@ToolParam(description = "Text to translate") String text,
@ToolParam(description = "Target language (e.g., 'Korean', 'English')") String targetLanguage
) {
// 번역 로직 구현
return "Translated: " + text;
}
}
而且 McpApplication.java在中注册Bean:
@Bean
public ToolCallbackProvider translationTools(TranslationService translationService) {
return MethodToolCallbackProvider.builder().toolObjects(translationService).build();
}
外部API集成示例
@Service
public class NewsService {
@Value("${news.api.key}")
private String apiKey;
private final RestClient restClient;
public NewsService(@Value("${news.api.key}") String apiKey) {
this.apiKey = apiKey;
this.restClient = RestClient.builder()
.baseUrl("https://newsapi.org/v2")
.build();
}
@Tool(description = "Get latest news headlines")
public String getNews(
@ToolParam(description = "Country code (e.g., 'kr', 'us')") String country
) {
try {
NewsResponse response = restClient.get()
.uri(uriBuilder -> uriBuilder
.path("/top-headlines")
.queryParam("country", country)
.queryParam("apiKey", apiKey)
.build())
.retrieve()
.body(NewsResponse.class);
return formatNewsResponse(response);
} catch (RestClientException e) {
return "뉴스 조회 실패: " + e.getMessage();
}
}
}
🧪 测试
运行单元测试
# Windows
.\gradlew test
# macOS/Linux
./gradlew test
运行集成测试
集成测试调用实际气象站API,因此需要API密钥。
# Windows
.\gradlew test --tests "*IntegrationTest"
# macOS/Linux
./gradlew test --tests "*IntegrationTest"
测试覆盖率报告
.\gradlew test jacocoTestReport
报告: build/reports/jacoco/test/html/index.html
📚 技术堆栈
- Java 17:最新LTS版本
- 弹簧靴3.5.8:企业级框架
- 春季AI 1.1.0:实施MCP协议
- 8.5级:构建工具
- Rest客户端:HTTP客户端
- JUnit5和AssertJ:测试框架
解决问题
服务器未连接
- 验证路径:
claude_desktop_config.json验证的JAR路径是否正确 - 验证版本:
.\gradlew clean build重新构建到 - 检查日志:
- 窗户:
%APPDATA%\Claude\logs\ - macOS:
~/Library/Logs/Claude/
- 窗户:
工具不起作用
- 确认注释:
@Service哇@Tool确认是否全部存在 - 扫描包:
dev.wony.mcp.tool检查包中是否存在 - Bean注册:
McpApplication.java在ToolCallbackProvider验证Bean是否已注册 - 重新构建:代码更改后必须重新构建
API响应错误
- 验证API密钥:
application.yml确保在中设置了正确的API密钥 - 呼叫限制:气象局API有流量限制,请注意过度呼叫
- 发布时间:根据每个API的发布时间更新数据,以确认时间
Java版本错误
java -version # Java 17 이상 확인
如果没有Java 17 艾多普蒂姆请从下载。
🔍 MCP协议工作原理
1.初始化(Initialization)
当Claude Desktop启动MCP服务器时:
→ Claude: {"jsonrpc":"2.0","method":"initialize","params":{...},"id":1}
← Server: {"jsonrpc":"2.0","result":{"protocolVersion":"1.0.0"},"id":1}
2.查看工具列表
→ Claude: {"jsonrpc":"2.0","method":"tools/list","params":{},"id":2}
← Server: {
"jsonrpc":"2.0",
"result":{
"tools":[
{"name":"getUltraSrtNcst","description":"Get current weather observation..."},
{"name":"getUltraSrtFcst","description":"Get ultra short-term forecast..."},
{"name":"getVilageFcst","description":"Get short-term forecast..."},
{"name":"getCurrentWeather","description":"한국 주요 도시의 현재 날씨를 조회..."},
{"name":"getSupportedCities","description":"날씨 조회가 가능한 한국 주요 도시 목록..."}
]
},
"id":2
}
3.调用工具
→ Claude: {
"jsonrpc":"2.0",
"method":"tools/call",
"params":{
"name":"getCurrentWeather",
"arguments":{"city":"서울"}
},
"id":3
}
← Server: {
"jsonrpc":"2.0",
"result":"📍 서울 현재 날씨 (기준시각: 11월 26일 14시)\n\n🌡️ 기온: 15.2°C\n...",
"id":3
}
🔗 参考资料
📝 许可证
MIT许可证
🤝 贡献
请将错误报告或功能建议登记为问题!
由...制作❤️ 通过 dev.wony
该服务器实现了真正的MCP协议。不使用REST API或HTTP通信,直接通过Claude Desktop和stdio进行通信。