03.使用spring-ai玩转MCP

发布于:2025-05-01 ⋅ 阅读:(26) ⋅ 点赞:(0)


接着上篇: 02.使用cline(VSCode插件)、continue(IDEA插件)、cherry-studio玩转MCP,我们介绍了,什么是MCP?使用cline插件/cherry-studio安装了Mcp Server,本篇我们要借助spring-ai实现MCP Client和Server。

使用spring-ai的话,需要spring-boot3和JDK17。

MCP Server

  1. 引入mcp-server依赖
<properties>
	<java.version>17</java.version>
	<spring-ai.version>1.0.0-M7</spring-ai.version>
</properties>
<dependency>
	<groupId>org.springframework.ai</groupId>
	<artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
</dependency>
<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>
  1. 使用@Tool声明方法,使用@ToolParam声明参数
@Service
public class EchoService {
    /**
     * echo
     *
     * @param msg
     * @return String
     */
    @Tool(description = "echo")
    public String echo(@ToolParam(description = "消息") String msg) {
        return msg;
    }
}
  1. 将EchoService注入到ToolCallbackProvider
@Configuration
public class McpServerConfig {
    @Bean
    public ToolCallbackProvider allTools(EchoService echoService) {
        return MethodToolCallbackProvider.builder()
                .toolObjects(echoService)
                .build();
    }
}
  1. 单元测试
class ToolTest {
    private final static String url = "http://localhost:8899";
    private static McpSyncClient client;

    @BeforeAll
    public static void init() {
        var transport = new WebFluxSseClientTransport(WebClient.builder().baseUrl(url));
        client = McpClient.sync(transport).build();

        client.initialize();

        client.ping();
    }

    @Test
    public void test() {
        // List and demonstrate tools
        ListToolsResult toolsList = client.listTools();
        System.out.println("Available Tools = " + toolsList);

        CallToolResult echo = client.callTool(new CallToolRequest("echo",
                Map.of("msg", "hello world")));
        System.out.println("echo: " + echo);

        client.closeGracefully();
    }
}
  1. 扩展mcp-server不仅提供了tool,还有prompt和resource
@Configuration
public class PromptManagement {
    @Bean
    public List<McpServerFeatures.SyncPromptSpecification> myPrompts() {
        var prompt = new McpSchema.Prompt("greeting", "A friendly greeting prompt",
                List.of(new McpSchema.PromptArgument("name", "The name to greet", true)));

        var promptSpecification = new McpServerFeatures.SyncPromptSpecification(prompt, (exchange, getPromptRequest) -> {
            String nameArgument = (String) getPromptRequest.arguments().get("name");
            if (nameArgument == null) { nameArgument = "friend"; }
            var userMessage = new McpSchema.PromptMessage(McpSchema.Role.USER, new McpSchema.TextContent("Hello " + nameArgument + "! How can I assist you today?"));
            return new McpSchema.GetPromptResult("A personalized greeting message", List.of(userMessage));
        });

        return List.of(promptSpecification);
    }
}
@Configuration
public class ResourceManagement {
    @Bean
    public List<McpServerFeatures.SyncResourceSpecification> myResources() {
        var systemInfoResource = new McpSchema.Resource("file:///logs/app.log", "Application Logs", "Application Logs", "text/plain",
                new McpSchema.Annotations(List.of(McpSchema.Role.USER), 1.0));
        var resourceSpecification = new McpServerFeatures.SyncResourceSpecification(systemInfoResource, (exchange, request) -> {
            try {
                var systemInfo = Map.of();
                String jsonContent = new ObjectMapper().writeValueAsString(systemInfo);
                return new McpSchema.ReadResourceResult(
                        List.of(new McpSchema.TextResourceContents(request.uri(), "application/json", jsonContent)));
            } catch (Exception e) {
                throw new RuntimeException("Failed to generate system info", e);
            }
        });

        return List.of(resourceSpecification);
    }
}

参考前面的单元测试:client.listTools(),下面两种应该也不在话下。
在这里插入图片描述

MCP Client

  1. 引入mcp-client依赖
<properties>
	<java.version>17</java.version>
	<spring-ai.version>1.0.0-M7</spring-ai.version>
</properties>

