@@ -44,7 +44,7 @@ MCP服务器可以提供三种主要功能:
4444本教程将主要关注工具。
4545
4646
47- <Tabs items = { [' Python' , ' Node' , ' Java' ,' Kotlin' ,' C#' ]} >
47+ <Tab items = { [' Python' , ' Node' , ' Java' ,' Kotlin' ,' C#' ]} >
4848 <Tab title = " Python" >
4949 让我们开始构建我们的天气服务器吧!【你可以在这里找到我们将要构建的完整代码。] ( https://github.com/modelcontextprotocol/quickstart-resources/tree/main/weather-server-python )
5050
@@ -1073,7 +1073,7 @@ MCP服务器可以提供三种主要功能:
10731073 它展示了如何使用Spring Boot的自动配置功能定义和注册MCP工具、资源和提示。
10741074 </Tab >
10751075
1076- <Tab title = " Kotlin" >
1076+ < title="Kotlin">
10771077 让我们开始构建我们的天气服务器吧![ 你可以在这里找到我们将要构建的完整代码。] ( https://github.com/modelcontextprotocol/kotlin-sdk/tree/main/samples/weather-stdio-server )
10781078
10791079 ### 必备知识
@@ -1257,212 +1257,212 @@ MCP服务器可以提供三种主要功能:
12571257 }
12581258 }
12591259
1260+ @Serializable
1261+ data class Points (
1262+ val properties : Properties
1263+ ) {
12601264 @Serializable
1261- data class Points (
1262- val properties : Properties
1263- ) {
1264- @Serializable
1265- data class Properties (val forecast : String )
1266- }
1265+ data class Properties (val forecast : String )
1266+ }
1267+
1268+ @Serializable
1269+ data class Forecast (
1270+ val properties : Properties
1271+ ) {
1272+ @Serializable
1273+ data class Properties (val periods : List <Period >)
12671274
12681275 @Serializable
1269- data class Forecast (
1270- val properties : Properties
1271- ) {
1276+ data class Period (
1277+ val number : Int , val name : String , val startTime : String , val endTime : String ,
1278+ val isDaytime : Boolean , val temperature : Int , val temperatureUnit : String ,
1279+ val temperatureTrend : String , val probabilityOfPrecipitation : JsonObject ,
1280+ val windSpeed : String , val windDirection : String ,
1281+ val shortForecast : String , val detailedForecast : String ,
1282+ )
1283+ }
1284+
1285+ @Serializable
1286+ data class Alert (
1287+ val features : List <Feature >
1288+ ) {
12721289 @Serializable
1273- data class Properties (val periods : List <Period >)
1274-
1275- @Serializable
1276- data class Period (
1277- val number : Int , val name : String , val startTime : String , val endTime : String ,
1278- val isDaytime : Boolean , val temperature : Int , val temperatureUnit : String ,
1279- val temperatureTrend : String , val probabilityOfPrecipitation : JsonObject ,
1280- val windSpeed : String , val windDirection : String ,
1281- val shortForecast : String , val detailedForecast : String ,
1282- )
1283- }
1290+ data class Feature (
1291+ val properties : Properties
1292+ )
12841293
12851294 @Serializable
1286- data class Alert (
1287- val features : List <Feature >
1288- ) {
1289- @Serializable
1290- data class Feature (
1291- val properties : Properties
1292- )
1295+ data class Properties (
1296+ val event : String , val areaDesc : String , val severity : String ,
1297+ val description : String , val instruction : String? ,
1298+ )
1299+ }
1300+ ```
12931301
1294- @Serializable
1295- data class Properties (
1296- val event : String , val areaDesc : String , val severity : String ,
1297- val description : String , val instruction : String? ,
1298- )
1299- }
1300- ```
1302+ ### 执行工具
13011303
1302- ### 执行工具
1304+ 工具执行处理程序负责实际执行每个工具的逻辑。让我们添加它:
13031305
1304- 工具执行处理程序负责实际执行每个工具的逻辑。让我们添加它:
13051306
1307+ ``` kotlin
1308+ // Create an HTTP client with a default request configuration and JSON content negotiation
1309+ val httpClient = HttpClient {
1310+ defaultRequest {
1311+ url(" https://api.weather.gov" )
1312+ headers {
1313+ append(" Accept" , " application/geo+json" )
1314+ append(" User-Agent" , " WeatherApiClient/1.0" )
1315+ }
1316+ contentType(ContentType .Application .Json )
1317+ }
1318+ // Install content negotiation plugin for JSON serialization/deserialization
1319+ install(ContentNegotiation ) { json(Json { ignoreUnknownKeys = true }) }
1320+ }
13061321
1307- ``` kotlin
1308- // Create an HTTP client with a default request configuration and JSON content negotiation
1309- val httpClient = HttpClient {
1310- defaultRequest {
1311- url(" https://api.weather.gov" )
1312- headers {
1313- append(" Accept" , " application/geo+json" )
1314- append(" User-Agent" , " WeatherApiClient/1.0" )
1315- }
1316- contentType(ContentType .Application .Json )
1317- }
1318- // Install content negotiation plugin for JSON serialization/deserialization
1319- install(ContentNegotiation ) { json(Json { ignoreUnknownKeys = true }) }
1322+ // Register a tool to fetch weather alerts by state
1323+ server.addTool(
1324+ name = " get_alerts" ,
1325+ description = """
1326+ Get weather alerts for a US state. Input is Two-letter US state code (e.g. CA, NY)
1327+ """ .trimIndent(),
1328+ inputSchema = Tool .Input (
1329+ properties = buildJsonObject {
1330+ putJsonObject(" state" ) {
1331+ put(" type" , " string" )
1332+ put(" description" , " Two-letter US state code (e.g. CA, NY)" )
1333+ }
1334+ },
1335+ required = listOf (" state" )
1336+ )
1337+ ) { request ->
1338+ val state = request.arguments[" state" ]?.jsonPrimitive?.content
1339+ if (state == null ) {
1340+ return @addTool CallToolResult (
1341+ content = listOf (TextContent (" The 'state' parameter is required." ))
1342+ )
13201343 }
13211344
1322- // Register a tool to fetch weather alerts by state
1345+ val alerts = httpClient.getAlerts(state)
1346+
1347+ CallToolResult (content = alerts.map { TextContent (it) })
1348+ }
1349+
1350+ // Register a tool to fetch weather forecast by latitude and longitude
13231351 server.addTool(
1324- name = " get_alerts " ,
1352+ name = " get_forecast " ,
13251353 description = """
1326- Get weather alerts for a US state. Input is Two-letter US state code (e.g. CA, NY)
1354+ Get weather forecast for a specific latitude/longitude
13271355 """ .trimIndent(),
13281356 inputSchema = Tool .Input (
13291357 properties = buildJsonObject {
1330- putJsonObject(" state" ) {
1331- put(" type" , " string" )
1332- put(" description" , " Two-letter US state code (e.g. CA, NY)" )
1333- }
1334- },
1335- required = listOf (" state" )
1358+ putJsonObject(" latitude" ) { put(" type" , " number" ) }
1359+ putJsonObject(" longitude" ) { put(" type" , " number" ) }
1360+ },
1361+ required = listOf (" latitude" , " longitude" )
13361362 )
13371363 ) { request ->
1338- val state = request.arguments[" state" ]?.jsonPrimitive?.content
1339- if (state == null ) {
1340- return @addTool CallToolResult (
1341- content = listOf (TextContent (" The 'state' parameter is required." ))
1342- )
1343- }
1344-
1345- val alerts = httpClient.getAlerts(state)
1346-
1347- CallToolResult (content = alerts.map { TextContent (it) })
1348- }
1349-
1350- // Register a tool to fetch weather forecast by latitude and longitude
1351- server.addTool(
1352- name = " get_forecast" ,
1353- description = """
1354- Get weather forecast for a specific latitude/longitude
1355- """ .trimIndent(),
1356- inputSchema = Tool .Input (
1357- properties = buildJsonObject {
1358- putJsonObject(" latitude" ) { put(" type" , " number" ) }
1359- putJsonObject(" longitude" ) { put(" type" , " number" ) }
1360- },
1361- required = listOf (" latitude" , " longitude" )
1362- )
1363- ) { request ->
1364- val latitude = request.arguments[" latitude" ]?.jsonPrimitive?.doubleOrNull
1365- val longitude = request.arguments[" longitude" ]?.jsonPrimitive?.doubleOrNull
1366- if (latitude == null || longitude == null ) {
1367- return @addTool CallToolResult (
1368- content = listOf (TextContent (" The 'latitude' and 'longitude' parameters are required." ))
1369- )
1370- }
1364+ val latitude = request.arguments[" latitude" ]?.jsonPrimitive?.doubleOrNull
1365+ val longitude = request.arguments[" longitude" ]?.jsonPrimitive?.doubleOrNull
1366+ if (latitude == null || longitude == null ) {
1367+ return @addTool CallToolResult (
1368+ content = listOf (TextContent (" The 'latitude' and 'longitude' parameters are required." ))
1369+ )
1370+ }
13711371
1372- val forecast = httpClient.getForecast(latitude, longitude)
1372+ val forecast = httpClient.getForecast(latitude, longitude)
13731373
1374- CallToolResult (content = forecast.map { TextContent (it) })
1375- }
1376- ```
1374+ CallToolResult (content = forecast.map { TextContent (it) })
1375+ }
1376+ ```
13771377
1378- ### 运行服务
1378+ ### 运行服务
13791379
1380- 最后,实现运行服务器的主要功能:
1380+ 最后,实现运行服务器的主要功能:
13811381
1382- ``` kotlin
1383- fun main () = `run mcp server`()
1384- ```
1382+ ``` kotlin
1383+ fun main () = `run mcp server`()
1384+ ```
13851385
1386- 一定要跑` /gradlew build ` 来构建你的服务器。这是让服务器连接的一个非常重要的步骤。
1386+ 一定要跑` /gradlew build ` 来构建你的服务器。这是让服务器连接的一个非常重要的步骤。
13871387
1388- 现在让我们从现有的MCP主机Claude for Desktop测试您的服务器。
1388+ 现在让我们从现有的MCP主机Claude for Desktop测试您的服务器。
13891389
1390- ## 使用Claude for Desktop测试您的服务器
1390+ ## 使用Claude for Desktop测试您的服务器
13911391
1392- <Note >
1393- Claude for Desktop尚未在Linux上可用。Linux用户可以继续学习[ 构建客户端] (https://mcp.thinkinai.xyz/docs/quick-start/client-developers)教程,以构建一个连接到我们刚刚构建的服务器的MCP客户端。
1394- </Note >
1392+ <Note >
1393+ Claude for Desktop尚未在Linux上可用。Linux用户可以继续学习[ 构建客户端] (https://mcp.thinkinai.xyz/docs/quick-start/client-developers)教程,以构建一个连接到我们刚刚构建的服务器的MCP客户端。
1394+ </Note >
13951395
1396- 首先,确保您安装了Claude for Desktop。[ 您可以安装最新版本在这里。] ( https://claude.ai/download ) 如果您已经拥有Claude for Desktop,** 请确保它已更新到最新版本**
1396+ 首先,确保您安装了Claude for Desktop。[ 您可以安装最新版本在这里。] ( https://claude.ai/download ) 如果您已经拥有Claude for Desktop,** 请确保它已更新到最新版本**
13971397
1398- 我们需要为您想要使用的任何MCP服务器配置Claude for Desktop。
1399- ` ~/Library/ApplicationSupport/Claude/Claude_Desktop_config.json ` 的Claude for Desktop App配置。
1398+ 我们需要为您想要使用的任何MCP服务器配置Claude for Desktop。
1399+ ` ~/Library/ApplicationSupport/Claude/Claude_Desktop_config.json ` 的Claude for Desktop App配置。
14001400
1401- 如果文件不存在,请确保创建该文件。
1401+ 如果文件不存在,请确保创建该文件。
14021402
1403- 例如,如果你有[ VS code] ( https://code.visualstudio.com/ ) 已安装:
1403+ 例如,如果你有[ VS code] ( https://code.visualstudio.com/ ) 已安装:
14041404
1405- <CodeGroup >
1406- <CodeGroupItem title = " JSON" >
1407- ``` bash MacOS/Linux
1408- code ~ /Library/Application\ Support/Claude/claude_desktop_config.json
1409- ```
1410- </CodeGroupItem >
1405+ <CodeGroup >
1406+ <CodeGroupItem title = " JSON" >
1407+ ``` bash MacOS/Linux
1408+ code ~ /Library/Application\ Support/Claude/claude_desktop_config.json
1409+ ```
1410+ </CodeGroupItem >
14111411
1412- <CodeGroupItem title = " PowerShell" >
1413- ``` powershell Windows
1414- code $env:AppData\Claude\claude_desktop_config.json
1415- ```
1416- </CodeGroupItem >
1417- </CodeGroup >
1412+ <CodeGroupItem title = " PowerShell" >
1413+ ``` powershell Windows
1414+ code $env:AppData\Claude\claude_desktop_config.json
1415+ ```
1416+ </CodeGroupItem >
1417+ </CodeGroup >
14181418
1419- 然后,您将在` mcpServers ` 键中添加服务器。
1419+ 然后,您将在` mcpServers ` 键中添加服务器。
14201420
1421- 如果至少有一台服务器配置正确,MCP UI元素将仅显示在Claude for Desktop中。
1421+ 如果至少有一台服务器配置正确,MCP UI元素将仅显示在Claude for Desktop中。
14221422
1423- 在这种情况下,我们将添加单个天气服务器,如下所示:
1423+ 在这种情况下,我们将添加单个天气服务器,如下所示:
14241424
1425- <CodeGroup >
1426- <CodeGroupItem title = " JSON" >
1427- ``` json MacOS/Linux
1428- {
1429- "mcpServers" : {
1430- "weather" : {
1431- "command" : " java" ,
1432- "args" : [
1433- " -jar" ,
1434- " /ABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/libs/weather-0.1.0-all.jar"
1435- ]
1436- }
1437- }
1425+ <CodeGroup >
1426+ <CodeGroupItem title = " JSON" >
1427+ ``` json MacOS/Linux
1428+ {
1429+ "mcpServers" : {
1430+ "weather" : {
1431+ "command" : " java" ,
1432+ "args" : [
1433+ " -jar" ,
1434+ " /ABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/libs/weather-0.1.0-all.jar"
1435+ ]
14381436 }
1439- ```
1440- </CodeGroupItem >
1437+ }
1438+ }
1439+ ```
1440+ </CodeGroupItem >
14411441
1442- <CodeGroupItem title = " JSON" >
1443- ``` json Windows
1444- {
1445- "mcpServers" : {
1446- "weather" : {
1447- "command" : " java" ,
1448- "args" : [
1449- " -jar" ,
1450- " C:\\ PATH\\ TO\\ PARENT\\ FOLDER\\ weather\\ build\\ libs\\ weather-0.1.0-all.jar"
1451- ]
1452- }
1453- }
1442+ <CodeGroupItem title = " JSON" >
1443+ ``` json Windows
1444+ {
1445+ "mcpServers" : {
1446+ "weather" : {
1447+ "command" : " java" ,
1448+ "args" : [
1449+ " -jar" ,
1450+ " C:\\ PATH\\ TO\\ PARENT\\ FOLDER\\ weather\\ build\\ libs\\ weather-0.1.0-all.jar"
1451+ ]
14541452 }
1455- ```
1456- </CodeGroupItem >
1457- </CodeGroup >
1453+ }
1454+ }
1455+ ```
1456+ </CodeGroupItem >
1457+ </CodeGroup >
14581458
1459- 这将告诉Claude for Desktop:
1459+ 这将告诉Claude for Desktop:
14601460
1461- 1.有一个名为“天气”的MCP服务器
1461+ 1.有一个名为“天气”的MCP服务器
14621462
1463- 2.通过运行` java-jar/AABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/libs/weather-0.1.0-all.jar启动它 `
1463+ 2.通过运行` java-jar/AABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/libs/weather-0.1.0-all.jar启动它 `
14641464
1465- 保存文件,然后重新启动** Claude for Desktop** 。
1465+ 保存文件,然后重新启动** Claude for Desktop** 。
14661466 </Tab >
14671467
14681468 <Tab title = " C#" >
0 commit comments