人工智能AI AgentAgent 框架工具调用Agent 工作流RAGMCP Clients强化学习【免费下载链接】agent-core-javaopenJiuwen agent core Java是 openJiuwen Core的 Java版本提供AI Agent开发、运行、调优与演进相关的全套SDK能力。项目地址https://gitcode.com/openJiuwen/agent-core-java点击查看免费下载导读com.openjiuwen.core.foundation.tool.mcp.client是 openJiuwen agent-core-java 中面向 Model Context ProtocolMCP的客户端实现集合覆盖基于 HTTP JSON-RPC、SSE、stdio 以及从 OpenAPI 规范派生工具等五种接入形态。本文以该包的结构为主线先梳理统一的McpClient接口契约与McpServerConfig配置模型再逐一解析五种客户端的实现要点最后说明 SDK 如何通过McpClients.registerDefaults()把客户端工厂注册进全局ClientRegistry并给出结合ResourceMgr/ToolManager的注册路径与直接使用ClientRegistry的两种接入方式。读完本文你将掌握在 Java 侧为 Agent 接入各类 MCP Server 的配置方法、clientType 归一化规则以及各传输形态在源码层面的工作机理。一、包结构与类型总览client.README.mddocuments/zh/2.开发指南/API文档/com.openjiuwen.core/foundation/tool/mcp/client.README.md给出了本包的顶层索引包内提供以下六种公开类型类型说明OpenApiClient从本地 OpenAPI JSON/YAML 文件生成工具卡片并可直接发起 HTTP 调用PlaywrightClient按serverPath自动在SseClient与StdioClient之间选择委托实现SseClient基于 SSE 风格的 MCP 客户端StdioClient通过Content-Length分帧 JSON-RPC 与本地子进程通信StreamableHttpClient面向 streamable-http 服务端的 HTTP JSON-RPC 客户端McpClientsMCP 客户端注册门面把默认 transport 注册到全局ClientRegistry这些实现类的源码位于 core/src/main/java/com/openjiuwen/core/foundation/tool/mcp/client/ 目录。除公开类型外包内还存在一个不作为公开文档页输出的抽象基类AbstractHttpMcpClient源码见 AbstractHttpMcpClient.java它是 HTTP 类传输的公共骨架。说明包内各实现类在代码注释中明确标注了其 Python 对应实现如stdio_client.py、openapi_client.py、sse_client.py本包是 openJiuwen Python 版 MCP client 体系的 Java 移植接口语义保持一致。二、统一契约McpClient 接口所有客户端实现都遵循McpClient接口McpClient.java该接口定义了连接、断开、列出工具、调用工具、查询工具信息的最小能力集方法说明boolean connect(int retryTimes, float timeout)建立到 MCP 服务端的连接可指定重试次数与超时秒default boolean connect()使用默认参数连接重试 1 次、无超时boolean disconnect(float timeout)断开连接default boolean disconnect()使用无超时参数断开ListObject listTools(float timeout)列出服务端暴露的工具元数据default ListObject listTools()使用无超时参数列出工具Object callTool(String toolName, MapString, Object arguments, float timeout)按工具名发起调用default Object callTool(String toolName, MapString, Object arguments)使用无超时参数调用工具OptionalObject getToolInfo(String toolName, float timeout)查询单个工具信息default OptionalObject getToolInfo(String toolName)使用无超时参数查询String getServerPath()返回客户端对应的服务端路径从源码看接口在connect、listTools、callTool等默认重载之外还补充了reconnect(float timeout)与reconnect()默认实现先disconnect再connect重试 1 次以及listResources(float timeout)、readResource(String uri, float timeout)两个资源类方法的默认空实现。也就是说各实现类可以只实现核心工具方法资源能力按需覆盖——例如OpenApiClient的listResources固定返回空列表而StdioClient与SseClient则真实实现了resources/list与resources/read的转发。所有默认重载均基于McpServerConfig.NO_TIMEOUT常量为-1.0F作为无超时哨兵值详见下文配置模型。三、配置模型McpServerConfigMcpServerConfigMcpServerConfig.java是 MCP 服务端的配置对象描述服务端标识、访问路径、客户端类型以及认证附加参数。源码通过 Builder 与 setter 提供两种构造方式显式字段如下字段类型默认值说明serverIdString优先取serverName否则随机 UUID去横线服务端唯一标识serverNameStringnull服务端显示名称serverPathStringnull服务端路径或 URLclientTypeStringsse客户端类型paramsMapString, Object空HashMap附加参数例如 stdio 命令、环境变量或 OpenAPI 额外配置authHeadersMapString, String空HashMap认证请求头authQueryParamsMapString, String空HashMap认证查询参数connectTimeoutSecondsDoublenull连接超时秒HTTP 类客户端读取callTimeoutSecondsDoublenull调用超时秒NO_TIMEOUTfloat-1无超时常量几个值得注意的源码细节serverId自动生成当serverId为空时normalizeServerId()会优先回退到serverName只有两者都缺失时才生成随机 UUID无横线。这一语义与文档描述一致。clientType归一化clientType会在 MCP Server 注册路径上做归一化后用于ClientRegistry查询但原始配置对象中的字段值不会被改写配置对象原样保留归一化只发生在查询键的构造上。支持的主要clientType包括sse、stdio、streamable-http、openapi、playwright具体别名映射见第五节。配置比较与日志脱敏源码还提供了sameConnectionAs(...)比较 serverId、serverName、serverPath 与归一化 clientType和toMaskedDescription()——后者只输出认证头/查询参数的名字而非值避免凭证泄漏到日志这一细节在接入需要鉴权的远端 MCP Server 时尤其重要。一个典型的 Builder 构造示例来自McpClientsTest的用法McpServerConfig config McpServerConfig.builder() .serverId(registry-srv) .serverName(registry) .serverPath(http://127.0.0.1:3001/mcp) .clientType(streamable-http) .build();四、五种客户端实现解析4.1 SseClient面向 SSE 服务端SseClientSseClient.java以构造方法public SseClient(McpServerConfig config)创建用于接入 SSE 风格的 MCP 服务端。源码实现要点底层借助官方 MCP Java SDK 的HttpClientSseClientTransport构建传输并用McpSyncClient封装同步会话连接时若未指定超时默认回退到DEFAULT_SSE_TIMEOUT_SECONDS 60.0秒。连接成功后执行initialize握手listTools/callTool等操作会把远端返回的McpSchema.Tool等对象转换为带serverName/serverId的McpToolCard。认证触发connect时会通过AuthCallback.unifiedAuthHandler(...)触发TOOL_AUTH事件从认证结果中提取auth_provider实现AuthHeaderAndQueryProvider的对象随后把其头信息注入 SSE 请求、把查询参数合并进 URL实现鉴权接入。自愈重连listTools/callTool遇到可重试的传输错误如connection reset、broken pipe、connection closed时会先reconnect一次再重放操作。根据 SseClient.md 的说明本类没有新增公开方法公共连接与调用能力全部继承自McpClient接口契约。测试见 SseClientTest.java。4.2 StdioClientContent-Length 分帧的本地子进程客户端StdioClientStdioClient.java通过Content-Length分帧的 JSON-RPC 协议与本地子进程通信是接入本地 MCP Server 可执行文件如python、java启动的 MCP 服务的标准形态。字段与公开方法字段类型默认值说明configMcpServerConfig-客户端配置requestCounterAtomicLongnew AtomicLong()JSON-RPC 请求编号processProcessnull启动后的子进程stdoutBufferedInputStreamnull读取子进程标准输出stdinBufferedOutputStreamnull写入子进程标准输入方法说明public boolean connect(int retryTimes, float timeout)按params.command或serverPath启动子进程并尝试发送initialize请求public boolean disconnect(float timeout)关闭输入输出流并终止子进程public ListObject listTools(float timeout)请求tools/list并把结果转成McpToolCard列表public Object callTool(String toolName, MapString, Object arguments, float timeout)请求tools/callpublic OptionalObject getToolInfo(String toolName, float timeout)通过listTools(...)过滤目标工具public String getServerPath()返回配置中的serverPath源码实现要点帧协议JsonRpcProcessSession.writeFrame直接向 stdin 写入 JSON 并以换行结尾readFrame则兼容两种读取方式——若行以content-length:开头则按头部解析后readNBytes(contentLength)读取定长 body否则按换行分隔的 JSON 行解析。读取响应时会循环跳过不匹配当前请求id的帧正确处理服务端主动推送的消息如ping会回写result未知方法回写-32601错误。初始化握手initialize发送protocolVersion 2024-11-05、clientInfo {name: agent-core-java, version: ...}随后发送notifications/initialized通知。参数注入params.args可追加命令行参数params.env可注入环境变量params.cwd可指定工作目录params.encoding_error_handler支持strict/ignore/replace非法值回退strict。安全约束命令解析有一套明确的校验链——默认允许的命令白名单仅包含java、python、python3及各自.exe变体若serverPath显式声明了命令则要求实际请求的命令与其toRealPath()解析结果一致否则抛出SecurityException详见resolveAllowedCommand与resolveDefaultAllowedCommand。启动前还会校验可执行文件存在且可执行命令含\0非法字符会直接拒绝。超时控制正值超时通过独立 reader 线程 Future.get实现超时后清理子进程并把 stderr 尾部最多 8192 字符拼进异常信息辅助排障。stderr 引流子进程 stderr 由守护线程持续引流避免管道写满导致子进程阻塞同时保留诊断尾部。对应文档 StdioClient.md测试见 StdioClientTest.java。4.3 StreamableHttpClientstreamable-http 服务端客户端StreamableHttpClientStreamableHttpClient.java面向 streamable-http 传输的 MCP 服务端是当前 MCP 规范推荐演进方向之一的 HTTP JSON-RPC 形态。它以public StreamableHttpClient(McpServerConfig config)创建另提供了StreamableHttpClient(String serverPath)等便捷构造。源码实现要点底层使用HttpClientStreamableHttpTransport连接默认超时DEFAULT_TIMEOUT_SECONDS 60.0F秒认证逻辑通过AuthStrategyRegistry.executeAuth(...)获取AuthHeaderAndQueryProvider随后注入请求头并把查询参数附加到 endpoint。有界超时执行凡是调用方传入正数超时的操作都提交到一个有界线程池核心 8、最大 192、SynchronousQueue交接队列执行超时统一表现为HttpTimeoutExceptionNO_TIMEOUT哨兵或非正数则内联执行。重试感知的超时预算retryAwareTimeout会把外层硬预算放大到调用方超时的 2 倍以容纳传输错误→重连→重放的两次尝试避免第一次慢请求吃掉重试机会源码注释对此有明确解释。URL 解析会把serverPath拆成 base URI 与 endpoint 两部分方便HttpClientStreamableHttpTransport.builder(baseUri).endpoint(...)使用。对应文档 StreamableHttpClient.md测试见 StreamableHttpClientTest.java。4.4 OpenApiClient从 OpenAPI 规范派生工具OpenApiClientOpenApiClient.java是一个特殊形态它不连接远端 MCP 服务端而是读取本地 OpenAPI JSON/YAML 规范把每个接口操作转换为McpToolCard并可按生成的参数结构直接发起 HTTP 请求。字段与公开方法字段类型默认值说明configMcpServerConfig-当前客户端配置httpClientHttpClientHttpClient.newHttpClient()发起 HTTP 请求的客户端operationsMapString, Operationnew LinkedHashMap()已加载的工具操作定义usedNamesMapString, Integernew HashMap()用于消除工具名冲突的计数器方法说明public boolean connect(int retryTimes, float timeout)清空已有状态读取serverPath中逗号分隔的多个规范文件并装载操作public boolean disconnect(float timeout)清空已加载操作并返回truepublic ListObject listTools(float timeout)返回当前已加载操作对应的McpToolCard列表public Object callTool(String toolName, MapString, Object arguments, float timeout)按工具名解析操作替换路径参数并以 GET 查询串或 JSON 请求体调用远端接口public OptionalObject getToolInfo(String toolName, float timeout)返回单个工具卡片信息public String getServerPath()返回配置中的serverPathpublic static MapString, Object loadConf(String filePath)读取并解析.json、.yaml或.yml格式的 OpenAPI 文件源码实现要点多文件装载connect会把serverPath按逗号拆分成多个规范文件路径依次加载因此一个配置即可注册多个 OpenAPI 接口集。文件安全校验loadConf(...)要求路径存在、为普通文件且不能是符号链接支持~开头的主目录展开扩展名仅接受.json/.yaml/.yml且解析结果必须是Map类型dict否则抛出TOOL_OPENAPI_CLIENT_EXECUTION_ERROR。工具名生成与去冲突工具名优先取operationId按__切分取首段其次取summary兜底为HTTP方法_路径长度超过 64 截断当工具名冲突时会在原名后追加_2、_3等后缀usedNames计数器实现。入参 Schema 构建buildInputSchema会合并 OpenAPIparameterspath/query/header 参数与requestBody的 content schema解析$ref引用标记必填项最终生成{type: object, properties, required}形式的输入 Schema。请求执行callTool时先解析出baseUrl优先取servers[0].url可用params.base_url覆盖并去掉尾部斜杠把{param}路径模板替换为 URL 编码后的实参请求体中的路径参数会在真正发送前移除bodyArgs.remove(pathParam)避免同时出现在 URL 与 JSON body 中GET 方法把剩余参数拼成查询串其他 HTTP 方法以 JSON body 发送。输出 Schema 从responses中的 200/201或任意 2xx响应内容中提取。支持的标准 HTTP 方法集合为get / put / post / delete / options / head / patch / trace。对应文档 OpenApiClient.md测试见 OpenApiClientTest.java。4.5 PlaywrightClient自动选择委托实现的门面PlaywrightClientPlaywrightClient.java是 Playwright MCP 客户端门面根据McpServerConfig.serverPath的前缀在SseClient与StdioClient之间自动选择实际委托对象。字段类型默认值说明delegateMcpClient-实际承担调用的客户端方法说明public boolean connect(int retryTimes, float timeout)委托到底层客户端public boolean disconnect(float timeout)委托到底层客户端public ListObject listTools(float timeout)委托到底层客户端public Object callTool(String toolName, MapString, Object arguments, float timeout)委托到底层客户端public OptionalObject getToolInfo(String toolName, float timeout)委托到底层客户端public String getServerPath()返回底层客户端的服务端路径源码实现要点传输选择规则构造时若serverPath以http://或https://开头则委托SseClient否则委托StdioClient此外params中的stdio_server_parametersServerParameters对象或server_path键可以显式覆盖默认取值来源rawServerPath()的优先级为params.stdio_server_parameters→params.server_path→config.getServerPath()。底层同样是McpSyncClientHttpClientSseClientTransport/StdioClientTransport统一完成初始化握手、工具列表与调用。对应文档 PlaywrightClient.md测试见 PlaywrightClientTest.java。五、注册机制McpClients 与 ClientRegistry5.1 为什么需要显式注册Java 版没有 PythonBaseClient.__init_subclass__形式的类定义时自动注册机制。因此 SDK 通过McpClients.registerDefaults()显式注册 MCP 客户端工厂McpClients.java使ResourceMgr与ToolManager可以继续按McpServerConfig.clientType走全局ClientRegistry创建客户端。registerDefaults()是一个synchronized的幂等操作每次注册前先通过listClients()检查mcp_name键是否已存在已存在则跳过因此重复调用不会报已注册异常McpClientsTest.registerDefaultsRegistersAllMcpClientFactoriesIdempotently对此有专门验证。默认注册项如下ClientRegistrykey实现mcp_sseSseClientmcp_stdioStdioClientmcp_streamable-httpStreamableHttpClientmcp_streamable_httpStreamableHttpClientmcp_openapiOpenApiClientmcp_playwrightPlaywrightClient从源码看registerIfMissing通过ClientRegistry.registerClient(name, mcp, factory)注册ClientRegistry内部会拼出完整键mcp_name存入工厂表ClientRegistry.java。注意streamable-http与streamable_http两个别名被同时注册且指向同一实现类这正是McpClientsTest中同时断言mcp_streamable-http与mcp_streamable_http两个键存在的原因。5.2 clientType 归一化规则McpClients.normalizeClientType(String clientType)是注册查询的关键入口其归一化算法在源码中清晰可见null或全空白字符串 →sse默认类型去除首尾空白把驼峰式拆成连字符streamableHttp→streamable-http统一转小写并把下划线替换为连字符STREAMABLE_HTTP→streamable-http去掉mcp-前缀mcp_stdio→stdio对结果做最终映射open-api→openapi其余保留。代表性映射输入示例归一化结果null、空字符串sseSSE、mcp_SSEssestdio、mcp_stdiostdiostreamable_http、streamableHttp、STREAMABLE_HTTPstreamable-httpmcp_streamable_http、mcp-streamable-httpstreamable-httpopen-apiopenapiplaywrightplaywright上述映射均有McpClientsTest.normalizeClientTypeSupportsCommonAliases的断言背书也就是说配置里写SSE、streamableHttp或mcp_streamable_http都能正确命中注册的工厂。5.3 工厂的 kwargs 契约每个注册的工厂都要求kwargs中包含config键且值必须是McpServerConfig。McpClients.requiredConfig(...)会对不符合的值抛出IllegalArgumentException错误信息形如MCP client factory requires kwargs[config] to be McpServerConfig, actual: 实际类型McpClientsTest.registryFactoryRejectsMissingOrWrongConfig同时验证了缺config与传错类型如字符串两种情况都会被拒绝。5.4 直接使用 ClientRegistry如果业务代码直接通过ClientRegistry.getClient(name, mcp, kwargs)创建 MCP client应先调用McpClients.registerDefaults()。典型用法McpClients.registerDefaults(); McpServerConfig config McpServerConfig.builder() .serverId(my-srv) .serverName(my-server) .serverPath(http://127.0.0.1:3001/mcp) .clientType(streamable-http) .authHeaders(Map.of(Authorization, Bearer token)) .build(); // 通过注册表按 clientType 动态创建客户端 McpClient client (McpClient) ClientRegistry.getClientRegistry() .getClient(McpClients.normalizeClientType(config.getClientType()), mcp, Map.of(config, config)); client.connect(); ListObject tools client.listTools(); Object result client.callTool(someTool, Map.of(param, value)); client.disconnect();创建出的实例类型与McpClientsTest.registryFactoriesCreateConcreteClientsFromMcpServerConfig的断言一致sse→SseClient、stdio→StdioClient、streamable-http/streamable_http→StreamableHttpClient、openapi→OpenApiClient、playwright→PlaywrightClient。六、与 ResourceMgr / ToolManager 的集成路径在 SDK 的更高层MCP Server 的注册是通过ResourceMgr.addMcpServer(McpServerConfig)系列方法支持单个、批量以及异步变体进入的见 ResourceMgr.java。其内部ToolManager在创建客户端时ToolManager.java 的defaultCreateClient遵循如下策略优先尝试com.openjiuwen.core.foundation.tool.mcp.McpClientFactory.create(config)SPI 工厂 / 显式注册若 SPI 工厂不支持抛出UnsupportedOperationException则回退到McpClients.registerDefaults()ClientRegistry.getClient(normalizeClientType(...), mcp, Map.of(config, config))。也就是说ResourceMgr与ToolManager的 MCP Server 注册路径会确保默认 MCP client 已注册业务代码通常无需手动调用registerDefaults()只有直接使用ClientRegistry时才需要先注册。注册完成后ToolManager会调用客户端的listTools拿到McpToolCard列表为每个工具分配全局唯一的serverId_serverName_toolName形式的工具 id并用McpTool包装成本地Tool供上层统一调用McpTool会把远端异常转换为TOOL_MCP_EXECUTION_ERROR且其stream方法固定抛出TOOL_STREAM_NOT_SUPPORTED详见 McpTool.java 与 McpToolCard.java。在 examples 侧仓库提供了对应的 MCP 接入示例基线examples/mcp/README.md覆盖openapi、sse、stdio、streamable_http、playwright五种形态的McpServerConfig构造示例并可用mvn -DtestMcpExampleSupportTest test验证。七、选型建议与使用要点场景推荐 clientType说明远端 MCP ServerHTTP SSEsse默认类型适合大多数托管 MCP 服务本地可执行文件型 MCP Serverstdio启动子进程注意命令白名单与params.args/params.env/params.cwd支持 streamable-http 的新式服务端streamable-httpHTTP JSON-RPC 形态具备有界超时与自愈重连已有 OpenAPI 规范的 HTTP 服务openapi无需 MCP 服务端即可把接口转成 Agent 工具Playwright 浏览器自动化playwright自动在 SSE / stdio 间选择使用要点归纳配置对象统一使用McpServerConfigclientType不区分大小写与连字符/下划线别名会被归一化兼容认证通过authHeaders与authQueryParams下发SSE 与 streamable-http 客户端都会在连接阶段触发统一认证流程日志中只会出现认证键名而非凭证值超时正值超时生效stdio 超时清理子进程、streamable-http 有界线程池超时表现为HttpTimeoutException-1NO_TIMEOUT表示无超时HTTP 类客户端的 discovery 类 RPCinitialize、tools/list在无超时参数时会回退到 30 秒默认值错误语义远端 MCP 工具异常统一转为TOOL_MCP_EXECUTION_ERROROpenAPI 客户端错误对应TOOL_OPENAPI_CLIENT_EXECUTION_ERROR可直接在 Agent 编排层捕获并分支处理。参考资料包索引client.README.md子文档McpClients.md、SseClient.md、StdioClient.md、StreamableHttpClient.md、OpenApiClient.md、PlaywrightClient.md接口与配置McpClient.md、McpServerConfig.md、McpTool.md、McpToolCard.md源码client 实现目录、McpClient.java、McpServerConfig.java、ClientRegistry.java测试McpClientsTest.java 及各客户端测试示例examples/mcp/README.md赞分享人工智能AI AgentAgent 框架工具调用Agent 工作流RAGMCP Clients强化学习【免费下载链接】agent-core-javaopenJiuwen agent core Java是 openJiuwen Core的 Java版本提供AI Agent开发、运行、调优与演进相关的全套SDK能力。项目地址https://gitcode.com/openJiuwen/agent-core-java点击查看免费下载相关推荐openjiuwen agent-core 五大 MCP 传输接入实战SSE、Stdio、Streamable HTTP、Playwright 与 OpenAPIopenjiuwen agent core 五大 MCP 传输接入实战SSE、Stdio、Streamable HTTP、Playwright 与 OpenA人工智能AI AgentAgent 框架大模型工具调用RAG提示工程强化学习openJiuwen Core Java 集成 MCP 工具一次打通 stdio、SSE 与 Streamable HTTPopenJiuwen Core Java 集成 MCP 工具一次打通 stdio、SSE 与 Streamable HTTP openJiuwen Core人工智能AI AgentAgent 框架工具调用Agent 工作流RAGMCP Clients强化学习openJiuwen Agent Core Java StreamableHttpClient 详解面向 Streamable HTTP 服务的 MCP 客户端openJiuwen Agent Core Java StreamableHttpClient 详解面向 Streamable HTTP 服务的 MCP 客户人工智能AI AgentAgent 框架工具调用Agent 工作流RAGMCP Clients强化学习创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考