
1. 为什么要把 r-nacos 里的 HTTP 接口变成 MCP 服务如果你手里已经有一堆注册在 r-nacos 上的普通 HTTP 接口比如用户查询、订单创建、库存扣减现在想让 AI 助手或 Agent 直接调用它们传统做法是给每个接口手写一层 MCP 适配代码。接口一多适配层比业务代码还厚改一个参数要动三四个文件。r-nacos 内置的 MCP Server 与接口转发能力解决的正是这个问题服务注册到 r-nacos 时在 metadata 里声明哪些 HTTP 路径要暴露成 MCP 工具r-nacos 会自动把这些接口转换成标准 MCP 服务对外提供。业务代码零改动接口变更后 MCP 工具定义也会跟着刷新。这套方案适合三类人一是已有微服务想快速接入 AI 工具链的后端开发者二是用 r-nacos 做服务发现、希望统一协议出口的架构同学三是想用 MCP 客户端调用内部 HTTP 接口、但不想写胶水代码的 AI 应用开发者。下面从环境准备到完整验证一步步走通。2. 前置准备r-nacos 与 MCP Server 开关r-nacos 的部署方式很轻单机 Docker 一条命令就能起来。注意端口要同时映射 8848HTTP API 与控制台和 9848gRPC 通信MCP Server 默认监听 9090也需要放出来。docker run -d --name r-nacos \ -p 8848:8848 \ -p 9848:9848 \ -p 9090:9090 \ -e MODEstandalone \ qingpan/rnacos:stable启动后访问http://localhost:8848能看到控制台即成功。接着在 r-nacos 的配置文件里打开 MCP Server 与转发开关。如果你用的是容器内配置文件可以挂载application.properties覆盖# 启用内置 MCP Server mcp.server.enabledtrue mcp.server.port9090 # 接口转发默认参数 mcp.forward.default-timeout5000 mcp.forward.max-retry3 mcp.forward.load-balanceround_robin改完重启容器生效。这里有个容易忽略的点mcp.server.port必须和容器映射端口一致否则 MCP 客户端连不上。我试过把 9090 写成 9091 但映射没改排查了十几分钟才发现是端口对不上。3. 可复制配置注册 HTTP 接口并声明 MCP 元数据先准备一个最普通的 HTTP 服务用 Flask 写两个接口一个 GET 查询、一个 POST 创建不做任何 MCP 相关改造。# user_service.py from flask import Flask, jsonify, request app Flask(__name__) users_db {1: {name: Alice, age: 30}, 2: {name: Bob, age: 25}} app.route(/api/user/int:user_id, methods[GET]) def get_user(user_id): user users_db.get(user_id) if user: return jsonify({code: 200, data: user}) return jsonify({code: 404, message: User not found}), 404 app.route(/api/user, methods[POST]) def create_user(): data request.json if not data or name not in data or age not in data: return jsonify({code: 400, message: Invalid input}), 400 new_id max(users_db.keys()) 1 users_db[new_id] {name: data[name], age: data[age]} return jsonify({code: 200, data: {id: new_id, **users_db[new_id]}}) if __name__ __main__: app.run(host0.0.0.0, port5000)启动这个服务后关键一步是注册到 r-nacos 时把 MCP 转换规则写进 metadata。r-nacos 会读取metadata.mcp字段按endpoints里的定义生成 MCP 工具。# register_service.py import requests, json NACOS_ADDR http://localhost:8848 SERVICE_NAME user-service params { serviceName: SERVICE_NAME, ip: 127.0.0.1, port: 5000, metadata: json.dumps({ mcp: { enabled: True, endpoints: [ { path: /api/user/{user_id}, method: GET, description: 根据用户ID查询用户信息, params: { user_id: {type: int, required: True} } }, { path: /api/user, method: POST, description: 创建新用户, params: { name: {type: string, required: True}, age: {type: int, required: True} } } ] } }) } resp requests.post(f{NACOS_ADDR}/nacos/v1/ns/instance, dataparams) print(注册结果:, resp.status_code, resp.text)注册成功后MCP 服务的访问地址形如http://localhost:9090/mcp/user-service。路径里的{user_id}是占位符r-nacos 转发时会自动替换成 MCP 调用传入的参数值。4. 验证请求从 MCP 客户端调用到成功结果MCP 客户端这边推荐用支持 stdio 和 HTTP 两种传输的通用客户端。下面用 Python 的 mcp 库演示先装依赖pip install mcp httpx然后写一个调用脚本分别验证 GET 和 POST 两个接口转换后的 MCP 工具# mcp_client.py import asyncio from mcp import ClientSession from mcp.client.streamable_http import streamablehttp_client async def main(): url http://localhost:9090/mcp/user-service async with streamablehttp_client(url) as (read, write, _): async with ClientSession(read, write) as session: await session.initialize() # 列出可用工具确认接口已转换 tools await session.list_tools() print(可用工具:, [t.name for t in tools.tools]) # 调用 GET 转换的查询工具 result await session.call_tool( get_user, {user_id: 1} ) print(查询结果:, result.content) # 调用 POST 转换的创建工具 result await session.call_tool( create_user, {name: Charlie, age: 28} ) print(创建结果:, result.content) asyncio.run(main())预期输出里list_tools会返回get_user和create_user两个工具名调用结果就是原始 HTTP 接口的 JSON 响应体。到这里一个普通 HTTP 接口就完成了到 MCP 服务的转换全程没有改业务代码。如果你用的是 Claude Code 这类支持 MCP 的编码工具可以在settings.json里直接配置这个 MCP Server{ mcpServers: { r-nacos-user: { type: http, url: http://localhost:9090/mcp/user-service } } }配置后重启工具就能在对话里直接让模型调用get_user查询用户。需要长期跑编码任务或 Agent 工作流的话可以到 Coding Plan 看下额度方案配合 MCP 工具链用起来更顺。5. 本篇常见错排查报错一MCP 客户端连不上 9090 端口。先确认容器端口映射是否包含 9090再检查mcp.server.enabled是否为 true。如果 r-nacos 跑在远程主机注意防火墙是否放行。报错二list_tools 返回空列表。大概率是注册时 metadata 格式不对。r-nacos 要求metadata是 JSON 字符串且mcp.endpoints必须是数组。用curl查一下实例详情确认curl http://localhost:8848/nacos/v1/ns/instance/detail?serviceNameuser-serviceip127.0.0.1port5000报错三调用工具返回 404。检查path里的占位符写法是否和 HTTP 接口路由一致。比如 Flask 的int:user_id在 MCP 配置里要写成{user_id}不能照抄尖括号。报错四POST 接口参数传不进去。MCP 调用时参数名必须和params里声明的 key 完全一致大小写敏感。另外确认 HTTP 接口读取的是request.json而不是表单。报错五接口变更后 MCP 工具没更新。r-nacos 的服务发现是动态的但 MCP 工具定义刷新有短暂延迟。重新注册实例或等待心跳周期即可。如果长时间不刷新检查客户端是否开启了自动刷新。排查过程中如果涉及 API Key 配置或接入文档细节可以到 API Keys 和 接入文档 对照检查避免因为鉴权配置漏项导致请求被拒。6. 把 MCP 调用接进你的日常工具链接口转换跑通之后下一步是把它用起来。最直接的方式是在支持 MCP 的对话工具里验证模型能否正确调用这些工具可以到 模型对话 里发一句「帮我查一下用户 1 的信息」看模型是否自动触发get_user工具。这一步能直观确认 MCP 服务对模型侧是否可见。如果要在 Claude Code 里长期使用除了前面settings.json的配置还可以把多个 r-nacos 服务聚合到同一个 MCP Server 下按服务名区分工具前缀避免工具名冲突。实际用下来把内部 HTTP 接口批量转成 MCP 工具后Agent 能直接操作业务系统省掉了大量手写适配层的工作。