AgentScope Java新手村系列:15 MCP协议工具
MCP协议作为LLM应用调用外部工具的统一标准,在AgentScope 2.0中通过tools.json文件实现声明式集成。本章将深入解析MCP Server的接入原理与实际配置方法,帮助开发者快速掌握这一核心功能。
第十五章 MCP 协议工具:tools.json 声明式接入 MCP Server,配置即集成
15.1 MCP 是什么?
Model Context Protocol(MCP)是2024年推出的开放协议,它为LLM应用提供统一的方式发现并调用外部工具。AgentScope 2.0将MCP server视为agent工具的一种来源,开发者只需在tools.json文件中声明一个MCP server,agent启动时就会通过stdio或sse协议自动连接,将server暴露的工具注册为agent自身的tool。

15.2 第一个 MCP 集成
{ "mcpServers": { "github": { "command": "npx","args": ["-y", "@modelcontextprotocol/server-github"],"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${env:GITHUB_TOKEN}"}}}}HarnessAgent.builder().workspace(path)启动时会自动扫描workspace/tools.json中的mcpServers段,连接每个server并将工具注册到agent,整个过程无需额外开关。
HarnessAgent agent = HarnessAgent.builder()....workspace(Path.of("./workspace")).build();运行后,agent即可调用GitHub MCP server暴露的工具,包括create_issue、list_repos、search_code等。
15.3 三种连接方式
| 协议 | 适用 | 声明方式 |
|---|---|---|
stdio | 本地进程,最常见 | command与args |
sse | 远程HTTP SSE server | url与headers |
ws | 双向WebSocket | url与headers |
stdio 示例:
{ "mcpServers": { "filesystem": { "command": "npx","args": ["-y", "@modelcontextprotocol/server-filesystem", "./data"]}}}sse 示例:
{ "mcpServers": { "remote-knowledge": { "url": "https://mcp.example.com/sse","headers": { "Authorization": "Bearer ${env:MCP_TOKEN}"}}}}15.4 不想写 JSON 文件?可以在 Java 代码里直接配
JSON文件固然方便,但有时需要在代码内动态配置参数,例如从环境变量读取token或根据环境切换超时。此时可通过ToolsConfig与McpServerConfig在Java代码中直接配置,效果等同于tools.json。
import io.agentscope.harness.agent.tools.McpServerConfig;import io.agentscope.harness.agent.tools.ToolsConfig;ToolsConfig cfg = new ToolsConfig();Map servers = new LinkedHashMap<>();McpServerConfig github = new McpServerConfig();github.setTransport("stdio");github.setCommand("npx");github.setArgs(List.of("-y", "@modelcontextprotocol/server-github"));github.setEnv(Map.of("GITHUB_PERSONAL_ACCESS_TOKEN", System.getenv("GITHUB_TOKEN")));servers.put("github", github);cfg.setMcpServers(servers);HarnessAgent agent = HarnessAgent.builder()....toolsConfig(cfg).build();McpServerConfig(位于io.agentscope.harness.agent.tools包内)支持transport、command、args、env、url、headers、timeout等字段,与tools.json中的mcpServers段完全对应。
15.5 与 Permission 协作
MCP工具默认经过Permission系统,开发者可直接在规则中使用MCP工具名称。
PermissionContextState perms = PermissionContextState.builder().mode(PermissionMode.ACCEPT_EDITS).addAskRule("create_issue",new PermissionRule("create_issue", null,PermissionBehavior.ASK, "userSettings")).addDenyRule("drop_table",new PermissionRule("drop_table", null,PermissionBehavior.DENY, "userSettings")).build();MCP工具与本地@Tool工具在Permission系统内地位完全平等,例如create_issue(来自GitHub MCP server)和drop_table(来自本地Java类)享受相同处理逻辑。
15.6 常见 MCP server 一览
| 名称 | 工具集 |
|---|---|
@modelcontextprotocol/server-github | 仓库、Issue、PR |
@modelcontextprotocol/server-filesystem | 读、写、列目录 |
@modelcontextprotocol/server-postgres | 查SQL、DDL |
@modelcontextprotocol/server-slack | 发消息、查频道 |
@modelcontextprotocol/server-puppeteer | 浏览器自动化 |
@modelcontextprotocol/server-git | git操作 |
完整工具清单可查阅MCP官方server仓库。
15.7 工具命名冲突
当多个MCP server暴露同名工具时,AgentScope按以下优先级保留一个:
Toolkit中Java端注册的工具(最高)- 第一个启动成功的MCP server
- 后面的同名工具被忽略
启动日志中会有WARN提示。为避免冲突,可通过toolFilter限制:
{ "mcpServers": {"...": "..." },"toolFilter": { "deny": ["github_legacy_*"]}}15.8 完整可运行示例
本示例展示了MCP工具在实际场景中的运用:
public class Chapter15_McpTools {public static class MockGitHubTools {@Tool(name = "create_issue", description = "创建GitHub Issue")public String createIssue(String repo, String title) { return "Issue "" + title + "" 已创建到 " + repo + "。";}@Tool(name = "list_repos", description = "列出用户的仓库")public String listRepos() { return "- agentscope/agentscope-java- agentscope/agentscope-python";}@Tool(name = "search_code", description = "在代码仓库中搜索")public String searchCode(String query) { return "搜索 "" + query + "" 的结果。";}}public static class MockFilesystemTools {@Tool(name = "read_file", description = "读取文件内容")public String readFile(String path) { return "文件 " + path + " 的内容。";}@Tool(name = "list_directory", description = "列出目录内容")public String listDirectory(String path) { return "目录 " + path + " 的内容。";}}public static void main(String[] args) { Toolkit toolkit = new Toolkit();toolkit.registerTool(new MockGitHubTools());toolkit.registerTool(new MockFilesystemTools());HarnessAgent agent = HarnessAgent.builder().name("devops").sysPrompt("你是一个 devops 助理,可以查GitHub issue和操作本地文件。").model(model()).workspace(Path.of("./workspace")).toolkit(toolkit).build();agent.call(List.of(new UserMessage("user","看看 agentscope/agentscope-java 最近有什么 Issue。")),RuntimeContext.empty()).block();}}生产环境的workspace/tools.json配置如下:
{ "mcpServers": { "github": { "transport": "stdio","command": "npx","args": ["-y", "@modelcontextprotocol/server-github"],"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${env:GITHUB_TOKEN}"}},"filesystem": { "transport": "stdio","command": "npx","args": ["-y", "@modelcontextprotocol/server-filesystem", "./data"]}}}15.9 MCP Tool Meta:在工具调用中传递元数据
RC2版本新增McpMeta机制,开发者可在RuntimeContext中放入元数据,包括traceId、userId、回调地址等,框架会自动将这些信息传递给MCP CallToolRequest的meta参数。
import io.agentscope.core.tool.mcp.McpMeta;McpMeta meta = new McpMeta(Map.of("traceId", "abc-123","callbackUrl", "https://hook.example.com/cb"));RuntimeContext ctx = RuntimeContext.builder().put(McpMeta.class, meta).build();agent.call(List.of(new UserMessage("user", "创建 issue")), ctx).block();调用MCP工具时,traceId和callbackUrl会自动出现在MCP server接收的meta参数中,便于日志关联和结果推送。
15.10 本章小结
- MCP server通过
stdio、sse、ws协议接入agent。 workspace/tools.json使用mcpServers段声明,运行时可动态修改。- Java端
McpServerSpec可补充超时、env、headers等配置。 - MCP工具与Permission系统实现无缝集成。
通过学习本章,您已掌握MCP协议在AgentScope中的声明式集成方法,涵盖配置文件配置、代码动态集成、权限协作及工具冲突处理,为构建智能Agent工具调用提供了完整解决方案。