<!-- web&webflux start -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- web&webflux end -->

<!-- model start -->
<dependency>
	<groupId>org.springframework.ai</groupId>
	<artifactId>spring-ai-starter-model-ollama</artifactId>
</dependency>
<!--		<dependency>-->
<!--			<groupId>org.springframework.ai</groupId>-->
<!--			<artifactId>spring-ai-starter-model-openai</artifactId>-->
<!--		</dependency>-->
<!-- model end -->

<!-- MCP start -->
<dependency>
	<groupId>org.springframework.ai</groupId>
	<artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.ai</groupId>
	<artifactId>spring-ai-starter-mcp-client-webflux</artifactId>
</dependency>
<!-- MCP end -->

<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>
  1. 在application.properties配置stdio方式的mcp-server
spring.ai.mcp.client.stdio.servers-configuration=classpath:/mcp-servers-config.json

发没发现,配置和之前的cline/cherry studio等客户端一致,mcp-servers-config.json如下:

{
  "mcpServers": {
    "time": {
      "command": "cmd",
      "args": [
        "/c",
        "uvx",
        "mcp-server-time",
        "--local-timezone=Asia/Shanghai"
      ]
    },
    "filesystem": {
      "command": "cmd",
      "args": [
        "/c",
        "npx",
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "D:\\SourceCode\\bsp-mcp"
      ]
    }
  }
}
  1. 在application.yaml配置模型和sse方式的mcp-server
spring:
  ai:
    ollama:
      base-url: http://192.168.199.255:11434
      chat:
        options:
          model: qwen2.5:32b
    mcp:
      client:
        toolcallback:
          enabled: true
        sse:
          connections:
            amap:
              url: https://mcp.amap.com?key=xxx
            my:
              url: http://localhost:8899
  1. 配置模型集成MCP
    ChatModel是对话模型,常见的还有Embedding是关于RAG的。
    在这里插入图片描述
    OllamaChatModel是支持function call的,我们就以它为例。
    在这里插入图片描述
    来自:https://docs.spring.io/spring-ai/reference/api/index.html#_ai_model_api
@Configuration
public class ChatClientConfig {
    @Bean
    public ChatClient client(OllamaChatModel ollamaChatModel,
                             SyncMcpToolCallbackProvider syncMcpToolCallbackProvider) {
        return ChatClient.builder(ollamaChatModel)
                .defaultTools(syncMcpToolCallbackProvider)
                .build();
    }
}
  1. 对外提供API
@RequiredArgsConstructor
@RestController
public class MCPController {
    private final ChatClient client;
    private final List<McpSyncClient> mcpClientList;

    @GetMapping("/ai/mcp/generate")
    public Map<String, String> generate(@RequestParam(value = "message", defaultValue = "几点了?") String message) {
        return Map.of("generation", client.prompt(message).call().content());
    }

    @GetMapping("/ai/mcp/servers")
    public List<McpSyncClient> servers() {
        return mcpClientList;
    }

    @GetMapping("/ai/mcp/tools")
    public McpSchema.ListToolsResult tools(String name) {
        return mcpClientList.stream().filter(mcpSyncClient ->
                StringUtils.endsWithIgnoreCase(name, mcpSyncClient.getServerInfo().name())
        ).findFirst().get().listTools();
    }

    @GetMapping("/ai/mcp/resources")
    public McpSchema.ListResourcesResult resources(String name) {
        return mcpClientList.stream().filter(mcpSyncClient ->
                StringUtils.endsWithIgnoreCase(name, mcpSyncClient.getServerInfo().name())
        ).findFirst().get().listResources();
    }

    @GetMapping("/ai/mcp/prompts")
    public McpSchema.ListPromptsResult prompts(String name) {
        return mcpClientList.stream().filter(mcpSyncClient ->
                StringUtils.endsWithIgnoreCase(name, mcpSyncClient.getServerInfo().name())
        ).findFirst().get().listPrompts();
    }
}

抓包分析交互流程

在这里插入图片描述
来自:https://docs.spring.io/spring-ai/reference/api/index.html#_tool_calling_api

