Compare commits

...

4 Commits
1.0.4 ... main

Author SHA1 Message Date
Sunrisea f24f12c4ba
Support service metadata, update nacos-sdk-python version (#22) 2025-08-08 11:00:09 +08:00
Sunrisea cf9477af7b
Update and optimize log (#19)
* update log

* version 1.0.8
2025-07-29 12:00:01 +08:00
Sunrisea 5ab63b71cd
version 1.0.7, update nacos-maintainer-sdk-python to 0.1.2 (#17)
* Fix bug

* version 1.0.7, update nacos-maintainer-sdk-python to 0.1.2
2025-07-17 21:04:52 +08:00
Sunrisea 291949b579
optimize register logic (#16) 2025-07-17 20:11:42 +08:00
4 changed files with 63 additions and 38 deletions

View File

@ -3,6 +3,7 @@ import json
import logging
from contextlib import AbstractAsyncContextManager
from typing import Literal, Callable, Any
from importlib import metadata
import jsonref
from maintainer.ai.model.nacos_mcp_info import McpToolMeta, McpServerDetailInfo, \
@ -188,29 +189,30 @@ class NacosServer(Server):
return True
def check_compatible(self,server_detail_info:McpServerDetailInfo) -> bool:
def check_compatible(self,server_detail_info:McpServerDetailInfo) -> (bool,str):
if server_detail_info.version != self.version:
return False
return False, f"version not compatible, local version:{self.version}, remote version:{server_detail_info.version}"
if server_detail_info.protocol != self.type:
return False
return False, f"protocol not compatible, local protocol:{self.type}, remote protocol:{server_detail_info.protocol}"
if types.ListToolsRequest in self.request_handlers:
checkToolsResult = self.check_tools_compatible(server_detail_info)
if not checkToolsResult:
return False
return False , f"tools not compatible, local tools:{self._tmp_tools}, remote tools:{server_detail_info.toolSpec}"
mcp_service_ref = server_detail_info.remoteServerConfig.serviceRef
if not self.is_service_ref_same(mcp_service_ref):
return False
is_same_service,error_msg = self.is_service_ref_same(mcp_service_ref)
if not is_same_service:
return False, error_msg
return True
return True, ""
def is_service_ref_same(self,mcp_service_ref:McpServiceRef) -> bool:
if self.get_register_service_name() != mcp_service_ref.serviceName:
return False
if mcp_service_ref.groupName != self._nacos_settings.SERVICE_GROUP:
return False
def is_service_ref_same(self,mcp_service_ref:McpServiceRef) -> (bool,str):
if self._nacos_settings.SERVICE_NAME is not None and self._nacos_settings.SERVICE_NAME != mcp_service_ref.serviceName:
return False, f"service name not compatible, local service name:{self._nacos_settings.SERVICE_NAME}, remote service name:{mcp_service_ref.serviceName}"
if self._nacos_settings.SERVICE_GROUP is not None and self._nacos_settings.SERVICE_GROUP != mcp_service_ref.groupName:
return False, f"group name not compatible, local group name:{self._nacos_settings.SERVICE_GROUP}, remote group name:{mcp_service_ref.groupName}"
if mcp_service_ref.namespaceId != self._nacos_settings.NAMESPACE:
return False
return True
return False, f"namespace id not compatible, local namespace id:{self._nacos_settings.NAMESPACE}, remote namespace id:{mcp_service_ref.namespaceId}"
return True, ""
def get_register_service_name(self) -> str:
@ -266,25 +268,32 @@ class NacosServer(Server):
self.list_tools()(self._list_tmp_tools)
if server_detail_info is not None:
if not self.check_compatible(server_detail_info):
logging.error(f"mcp server info is not compatible,{self.name},version:{self.version}")
is_compatible, error_msg = self.check_compatible(server_detail_info)
if not is_compatible:
logging.error(f"mcp server info is not compatible,{self.name},version:{self.version},reason:{error_msg}")
raise NacosException(
f"mcp server info is not compatible,{self.name},version:{self.version}"
f"mcp server info is not compatible,{self.name},version:{self.version},reason:{error_msg}"
)
if types.ListToolsRequest in self.request_handlers:
self.update_tools(server_detail_info)
asyncio.create_task(self.subscribe())
if self._nacos_settings.SERVICE_REGISTER and (self.type == "mcp-sse"
or self.type == "mcp-streamable"):
version = metadata.version('nacos-mcp-wrapper-python')
service_meta_data = {
"source": f"nacos-mcp-wrapper-python-{version}",
**self._nacos_settings.SERVICE_META_DATA}
await self.naming_client.register_instance(
request=RegisterInstanceParam(
group_name=self._nacos_settings.SERVICE_GROUP,
service_name=self.get_register_service_name(),
group_name=server_detail_info.remoteServerConfig.serviceRef.groupName,
service_name=server_detail_info.remoteServerConfig.serviceRef.serviceName,
ip=self._nacos_settings.SERVICE_IP,
port=self._nacos_settings.SERVICE_PORT if self._nacos_settings.SERVICE_PORT else port,
ephemeral=self._nacos_settings.SERVICE_EPHEMERAL,
metadata=service_meta_data
)
)
logging.info(f"Register to nacos success,{self.name},version:{self.version}")
return
mcp_tool_specification = None
@ -316,7 +325,7 @@ class NacosServer(Server):
endpoint_spec.type = "REF"
data = {
"serviceName": self.get_register_service_name(),
"groupName": self._nacos_settings.SERVICE_GROUP,
"groupName": "DEFAULT_GROUP" if self._nacos_settings.SERVICE_GROUP is None else self._nacos_settings.SERVICE_GROUP,
"namespaceId": self._nacos_settings.NAMESPACE,
}
endpoint_spec.data = data
@ -326,16 +335,6 @@ class NacosServer(Server):
server_basic_info.remoteServerConfig = remote_server_config_info
server_basic_info.protocol = self.type
server_basic_info.frontProtocol = self.type
if self._nacos_settings.SERVICE_REGISTER:
await self.naming_client.register_instance(
request=RegisterInstanceParam(
group_name=self._nacos_settings.SERVICE_GROUP,
service_name=self.get_register_service_name(),
ip=self._nacos_settings.SERVICE_IP,
port=self._nacos_settings.SERVICE_PORT if self._nacos_settings.SERVICE_PORT else port,
ephemeral=self._nacos_settings.SERVICE_EPHEMERAL,
)
)
try:
await self.mcp_service.create_mcp_server(self._nacos_settings.NAMESPACE,
self.name,
@ -343,7 +342,7 @@ class NacosServer(Server):
mcp_tool_specification,
endpoint_spec)
except Exception as e:
logger.info(f"Failed to create MCP server to Nacos,try to update mcp server")
logger.info(f"Found MCP server {self.name} in Nacos,try to update it")
version_detail = None
try:
version_detail = await self.mcp_service.get_mcp_server_detail(
@ -352,15 +351,37 @@ class NacosServer(Server):
self.version
)
except Exception as e_2:
logger.info(f"Cant found version {self.version} of Mcp server {self.name}")
logger.info(f" Version {self.version} of Mcp server {self.name} is not in Nacos, try to update it")
if version_detail is None:
await self.mcp_service.update_mcp_server(
self._nacos_settings.NAMESPACE,
self.name,
False,
True,
server_basic_info,
mcp_tool_specification,
endpoint_spec
)
else:
_is_compatible,error_msg = self.check_compatible(version_detail)
if not _is_compatible:
logging.error(f"mcp server info is not compatible,{self.name},version:{self.version},reason:{error_msg}")
raise NacosException(
f"mcp server info is not compatible,{self.name},version:{self.version},reason:{error_msg}"
)
if self._nacos_settings.SERVICE_REGISTER:
version = metadata.version('nacos-mcp-wrapper-python')
service_meta_data = {"source": f"nacos-mcp-wrapper-python-{version}",**self._nacos_settings.SERVICE_META_DATA}
await self.naming_client.register_instance(
request=RegisterInstanceParam(
group_name="DEFAULT_GROUP" if self._nacos_settings.SERVICE_GROUP is None else self._nacos_settings.SERVICE_GROUP,
service_name=self.get_register_service_name(),
ip=self._nacos_settings.SERVICE_IP,
port=self._nacos_settings.SERVICE_PORT if self._nacos_settings.SERVICE_PORT else port,
ephemeral=self._nacos_settings.SERVICE_EPHEMERAL,
metadata=service_meta_data,
)
)
asyncio.create_task(self.subscribe())
logging.info(f"Register to nacos success,{self.name},version:{self.version}")
except Exception as e:
logging.error(f"Failed to register MCP server to Nacos: {e}")

View File

@ -23,9 +23,9 @@ class NacosSettings(BaseSettings):
description="nacos namespace",
default="public")
SERVICE_GROUP : str = Field(
SERVICE_GROUP : Optional[str] = Field(
description="nacos service group",
default="DEFAULT_GROUP")
default=None)
SERVICE_NAME : Optional[str] = Field(
description="nacos service name",
@ -63,6 +63,10 @@ class NacosSettings(BaseSettings):
description="nacos connection labels",
default={})
SERVICE_META_DATA : Optional[dict] = Field(
description="nacos service metadata",
default={})
class Config:
env_prefix = "NACOS_MCP_SERVER_"

View File

@ -1,9 +1,9 @@
psutil==7.0.0
anyio==4.9.0
mcp==1.9.2
nacos-sdk-python==2.0.7
nacos-sdk-python>=2.0.9
pydantic==2.11.3
pydantic-settings==2.9.1
jsonref==1.1.0
uvicorn==0.34.2
nacos-maintainer-sdk-python==0.1.0
nacos-maintainer-sdk-python>=0.1.2

View File

@ -9,7 +9,7 @@ def read_requirements():
setup(
name='nacos-mcp-wrapper-python',
version='1.0.4', # 项目的版本号
version='1.0.9', # 项目的版本号
packages=find_packages(
exclude=["test", "*.tests", "*.tests.*", "tests.*", "tests"]), # 自动发现所有包
url="https://github.com/nacos-group/nacos-mcp-wrapper-python",