下面是使用wireshark抓的包,我们来一一分析下:
在这里插入图片描述

  1. 将用户提示词和工具交给大模型,让其选择工具
{
    "messages": [
        {
            "content": "现在几点了?",
            "role": "user"
        }
    ],
    "model": "qwen2.5:3b",
    "options": {
    },
    "stream": false,
    "tools": [
        {
            "function": {
                "description": "Read the complete contents of a file from the file system. Handles various text encodings and provides detailed error messages if the file cannot be read. Use this tool when you need to examine the contents of a single file. Only works within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_read_file",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "path": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "path"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Read the contents of multiple files simultaneously. This is more efficient than reading files one by one when you need to analyze or compare multiple files. Each file's content is returned with its path as a reference. Failed reads for individual files won't stop the entire operation. Only works within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_read_multiple_files",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "paths": {
                            "items": {
                                "type": "string"
                            },
                            "type": "array"
                        }
                    },
                    "required": [
                        "paths"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Create a new file or completely overwrite an existing file with new content. Use with caution as it will overwrite existing files without warning. Handles text content with proper encoding. Only works within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_write_file",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "content": {
                            "type": "string"
                        },
                        "path": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "path",
                        "content"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Make line-based edits to a text file. Each edit replaces exact line sequences with new content. Returns a git-style diff showing the changes made. Only works within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_edit_file",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "dryRun": {
                            "default": false,
                            "description": "Preview changes using git-style diff format",
                            "type": "boolean"
                        },
                        "edits": {
                            "items": {
                                "additionalProperties": false,
                                "properties": {
                                    "newText": {
                                        "description": "Text to replace with",
                                        "type": "string"
                                    },
                                    "oldText": {
                                        "description": "Text to search for - must match exactly",
                                        "type": "string"
                                    }
                                },
                                "required": [
                                    "oldText",
                                    "newText"
                                ],
                                "type": "object"
                            },
                            "type": "array"
                        },
                        "path": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "path",
                        "edits"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Create a new directory or ensure a directory exists. Can create multiple nested directories in one operation. If the directory already exists, this operation will succeed silently. Perfect for setting up directory structures for projects or ensuring required paths exist. Only works within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_create_directory",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "path": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "path"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Get a detailed listing of all files and directories in a specified path. Results clearly distinguish between files and directories with [FILE] and [DIR] prefixes. This tool is essential for understanding directory structure and finding specific files within a directory. Only works within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_list_directory",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "path": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "path"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Get a recursive tree view of files and directories as a JSON structure. Each entry includes 'name', 'type' (file/directory), and 'children' for directories. Files have no children array, while directories always have a children array (which may be empty). The output is formatted with 2-space indentation for readability. Only works within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_directory_tree",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "path": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "path"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Move or rename files and directories. Can move files between directories and rename them in a single operation. If the destination exists, the operation will fail. Works across different directories and can be used for simple renaming within the same directory. Both source and destination must be within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_move_file",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "destination": {
                            "type": "string"
                        },
                        "source": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "source",
                        "destination"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Recursively search for files and directories matching a pattern. Searches through all subdirectories from the starting path. The search is case-insensitive and matches partial names. Returns full paths to all matching items. Great for finding files when you don't know their exact location. Only searches within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_search_files",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "excludePatterns": {
                            "default": [
                            ],
                            "items": {
                                "type": "string"
                            },
                            "type": "array"
                        },
                        "path": {
                            "type": "string"
                        },
                        "pattern": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "path",
                        "pattern"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Retrieve detailed metadata about a file or directory. Returns comprehensive information including size, creation time, last modified time, permissions, and type. This tool is perfect for understanding file characteristics without reading the actual content. Only works within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_get_file_info",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "path": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "path"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Returns the list of directories that this server is allowed to access. Use this to understand which directories are available before trying to access files.",
                "name": "spring_ai_mcp_client_filesystem_list_allowed_directories",
                "parameters": {
                    "properties": {
                    },
                    "required": [
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Get current time in a specific timezones",
                "name": "spring_ai_mcp_client_time_get_current_time",
                "parameters": {
                    "properties": {
                        "timezone": {
                            "description": "IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'Asia/Shanghai' as local timezone if no timezone provided by the user.",
                            "type": "string"
                        }
                    },
                    "required": [
                        "timezone"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Convert time between timezones",
                "name": "spring_ai_mcp_client_time_convert_time",
                "parameters": {
                    "properties": {
                        "source_timezone": {
                            "description": "Source IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'Asia/Shanghai' as local timezone if no source timezone provided by the user.",
                            "type": "string"
                        },
                        "target_timezone": {
                            "description": "Target IANA timezone name (e.g., 'Asia/Tokyo', 'America/San_Francisco'). Use 'Asia/Shanghai' as local timezone if no target timezone provided by the user.",
                            "type": "string"
                        },
                        "time": {
                            "description": "Time to convert in 24-hour format (HH:MM)",
                            "type": "string"
                        }
                    },
                    "required": [
                        "source_timezone",
                        "time",
                        "target_timezone"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        }
    ]
}

  1. 大模型告诉spring-ai需要调用的方法名和参数,经由执行工具调用,可以是本地调用stdio,也可以是远程调用sse。
{
    "created_at": "2025-04-23T02:37:52.648573594Z",
    "done": true,
    "done_reason": "stop",
    "eval_count": 29,
    "eval_duration": 1492000000,
    "load_duration": 1301479401,
    "message": {
        "content": "",
        "role": "assistant",
        "tool_calls": [
            {
                "function": {
                    "arguments": {
                        "timezone": "Asia/Shanghai"
                    },
                    "name": "spring_ai_mcp_client_time_get_current_time"
                }
            }
        ]
    },
    "model": "qwen2.5:3b",
    "prompt_eval_count": 1507,
    "prompt_eval_duration": 26128000000,
    "total_duration": 29364424135
}
  1. 将工具执行结果,再次给大模型,这步其实不是必须的。但我们从中可以看出消息历史:
  • 用户user问:现在几点了?
  • 助手assistant:你需要调用工具spring_ai_mcp_client_time_get_current_time
  • 工具tool:我执行工具结果是"datetime": “2025-04-23T10:37:52+08:00”
{
    "messages": [
        {
            "content": "现在几点了?",
            "role": "user"
        },
        {
            "content": "",
            "role": "assistant",
            "tool_calls": [
                {
                    "function": {
                        "arguments": {
                            "timezone": "Asia/Shanghai"
                        },
                        "name": "spring_ai_mcp_client_time_get_current_time"
                    }
                }
            ]
        },
        {
            "content": "[{\"text\":\"{\\n  \\\"timezone\\\": \\\"Asia/Shanghai\\\",\\n  \\\"datetime\\\": \\\"2025-04-23T10:37:52+08:00\\\",\\n  \\\"is_dst\\\": false\\n}\"}]",
            "role": "tool"
        }
    ],
    "model": "qwen2.5:3b",
    "options": {
    },
    "stream": false,
    "tools": [
        {
            "function": {
                "description": "Read the complete contents of a file from the file system. Handles various text encodings and provides detailed error messages if the file cannot be read. Use this tool when you need to examine the contents of a single file. Only works within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_read_file",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "path": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "path"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Read the contents of multiple files simultaneously. This is more efficient than reading files one by one when you need to analyze or compare multiple files. Each file's content is returned with its path as a reference. Failed reads for individual files won't stop the entire operation. Only works within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_read_multiple_files",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "paths": {
                            "items": {
                                "type": "string"
                            },
                            "type": "array"
                        }
                    },
                    "required": [
                        "paths"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Create a new file or completely overwrite an existing file with new content. Use with caution as it will overwrite existing files without warning. Handles text content with proper encoding. Only works within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_write_file",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "content": {
                            "type": "string"
                        },
                        "path": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "path",
                        "content"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Make line-based edits to a text file. Each edit replaces exact line sequences with new content. Returns a git-style diff showing the changes made. Only works within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_edit_file",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "dryRun": {
                            "default": false,
                            "description": "Preview changes using git-style diff format",
                            "type": "boolean"
                        },
                        "edits": {
                            "items": {
                                "additionalProperties": false,
                                "properties": {
                                    "newText": {
                                        "description": "Text to replace with",
                                        "type": "string"
                                    },
                                    "oldText": {
                                        "description": "Text to search for - must match exactly",
                                        "type": "string"
                                    }
                                },
                                "required": [
                                    "oldText",
                                    "newText"
                                ],
                                "type": "object"
                            },
                            "type": "array"
                        },
                        "path": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "path",
                        "edits"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Create a new directory or ensure a directory exists. Can create multiple nested directories in one operation. If the directory already exists, this operation will succeed silently. Perfect for setting up directory structures for projects or ensuring required paths exist. Only works within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_create_directory",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "path": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "path"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Get a detailed listing of all files and directories in a specified path. Results clearly distinguish between files and directories with [FILE] and [DIR] prefixes. This tool is essential for understanding directory structure and finding specific files within a directory. Only works within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_list_directory",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "path": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "path"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Get a recursive tree view of files and directories as a JSON structure. Each entry includes 'name', 'type' (file/directory), and 'children' for directories. Files have no children array, while directories always have a children array (which may be empty). The output is formatted with 2-space indentation for readability. Only works within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_directory_tree",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "path": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "path"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Move or rename files and directories. Can move files between directories and rename them in a single operation. If the destination exists, the operation will fail. Works across different directories and can be used for simple renaming within the same directory. Both source and destination must be within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_move_file",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "destination": {
                            "type": "string"
                        },
                        "source": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "source",
                        "destination"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Recursively search for files and directories matching a pattern. Searches through all subdirectories from the starting path. The search is case-insensitive and matches partial names. Returns full paths to all matching items. Great for finding files when you don't know their exact location. Only searches within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_search_files",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "excludePatterns": {
                            "default": [
                            ],
                            "items": {
                                "type": "string"
                            },
                            "type": "array"
                        },
                        "path": {
                            "type": "string"
                        },
                        "pattern": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "path",
                        "pattern"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Retrieve detailed metadata about a file or directory. Returns comprehensive information including size, creation time, last modified time, permissions, and type. This tool is perfect for understanding file characteristics without reading the actual content. Only works within allowed directories.",
                "name": "spring_ai_mcp_client_filesystem_get_file_info",
                "parameters": {
                    "additionalProperties": false,
                    "properties": {
                        "path": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "path"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Returns the list of directories that this server is allowed to access. Use this to understand which directories are available before trying to access files.",
                "name": "spring_ai_mcp_client_filesystem_list_allowed_directories",
                "parameters": {
                    "properties": {
                    },
                    "required": [
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Get current time in a specific timezones",
                "name": "spring_ai_mcp_client_time_get_current_time",
                "parameters": {
                    "properties": {
                        "timezone": {
                            "description": "IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'Asia/Shanghai' as local timezone if no timezone provided by the user.",
                            "type": "string"
                        }
                    },
                    "required": [
                        "timezone"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        },
        {
            "function": {
                "description": "Convert time between timezones",
                "name": "spring_ai_mcp_client_time_convert_time",
                "parameters": {
                    "properties": {
                        "source_timezone": {
                            "description": "Source IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'Asia/Shanghai' as local timezone if no source timezone provided by the user.",
                            "type": "string"
                        },
                        "target_timezone": {
                            "description": "Target IANA timezone name (e.g., 'Asia/Tokyo', 'America/San_Francisco'). Use 'Asia/Shanghai' as local timezone if no target timezone provided by the user.",
                            "type": "string"
                        },
                        "time": {
                            "description": "Time to convert in 24-hour format (HH:MM)",
                            "type": "string"
                        }
                    },
                    "required": [
                        "source_timezone",
                        "time",
                        "target_timezone"
                    ],
                    "type": "object"
                }
            },
            "type": "function"
        }
    ]
}

  1. 大模型给出用户回答
{
    "created_at": "2025-04-23T02:37:57.016046085Z",
    "done": true,
    "done_reason": "stop",
    "eval_count": 52,
    "eval_duration": 2752000000,
    "load_duration": 16569232,
    "message": {
        "content": "现在的时间是:2025年04月23日 10点37分52秒(北京时间)。注意,这里的时间格式为ISO 8601标准。如果你需要其他时间格式的信息,请告诉我!",
        "role": "assistant"
    },
    "model": "qwen2.5:3b",
    "prompt_eval_count": 1610,
    "prompt_eval_duration": 1528000000,
    "total_duration": 4350731235
}


网站公告

今日签到

点亮在社区的每一天
去签到