This is an automated email from the ASF dual-hosted git repository.

zhaoqingran pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git


The following commit(s) were added to refs/heads/master by this push:
     new c88c232889 feat: support mcp streamable http protocol and upgrade 
spring ai version (#3890)
c88c232889 is described below

commit c88c232889499507b1cb1bb199c120f6b7c3d990
Author: Tomsun28 <[email protected]>
AuthorDate: Mon Dec 8 22:12:35 2025 +0800

    feat: support mcp streamable http protocol and upgrade spring ai version 
(#3890)
    
    Signed-off-by: tomsun28 <[email protected]>
    Co-authored-by: shown <[email protected]>
---
 .markdownlint-cli2.jsonc                           |   2 +-
 hertzbeat-ai/pom.xml                               |   2 +-
 .../ai/config/CustomSseServerTransport.java        | 246 ---------------
 .../hertzbeat/ai/service/McpServerService.java     |  23 --
 .../impl/ChatClientProviderServiceImpl.java        |   4 +-
 .../ai/service/impl/McpServerServiceImpl.java      |  38 ---
 .../apache/hertzbeat/ai/tools/MonitorTools.java    |  28 +-
 .../ai/tools/impl/AlertDefineToolsImpl.java        |  12 +-
 .../hertzbeat/ai/tools/impl/AlertToolsImpl.java    |   4 +-
 .../hertzbeat/ai/tools/impl/MetricsToolsImpl.java  |   6 +-
 .../hertzbeat/ai/tools/impl/MonitorToolsImpl.java  | 334 +++++++++++----------
 .../apache/hertzbeat/common/util/IpDomainUtil.java |  26 +-
 .../hertzbeat/manager/pojo/dto/MonitorDto.java     |  16 +-
 .../manager/service/impl/MonitorServiceImpl.java   |   3 +-
 .../src/main/resources/application.yml             |  15 +-
 hertzbeat-startup/src/main/resources/sureness.yml  |  21 +-
 home/docs/community/become_committer.md            |   2 +-
 home/docs/community/become_pmc_member.md           |  16 +-
 home/docs/community/how-to-verify.md               |  31 +-
 home/docs/community/maturity.md                    |   2 +-
 home/docs/community/new_committer_process.md       |  28 +-
 home/docs/community/new_pmc_member_process.md      | 104 +++----
 home/docs/help/mcp_server.md                       |  74 ++++-
 .../current/community/become_committer.md          |   2 +-
 .../current/community/become_pmc_member.md         |   8 +-
 .../current/community/how-to-verify.md             |  31 +-
 .../current/community/new_committer_process.md     |  30 +-
 .../current/community/new_pmc_member_process.md    |  78 ++---
 .../current/help/mcp_server.md                     |  82 ++++-
 script/application.yml                             |  15 +-
 .../hertzbeat-mysql-iotdb/conf/application.yml     |  15 +-
 .../hertzbeat-mysql-iotdb/conf/sureness.yml        |  21 +-
 .../hertzbeat-mysql-tdengine/conf/application.yml  |  15 +-
 .../hertzbeat-mysql-tdengine/conf/sureness.yml     |  21 +-
 .../conf/application.yml                           |  15 +-
 .../conf/sureness.yml                              |  21 +-
 .../conf/application.yml                           |  15 +-
 .../conf/sureness.yml                              |  21 +-
 .../conf/application.yml                           |  15 +-
 .../conf/sureness.yml                              |  21 +-
 script/helm/hertzbeat-helm-chart                   |   2 +-
 script/sureness.yml                                |  21 +-
 42 files changed, 578 insertions(+), 908 deletions(-)

diff --git a/.markdownlint-cli2.jsonc b/.markdownlint-cli2.jsonc
index 97b4b771de..2ecdd1aea9 100644
--- a/.markdownlint-cli2.jsonc
+++ b/.markdownlint-cli2.jsonc
@@ -31,7 +31,7 @@
     "MD025": true,
     "MD029": true,
     "MD033": {
-      "allowed_elements": ["table", "tr", "td", "a", "img", "sub", "b", "br", 
"img", "tbody", "mark", "font"]
+      "allowed_elements": ["table", "tr", "td", "a", "img", "sub", "b", "br", 
"img", "tbody", "mark", "font", "Tabs", "TabItem"]
     },
     "MD036": false,
     "MD040": true,
diff --git a/hertzbeat-ai/pom.xml b/hertzbeat-ai/pom.xml
index de91bf7fa9..d026a98b3b 100644
--- a/hertzbeat-ai/pom.xml
+++ b/hertzbeat-ai/pom.xml
@@ -26,7 +26,7 @@
        <artifactId>hertzbeat-ai</artifactId>
        <version>${hertzbeat.version}</version>
        <properties>
-               <spring-ai.version>1.0.3</spring-ai.version>
+               <spring-ai.version>1.1.1</spring-ai.version>
                <java.version>17</java.version>
        </properties>
 
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/config/CustomSseServerTransport.java
 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/config/CustomSseServerTransport.java
deleted file mode 100644
index 825985e86a..0000000000
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/config/CustomSseServerTransport.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.hertzbeat.ai.config;
-
-
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.usthe.sureness.mgt.SurenessSecurityManager;
-import com.usthe.sureness.subject.SubjectSum;
-import io.modelcontextprotocol.spec.McpError;
-import io.modelcontextprotocol.spec.McpSchema;
-import io.modelcontextprotocol.spec.McpServerSession;
-import io.modelcontextprotocol.spec.McpServerTransport;
-import io.modelcontextprotocol.spec.McpServerTransportProvider;
-import io.modelcontextprotocol.util.Assert;
-import java.io.IOException;
-import java.time.Duration;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-
-import jakarta.servlet.http.HttpServletRequest;
-import lombok.Getter;
-import lombok.Setter;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.HttpStatus;
-import org.springframework.web.servlet.function.RouterFunction;
-import org.springframework.web.servlet.function.RouterFunctions;
-import org.springframework.web.servlet.function.ServerRequest;
-import org.springframework.web.servlet.function.ServerResponse;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-/**
- * Custom Server-Sent Events transport provider for Model Context Protocol.
- */
-@Slf4j
-public class CustomSseServerTransport implements McpServerTransportProvider {
-    private final ObjectMapper objectMapper;
-    private final String messageEndpoint;
-    private final String sseEndpoint;
-    private final String baseUrl;
-    @Getter
-    private final RouterFunction<ServerResponse> routerFunction;
-    @Setter
-    private McpServerSession.Factory sessionFactory;
-    private final Map<String, Object> sessionRequest = new HashMap<>();
-    private final ConcurrentHashMap<String, McpServerSession> sessions;
-    private volatile boolean isClosing;
-
-    public CustomSseServerTransport(ObjectMapper objectMapper, String 
messageEndpoint) {
-        this(objectMapper, messageEndpoint, "/sse");
-    }
-
-
-    public CustomSseServerTransport(ObjectMapper objectMapper, String 
messageEndpoint, String sseEndpoint) {
-        this(objectMapper, "", messageEndpoint, sseEndpoint);
-    }
-
-    public CustomSseServerTransport(ObjectMapper objectMapper, String baseUrl, 
String messageEndpoint, String sseEndpoint) {
-        this.sessions = new ConcurrentHashMap();
-        this.isClosing = false;
-        Assert.notNull(objectMapper, "ObjectMapper must not be null");
-        Assert.notNull(baseUrl, "Message base URL must not be null");
-        Assert.notNull(messageEndpoint, "Message endpoint must not be null");
-        Assert.notNull(sseEndpoint, "SSE endpoint must not be null");
-        this.objectMapper = objectMapper;
-        this.baseUrl = baseUrl;
-        this.messageEndpoint = messageEndpoint;
-        this.sseEndpoint = sseEndpoint;
-        this.routerFunction = RouterFunctions.route().GET(this.sseEndpoint, 
this::handleSseConnection).POST(this.messageEndpoint, 
this::handleMessage).build();
-    }
-
-    public Mono<Void> notifyClients(String method, Object params) {
-        if (this.sessions.isEmpty()) {
-            log.debug("No active sessions to broadcast message to");
-            return Mono.empty();
-        } else {
-            log.debug("Attempting to broadcast message to {} active sessions", 
this.sessions.size());
-            return Flux.fromIterable(this.sessions.values())
-                    .flatMap((session) -> session.sendNotification(method, 
params)
-                            .doOnError((e) -> log.error("Failed to send 
message to session {}: {}", session.getId(), e.getMessage()))
-                            .onErrorComplete())
-                    .then();
-        }
-    }
-
-    public Mono<Void> closeGracefully() {
-        return Flux.fromIterable(this.sessions.values()).doFirst(() -> {
-            this.isClosing = true;
-            log.debug("Initiating graceful shutdown with {} active sessions", 
this.sessions.size());
-        }).flatMap(McpServerSession::closeGracefully).then().doOnSuccess((v) 
-> log.debug("Graceful shutdown completed"));
-    }
-
-    private ServerResponse handleSseConnection(ServerRequest request) {
-        log.debug("Handling SSE connection for request: {}", request);
-        HttpServletRequest servletRequest = request.servletRequest();
-
-        try {
-
-            log.debug("Processing SSE connection for servlet request: {}", 
servletRequest);
-            log.debug("Authorization header: {}", 
servletRequest.getHeader("Authorization"));
-
-
-        } catch (Exception e) {
-            log.error("Authentication failed for SSE connection: {}", 
e.getMessage());
-            return 
ServerResponse.status(HttpStatus.UNAUTHORIZED).body("Unauthorized: " + 
e.getMessage());
-        }
-
-
-
-        if (this.isClosing) {
-            return 
ServerResponse.status(HttpStatus.SERVICE_UNAVAILABLE).body("Server is shutting 
down");
-        } else {
-            String sessionId = UUID.randomUUID().toString();
-            log.debug("Generated session ID for SSE connection: {}", 
sessionId);
-            log.debug("Creating new SSE connection for session: {}", 
sessionId);
-
-
-            return ServerResponse.sse((sseBuilder) -> {
-                sseBuilder.onComplete(() -> {
-                    log.debug("SSE connection completed for session: {}", 
sessionId);
-                    this.sessions.remove(sessionId);
-                });
-                sseBuilder.onTimeout(() -> {
-                    log.debug("SSE connection timed out for session: {}", 
sessionId);
-                    this.sessions.remove(sessionId);
-                });
-                CustomSseServerTransport.WebMvcMcpSessionTransport 
sessionTransport = new 
CustomSseServerTransport.WebMvcMcpSessionTransport(sessionId, sseBuilder);
-                McpServerSession session = 
this.sessionFactory.create(sessionTransport);
-                this.sessionRequest.put(sessionId, request.servletRequest());
-                this.sessions.put(sessionId, session);
-
-                try {
-                    
sseBuilder.id(sessionId).event("endpoint").data(this.baseUrl + 
this.messageEndpoint + "?sessionId=" + sessionId);
-                } catch (Exception e) {
-                    log.error("Failed to send initial endpoint event: {}", 
e.getMessage());
-                    sseBuilder.error(e);
-                }
-
-            }, Duration.ZERO);
-
-        }
-    }
-
-    private ServerResponse handleMessage(ServerRequest request) {
-        if (this.isClosing) {
-            return 
ServerResponse.status(HttpStatus.SERVICE_UNAVAILABLE).body("Server is shutting 
down");
-        } else if (request.param("sessionId").isEmpty()) {
-            return ServerResponse.badRequest().body(new McpError("Session ID 
missing in message endpoint"));
-        } else {
-            String sessionId = (String) request.param("sessionId").get();
-            McpServerSession session = (McpServerSession) 
this.sessions.get(sessionId);
-            log.debug("Authorization header for message request: {}", 
request.servletRequest().getHeader("Authorization"));
-            SubjectSum subject = 
SurenessSecurityManager.getInstance().checkIn(sessionRequest.get(sessionId));
-            McpContextHolder.setSubject(subject);
-
-
-            if (session == null) {
-                return ServerResponse.status(HttpStatus.NOT_FOUND).body(new 
McpError("Session not found: " + sessionId));
-            } else {
-                try {
-                    String body = request.body(String.class);
-                    McpSchema.JSONRPCMessage message = 
McpSchema.deserializeJsonRpcMessage(this.objectMapper, body);
-                    session.handle(message).block();
-                    return ServerResponse.ok().build();
-                } catch (IOException | IllegalArgumentException e) {
-                    log.error("Failed to deserialize message: {}", 
((Exception) e).getMessage());
-                    return ServerResponse.badRequest().body(new 
McpError("Invalid message format"));
-                } catch (Exception e) {
-                    log.error("Error handling message: {}", e.getMessage());
-                    return 
ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new 
McpError(e.getMessage()));
-                }
-            }
-        }
-    }
-
-    private class WebMvcMcpSessionTransport implements McpServerTransport {
-        private final String sessionId;
-        private final ServerResponse.SseBuilder sseBuilder;
-
-        WebMvcMcpSessionTransport(String sessionId, ServerResponse.SseBuilder 
sseBuilder) {
-            this.sessionId = sessionId;
-            this.sseBuilder = sseBuilder;
-            log.debug("Session transport {} initialized with SSE builder", 
sessionId);
-        }
-
-        public Mono<Void> sendMessage(McpSchema.JSONRPCMessage message) {
-            return Mono.fromRunnable(() -> {
-                try {
-                    String jsonText = 
CustomSseServerTransport.this.objectMapper.writeValueAsString(message);
-                    
this.sseBuilder.id(this.sessionId).event("message").data(jsonText);
-                    log.debug("Message sent to session {}", this.sessionId);
-                } catch (Exception e) {
-                    log.error("Failed to send message to session {}: {}", 
this.sessionId, e.getMessage());
-                    this.sseBuilder.error(e);
-                }
-
-            });
-        }
-
-        public <T> T unmarshalFrom(Object data, TypeReference<T> typeRef) {
-            return (T) 
CustomSseServerTransport.this.objectMapper.convertValue(data, typeRef);
-        }
-
-        public Mono<Void> closeGracefully() {
-            return Mono.fromRunnable(() -> {
-                log.debug("Closing session transport: {}", this.sessionId);
-
-                try {
-                    this.sseBuilder.complete();
-                    log.debug("Successfully completed SSE builder for session 
{}", this.sessionId);
-                } catch (Exception e) {
-                    log.warn("Failed to complete SSE builder for session {}: 
{}", this.sessionId, e.getMessage());
-                }
-
-            });
-        }
-
-        public void close() {
-            try {
-                this.sseBuilder.complete();
-                log.debug("Successfully completed SSE builder for session {}", 
this.sessionId);
-            } catch (Exception e) {
-                log.warn("Failed to complete SSE builder for session {}: {}", 
this.sessionId, e.getMessage());
-            }
-
-        }
-    }
-}
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/McpServerService.java
 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/McpServerService.java
index 6b518413d2..695a26ae03 100644
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/McpServerService.java
+++ 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/McpServerService.java
@@ -18,12 +18,7 @@
 
 package org.apache.hertzbeat.ai.service;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.apache.hertzbeat.ai.config.CustomSseServerTransport;
-import org.springframework.ai.mcp.server.autoconfigure.McpServerProperties;
 import org.springframework.ai.tool.ToolCallbackProvider;
-import org.springframework.web.servlet.function.RouterFunction;
-import org.springframework.web.servlet.function.ServerResponse;
 
 /**
  * Service interface for MCP server operations.
@@ -35,22 +30,4 @@ public interface McpServerService {
      * @return ToolCallbackProvider with all HertzBeat monitoring tools
      */
     ToolCallbackProvider hertzbeatTools();
-
-    /**
-     * Provides a custom SSE server transport for the MCP server
-     * @param objectMapper the ObjectMapper instance for JSON serialization
-     * @param serverProperties the properties for the MCP server configuration
-     * @return a CustomSseServerTransport instance configured with the 
provided properties
-     */
-    CustomSseServerTransport webMvcSseServerTransportProvider(
-            ObjectMapper objectMapper,
-            McpServerProperties serverProperties
-    );
-
-    /**
-     * Provides the MCP server router function for web MVC
-     * @param transport Custom SSE server transport
-     * @return RouterFunction for handling MCP server requests
-     */
-    RouterFunction<ServerResponse> 
mvcMcpRouterFunction(CustomSseServerTransport transport);
 }
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/impl/ChatClientProviderServiceImpl.java
 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/impl/ChatClientProviderServiceImpl.java
index 38e49c3a35..293edf11a2 100644
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/impl/ChatClientProviderServiceImpl.java
+++ 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/impl/ChatClientProviderServiceImpl.java
@@ -34,7 +34,6 @@ import org.springframework.ai.chat.messages.Message;
 import org.springframework.ai.chat.messages.UserMessage;
 import org.springframework.ai.tool.ToolCallbackProvider;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.ApplicationContext;
 import reactor.core.publisher.Flux;
 
@@ -53,8 +52,7 @@ public class ChatClientProviderServiceImpl implements 
ChatClientProviderService
     private final ApplicationContext applicationContext;
 
     private final GeneralConfigDao generalConfigDao;
-
-    @Qualifier("hertzbeatTools")
+    
     @Autowired
     private ToolCallbackProvider toolCallbackProvider;
     
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/impl/McpServerServiceImpl.java
 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/impl/McpServerServiceImpl.java
index 6af80b1b12..cdb2418397 100644
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/impl/McpServerServiceImpl.java
+++ 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/impl/McpServerServiceImpl.java
@@ -18,23 +18,17 @@
 
 package org.apache.hertzbeat.ai.service.impl;
 
-import org.apache.hertzbeat.ai.config.CustomSseServerTransport;
 import org.apache.hertzbeat.ai.service.McpServerService;
 import org.apache.hertzbeat.ai.tools.AlertDefineTools;
 import org.apache.hertzbeat.ai.tools.AlertTools;
 import org.apache.hertzbeat.ai.tools.MetricsTools;
 import org.apache.hertzbeat.ai.tools.MonitorTools;
-import org.springframework.ai.mcp.server.autoconfigure.McpServerProperties;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Primary;
 import org.springframework.stereotype.Service;
 import org.springframework.ai.tool.ToolCallbackProvider;
 import org.springframework.ai.tool.method.MethodToolCallbackProvider;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.springframework.web.servlet.function.RouterFunction;
-import org.springframework.web.servlet.function.ServerResponse;
 
 /**
  * Implementation of the McpServerService interface.
@@ -56,36 +50,4 @@ public class McpServerServiceImpl implements 
McpServerService {
     public ToolCallbackProvider hertzbeatTools() {
         return MethodToolCallbackProvider.builder().toolObjects(monitorTools, 
alertTools, alertDefineTools, metricsTools).build();
     }
-    /**
-     * Provides a custom SSE server transport for the MCP server.
-     *
-     * @param objectMapper the ObjectMapper instance for JSON serialization
-     * @param serverProperties the properties for the MCP server configuration
-     * @return a CustomSseServerTransport instance configured with the 
provided properties
-     */
-
-    @Bean
-    public CustomSseServerTransport webMvcSseServerTransportProvider(
-            ObjectMapper objectMapper,
-            McpServerProperties serverProperties
-    ) {
-        return new CustomSseServerTransport(
-                objectMapper,
-                serverProperties.getBaseUrl(),
-                serverProperties.getSseMessageEndpoint(),
-                serverProperties.getSseEndpoint()
-        );
-    }
-    /**
-     * Provides the MCP server transport bean.
-     *
-     * @param transport the custom SSE server transport
-     * @return the MCP server transport instance
-     */
-
-    @Primary
-    @Bean
-    public RouterFunction<ServerResponse> 
mvcMcpRouterFunction(CustomSseServerTransport transport) {
-        return transport.getRouterFunction();
-    }
 }
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/MonitorTools.java 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/MonitorTools.java
index 95d6cfe676..24a32313de 100644
--- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/MonitorTools.java
+++ b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/MonitorTools.java
@@ -27,35 +27,25 @@ public interface MonitorTools {
 
     /**
      * Add a new monitor with comprehensive configuration
-     * 
+     *
      * @param name Monitor name
      * @param app Monitor type/application (e.g., 'linux', 'mysql', 'http')
-     * @param host Target host (IP address or domain name)
-     * @param port Target port (optional, depends on monitor type)
      * @param intervals Collection interval in seconds (default: 600)
-     * @param username Username for authentication (optional)
-     * @param password Password for authentication (optional)
-     * @param database Database name (for database monitors)
-     * @param additionalParams Additional app-specific parameters as JSON 
string (optional)
+     * @param params Monitor-specific parameters as JSON string (e.g., host, 
port, username, password, etc.)
      * @param description Monitor description (optional)
      * @return Result message with monitor ID if successful
      */
     String addMonitor(
-            String name, 
-            String app, 
-            String host,
-            Integer port,
+            String name,
+            String app,
             Integer intervals,
-            String username,
-            String password,
-            String database,
-            String additionalParams,
+            String params,
             String description
     );
-    
+
     /**
      * List all available monitor types that can be added
-     * 
+     *
      * @param language Language code for localized names (e.g., 'en-US', 
'zh-CN')
      * @return Formatted string list of available monitor types with 
descriptions
      */
@@ -89,9 +79,9 @@ public interface MonitorTools {
 
     /**
      * Get parameter definitions required for a specific monitor type
-     * 
+     *
      * @param app Monitor type/application name (e.g., 'linux', 'mysql', 
'redis')
      * @return Formatted string with parameter definitions including field 
names, types, and requirements
      */
-    String getMonitorAdditionalParams(String app);
+    String getMonitorParams(String app);
 }
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertDefineToolsImpl.java
 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertDefineToolsImpl.java
index 726617d815..561de4cb19 100644
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertDefineToolsImpl.java
+++ 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertDefineToolsImpl.java
@@ -54,7 +54,7 @@ public class AlertDefineToolsImpl implements AlertDefineTools 
{
 
     @Override
     @Tool(name = "create_alert_rule", description = """
-            ALERT RULE means when to alert a user
+            HertzBeat: ALERT RULE means when to alert a user
             THESE ARE ALERT RULES WITH THRESHOLD VALUES. USERS CAN SPECIFY THE 
THRESHOLD VALUES FOR EXAMPLE,
             IF THE USER SAYS "ALERT ME WHEN MY COST EXCEEDS 700, THE 
EXPRESSION SHOULD BE 'cost > 700' NOT 'cost < 700'.
             APPLY THE SAME LOGIC FOR LESS THAN OPERATOR.
@@ -281,7 +281,7 @@ public class AlertDefineToolsImpl implements 
AlertDefineTools {
 
     @Override
     @Tool(name = "list_alert_rules", description = """
-            List existing alert rules with filtering options.
+            HertzBeat: List existing alert rules with filtering options.
             Shows configured thresholds and alert definitions.
             """)
     public String listAlertRules(
@@ -343,7 +343,7 @@ public class AlertDefineToolsImpl implements 
AlertDefineTools {
 
     @Override
     @Tool(name = "toggle_alert_rule", description = """
-            Enable or disable an alert rule.
+            HertzBeat: Enable or disable an alert rule.
             Allows activating or deactivating threshold monitoring.
             """)
     public String toggleAlertRule(
@@ -382,7 +382,7 @@ public class AlertDefineToolsImpl implements 
AlertDefineTools {
 
     @Override
     @Tool(name = "get_alert_rule_details", description = """
-            Get detailed information about a specific alert rule.
+            HertzBeat: Get detailed information about a specific alert rule.
             Shows complete threshold configuration and rule settings.
             """)
     public String getAlertRuleDetails(
@@ -441,7 +441,7 @@ public class AlertDefineToolsImpl implements 
AlertDefineTools {
 
     @Override
     @Tool(name = "get_apps_metrics_hierarchy", description = """
-            Get the hierarchical structure of all available apps and their 
metrics for alert rule creation.
+            HertzBeat: Get the hierarchical structure of all available apps 
and their metrics for alert rule creation.
             This tool provides the exact app name, metric name and 
corresponding param names according to each metric.
             Returns structured JSON data showing the complete hierarchy with 
field parameters for alert expressions.
             
@@ -494,7 +494,7 @@ public class AlertDefineToolsImpl implements 
AlertDefineTools {
 
     @Override
     @Tool(name = "bind_monitors_to_alert_rule", description = """
-            Bind monitors to an alert rule.
+            HertzBeat: Bind monitors to an alert rule.
             Call this tool if users want to bind specific monitors to their 
alert rule.
             Get the right monitor ids for a particular app using the 
query_monitors tool.
             Get the alert rule ID from the create_alert_rule tool output OR 
use the list_alert_rules tool with app_name search filter, if the output of 
create_alert_rule is not applicable.
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertToolsImpl.java
 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertToolsImpl.java
index ad1f978828..d90de29b28 100644
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertToolsImpl.java
+++ 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertToolsImpl.java
@@ -45,7 +45,7 @@ public class AlertToolsImpl implements AlertTools {
 
     @Override
     @Tool(name = "query_alerts", description = """
-            Query alerts with comprehensive filtering and pagination options.
+            HertzBeat: Query alerts with comprehensive filtering and 
pagination options.
             
             ALERT TYPES:
             - Pass alertType='single' for individual alert instances
@@ -196,7 +196,7 @@ public class AlertToolsImpl implements AlertTools {
 
     @Override
     @Tool(name = "get_alerts_summary", description = """
-            Get alerts summary statistics including total counts, status 
distribution, and recent trends.
+            HertzBeat: Get alerts summary statistics including total counts, 
status distribution, and recent trends.
             Returns comprehensive overview of the current alerting status 
across all monitors.
             """)
     public String getAlertsSummary() {
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/MetricsToolsImpl.java
 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/MetricsToolsImpl.java
index 439a85d801..1cd0f85827 100644
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/MetricsToolsImpl.java
+++ 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/MetricsToolsImpl.java
@@ -47,7 +47,7 @@ public class MetricsToolsImpl implements MetricsTools {
 
     @Override
     @Tool(name = "query_realtime_metrics", description = """
-            Get the supported monitor types/names from the list_monitor_types 
tool, make sure to use right name in the next call
+            HertzBeat: Get the supported monitor types/names from the 
list_monitor_types tool, make sure to use right name in the next call
             Use the query_monitors tool to find monitor IDs in case the user 
does not tell the id explicitly. You might have to use this multiple times 
based on the user's query
             Get real-time metrics data for a specific monitor.
             Returns current metrics values including CPU, memory, disk usage, 
etc.
@@ -144,7 +144,7 @@ public class MetricsToolsImpl implements MetricsTools {
 
     @Override
     @Tool(name = "get_historical_metrics", description = """
-            Get historical metrics data for analysis and trending.
+            HertzBeat: Get historical metrics data for analysis and trending.
             Returns time-series data for specified metrics over a time range.
             Use the query_monitors tool to find the correct monitor IDs/ name 
or type for the monitor(s) user asked the metrics for
             Pass that name into the get_apps_metrics_hierarchy tool to get the 
metrics hierarchy i.e metrics and the field paramater
@@ -226,7 +226,7 @@ public class MetricsToolsImpl implements MetricsTools {
 
     @Override
     @Tool(name = "get_warehouse_status", description = """
-            Check the status of the metrics storage warehouse system.
+            HertzBeat: Check the status of the metrics storage warehouse 
system.
             Returns whether the metrics storage is operational and accessible.
             """)
     public String getWarehouseStatus() {
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/MonitorToolsImpl.java
 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/MonitorToolsImpl.java
index 5da5e53269..0c2ec738b4 100644
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/MonitorToolsImpl.java
+++ 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/MonitorToolsImpl.java
@@ -20,6 +20,7 @@ package org.apache.hertzbeat.ai.tools.impl;
 import com.usthe.sureness.subject.SubjectSum;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.hertzbeat.ai.config.McpContextHolder;
+import org.apache.hertzbeat.manager.pojo.dto.MonitorDto;
 import org.apache.hertzbeat.manager.service.MonitorService;
 import org.apache.hertzbeat.manager.service.AppService;
 import org.apache.hertzbeat.ai.utils.UtilityClass;
@@ -36,7 +37,6 @@ import org.apache.hertzbeat.common.entity.manager.ParamDefine;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 
 /**
  * Implementation of Monitoring Tools functionality
@@ -57,48 +57,48 @@ public class MonitorToolsImpl implements MonitorTools {
      * Returns detailed monitor information including ID, name, type, host, 
and status.
      */
     @Override
-    @Tool(name = "query_monitors", description = """ 
-            Query Existing/configured monitors in HertzBeat.
+    @Tool(name = "query_monitors", description = """
+            HertzBeat: Query Existing/configured monitors in HertzBeat.
             This tool retrieves monitors based on various filters and 
parameters.
             Comprehensive monitor querying with flexible filtering, 
pagination, and specialized views.
-            
+
             MONITOR STATUSES:
             - status=1: Online/Active monitors (healthy, responding normally)
             - status=2: Offline monitors (not responding, connection failed)
             - status=3: Unreachable monitors (network/connectivity issues)
             - status=0: Paused monitors (manually disabled/suspended)
             - status=9 or null: All monitors regardless of status (default)
-            
+
             COMMON USE CASES & PARAMETER COMBINATIONS:
-            
+
             1. BASIC MONITOR LISTING:
                - Default: No parameters (shows all monitors, 8 per page)
                - By type: app='linux' (show only Linux monitors)
                - Search: search='web' (find monitors with 'web' in name/host)
-            
+
             2. STATUS-BASED QUERIES:
                - Healthy monitors: status=1, pageSize=50
                - Problem monitors: status=2 or status=3, pageSize=50
                - Offline monitors only: status=2
                - Unreachable monitors only: status=3
                - Paused monitors: status=0
-            
+
             3. MONITORING HEALTH OVERVIEW:
                - All statuses with statistics: status=9, includeStats=true, 
pageSize=100
                - Unhealthy monitors: Pass both status=2 AND status=3 (make 2 
separate calls)
-            
+
             4. ADVANCED FILTERING:
                - Specific monitor types: app='mysql', status=1 (healthy MySQL 
monitors)
                - Label-based: labels='env:prod,critical:true'
                - Host search: search='192.168' (find by IP pattern)
                - Monitor IDs: ids=[1,2,3] (specific monitors by ID)
-            
+
             5. SORTING & PAGINATION:
                - Recently updated: sort='gmtUpdate', order='desc'
                - Alphabetical: sort='name', order='asc'
                - By creation: sort='gmtCreate', order='desc' (newest first)
                - Large datasets: pageSize=50-100 for bulk operations
-            
+
             RESPONSE FORMAT:
             - includeStats=true: Adds status distribution summary at top
             - Default: Simple list with ID, name, type, host, status
@@ -126,18 +126,18 @@ public class MonitorToolsImpl implements MonitorTools {
             if (includeStats == null) {
                 includeStats = false;
             }
-            
+
             SubjectSum subjectSum = McpContextHolder.getSubject();
             log.debug("Current security subject: {}", subjectSum);
 
             Page<Monitor> result = monitorService.getMonitors(
                     ids, app, search, status, sort, order, pageIndex, 
pageSize, labels);
             log.debug("MonitorService.getMonitors result: {}", result);
-            
+
             StringBuilder response = new StringBuilder();
             response.append("MONITOR QUERY RESULTS\n");
             response.append("====================\n\n");
-            
+
             // Include statistics if requested
             if (includeStats) {
                 // Get status distribution by calling with different status 
values
@@ -145,13 +145,13 @@ public class MonitorToolsImpl implements MonitorTools {
                 long offlineCount = monitorService.getMonitors(null, app, 
search, (byte) 2, null, null, 0, 1000, labels).getTotalElements();
                 long unreachableCount = monitorService.getMonitors(null, app, 
search, (byte) 3, null, null, 0, 1000, labels).getTotalElements();
                 long pausedCount = monitorService.getMonitors(null, app, 
search, (byte) 0, null, null, 0, 1000, labels).getTotalElements();
-                
+
                 response.append("STATUS OVERVIEW:\n");
                 response.append("- Online: ").append(onlineCount).append("\n");
-                response.append("- Offline: 
").append(offlineCount).append("\n"); 
+                response.append("- Offline: 
").append(offlineCount).append("\n");
                 response.append("- Unreachable: 
").append(unreachableCount).append("\n");
                 response.append("- Paused: ").append(pausedCount).append("\n");
-                
+
                 long total = onlineCount + offlineCount + unreachableCount + 
pausedCount;
                 if (total > 0) {
                     double healthPercentage = (onlineCount * 100.0) / total;
@@ -159,34 +159,34 @@ public class MonitorToolsImpl implements MonitorTools {
                 }
                 response.append("\n");
             }
-            
+
             response.append("Query Results: 
").append(result.getContent().size())
                    .append(" monitors (Total: 
").append(result.getTotalElements()).append(")\n");
-            
+
             if (result.getTotalPages() > 1) {
                 response.append("Page ").append(pageIndex + 1).append(" of 
").append(result.getTotalPages()).append("\n");
             }
             response.append("\n");
-            
+
             for (Monitor monitor : result.getContent()) {
                 response.append("ID: ").append(monitor.getId())
                        .append(" | Name: ").append(monitor.getName())
                        .append(" | Type: ").append(monitor.getApp())
                        .append(" | Instance: ").append(monitor.getInstance())
                        .append(" | Status: 
").append(UtilityClass.getStatusText(monitor.getStatus()));
-                       
+
                 // Add creation date for better context
                 if (monitor.getGmtCreate() != null) {
                     response.append(" | Created: 
").append(monitor.getGmtCreate().toString(), 0, 10);
                 }
                 response.append("\n");
             }
-            
+
             if (result.getContent().isEmpty()) {
                 response.append("No monitors found matching the specified 
criteria.\n");
                 response.append("Try adjusting your filters or search terms.");
             }
-            
+
             return response.toString();
         } catch (Exception e) {
             return "Error retrieving monitors: " + e.getMessage();
@@ -196,11 +196,11 @@ public class MonitorToolsImpl implements MonitorTools {
 
     @Override
     @Tool(name = "add_monitor", description = """
-            Add a new monitoring target to HertzBeat with comprehensive 
configuration.
+            HertzBeat: Add a new monitoring target to HertzBeat with 
comprehensive configuration.
             This tool dynamically handles different parameter requirements for 
each monitor type.
-            
+
             This tool creates monitors with proper app-specific parameters.
-            
+
             *********
             VERY IMPORTANT:
             ALWAYS use get_monitor_additional_params to check the additional 
required parameters for the chosen type before adding a monitor or even 
mentioning it.
@@ -208,41 +208,36 @@ public class MonitorToolsImpl implements MonitorTools {
             Use the information obtained from this to query user for 
parameters.
             If the User has not given any parameters, ask them to provide the 
necessary parameters, until all the necessary parameters are provided.
             **********
-            
+
             Examples of natural language requests this tool handles:
             - "Monitor website example.com with HTTPS on port 443"
             - "Add MySQL monitoring for database server at 192.168.1.10 with 
user admin"
             - "Monitor Linux server health on host server.company.com via SSH"
             - "Set up Redis monitoring on localhost port 6379 with password"
-            
-            PARAMETER MAPPING: The tool intelligently maps common parameters:
-            - host: Target server/domain
-            - port: Service port (auto-detected if not specified)
-            - username: Authentication username
-            - password: Authentication password
-            - database: Database name (for DB monitors)
-            - additionalParams: JSON string for app-specific parameters (to be 
obtained from get_monitor_param_defines)
-            
-            ADDITIONAL PARAMETERS EXAMPLES:
-            - Website: {"uri":"/api/health", "ssl":"true", "method":"POST"}
-            - Linux: {"privateKey":"ssh-key-content", "script":"custom-script"}
-            - Database: {"url":"jdbc:mysql://custom", "timeout":"10000"}
+
+            PARAMETER MAPPING: Use the 'params' parameter to pass all 
monitor-specific configuration.
+            The params should be a JSON string containing key-value pairs for 
the monitor type.
+            Use get_monitor_additional_params tool to see what parameters are 
required for each monitor type.
+
+            PARAMS EXAMPLES:
+            - Website: {"host":"example.com", "port":"443", 
"uri":"/api/health", "ssl":"true", "method":"GET"}
+            - Linux: {"host":"192.168.1.10", "port":"22", "username":"root", 
"password":"xxx"}
+            - MySQL: {"host":"db.server.com", "port":"3306", 
"username":"admin", "password":"xxx", "database":"mydb"}
+            - Redis: {"host":"redis.server.com", "port":"6379", 
"password":"xxx"}
             """)
     public String addMonitor(
             @ToolParam(description = "Monitor name (required)", required = 
true) String name,
             @ToolParam(description = "Monitor type: website, mysql, 
postgresql, redis, linux, windows, etc.", required = true) String app,
-            @ToolParam(description = "Target host: IP address or domain name", 
required = true) String host,
-            @ToolParam(description = "Target port (optional, auto-detected if 
not specified)", required = false) Integer port,
             @ToolParam(description = "Collection interval in seconds (default: 
600)", required = false) Integer intervals,
-            @ToolParam(description = "Username for authentication (optional)", 
required = false) String username,
-            @ToolParam(description = "Password for authentication (optional)", 
required = false) String password,
-            @ToolParam(description = "Database name (for database monitors)", 
required = false) String database,
-            @ToolParam(description = "Additional app-specific parameters as 
JSON: {\"uri\":\"/api\", \"ssl\":\"true\", \"method\":\"POST\"}", required = 
false) String additionalParams,
+            @ToolParam(description = "Monitor-specific parameters as JSON 
string. "
+                    + "Use get_monitor_additional_params to see required 
fields. "
+                    + "Example: {\"host\":\"192.168.1.1\", \"port\":\"22\", 
\"username\":\"root\"}",
+                    required = true) String params,
             @ToolParam(description = "Monitor description (optional)", 
required = false) String description) {
-        
+
         try {
-            log.info("Adding monitor: name={}, app={}, host={}", name, app, 
host);
-            
+            log.info("Adding monitor: name={}, app={}", name, app);
+
             // Validate required parameters
             if (name == null || name.trim().isEmpty()) {
                 return "Error: Monitor name is required";
@@ -250,16 +245,29 @@ public class MonitorToolsImpl implements MonitorTools {
             if (app == null || app.trim().isEmpty()) {
                 return "Error: Monitor type/application is required";
             }
-            if (host == null || host.trim().isEmpty()) {
-                return "Error: Host is required";
+            if (params == null || params.trim().isEmpty()) {
+                return "Error: Monitor params is required. Use 
get_monitor_additional_params to see required fields for this monitor type.";
             }
-            
+
             // Set defaults
             if (intervals == null || intervals < 10) {
                 intervals = 600;
             }
 
-            String instance = Objects.nonNull(port) ? host.trim() + ":" + port 
: host.trim();
+            // Parse params to extract host and port for instance
+            List<Param> paramList = parseParams(params);
+            String host = paramList.stream()
+                    .filter(p -> "host".equals(p.getField()))
+                    .map(Param::getParamValue)
+                    .findFirst()
+                    .orElse("");
+            String port = paramList.stream()
+                    .filter(p -> "port".equals(p.getField()))
+                    .map(Param::getParamValue)
+                    .findFirst()
+                    .orElse(null);
+
+            String instance = (port != null && !port.isEmpty()) ? host.trim() 
+ ":" + port : host.trim();
 
             // Create Monitor entity
             Monitor monitor = Monitor.builder()
@@ -271,109 +279,119 @@ public class MonitorToolsImpl implements MonitorTools {
                     .type((byte) 0)
                     .description(description != null ? description.trim() : "")
                     .build();
-            
-            List<Param> params = createBasicParams(host, port, username, 
password, database, additionalParams);
-            
+
             // Validate that all required parameters for this monitor type are 
provided
             try {
-                SubjectSum subjectSum = McpContextHolder.getSubject();
-                log.debug("Current security subject for 
getMonitorParamDefines: {}", subjectSum);
-
-                List<ParamDefine> requiredParams = 
appService.getAppParamDefines(app.toLowerCase().trim());
-                log.info("Checking required parameters for monitor type '{}': 
{}", app, requiredParams);
-                List<String> missingParams = new ArrayList<>();
-                
-                for (ParamDefine paramDefine : requiredParams) {
-                    if (paramDefine.isRequired()) {
-                        String fieldName = paramDefine.getField();
-                        boolean hasParam = params.stream()
-                                .anyMatch(param -> 
fieldName.equals(param.getField()));
-                        if (!hasParam) {
-                            missingParams.add(fieldName);
-                        }
-                    }
-                }
-                
-                if (!missingParams.isEmpty()) {
-                    return String.format("Error: Missing required parameters 
for monitor type '%s': %s. "
-                            + "Use get_monitor_additional_params tool to see 
all required parameters.", 
-                            app, String.join(", ", missingParams));
+                MonitorDto monitorDto = 
MonitorDto.builder().monitor(monitor).params(paramList).build();
+                monitorService.validate(monitorDto, false);
+            } catch (IllegalArgumentException argumentException) {
+                if (argumentException.getMessage().contains("required")) {
+                    return String.format("Error: %s. "
+                            + "Or use get_monitor_additional_params tool to 
see all required parameters.",
+                        argumentException.getMessage());
+                } else {
+                    return String.format("Error: %s. ", 
argumentException.getMessage());
                 }
-            } catch (Exception e) {
-                log.warn("Could not validate required parameters for monitor 
type '{}': {}", app, e.getMessage());
             }
-            
-            // Call monitor service - it handles all the complexity 
(validation, defaults, app-specific logic)
-            SubjectSum subjectSum = McpContextHolder.getSubject();
-            log.debug("Current security subject for addMonitor: {}", 
subjectSum);
-
-            monitorService.addMonitor(monitor, params, null, null);
-            Long monitorId = monitor.getId();
-            
-            log.info("Successfully added monitor '{}' with ID: {}", name, 
monitorId);
-            return String.format("Successfully added %s monitor '%s' with ID: 
%d (Host: %s, Interval: %d seconds)", 
-                    app.toUpperCase(), name, monitorId, host, intervals);
-            
+            monitorService.addMonitor(monitor, paramList, null, null);
+            log.info("Successfully added monitor '{}' with ID: {}", 
monitor.getName(), monitor.getId());
+            return String.format("Successfully added %s monitor '%s' with ID: 
%d (Instance: %s, Interval: %d seconds)",
+                    app.toUpperCase(), monitor.getName(), monitor.getId(), 
monitor.getInstance(), monitor.getIntervals());
+
         } catch (Exception e) {
             log.error("Failed to add monitor '{}': {}", name, e.getMessage(), 
e);
             return "Error adding monitor '" + name + "': " + e.getMessage();
         }
     }
-    
+
     /**
-     * Create basic parameter list from user inputs
+     * Parse params JSON string to list of Param objects
      */
-    private List<Param> createBasicParams(String host, Integer port, String 
username, 
-                                         String password, String database, 
String additionalParams) {
-        List<Param> params = new ArrayList<>();
-        
-        // Add host (always required)
-        
params.add(Param.builder().field("host").paramValue(host.trim()).type((byte) 
1).build());
-        
-        // Add optional common parameters
-        if (port != null) {
-            
params.add(Param.builder().field("port").paramValue(port.toString()).type((byte)
 0).build());
-        }
-        if (username != null && !username.trim().isEmpty()) {
-            
params.add(Param.builder().field("username").paramValue(username.trim()).type((byte)
 1).build());
-        }
-        if (password != null && !password.trim().isEmpty()) {
-            
params.add(Param.builder().field("password").paramValue(password.trim()).type((byte)
 2).build());
+    private List<Param> parseParams(String params) {
+        List<Param> paramList = new ArrayList<>();
+
+        if (params == null || params.trim().isEmpty()) {
+            return paramList;
         }
-        if (database != null && !database.trim().isEmpty()) {
-            
params.add(Param.builder().field("database").paramValue(database.trim()).type((byte)
 1).build());
+
+        try {
+            String cleaned = params.trim();
+            // Remove outer braces if present
+            if (cleaned.startsWith("{") && cleaned.endsWith("}")) {
+                cleaned = cleaned.substring(1, cleaned.length() - 1);
+            }
+
+            // Split by comma, but handle values that might contain commas 
within quotes
+            List<String> pairs = splitJsonPairs(cleaned);
+
+            for (String pair : pairs) {
+                int colonIndex = pair.indexOf(':');
+                if (colonIndex > 0) {
+                    String key = pair.substring(0, 
colonIndex).trim().replaceAll("\"", "");
+                    String value = pair.substring(colonIndex + 
1).trim().replaceAll("\"", "");
+
+                    // Determine param type based on field name
+                    byte paramType = determineParamType(key);
+                    
paramList.add(Param.builder().field(key).paramValue(value).type(paramType).build());
+                }
+            }
+        } catch (Exception e) {
+            log.warn("Failed to parse params: {}", e.getMessage());
         }
-        
-        // Parse additional parameters if provided
-        if (additionalParams != null && !additionalParams.trim().isEmpty()) {
-            try {
-                String cleaned = additionalParams.trim().replaceAll("[{}]", 
"");
-                String[] pairs = cleaned.split(",");
-                for (String pair : pairs) {
-                    String[] keyValue = pair.split(":");
-                    if (keyValue.length == 2) {
-                        String key = keyValue[0].trim().replaceAll("\"", "");
-                        String value = keyValue[1].trim().replaceAll("\"", "");
-                        
params.add(Param.builder().field(key).paramValue(value).type((byte) 1).build());
-                    }
+
+        return paramList;
+    }
+
+    /**
+     * Split JSON key-value pairs, handling quoted values that may contain 
commas
+     */
+    private List<String> splitJsonPairs(String json) {
+        List<String> pairs = new ArrayList<>();
+        StringBuilder current = new StringBuilder();
+        boolean inQuotes = false;
+
+        for (char c : json.toCharArray()) {
+            if (c == '"') {
+                inQuotes = !inQuotes;
+                current.append(c);
+            } else if (c == ',' && !inQuotes) {
+                if (current.length() > 0) {
+                    pairs.add(current.toString().trim());
+                    current = new StringBuilder();
                 }
-            } catch (Exception e) {
-                log.warn("Failed to parse additionalParams: {}", 
e.getMessage());
+            } else {
+                current.append(c);
             }
         }
-        
-        return params;
+
+        if (current.length() > 0) {
+            pairs.add(current.toString().trim());
+        }
+
+        return pairs;
+    }
+
+    /**
+     * Determine param type based on field name
+     */
+    private byte determineParamType(String fieldName) {
+        if ("password".equalsIgnoreCase(fieldName) || 
"privateKey".equalsIgnoreCase(fieldName)) {
+            return (byte) 2; // Password type
+        } else if ("port".equalsIgnoreCase(fieldName) || 
"timeout".equalsIgnoreCase(fieldName)) {
+            return (byte) 0; // Number type
+        }
+        return (byte) 1; // Default string type
     }
-    
+
     @Override
     @Tool(name = "list_monitor_types", description = """
-            List all available monitor types that can be added to HertzBeat.
+            HertzBeat: List all available monitor types that can be added to 
HertzBeat.
             This tool shows all supported monitor types with their display 
names.
             Use this to see what types of monitors you can create with the 
add_monitor tool.
             """)
     public String listMonitorTypes(
             @ToolParam(description = "Language code for localized names 
(en-US, zh-CN, etc.). Default: en-US", required = false) String language) {
-        
+
         try {
             log.info("Listing available monitor types for language: {}", 
language);
             SubjectSum subjectSum = McpContextHolder.getSubject();
@@ -386,20 +404,20 @@ public class MonitorToolsImpl implements MonitorTools {
 
             // Get available monitor types from app service
             Map<String, String> monitorTypes = 
appService.getI18nApps(language);
-            
+
             if (monitorTypes == null || monitorTypes.isEmpty()) {
                 return "No monitor types are currently available.";
             }
-            
+
             // Format the response as a nice list
             StringBuilder response = new StringBuilder();
             response.append("Available Monitor Types (Total: 
").append(monitorTypes.size()).append("):\n\n");
-            
+
             // Sort monitor types alphabetically by key
             List<Map.Entry<String, String>> sortedTypes = 
monitorTypes.entrySet().stream()
                     .sorted(Map.Entry.comparingByKey())
                     .toList();
-            
+
             for (Map.Entry<String, String> entry : sortedTypes) {
                 String typeKey = entry.getKey();
                 String displayName = entry.getValue();
@@ -407,28 +425,28 @@ public class MonitorToolsImpl implements MonitorTools {
                        .append(" - ").append(displayName)
                        .append("\n");
             }
-            
+
             response.append("\nTo add a monitor, use the add_monitor tool with 
one of these types as the 'app' parameter.");
 
             log.info("Successfully listed {} monitor types", monitorTypes);
             return response.toString();
-            
+
         } catch (Exception e) {
             log.error("Failed to list monitor types: {}", e.getMessage(), e);
             return "Error retrieving monitor types: " + e.getMessage();
         }
     }
-    
+
     @Override
-    @Tool(name = "get_monitor_additional_params", description = """
-            Get the parameter definitions required for a specific monitor type.
+    @Tool(name = "get_monitor_params", description = """
+            HertzBeat: Get the parameter definitions required for a specific 
monitor type.
             This tool shows what parameters are needed when adding a monitor 
of the specified type,
             ALWAYS use this before adding a monitor to understand what 
parameters the user needs to provide.
             Use the app parameter to specify the monitor type/application name 
(e.g., 'linux', 'mysql', 'redis') this can be obtained from the 
list_monitor_types tool.
             """)
-    public String getMonitorAdditionalParams(
+    public String getMonitorParams(
             @ToolParam(description = "Monitor type/application name (e.g., 
'linux', 'mysql', 'redis')", required = true) String app) {
-        
+
         try {
             log.info("Getting parameter definitions for monitor type: {}", 
app);
             SubjectSum subjectSum = McpContextHolder.getSubject();
@@ -441,62 +459,62 @@ public class MonitorToolsImpl implements MonitorTools {
 
             // Get parameter definitions from app service
             List<ParamDefine> paramDefines = 
appService.getAppParamDefines(app.toLowerCase().trim());
-            
+
             if (paramDefines == null || paramDefines.isEmpty()) {
                 return String.format("No parameter definitions found for 
monitor type '%s'. "
                    + "This monitor type may not exist or may not require 
additional parameters.", app);
             }
-            
+
             // Format the response
             StringBuilder response = new StringBuilder();
-            response.append(String.format("Parameter Definitions for Monitor 
Type '%s' (Total: %d):\n\n", 
+            response.append(String.format("Parameter Definitions for Monitor 
Type '%s' (Total: %d):\n\n",
                 app, paramDefines.size()));
-            
+
             for (ParamDefine paramDefine : paramDefines) {
                 response.append("• Field: 
").append(paramDefine.getField()).append("\n");
-                
+
                 // Add display name if available
                 if (paramDefine.getName() != null && 
!paramDefine.getName().toString().trim().isEmpty()) {
                     response.append("  Name: 
").append(paramDefine.getName()).append("\n");
                 }
-                
+
                 // Add type
                 if (paramDefine.getType() != null && 
!paramDefine.getType().trim().isEmpty()) {
                     response.append("  Type: 
").append(paramDefine.getType()).append("\n");
                 }
-                
+
                 // Add required status
                 response.append("  Required: 
").append(paramDefine.isRequired() ? "Yes" : "No").append("\n");
-                
+
                 // Add default value if present
                 if (paramDefine.getDefaultValue() != null && 
!paramDefine.getDefaultValue().trim().isEmpty()) {
                     response.append("  Default: 
").append(paramDefine.getDefaultValue()).append("\n");
                 }
-                
+
                 // Add validation range if present
                 if (paramDefine.getRange() != null && 
!paramDefine.getRange().trim().isEmpty()) {
                     response.append("  Range: 
").append(paramDefine.getRange()).append("\n");
                 }
-                
+
                 // Add limit if present
                 if (paramDefine.getLimit() != null) {
                     response.append("  Limit: 
").append(paramDefine.getLimit()).append("\n");
                 }
-                
+
                 // Add placeholder text if present
                 if (paramDefine.getPlaceholder() != null && 
!paramDefine.getPlaceholder().trim().isEmpty()) {
                     response.append("  Placeholder: 
").append(paramDefine.getPlaceholder()).append("\n");
                 }
-                
+
                 response.append("\n");
             }
-            
+
             response.append("To add a monitor of this type, use the 
add_monitor tool with these parameters.\n");
             response.append(String.format("Example: 
add_monitor(name='my-monitor', app='%s', host='your-host', ...)", app));
-            
+
             log.info("Successfully retrieved {} parameter definitions for 
monitor type: {}", paramDefines.size(), app);
             return response.toString();
-            
+
         } catch (Exception e) {
             log.error("Failed to get parameter definitions for monitor type 
'{}': {}", app, e.getMessage(), e);
             return "Error retrieving parameter definitions for monitor type '" 
+ app + "': " + e.getMessage();
diff --git 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/util/IpDomainUtil.java
 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/util/IpDomainUtil.java
index 8845fcfaf8..e882cbef59 100644
--- 
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/util/IpDomainUtil.java
+++ 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/util/IpDomainUtil.java
@@ -25,6 +25,7 @@ import java.util.Enumeration;
 import java.util.regex.Pattern;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.hertzbeat.common.constants.NetworkConstants;
+import org.apache.hertzbeat.common.constants.SignConstants;
 import org.apache.http.conn.util.InetAddressUtils;
 import org.springframework.util.StringUtils;
 
@@ -33,7 +34,7 @@ import org.springframework.util.StringUtils;
  */
 @Slf4j
 public final class IpDomainUtil {
-    
+
     private static final Pattern DOMAIN_PATTERN =
             Pattern.compile("^[-\\w]+(\\.[-\\w]+)*$");
 
@@ -81,6 +82,23 @@ public final class IpDomainUtil {
         return DOMAIN_SCHEMA.matcher(domainIp).matches();
     }
 
+    /**
+     * if instance has the port with mark
+     * @param instance instance ip:port
+     * @return true if has
+     */
+    public static boolean isHasPortWithMark(String instance) {
+        if (instance == null || !StringUtils.hasText(instance)) {
+            return false;
+        }
+        String[] parts = instance.split(SignConstants.DOUBLE_MARK);
+        if (parts.length >= 2) {
+            String port = parts[parts.length - 1];
+            return CommonUtil.isNumeric(port);
+        }
+        return false;
+    }
+
     /**
      * get localhost IP.
      * @return ip
@@ -106,7 +124,7 @@ public final class IpDomainUtil {
         }
         return null;
     }
-    
+
     /**
      * check IP address type.
      * @param ipDomain ip domain
@@ -118,7 +136,7 @@ public final class IpDomainUtil {
         }
         return NetworkConstants.IPV4;
     }
-    
+
     /**
      * get current local host name.
      * @return hostname
@@ -126,7 +144,7 @@ public final class IpDomainUtil {
     public static String getCurrentHostName() {
         try {
             InetAddress inetAddress = InetAddress.getLocalHost();
-            return inetAddress.getHostName();   
+            return inetAddress.getHostName();
         } catch (UnknownHostException e) {
             return null;
         }
diff --git 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/pojo/dto/MonitorDto.java
 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/pojo/dto/MonitorDto.java
index 6832c00c69..b194f85391 100644
--- 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/pojo/dto/MonitorDto.java
+++ 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/pojo/dto/MonitorDto.java
@@ -24,7 +24,10 @@ import jakarta.validation.Valid;
 import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.NotNull;
 import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 import org.apache.hertzbeat.common.entity.grafana.GrafanaDashboard;
 import org.apache.hertzbeat.common.entity.manager.Monitor;
 import org.apache.hertzbeat.common.entity.manager.Param;
@@ -34,24 +37,27 @@ import org.apache.hertzbeat.common.entity.manager.Param;
  */
 @Data
 @Schema(description = "Monitoring information entities")
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
 public class MonitorDto {
-    
+
     @Schema(description = "monitor content", accessMode = READ_WRITE)
     @NotNull
     @Valid
     private Monitor monitor;
-    
+
     @Schema(description = "monitor params", accessMode = READ_WRITE)
     @NotEmpty
     @Valid
     private List<Param> params;
-    
+
     @Schema(description = "Monitor Metrics", accessMode = READ_ONLY)
     private List<MetricsInfo> metrics;
-    
+
     @Schema(description = "pinned collector, default null if system dispatch", 
accessMode = READ_WRITE)
     private String collector;
-    
+
     @Schema(description = "grafana dashboard")
     private GrafanaDashboard grafanaDashboard;
 }
diff --git 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/MonitorServiceImpl.java
 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/MonitorServiceImpl.java
index 07a1522fbf..b42e1ea030 100644
--- 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/MonitorServiceImpl.java
+++ 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/MonitorServiceImpl.java
@@ -43,6 +43,7 @@ import org.apache.hertzbeat.common.entity.manager.ParamDefine;
 import org.apache.hertzbeat.common.entity.message.CollectRep;
 import org.apache.hertzbeat.common.support.event.MonitorDeletedEvent;
 
+import org.apache.hertzbeat.common.util.IpDomainUtil;
 import org.apache.hertzbeat.common.util.JexlCheckerUtil;
 import org.apache.hertzbeat.common.util.SnowFlakeIdGenerator;
 import org.apache.hertzbeat.grafana.service.DashboardService;
@@ -188,7 +189,7 @@ public class MonitorServiceImpl implements MonitorService {
         String portWithMark = (Objects.isNull(portParam) || 
!StringUtils.hasText(portParam.getParamValue()))
                 ? ""
                 : SignConstants.DOUBLE_MARK + portParam.getParamValue();
-        if (Objects.nonNull(instance)) {
+        if (!IpDomainUtil.isHasPortWithMark(instance)) {
             instance = instance + portWithMark;
         }
         monitor.setInstance(instance);
diff --git a/hertzbeat-startup/src/main/resources/application.yml 
b/hertzbeat-startup/src/main/resources/application.yml
index ea661edf93..c5d00079ed 100644
--- a/hertzbeat-startup/src/main/resources/application.yml
+++ b/hertzbeat-startup/src/main/resources/application.yml
@@ -24,19 +24,12 @@ spring:
       server:
         enabled: true
         stdio: false
-        name: sse-mcp-server
+        protocol: streamable
+        streamable-http:
+          mcp-endpoint: /api/mcp
+        name: hertzbeat-mcp-server
         version: 1.0.0
-        resource-change-notification: true
-        tool-change-notification: true
-        prompt-change-notification: true
-        sse-endpoint: /api/sse
-        sse-message-endpoint: /api/mcp/message
         type: SYNC
-        capabilities:
-          tool: true
-          resource: true
-          prompt: true
-          completion: true
 
   mvc:
     static-path-pattern: /**
diff --git a/hertzbeat-startup/src/main/resources/sureness.yml 
b/hertzbeat-startup/src/main/resources/sureness.yml
index b547db30c4..282e93928a 100644
--- a/hertzbeat-startup/src/main/resources/sureness.yml
+++ b/hertzbeat-startup/src/main/resources/sureness.yml
@@ -66,10 +66,10 @@ resourceRole:
   - /api/bulletin/**===post===[admin,user]
   - /api/bulletin/**===put===[admin,user]
   - /api/bulletin/**===delete===[admin]
-  - /api/sse/**===get===[admin,user]
-  - /api/sse/**===post===[admin,user]
+  - /api/mcp/**===get===[admin]
+  - /api/mcp/**===post===[admin]
   - /api/chat/**===get===[admin,user]
-  - /api/chat/**===post===[admin,user]
+  - /api/chat/**===post===[admin]
   - /api/logs/ingest/**===post===[admin,user]
 
 # config the resource restful api that need bypass auth protection
@@ -114,7 +114,7 @@ excludedResource:
   # h2 database
   - /h2-console/**===*
 
-# account info config
+# account info config refer the 
https://hertzbeat.apache.org/docs/start/account-modify
 # eg: admin has role [admin,user], password is hertzbeat
 # eg: tom has role [user], password is hertzbeat
 # eg: lili has role [guest], plain password is lili, salt is 123, salted 
password is 1A676730B0C7F54654B0E09184448289
@@ -122,16 +122,3 @@ account:
   - appId: admin
     credential: hertzbeat
     role: [admin]
-  - appId: tom
-    credential: hertzbeat
-    role: [user]
-  - appId: guest
-    credential: hertzbeat
-    role: [guest]
-  - appId: lili
-    # credential = MD5(password + salt)
-    # plain password: hertzbeat
-    # attention: digest authentication does not support salted encrypted 
password accounts
-    credential: 94C6B34E7A199A9F9D4E1F208093B489
-    salt: 123
-    role: [user]
diff --git a/home/docs/community/become_committer.md 
b/home/docs/community/become_committer.md
index fcecdddc3d..939edc29f1 100644
--- a/home/docs/community/become_committer.md
+++ b/home/docs/community/become_committer.md
@@ -46,7 +46,7 @@ contributing to our community's success.
 
 ## Committer requirements
 
-There are no strict rules for becoming a committer or PPMC member.
+There are no strict rules for becoming a committer or new PMC member.
 Candidates for new committers are typically people that are active
 contributors and community members. Anyway, if the rules can be
 clarified a little bit, it can somehow clear the doubts in the minds
diff --git a/home/docs/community/become_pmc_member.md 
b/home/docs/community/become_pmc_member.md
index c10ccd0ebd..660d189cd4 100644
--- a/home/docs/community/become_pmc_member.md
+++ b/home/docs/community/become_pmc_member.md
@@ -1,6 +1,6 @@
 ---
 id: 'become_pmc_member'
-title: 'Become A PPMC member'
+title: 'Become A new PMC member'
 sidebar_position: 3
 ---
 
@@ -21,10 +21,10 @@ See the License for the specific language governing 
permissions and
 limitations under the License.
 -->
 
-## Become A PPMC member of Apache HertzBeat
+## Become A new PMC member of Apache HertzBeat
 
 Anyone being supportive of the community and working in any of the
-CoPDoC areas can become an Apache HertzBeat™ PPMC member. The CoPDoC is an
+CoPDoC areas can become an Apache HertzBeat™ new PMC member. The CoPDoC is an
 acronym from ASF to describe how we recognize your contributions not
 only by code.
 
@@ -38,16 +38,16 @@ only by code.
 
 Apache HertzBeat™ community strives to be meritocratic. Thus, once someone
 has contributed sufficiently to any area of CoPDoC they can be a
-candidate for PPMC membership and at last voted in as a HertzBeat
-PMC member. Being an Apache HertzBeat™ PPMC member does not necessarily mean
+candidate for new PMC membership and at last voted in as a HertzBeat
+PMC member. Being an Apache HertzBeat™ new PMC member does not necessarily mean
 you must commit code with your commit privilege to the codebase; it
 means you are committed to the HertzBeat project and are productively
 contributing to our community's success.
 
-## PPMC member requirements
+## new PMC member requirements
 
-There are no strict rules for becoming a committer or PPMC member.
-Candidates for new PPMC member are typically people that are active
+There are no strict rules for becoming a committer or new PMC member.
+Candidates for new PMC member are typically people that are active
 contributors and community members. Anyway, if the rules can be
 clarified a little bit, it can somehow clear the doubts in the minds
 of contributors and make the community more transparent, reasonable,
diff --git a/home/docs/community/how-to-verify.md 
b/home/docs/community/how-to-verify.md
index f24fb77bc9..ad5a8e8b3e 100644
--- a/home/docs/community/how-to-verify.md
+++ b/home/docs/community/how-to-verify.md
@@ -75,9 +75,9 @@ Please decide how far you trust this user to correctly verify 
other users' keys
 
 Your decision? 5 #choose 5
 Do you really want to set this key to ultimate trust? (y/N) y  #choose y
-                                                            
+
 gpg>
-         
+
 ```
 
 ##### 2.2.3 Check the gpg signature
@@ -149,26 +149,14 @@ You can refer to this article: [ASF Third Party License 
Policy](https://apache.o
 ### 3. Email reply
 
 If you initiate a posting vote, you can refer to this response example to 
reply to the email after verification
-<font color="red">
-When replying to the email, you must bring the information that you have 
checked by yourself. Simply replying to `+1 approve` is invalid.
-
-When PPMC votes in the <[email protected]> hertzbeat community, Please 
bring the binding suffix to indicate that it has a binding vote for the vote in 
the hertzbeat community, and it is convenient to count the voting results.
-
-When IPMC votes in the <[email protected]> incubator community. 
Please bring the binding suffix to indicate that the voting in the incubator 
community has a binding vote, which is convenient for counting the voting 
results.
-</font>
 
-:::caution
-If you have already voted on <[email protected]>, you can take it 
directly to the incubator community when you reply to the vote, such as:
-
-```html
-//Incubator community voting, only IPMC members have binding binding,PPMC 
needs to be aware of binding changes
-Forward my +1 from dev@listhertzbeatnkis (non-binding)
-Copy my +1 from hertzbeat DEV ML (non-binding)
-```
+:::caution Attention
+When replying to the email, you must bring the information that you have 
checked by yourself. Simply replying to `+1 approve` is invalid.
 
+When new PMC votes in the <[email protected]> hertzbeat community, 
Please bring the binding suffix to indicate that it has a binding vote for the 
vote in the hertzbeat community, and it is convenient to count the voting 
results.
 :::
 
-Non-PPMC/Non-IPMC member:
+Non-PMC member:
 
 ```text
 +1 (non-binding)
@@ -177,20 +165,19 @@ I checked:
      2. Checksum and signature are OK
      3. LICENSE and NOTICE are exist
      4. Build successfully on macOS(Big Sur)
-     5. 
+     5.
 ```
 
-PPMC/IPMC member:
+PMC member:
 
 ```text
-//Incubator community voting, only IPMC members have binding binding
 +1 (binding)
 I checked:
      1. All download links are valid
      2. Checksum and signature are OK
      3. LICENSE and NOTICE are exist
      4. Build successfully on macOS(Big Sur)
-     5. 
+     5.
 ```
 
 ---
diff --git a/home/docs/community/maturity.md b/home/docs/community/maturity.md
index a60f7b26b1..d3988fd2d4 100644
--- a/home/docs/community/maturity.md
+++ b/home/docs/community/maturity.md
@@ -69,7 +69,7 @@ community members are welcome to comment and modify it.
 | **CO10** | The project has a well-known homepage that points to all the 
information required to operate according to this maturity model.               
                          | **YES** The [official 
website](https://hertzbeat.apache.org/) includes all information user need to 
run Apache HertzBeat.                                                           
                          |
 | **CO20** | The community welcomes contributions from anyone who acts in good 
faith and in a respectful manner, and who adds value to the project.            
                     | **Yes** We provide contributing guides for every 
component. And we also have a [general contributing 
guide](https://hertzbeat.apache.org/docs/community/contribution)                
                         |
 | **CO30** | Contributions include source code, documentation, constructive 
bug reports, constructive discussions, marketing and generally anything that 
adds value to the project. | **YES** All good contributions including code and 
non-code are welcomed.                                                          
                                                                            |
-| **CO40** | The community strives to be meritocratic and gives more rights 
and responsibilities to contributors who, over time, add value to the project.  
                        | **YES** The community has elected 3 new PPMC members 
and 13 new committers so far.                                                   
                                                                         |
+| **CO40** | The community strives to be meritocratic and gives more rights 
and responsibilities to contributors who, over time, add value to the project.  
                        | **YES** The community has elected 3 new PMC members 
and 13 new committers so far.                                                   
                                                                         |
 | **CO50** | The project documents how contributors can earn more rights such 
as commit access or decision power, and applies these principles consistently.  
                      | **YES** The community has clear docs on nominating 
committers and PPMC members                                                     
                                                                           |
 | **CO60** | The community operates based on consensus of its members (see 
CS10) who have decision power. Dictators, benevolent or not, are not welcome in 
Apache projects.         | **YES** All decisions are made after vote by 
community members.                                                              
                                                                                
 |
 | **CO70** | The project strives to answer user questions in a timely manner.  
                                                                                
                     | **YES** We use <[email protected]>, [GitHub 
issue](https://github.com/apache/hertzbeat/issues) and [GitHub 
discussion](https://github.com/apache/hertzbeat/discussions) to do this in a 
timely manner. |
diff --git a/home/docs/community/new_committer_process.md 
b/home/docs/community/new_committer_process.md
index 6670d35719..01a5583ebf 100644
--- a/home/docs/community/new_committer_process.md
+++ b/home/docs/community/new_committer_process.md
@@ -73,7 +73,7 @@ Subject: [VOTE] New committer: ${NEW_COMMITTER_NAME}
 ```
 
 ```text
-Hi HertzBeat PPMC,
+Hi HertzBeat PMC,
 
 This is a formal vote about inviting ${NEW_COMMITTER_NAME} as our community 
new committer.
 
@@ -121,7 +121,7 @@ Subject: [RESULT] [VOTE] New committer: 
${NEW_COMMITTER_NAME}
 ```
 
 ```text
-Hi HertzBeat PPMC,
+Hi HertzBeat PMC,
 
 The vote has now closed. The results are:
 
@@ -145,23 +145,23 @@ Subject: Invitation to become HertzBeat committer: 
${NEW_COMMITTER_NAME}
 ```text
 Hello ${NEW_COMMITTER_NAME},
 
-The HertzBeat Project Management Committee (PMC) 
+The HertzBeat Project Management Committee (PMC)
 hereby offers you committer privileges to the project.
 
 These privileges are offered on the understanding that
 you'll use them reasonably and with common sense.
-We like to work on trust rather than unnecessary constraints. 
+We like to work on trust rather than unnecessary constraints.
 
-Being a committer enables you to more easily make 
-changes without needing to go through the patch 
+Being a committer enables you to more easily make
+changes without needing to go through the patch
 submission process.
 
-Being a committer does not require you to 
-participate any more than you already do. It does 
-tend to make one even more committed.  You will 
+Being a committer does not require you to
+participate any more than you already do. It does
+tend to make one even more committed.  You will
 probably find that you spend more time here.
 
-Of course, you can decline and instead remain as a 
+Of course, you can decline and instead remain as a
 contributor, participating as you do now.
 
 This personal invitation is a chance for you to accept or decline in private.
@@ -235,10 +235,10 @@ You need to choose a preferred ASF user name and 
alternatives.
 In order to ensure it is available you can view a list of taken IDs at
 https://people.apache.org/committer-index.html
 
-Please notify us when you have submitted the CLA and by what means 
+Please notify us when you have submitted the CLA and by what means
 you did so. This will enable us to monitor its progress.
 
-We will arrange for your Apache user account when the CLA has 
+We will arrange for your Apache user account when the CLA has
 been recorded.
 
 After that is done, please make followup replies to the 
[email protected] list.
@@ -260,7 +260,7 @@ requires adherence to the ASF Code of Conduct:
   https://www.apache.org/foundation/policies/conduct.html
 
 Yours,
-The Apache HertzBeat PPMC
+The Apache HertzBeat new PMC
 ```
 
 ### Announce New Committer Template
@@ -273,7 +273,7 @@ Subject: [ANNOUNCE] New committer: ${NEW_COMMITTER_NAME}
 ```text
 Hello Community,
 
-The Podling Project Management Committee (PPMC) for Apache HertzBeat
+The Podling Project Management Committee (new PMC) for Apache HertzBeat
 has invited ${NEW_COMMITTER_NAME} to become a committer and we are pleased to
 announce that he has accepted.
 
diff --git a/home/docs/community/new_pmc_member_process.md 
b/home/docs/community/new_pmc_member_process.md
index 291efc0da6..c1093dbe30 100644
--- a/home/docs/community/new_pmc_member_process.md
+++ b/home/docs/community/new_pmc_member_process.md
@@ -1,6 +1,6 @@
 ---
 id: 'new_pmc_ember_process'
-title: 'New PPMC Member Process'
+title: 'new PMC Member Process'
 sidebar_position: 5
 ---
 
@@ -23,7 +23,7 @@ limitations under the License.
 
 [Apache New Committer 
Guideline](https://community.apache.org/newcommitter.html#new-committer-process)
 
-## The process of new PPMC member
+## The process of new PMC member
 
 - Call a vote in mailing `[email protected]`
 
@@ -33,23 +33,23 @@ limitations under the License.
 
   see **Close Vote Template**
 
-- Board Approval of new PPMC member
+- Board Approval of new PMC member
 
-  see **Board Approval of new PPMC member**
+  see **Board Approval of new PMC member**
 
-- If the result is positive, invite the new PPMC member
+- If the result is positive, invite the new PMC member
 
   see **PMC member Invite Template**
 
-- If accept, then: Accept the PPMC member
+- If accept, then: Accept the PMC member
 
   see **PMC Member Accept Template**
 
-- Notify the PPMC member of completion
+- Notify the PMC member of completion
 
   see **PMC Member Done Template**
 
-- Announce the new PPMC member
+- Announce the new PMC member
 
   see **PMC Member Announce Template**
 
@@ -61,17 +61,17 @@ Note that, there are three placeholder in template should 
be replaced before usi
 - NEW_PMC_EMAIL
 - NEW_PMC_APACHE_NAME
 
-### PPMC Member Vote Template
+### PMC member Vote Template
 
 ```text
 To: [email protected]
-Subject: [VOTE] New PPMC member candidate: ${NEW_PMC_NAME}
+Subject: [VOTE] new PMC member candidate: ${NEW_PMC_NAME}
 ```
 
 ```text
-Hi HertzBeat PPMC,
+Hi HertzBeat PMC,
 
-This is a formal vote about inviting ${NEW_PMC_NAME} as our new PPMC member.
+This is a formal vote about inviting ${NEW_PMC_NAME} as our new PMC member.
 
 ${Work list}[1]
 
@@ -85,11 +85,11 @@ Note that, Voting ends one week from today, i.e. [midnight 
UTC on YYYY-MM-DD](ht
 
 ```text
 To: [email protected]
-Subject: [RESULT] [VOTE] New PPMC member: ${NEW_PMC_NAME}
+Subject: [RESULT] [VOTE] new PMC member: ${NEW_PMC_NAME}
 ```
 
 ```text
-Hi HertzBeat PPMC,
+Hi HertzBeat PMC,
 
 The vote has now closed. The results are:
 
@@ -102,12 +102,12 @@ Binding Votes:
 The vote is ***successful/not successful***
 ```
 
-### Board Approval of new PPMC member Template
+### Board Approval of new PMC member Template
 
 ```text
 To: [email protected]
 Cc: private@<project>.apache.org
-Subject: [NOTICE] ${NEW_PMC_NAME} for HertzBeat PPMC member
+Subject: [NOTICE] ${NEW_PMC_NAME} for HertzBeat PMC member
 ```
 
 ```text
@@ -118,66 +118,66 @@ The vote result is available here: 
https://lists.apache.org/...
 
 [Apache New Pmc Guide](https://www.apache.org/dev/pmc.html#newpmc)
 
-### PPMC Member Invite Template
+### PMC member Invite Template
 
 ```text
 To: ${NEW_PMC_EMAIL}
 Cc: [email protected]
-Subject: Invitation to become HertzBeat PPMC member: ${NEW_PMC_NAME}
+Subject: Invitation to become HertzBeat PMC member: ${NEW_PMC_NAME}
 ```
 
 ```text
 Hello ${NEW_PMC_NAME},
 
-The HertzBeat Project Management Committee (PMC) 
+The HertzBeat Project Management Committee (PMC)
 hereby offers you committer privileges to the project
 as well as membership in the PMC.
 These privileges are offered on the understanding that
 you'll use them reasonably and with common sense.
-We like to work on trust rather than unnecessary constraints. 
+We like to work on trust rather than unnecessary constraints.
 
-Being a PPMC member enables you to guide the direction of the project.
+Being a PMC member enables you to guide the direction of the project.
 
-Being a PPMC member does not require you to 
-participate any more than you already do. It does 
-tend to make one even more committed.  You will 
+Being a PMC member does not require you to
+participate any more than you already do. It does
+tend to make one even more committed.  You will
 probably find that you spend more time here.
 
-Of course, you can decline and instead remain as a 
+Of course, you can decline and instead remain as a
 contributor, participating as you do now.
 
-A. This personal invitation is a chance for you to 
-accept or decline in private.  Either way, please 
+A. This personal invitation is a chance for you to
+accept or decline in private.  Either way, please
 let us know in reply to the [email protected]
 address only.
 
 B. If you accept, the next step is to register an iCLA:
-    1. Details of the iCLA and the forms are found 
+    1. Details of the iCLA and the forms are found
     through this link: https://www.apache.org/licenses/#clas
 
-    2. Instructions for its completion and return to 
+    2. Instructions for its completion and return to
     the Secretary of the ASF are found at
     https://www.apache.org/licenses/#submitting
 
-    3. When you transmit the completed iCLA, request 
-    to notify the Apache HertzBeat and choose a 
-    unique Apache ID. Look to see if your preferred 
-    ID is already taken at 
+    3. When you transmit the completed iCLA, request
+    to notify the Apache HertzBeat and choose a
+    unique Apache ID. Look to see if your preferred
+    ID is already taken at
     https://people.apache.org/committer-index.html
-    This will allow the Secretary to notify the PPMC 
+    This will allow the Secretary to notify the PMC
     when your iCLA has been recorded.
 
-When recording of your iCLA is noted, you will 
-receive a follow-up message with the next steps for 
-establishing you as a PPMC member.
+When recording of your iCLA is noted, you will
+receive a follow-up message with the next steps for
+establishing you as a PMC member.
 ```
 
-### PPMC Member Accept Template
+### PMC member Accept Template
 
 ```text
 To: ${NEW_PMC_EMAIL}
 Cc: [email protected]
-Subject: Re: invitation to become HertzBeat PPMC member
+Subject: Re: invitation to become HertzBeat PMC member
 ```
 
 ```text
@@ -194,10 +194,10 @@ You need to choose a preferred ASF user name and 
alternatives.
 In order to ensure it is available you can view a list of taken IDs at
 https://people.apache.org/committer-index.html
 
-Please notify us when you have submitted the CLA and by what means 
+Please notify us when you have submitted the CLA and by what means
 you did so. This will enable us to monitor its progress.
 
-We will arrange for your Apache user account when the CLA has 
+We will arrange for your Apache user account when the CLA has
 been recorded.
 
 After that is done, please make followup replies to the 
[email protected] list.
@@ -214,15 +214,15 @@ in incubating projects:
   https://incubator.apache.org/guides/committer.html
   https://incubator.apache.org/guides/ppmc.html
 
-Just as before you became a PPMC member, participation in any ASF community
+Just as before you became a PMC member, participation in any ASF community
 requires adherence to the ASF Code of Conduct:
   https://www.apache.org/foundation/policies/conduct.html
 
 Yours,
-The Apache HertzBeat PPMC
+The Apache HertzBeat PMC
 ```
 
-### PPMC Member Done Template
+### PMC member Done Template
 
 ```text
 To: [email protected], ${NEW_PMC_EMAIL}
@@ -249,25 +249,25 @@ see the following resources:
 Apache developer's pages: https://www.apache.org/dev/
 Incubator committer guide: https://incubator.apache.org/guides/committer.html
 
-Naturally, if you don't understand anything be sure to ask us on the 
[email protected] mailing list. 
+Naturally, if you don't understand anything be sure to ask us on the 
[email protected] mailing list.
 Documentation is maintained by volunteers and hence can be out-of-date and 
incomplete - of course
 you can now help fix that.
 
-A PPMC member will announce your election to the dev list soon.
+A PMC member will announce your election to the dev list soon.
 ```
 
-### PPMC Member Announce Template
+### PMC member Announce Template
 
 ```text
 To: [email protected]
-[ANNONCE] New PPMC member: ${NEW_PMC_NAME}
+[ANNONCE] new PMC member: ${NEW_PMC_NAME}
 ```
 
 ```text
 Hi HertzBeat Community,
 
-The Podling Project Management Committee (PPMC) for Apache HertzBeat
-has invited ${NEW_PMC_NAME} to become our PPMC member and
+The Podling Project Management Committee (PMC) for Apache HertzBeat
+has invited ${NEW_PMC_NAME} to become our PMC member and
 we are pleased to announce that he has accepted.
 
 ### add specific details here ###
@@ -277,8 +277,8 @@ Please join me in congratulating ${NEW_PMC_NAME}!
 Being a committer enables easier contribution to the
 project since there is no need to go via the patch
 submission process. This should enable better productivity.
-A PPMC member helps manage and guide the direction of the project.
+A PMC member helps manage and guide the direction of the project.
 
 Thanks,
-On behalf of the Apache HertzBeat PPMC
+On behalf of the Apache HertzBeat PMC
 ```
diff --git a/home/docs/help/mcp_server.md b/home/docs/help/mcp_server.md
index 82ec71cefa..963d4a53e3 100644
--- a/home/docs/help/mcp_server.md
+++ b/home/docs/help/mcp_server.md
@@ -2,21 +2,24 @@
 id: mcp_server
 title: MCP Server
 sidebar_label: MCP Server
-keywords: [MCP, SSE, streaming, server]
+keywords: [MCP, StreamableHttp, streaming, server]
 ---
 
-This page explains how connect to the HertzBeat MCP SSE server. The MCP server 
auto starts on the default port 1157 when you start the HertzBeat server.
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+This page explains how connect to the HertzBeat MCP server. The MCP server 
auto starts on the default port 1157 when you start the HertzBeat server.
 
 ### Overview
 
-- Provides a Server‑Sent Events (SSE) stream for tool calling.
+- Provides Streamable-Http protocol MCP server.
 - Intended for MCP integrations and clients that consume streaming events.
 
 ### Connect to the MCP server
 
 Make sure that hertzbeat server is up and running. If you are using any other 
port than 1157, replace the following accordingly
 
-- URL: `http://localhost:1157/api/sse`
+- URL: `http://your-hertzbeat-server-host:1157/api/mcp`
 
 ### Authentication
 
@@ -31,7 +34,57 @@ Note: You can generate a JWT token from the HertzBeat web UI 
under the Log Integ
 - Basic authentication
   - Header: `Authorization: Basic <base64(username:password)>`
 
-### Cursor MCP configuration
+### Editor MCP configuration
+
+<Tabs>
+  <TabItem value="claude-code" label="Claude Code MCP">
+
+Claude Code use a global config file `~/.claude.json` to config mcp server. 
You can add HertzBeat MCP by CLI or edit this file directly.
+
+Method A: Use the CLI.
+
+```bash
+claude mcp add -s user -t http hertzbeat-mcp 
http://your-hertzbeat-server-host:1157/api/mcp --header "Authorization: Bearer 
your_jwt_key"
+```
+
+Method B: Edit the file directly.
+
+Basic auth:
+
+```jsonc
+{
+  "mcpServers": {
+    "hertzbeat-mcp": {
+      "type": "sse",
+      "url": "http://your-hertzbeat-server-host:1157/api/mcp";,
+      "headers": {
+        "Authorization": "Basic <base64(username:password)>"
+      }
+    }
+  }
+}
+```
+
+JWT bearer:
+
+```jsonc
+{
+  "mcpServers": {
+    "hertzbeat-mcp": {
+      "type": "sse",
+      "url": "http://your-hertzbeat-server-host:1157/api/mcp";,
+      "headers": {
+        "Authorization": "Bearer <your-jwt-token>"
+      }
+    }
+  }
+}
+```
+
+After saving `~/.claude.json`, restart or reload Claude Code to make the new 
MCP configuration take effect.
+
+  </TabItem>
+  <TabItem value="cursor" label="Cursor MCP" default>
 
 Create or edit `.cursor/mcp.json` in your home directory or project root.
 
@@ -39,8 +92,8 @@ Basic auth:
 
 ```json
 {
-      "Hertzbeat-MCP": {
-            "url": "http://localhost:1157/api/sse";,
+      "hertzbeat-mcp": {
+            "url": "http://your-hertzbeat-server-host:1157/api/mcp";,
             "headers": {
                   "Authorization": "Basic <base64(username:password)>"
             }
@@ -52,8 +105,8 @@ JWT bearer:
 
 ```json
 {
-      "Hertzbeat-MCP": {
-            "url": "http://localhost:1157/api/sse";,
+      "hertzbeat-mcp": {
+            "url": "http://your-hertzbeat-server-host:1157/api/mcp";,
             "headers": {
                   "Authorization": "Bearer <your-jwt-token>"
             }
@@ -63,6 +116,9 @@ JWT bearer:
 
 After saving, reload MCP in Cursor or restart the editor.
 
+  </TabItem>
+</Tabs>
+
 ### Tools available
 
 #### Monitor Management Tools
diff --git 
a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/become_committer.md
 
b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/become_committer.md
index 5245663444..aa7928afa7 100644
--- 
a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/become_committer.md
+++ 
b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/become_committer.md
@@ -34,7 +34,7 @@ Apache HertzBeat™ 社区努力追求基于功绩的原则。因此,一旦有
 
 ## Committer 的要求
 
-没有成为 Committer 或 PPMC 成员的严格规则。新的 Committer 
的候选人通常是积极的贡献者和社区成员。但是,如果能稍微明确一些规则,就可以在一定程度上消除贡献者的疑虑,使社区更加透明、合理和公平。
+没有成为 Committer 或 PMC 成员的严格规则。新的 Committer 
的候选人通常是积极的贡献者和社区成员。但是,如果能稍微明确一些规则,就可以在一定程度上消除贡献者的疑虑,使社区更加透明、合理和公平。
 
 ### 持续的贡献
 
diff --git 
a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/become_pmc_member.md
 
b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/become_pmc_member.md
index 7f6b5c0286..3829bf75b1 100644
--- 
a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/become_pmc_member.md
+++ 
b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/become_pmc_member.md
@@ -21,7 +21,7 @@ See the License for the specific language governing 
permissions and
 limitations under the License.
 -->
 
-## 成为 Apache HertzBeat™ 的 PPMC 成员
+## 成为 Apache HertzBeat™ 的 PMC 成员
 
 任何支持社区并在 CoPDoC 领域中工作的人都可以成为 Apache HertzBeat™ 的PMC 成员。CoPDoC 是 ASF 
的缩写,用来描述我们如何不仅仅通过代码来认识到您的贡献。
 
@@ -30,11 +30,11 @@ limitations under the License.
 - **Documentation** - 没有它,内容只会停留在作者的头脑中。
 - **Code** - 没有代码,讨论就毫无意义。
 
-Apache HertzBeat™ 社区努力追求基于功绩的原则。因此,一旦有人在 CoPDoC 的任何领域有了足够的贡献,他们就可以成为 PPMC 
成员资格的候选人,最终被投票选为 HertzBeat 的 PPMC 成员。成为 Apache HertzBeat™ 的 PPMC 
成员并不一定意味着您必须使用您的提交权限向代码库提交代码;它意味着您致力于 HertzBeat 项目并为我们社区的成功做出了积极的贡献。
+Apache HertzBeat™ 社区努力追求基于功绩的原则。因此,一旦有人在 CoPDoC 的任何领域有了足够的贡献,他们就可以成为 PMC 
成员资格的候选人,最终被投票选为 HertzBeat 的 PMC 成员。成为 Apache HertzBeat™ 的 PMC 
成员并不一定意味着您必须使用您的提交权限向代码库提交代码;它意味着您致力于 HertzBeat 项目并为我们社区的成功做出了积极的贡献。
 
-## PPMC 成员的要求
+## PMC 成员的要求
 
-没有成为 Committer 或 PPMC 成员的严格规则。新的 PPMC 
成员的候选人通常是积极的贡献者和社区成员。但是,如果能稍微明确一些规则,就可以在一定程度上消除贡献者的疑虑,使社区更加透明、合理和公平。
+没有成为 Committer 或 PMC 成员的严格规则。新的 PMC 
成员的候选人通常是积极的贡献者和社区成员。但是,如果能稍微明确一些规则,就可以在一定程度上消除贡献者的疑虑,使社区更加透明、合理和公平。
 
 ### 持续的贡献
 
diff --git 
a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/how-to-verify.md
 
b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/how-to-verify.md
index b9ad926263..cde6606c57 100644
--- 
a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/how-to-verify.md
+++ 
b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/how-to-verify.md
@@ -15,7 +15,7 @@ sidebar_position: 4
 > 需要依赖gpg工具,如果没有,建议安装gpg2
 
 ```shell
-#如果本地有svn,可以clone到本地 
+#如果本地有svn,可以clone到本地
 svn co 
https://dist.apache.org/repos/dist/dev/incubator/hertzbeat/${release_version}-${rc_version}/
 #或者 直接下载物料文件
 wget 
https://dist.apache.org/repos/dist/dev/incubator/hertzbeat/${release_version}-${rc_version}/xxx.xxx
@@ -70,9 +70,9 @@ Please decide how far you trust this user to correctly verify 
other users' keys
 
 Your decision? 5 #选择5
 Do you really want to set this key to ultimate trust? (y/N) y #选择y
-                                                            
-gpg> 
-     
+
+gpg>
+
 ```
 
 ##### 2.2.3 检查签名
@@ -150,23 +150,11 @@ cd apache-hertzbeat-${release_version}-incubating-src
 :::caution 注意
 回复的邮件一定要带上自己检查了那些项信息,仅仅回复`+1 approve`,是无效的。
 
-PPMC 在 <[email protected]> HertzBeat 的社区投票时,请带上 binding 后缀,表示对 
HertzBeat 社区中的投票具有约束性投票,方便统计投票结果。
-
-IPMC 在 <[email protected]> incubator 社区投票,请带上 binding 后缀,表示对 
incubator 社区中的投票具有约束性投票,方便统计投票结果。
-:::
-
-:::caution 注意
-如果在<[email protected]>已经投过票,在incubator社区进行投票回复时,可以直接带过去,<font 
color="red">需要注意约束性</font>  如:
-
-```html
-//incubator社区 投票时,只有IPMC成员才具有约束性 binding,PPMC需要注意约束性的变化
-Forward my +1 from dev@hertzbeat (non-binding)
-Copy my +1 from hertzbeat DEV ML (non-binding)
-```
+PMC 在 <[email protected]> HertzBeat 的社区投票时,请带上 binding 后缀,表示对 
HertzBeat 社区中的投票具有约束性投票,方便统计投票结果。
 
 :::
 
-非PPMC/IPMC成员
+非PMC成员
 
 ```html
 +1 (non-binding)
@@ -174,20 +162,19 @@ I  checked:
     1. All download links are valid
     2. Checksum and signature are OK
     3. LICENSE and NOTICE are exist
-    4. Build successfully on macOS(Big Sur) 
+    4. Build successfully on macOS(Big Sur)
     5. ....
 ```
 
-PPMC/IPMC成员
+PMC成员
 
 ```html
-//incubator社区 投票时,只有IPMC成员才具有约束性 binding
 +1 (binding)
 I  checked:
     1. All download links are valid
     2. Checksum and signature are OK
     3. LICENSE and NOTICE are exist
-    4. Build successfully on macOS(Big Sur) 
+    4. Build successfully on macOS(Big Sur)
     5. ....
 ```
 
diff --git 
a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/new_committer_process.md
 
b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/new_committer_process.md
index a4b0f9ea41..ce3ef12ee5 100644
--- 
a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/new_committer_process.md
+++ 
b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/new_committer_process.md
@@ -73,7 +73,7 @@ Subject: [VOTE] New committer: ${NEW_COMMITTER_NAME}
 ```
 
 ```text
-Hi HertzBeat PPMC,
+Hi HertzBeat PMC,
 
 This is a formal vote about inviting ${NEW_COMMITTER_NAME} as our community 
new committer.
 
@@ -118,7 +118,7 @@ Subject: [RESULT] [VOTE] New committer: 
${NEW_COMMITTER_NAME}
 ```
 
 ```text
-Hi HertzBeat PPMC,
+Hi HertzBeat PMC,
 
 The vote has now closed. The results are:
 
@@ -142,23 +142,23 @@ Subject: Invitation to become HertzBeat committer: 
${NEW_COMMITTER_NAME}
 ```text
 Hello ${NEW_COMMITTER_NAME},
 
-The HertzBeat Project Management Committee (PMC) 
+The HertzBeat Project Management Committee (PMC)
 hereby offers you committer privileges to the project.
 
 These privileges are offered on the understanding that
 you'll use them reasonably and with common sense.
-We like to work on trust rather than unnecessary constraints. 
+We like to work on trust rather than unnecessary constraints.
 
-Being a committer enables you to more easily make 
-changes without needing to go through the patch 
+Being a committer enables you to more easily make
+changes without needing to go through the patch
 submission process.
 
-Being a committer does not require you to 
-participate any more than you already do. It does 
-tend to make one even more committed.  You will 
+Being a committer does not require you to
+participate any more than you already do. It does
+tend to make one even more committed.  You will
 probably find that you spend more time here.
 
-Of course, you can decline and instead remain as a 
+Of course, you can decline and instead remain as a
 contributor, participating as you do now.
 
 This personal invitation is a chance for you to accept or decline in private.
@@ -232,10 +232,10 @@ You need to choose a preferred ASF user name and 
alternatives.
 In order to ensure it is available you can view a list of taken IDs at
 https://people.apache.org/committer-index.html
 
-Please notify us when you have submitted the CLA and by what means 
+Please notify us when you have submitted the CLA and by what means
 you did so. This will enable us to monitor its progress.
 
-We will arrange for your Apache user account when the CLA has 
+We will arrange for your Apache user account when the CLA has
 been recorded.
 
 After that is done, please make followup replies to the 
[email protected] list.
@@ -257,7 +257,7 @@ requires adherence to the ASF Code of Conduct:
   https://www.apache.org/foundation/policies/conduct.html
 
 Yours,
-The Apache HertzBeat PPMC
+The Apache HertzBeat PMC
 ```
 
 ### Announce New Committer Template
@@ -270,7 +270,7 @@ Subject: [ANNOUNCE] New committer: ${NEW_COMMITTER_NAME}
 ```text
 Hello Community,
 
-The Podling Project Management Committee (PPMC) for Apache HertzBeat
+The Podling Project Management Committee (PMC) for Apache HertzBeat
 has invited ${NEW_COMMITTER_NAME} to become a committer and we are pleased to
 announce that he has accepted.
 
@@ -290,7 +290,7 @@ Best Wishes!
 ```text
 Hello xxxx,
 
-The HertzBeat Project Management Committee (PPMC)
+The HertzBeat Project Management Committee (PMC)
 hereby offers you committer privileges to the project.
 These privileges are offered on the understanding that
 you'll use them reasonably and with common sense.
diff --git 
a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/new_pmc_member_process.md
 
b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/new_pmc_member_process.md
index 9b92fdb5a0..b7cd8435e7 100644
--- 
a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/new_pmc_member_process.md
+++ 
b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/community/new_pmc_member_process.md
@@ -65,13 +65,13 @@ limitations under the License.
 
 ```text
 To: [email protected]
-Subject: [VOTE] New PPMC member candidate: ${NEW_PMC_NAME}
+Subject: [VOTE] New PMC member candidate: ${NEW_PMC_NAME}
 ```
 
 ```text
-Hi HertzBeat PPMC,
+Hi HertzBeat PMC,
 
-This is a formal vote about inviting ${NEW_PMC_NAME} as our new PPMC member.
+This is a formal vote about inviting ${NEW_PMC_NAME} as our new PMC member.
 
 ${Work list}[1]
 
@@ -86,11 +86,11 @@ ${Work list}[1]
 
 ```text
 To: [email protected]
-Subject: [RESULT] [VOTE] New PPMC member: ${NEW_PMC_NAME}
+Subject: [RESULT] [VOTE] New PMC member: ${NEW_PMC_NAME}
 ```
 
 ```text
-Hi HertzBeat PPMC,
+Hi HertzBeat PMC,
 
 The vote has now closed. The results are:
 
@@ -103,12 +103,12 @@ Binding Votes:
 The vote is ***successful/not successful***
 ```
 
-### Board Approval of new PPMC member Template
+### Board Approval of new PMC member Template
 
 ```text
 To: [email protected]
 Cc: private@<project>.apache.org
-Subject: [NOTICE] ${NEW_PMC_NAME} for HertzBeat PPMC member
+Subject: [NOTICE] ${NEW_PMC_NAME} for HertzBeat PMC member
 ```
 
 ```text
@@ -124,53 +124,53 @@ The vote result is available here: 
https://lists.apache.org/...
 ```text
 To: ${NEW_PMC_EMAIL}
 Cc: [email protected]
-Subject: Invitation to become HertzBeat PPMC member: ${NEW_PMC_NAME}
+Subject: Invitation to become HertzBeat PMC member: ${NEW_PMC_NAME}
 ```
 
 ```text
 Hello ${NEW_PMC_NAME},
 
-The HertzBeat Project Management Committee (PMC) 
+The HertzBeat Project Management Committee (PMC)
 hereby offers you committer privileges to the project
 as well as membership in the PMC.
 These privileges are offered on the understanding that
 you'll use them reasonably and with common sense.
-We like to work on trust rather than unnecessary constraints. 
+We like to work on trust rather than unnecessary constraints.
 
-Being a PPMC member enables you to guide the direction of the project.
+Being a PMC member enables you to guide the direction of the project.
 
-Being a PPMC member does not require you to 
-participate any more than you already do. It does 
-tend to make one even more committed.  You will 
+Being a PMC member does not require you to
+participate any more than you already do. It does
+tend to make one even more committed.  You will
 probably find that you spend more time here.
 
-Of course, you can decline and instead remain as a 
+Of course, you can decline and instead remain as a
 contributor, participating as you do now.
 
-A. This personal invitation is a chance for you to 
-accept or decline in private.  Either way, please 
+A. This personal invitation is a chance for you to
+accept or decline in private.  Either way, please
 let us know in reply to the [email protected]
 address only.
 
 B. If you accept, the next step is to register an iCLA:
-    1. Details of the iCLA and the forms are found 
+    1. Details of the iCLA and the forms are found
     through this link: https://www.apache.org/licenses/#clas
 
-    2. Instructions for its completion and return to 
+    2. Instructions for its completion and return to
     the Secretary of the ASF are found at
     https://www.apache.org/licenses/#submitting
 
-    3. When you transmit the completed iCLA, request 
-    to notify the Apache HertzBeat and choose a 
-    unique Apache ID. Look to see if your preferred 
-    ID is already taken at 
+    3. When you transmit the completed iCLA, request
+    to notify the Apache HertzBeat and choose a
+    unique Apache ID. Look to see if your preferred
+    ID is already taken at
     https://people.apache.org/committer-index.html
-    This will allow the Secretary to notify the PPMC 
+    This will allow the Secretary to notify the PMC
     when your iCLA has been recorded.
 
-When recording of your iCLA is noted, you will 
-receive a follow-up message with the next steps for 
-establishing you as a PPMC member.
+When recording of your iCLA is noted, you will
+receive a follow-up message with the next steps for
+establishing you as a PMC member.
 ```
 
 ### PMC成员接受模板
@@ -178,7 +178,7 @@ establishing you as a PPMC member.
 ```text
 To: ${NEW_PMC_EMAIL}
 Cc: [email protected]
-Subject: Re: invitation to become HertzBeat PPMC member
+Subject: Re: invitation to become HertzBeat PMC member
 ```
 
 ```text
@@ -195,10 +195,10 @@ You need to choose a preferred ASF user name and 
alternatives.
 In order to ensure it is available you can view a list of taken IDs at
 https://people.apache.org/committer-index.html
 
-Please notify us when you have submitted the CLA and by what means 
+Please notify us when you have submitted the CLA and by what means
 you did so. This will enable us to monitor its progress.
 
-We will arrange for your Apache user account when the CLA has 
+We will arrange for your Apache user account when the CLA has
 been recorded.
 
 After that is done, please make followup replies to the 
[email protected] list.
@@ -215,12 +215,12 @@ in incubating projects:
   https://incubator.apache.org/guides/committer.html
   https://incubator.apache.org/guides/ppmc.html
 
-Just as before you became a PPMC member, participation in any ASF community
+Just as before you became a PMC member, participation in any ASF community
 requires adherence to the ASF Code of Conduct:
   https://www.apache.org/foundation/policies/conduct.html
 
 Yours,
-The Apache HertzBeat PPMC
+The Apache HertzBeat PMC
 ```
 
 ### PMC成员完成模板
@@ -250,25 +250,25 @@ see the following resources:
 Apache developer's pages: https://www.apache.org/dev/
 Incubator committer guide: https://incubator.apache.org/guides/committer.html
 
-Naturally, if you don't understand anything be sure to ask us on the 
[email protected] mailing list. 
+Naturally, if you don't understand anything be sure to ask us on the 
[email protected] mailing list.
 Documentation is maintained by volunteers and hence can be out-of-date and 
incomplete - of course
 you can now help fix that.
 
-A PPMC member will announce your election to the dev list soon.
+A PMC member will announce your election to the dev list soon.
 ```
 
 ### PMC成员通知模板
 
 ```text
 To: [email protected]
-[ANNONCE] New PPMC member: ${NEW_PMC_NAME}
+[ANNONCE] New PMC member: ${NEW_PMC_NAME}
 ```
 
 ```text
 Hi HertzBeat Community,
 
-The Podling Project Management Committee (PPMC) for Apache HertzBeat
-has invited ${NEW_PMC_NAME} to become our PPMC member and
+The Podling Project Management Committee (PMC) for Apache HertzBeat
+has invited ${NEW_PMC_NAME} to become our PMC member and
 we are pleased to announce that he has accepted.
 
 ### add specific details here ###
@@ -278,8 +278,8 @@ Please join me in congratulating ${NEW_PMC_NAME}!
 Being a committer enables easier contribution to the
 project since there is no need to go via the patch
 submission process. This should enable better productivity.
-A PPMC member helps manage and guide the direction of the project.
+A PMC member helps manage and guide the direction of the project.
 
 Thanks,
-On behalf of the Apache HertzBeat PPMC
+On behalf of the Apache HertzBeat PMC
 ```
diff --git 
a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/help/mcp_server.md 
b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/help/mcp_server.md
index 0e04620e19..1680655c7d 100644
--- a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/help/mcp_server.md
+++ b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/help/mcp_server.md
@@ -2,21 +2,24 @@
 id: mcp_server
 title: MCP 服务器
 sidebar_label: MCP 服务器
-keywords: [MCP, SSE, 流式传输, 服务器]
+keywords: [MCP, StreamabelHttp, 流式传输, 服务器]
 ---
 
-本页面介绍如何连接到 HertzBeat MCP SSE 服务器。当您启动 HertzBeat 服务器时,MCP 服务器会自动在默认端口 1157 上启动。
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+本页面介绍如何连接到 HertzBeat MCP 服务器。当您启动 HertzBeat 服务器时,MCP 服务器会自动在默认端口 1157 上启动。
 
 ### 概述
 
-- 提供用于工具调用的服务器发送事件 (SSE) 流。
+- 提供 StreamabelHttp 协议的 MCP服务器。
 - 专为 MCP 集成和消费流式事件的客户端而设计。
 
 ### 连接到 MCP 服务器
 
 确保 HertzBeat 服务器已启动并正在运行。如果您使用的端口不是 1157,请相应地替换以下内容:
 
-- URL: `http://localhost:1157/api/sse`
+- URL: `http://your-hertzbeat-server-host:1157/api/mcp`
 
 ### 身份验证
 
@@ -31,16 +34,66 @@ keywords: [MCP, SSE, 流式传输, 服务器]
 - 基本身份验证
   - 请求头: `Authorization: Basic <base64(username:password)>`
 
-### Cursor MCP 配置
+### MCP 配置
+
+<Tabs>
+  <TabItem value="claude-code" label="Claude Code MCP">
+
+Claude Code 使用一个全局配置文件 `~/.claude.json` 来管理 MCP 服务器,你可以通过 CLI 或直接编辑这个文件来添加 
HertzBeat MCP:
+
+方式一: 使用 CLI 快速创建:
+
+```bash
+claude mcp add -s user -t http hertzbeat-mcp 
http://your-hertzbeat-server-host:1157/api/mcp --header "Authorization: Bearer 
your_jwt_key"
+```
+
+方式二:打开 `~/.claude.json`,在顶层的 `mcpServers` 下添加 HertzBeat MCP 配置。
+
+Basic auth:
+
+```jsonc
+{
+  "mcpServers": {
+    "hertzbeat-mcp": {
+      "type": "sse",
+      "url": "http://your-hertzbeat-server-host:1157/api/mcp";,
+      "headers": {
+        "Authorization": "Basic <base64(username:password)>"
+      }
+    }
+  }
+}
+```
+
+JWT bearer:
 
-在您的主目录或项目根目录中创建或编辑 `.cursor/mcp.json`。
+```jsonc
+{
+  "mcpServers": {
+    "hertzbeat-mcp": {
+      "type": "sse",
+      "url": "http://your-hertzbeat-server-host:1157/api/mcp";,
+      "headers": {
+        "Authorization": "Bearer <your-jwt-token>"
+      }
+    }
+  }
+}
+```
+
+保存 `~/.claude.json` 后,重启或重新加载 Claude Code,让新的 MCP 配置生效。
+
+  </TabItem>
+  <TabItem value="cursor" label="Cursor MCP" default>
 
-基本身份验证:
+Cursor 使用配置文件 `.cursor/mcp.json` 来管理 MCP 服务器,在用户目录或者项目目录下创建或者编辑这个文件:
+
+Basic auth:
 
 ```json
 {
-      "Hertzbeat-MCP": {
-            "url": "http://localhost:1157/api/sse";,
+      "hertzbeat-mcp": {
+            "url": "http://your-hertzbeat-server-host:1157/api/mcp";,
             "headers": {
                   "Authorization": "Basic <base64(username:password)>"
             }
@@ -48,12 +101,12 @@ keywords: [MCP, SSE, 流式传输, 服务器]
 }
 ```
 
-JWT Bearer:
+JWT bearer:
 
 ```json
 {
-      "Hertzbeat-MCP": {
-            "url": "http://localhost:1157/api/sse";,
+      "hertzbeat-mcp": {
+            "url": "http://your-hertzbeat-server-host:1157/api/mcp";,
             "headers": {
                   "Authorization": "Bearer <your-jwt-token>"
             }
@@ -61,7 +114,10 @@ JWT Bearer:
 }
 ```
 
-保存后,在 Cursor 中重新加载 MCP 或重启编辑器。
+After saving, reload MCP in Cursor or restart the editor.
+
+  </TabItem>
+</Tabs>
 
 ### 可用工具
 
diff --git a/script/application.yml b/script/application.yml
index ea661edf93..c5d00079ed 100644
--- a/script/application.yml
+++ b/script/application.yml
@@ -24,19 +24,12 @@ spring:
       server:
         enabled: true
         stdio: false
-        name: sse-mcp-server
+        protocol: streamable
+        streamable-http:
+          mcp-endpoint: /api/mcp
+        name: hertzbeat-mcp-server
         version: 1.0.0
-        resource-change-notification: true
-        tool-change-notification: true
-        prompt-change-notification: true
-        sse-endpoint: /api/sse
-        sse-message-endpoint: /api/mcp/message
         type: SYNC
-        capabilities:
-          tool: true
-          resource: true
-          prompt: true
-          completion: true
 
   mvc:
     static-path-pattern: /**
diff --git a/script/docker-compose/hertzbeat-mysql-iotdb/conf/application.yml 
b/script/docker-compose/hertzbeat-mysql-iotdb/conf/application.yml
index 1e847ec970..feceab674d 100644
--- a/script/docker-compose/hertzbeat-mysql-iotdb/conf/application.yml
+++ b/script/docker-compose/hertzbeat-mysql-iotdb/conf/application.yml
@@ -25,19 +25,12 @@ spring:
       server:
         enabled: true
         stdio: false
-        name: sse-mcp-server
+        protocol: streamable
+        streamable-http:
+          mcp-endpoint: /api/mcp
+        name: hertzbeat-mcp-server
         version: 1.0.0
-        resource-change-notification: true
-        tool-change-notification: true
-        prompt-change-notification: true
-        sse-endpoint: /api/sse
-        sse-message-endpoint: /api/mcp/message
         type: SYNC
-        capabilities:
-          tool: true
-          resource: true
-          prompt: true
-          completion: true
   mvc:
     static-path-pattern: /**
   jackson:
diff --git a/script/docker-compose/hertzbeat-mysql-iotdb/conf/sureness.yml 
b/script/docker-compose/hertzbeat-mysql-iotdb/conf/sureness.yml
index b547db30c4..282e93928a 100644
--- a/script/docker-compose/hertzbeat-mysql-iotdb/conf/sureness.yml
+++ b/script/docker-compose/hertzbeat-mysql-iotdb/conf/sureness.yml
@@ -66,10 +66,10 @@ resourceRole:
   - /api/bulletin/**===post===[admin,user]
   - /api/bulletin/**===put===[admin,user]
   - /api/bulletin/**===delete===[admin]
-  - /api/sse/**===get===[admin,user]
-  - /api/sse/**===post===[admin,user]
+  - /api/mcp/**===get===[admin]
+  - /api/mcp/**===post===[admin]
   - /api/chat/**===get===[admin,user]
-  - /api/chat/**===post===[admin,user]
+  - /api/chat/**===post===[admin]
   - /api/logs/ingest/**===post===[admin,user]
 
 # config the resource restful api that need bypass auth protection
@@ -114,7 +114,7 @@ excludedResource:
   # h2 database
   - /h2-console/**===*
 
-# account info config
+# account info config refer the 
https://hertzbeat.apache.org/docs/start/account-modify
 # eg: admin has role [admin,user], password is hertzbeat
 # eg: tom has role [user], password is hertzbeat
 # eg: lili has role [guest], plain password is lili, salt is 123, salted 
password is 1A676730B0C7F54654B0E09184448289
@@ -122,16 +122,3 @@ account:
   - appId: admin
     credential: hertzbeat
     role: [admin]
-  - appId: tom
-    credential: hertzbeat
-    role: [user]
-  - appId: guest
-    credential: hertzbeat
-    role: [guest]
-  - appId: lili
-    # credential = MD5(password + salt)
-    # plain password: hertzbeat
-    # attention: digest authentication does not support salted encrypted 
password accounts
-    credential: 94C6B34E7A199A9F9D4E1F208093B489
-    salt: 123
-    role: [user]
diff --git 
a/script/docker-compose/hertzbeat-mysql-tdengine/conf/application.yml 
b/script/docker-compose/hertzbeat-mysql-tdengine/conf/application.yml
index 8f55b03994..31776c5218 100644
--- a/script/docker-compose/hertzbeat-mysql-tdengine/conf/application.yml
+++ b/script/docker-compose/hertzbeat-mysql-tdengine/conf/application.yml
@@ -25,19 +25,12 @@ spring:
       server:
         enabled: true
         stdio: false
-        name: sse-mcp-server
+        protocol: streamable
+        streamable-http:
+          mcp-endpoint: /api/mcp
+        name: hertzbeat-mcp-server
         version: 1.0.0
-        resource-change-notification: true
-        tool-change-notification: true
-        prompt-change-notification: true
-        sse-endpoint: /api/sse
-        sse-message-endpoint: /api/mcp/message
         type: SYNC
-        capabilities:
-          tool: true
-          resource: true
-          prompt: true
-          completion: true
   mvc:
     static-path-pattern: /**
   jackson:
diff --git a/script/docker-compose/hertzbeat-mysql-tdengine/conf/sureness.yml 
b/script/docker-compose/hertzbeat-mysql-tdengine/conf/sureness.yml
index b547db30c4..282e93928a 100644
--- a/script/docker-compose/hertzbeat-mysql-tdengine/conf/sureness.yml
+++ b/script/docker-compose/hertzbeat-mysql-tdengine/conf/sureness.yml
@@ -66,10 +66,10 @@ resourceRole:
   - /api/bulletin/**===post===[admin,user]
   - /api/bulletin/**===put===[admin,user]
   - /api/bulletin/**===delete===[admin]
-  - /api/sse/**===get===[admin,user]
-  - /api/sse/**===post===[admin,user]
+  - /api/mcp/**===get===[admin]
+  - /api/mcp/**===post===[admin]
   - /api/chat/**===get===[admin,user]
-  - /api/chat/**===post===[admin,user]
+  - /api/chat/**===post===[admin]
   - /api/logs/ingest/**===post===[admin,user]
 
 # config the resource restful api that need bypass auth protection
@@ -114,7 +114,7 @@ excludedResource:
   # h2 database
   - /h2-console/**===*
 
-# account info config
+# account info config refer the 
https://hertzbeat.apache.org/docs/start/account-modify
 # eg: admin has role [admin,user], password is hertzbeat
 # eg: tom has role [user], password is hertzbeat
 # eg: lili has role [guest], plain password is lili, salt is 123, salted 
password is 1A676730B0C7F54654B0E09184448289
@@ -122,16 +122,3 @@ account:
   - appId: admin
     credential: hertzbeat
     role: [admin]
-  - appId: tom
-    credential: hertzbeat
-    role: [user]
-  - appId: guest
-    credential: hertzbeat
-    role: [guest]
-  - appId: lili
-    # credential = MD5(password + salt)
-    # plain password: hertzbeat
-    # attention: digest authentication does not support salted encrypted 
password accounts
-    credential: 94C6B34E7A199A9F9D4E1F208093B489
-    salt: 123
-    role: [user]
diff --git 
a/script/docker-compose/hertzbeat-mysql-victoria-metrics/conf/application.yml 
b/script/docker-compose/hertzbeat-mysql-victoria-metrics/conf/application.yml
index b85eadbce1..30137ac088 100644
--- 
a/script/docker-compose/hertzbeat-mysql-victoria-metrics/conf/application.yml
+++ 
b/script/docker-compose/hertzbeat-mysql-victoria-metrics/conf/application.yml
@@ -25,19 +25,12 @@ spring:
       server:
         enabled: true
         stdio: false
-        name: sse-mcp-server
+        protocol: streamable
+        streamable-http:
+          mcp-endpoint: /api/mcp
+        name: hertzbeat-mcp-server
         version: 1.0.0
-        resource-change-notification: true
-        tool-change-notification: true
-        prompt-change-notification: true
-        sse-endpoint: /api/sse
-        sse-message-endpoint: /api/mcp/message
         type: SYNC
-        capabilities:
-          tool: true
-          resource: true
-          prompt: true
-          completion: true
   mvc:
     static-path-pattern: /**
   jackson:
diff --git 
a/script/docker-compose/hertzbeat-mysql-victoria-metrics/conf/sureness.yml 
b/script/docker-compose/hertzbeat-mysql-victoria-metrics/conf/sureness.yml
index b547db30c4..282e93928a 100644
--- a/script/docker-compose/hertzbeat-mysql-victoria-metrics/conf/sureness.yml
+++ b/script/docker-compose/hertzbeat-mysql-victoria-metrics/conf/sureness.yml
@@ -66,10 +66,10 @@ resourceRole:
   - /api/bulletin/**===post===[admin,user]
   - /api/bulletin/**===put===[admin,user]
   - /api/bulletin/**===delete===[admin]
-  - /api/sse/**===get===[admin,user]
-  - /api/sse/**===post===[admin,user]
+  - /api/mcp/**===get===[admin]
+  - /api/mcp/**===post===[admin]
   - /api/chat/**===get===[admin,user]
-  - /api/chat/**===post===[admin,user]
+  - /api/chat/**===post===[admin]
   - /api/logs/ingest/**===post===[admin,user]
 
 # config the resource restful api that need bypass auth protection
@@ -114,7 +114,7 @@ excludedResource:
   # h2 database
   - /h2-console/**===*
 
-# account info config
+# account info config refer the 
https://hertzbeat.apache.org/docs/start/account-modify
 # eg: admin has role [admin,user], password is hertzbeat
 # eg: tom has role [user], password is hertzbeat
 # eg: lili has role [guest], plain password is lili, salt is 123, salted 
password is 1A676730B0C7F54654B0E09184448289
@@ -122,16 +122,3 @@ account:
   - appId: admin
     credential: hertzbeat
     role: [admin]
-  - appId: tom
-    credential: hertzbeat
-    role: [user]
-  - appId: guest
-    credential: hertzbeat
-    role: [guest]
-  - appId: lili
-    # credential = MD5(password + salt)
-    # plain password: hertzbeat
-    # attention: digest authentication does not support salted encrypted 
password accounts
-    credential: 94C6B34E7A199A9F9D4E1F208093B489
-    salt: 123
-    role: [user]
diff --git 
a/script/docker-compose/hertzbeat-postgresql-greptimedb/conf/application.yml 
b/script/docker-compose/hertzbeat-postgresql-greptimedb/conf/application.yml
index 1bfe96d105..bd4fa8f29b 100644
--- a/script/docker-compose/hertzbeat-postgresql-greptimedb/conf/application.yml
+++ b/script/docker-compose/hertzbeat-postgresql-greptimedb/conf/application.yml
@@ -25,19 +25,12 @@ spring:
       server:
         enabled: true
         stdio: false
-        name: sse-mcp-server
+        protocol: streamable
+        streamable-http:
+          mcp-endpoint: /api/mcp
+        name: hertzbeat-mcp-server
         version: 1.0.0
-        resource-change-notification: true
-        tool-change-notification: true
-        prompt-change-notification: true
-        sse-endpoint: /api/sse
-        sse-message-endpoint: /api/mcp/message
         type: SYNC
-        capabilities:
-          tool: true
-          resource: true
-          prompt: true
-          completion: true
   mvc:
     static-path-pattern: /**
   jackson:
diff --git 
a/script/docker-compose/hertzbeat-postgresql-greptimedb/conf/sureness.yml 
b/script/docker-compose/hertzbeat-postgresql-greptimedb/conf/sureness.yml
index b547db30c4..282e93928a 100644
--- a/script/docker-compose/hertzbeat-postgresql-greptimedb/conf/sureness.yml
+++ b/script/docker-compose/hertzbeat-postgresql-greptimedb/conf/sureness.yml
@@ -66,10 +66,10 @@ resourceRole:
   - /api/bulletin/**===post===[admin,user]
   - /api/bulletin/**===put===[admin,user]
   - /api/bulletin/**===delete===[admin]
-  - /api/sse/**===get===[admin,user]
-  - /api/sse/**===post===[admin,user]
+  - /api/mcp/**===get===[admin]
+  - /api/mcp/**===post===[admin]
   - /api/chat/**===get===[admin,user]
-  - /api/chat/**===post===[admin,user]
+  - /api/chat/**===post===[admin]
   - /api/logs/ingest/**===post===[admin,user]
 
 # config the resource restful api that need bypass auth protection
@@ -114,7 +114,7 @@ excludedResource:
   # h2 database
   - /h2-console/**===*
 
-# account info config
+# account info config refer the 
https://hertzbeat.apache.org/docs/start/account-modify
 # eg: admin has role [admin,user], password is hertzbeat
 # eg: tom has role [user], password is hertzbeat
 # eg: lili has role [guest], plain password is lili, salt is 123, salted 
password is 1A676730B0C7F54654B0E09184448289
@@ -122,16 +122,3 @@ account:
   - appId: admin
     credential: hertzbeat
     role: [admin]
-  - appId: tom
-    credential: hertzbeat
-    role: [user]
-  - appId: guest
-    credential: hertzbeat
-    role: [guest]
-  - appId: lili
-    # credential = MD5(password + salt)
-    # plain password: hertzbeat
-    # attention: digest authentication does not support salted encrypted 
password accounts
-    credential: 94C6B34E7A199A9F9D4E1F208093B489
-    salt: 123
-    role: [user]
diff --git 
a/script/docker-compose/hertzbeat-postgresql-victoria-metrics/conf/application.yml
 
b/script/docker-compose/hertzbeat-postgresql-victoria-metrics/conf/application.yml
index 6d3ad23061..24fc28223d 100644
--- 
a/script/docker-compose/hertzbeat-postgresql-victoria-metrics/conf/application.yml
+++ 
b/script/docker-compose/hertzbeat-postgresql-victoria-metrics/conf/application.yml
@@ -25,19 +25,12 @@ spring:
       server:
         enabled: true
         stdio: false
-        name: sse-mcp-server
+        protocol: streamable
+        streamable-http:
+          mcp-endpoint: /api/mcp
+        name: hertzbeat-mcp-server
         version: 1.0.0
-        resource-change-notification: true
-        tool-change-notification: true
-        prompt-change-notification: true
-        sse-endpoint: /api/sse
-        sse-message-endpoint: /api/mcp/message
         type: SYNC
-        capabilities:
-          tool: true
-          resource: true
-          prompt: true
-          completion: true
   mvc:
     static-path-pattern: /**
   jackson:
diff --git 
a/script/docker-compose/hertzbeat-postgresql-victoria-metrics/conf/sureness.yml 
b/script/docker-compose/hertzbeat-postgresql-victoria-metrics/conf/sureness.yml
index b547db30c4..282e93928a 100644
--- 
a/script/docker-compose/hertzbeat-postgresql-victoria-metrics/conf/sureness.yml
+++ 
b/script/docker-compose/hertzbeat-postgresql-victoria-metrics/conf/sureness.yml
@@ -66,10 +66,10 @@ resourceRole:
   - /api/bulletin/**===post===[admin,user]
   - /api/bulletin/**===put===[admin,user]
   - /api/bulletin/**===delete===[admin]
-  - /api/sse/**===get===[admin,user]
-  - /api/sse/**===post===[admin,user]
+  - /api/mcp/**===get===[admin]
+  - /api/mcp/**===post===[admin]
   - /api/chat/**===get===[admin,user]
-  - /api/chat/**===post===[admin,user]
+  - /api/chat/**===post===[admin]
   - /api/logs/ingest/**===post===[admin,user]
 
 # config the resource restful api that need bypass auth protection
@@ -114,7 +114,7 @@ excludedResource:
   # h2 database
   - /h2-console/**===*
 
-# account info config
+# account info config refer the 
https://hertzbeat.apache.org/docs/start/account-modify
 # eg: admin has role [admin,user], password is hertzbeat
 # eg: tom has role [user], password is hertzbeat
 # eg: lili has role [guest], plain password is lili, salt is 123, salted 
password is 1A676730B0C7F54654B0E09184448289
@@ -122,16 +122,3 @@ account:
   - appId: admin
     credential: hertzbeat
     role: [admin]
-  - appId: tom
-    credential: hertzbeat
-    role: [user]
-  - appId: guest
-    credential: hertzbeat
-    role: [guest]
-  - appId: lili
-    # credential = MD5(password + salt)
-    # plain password: hertzbeat
-    # attention: digest authentication does not support salted encrypted 
password accounts
-    credential: 94C6B34E7A199A9F9D4E1F208093B489
-    salt: 123
-    role: [user]
diff --git a/script/helm/hertzbeat-helm-chart b/script/helm/hertzbeat-helm-chart
index 2906774fe8..4a4fbb796e 160000
--- a/script/helm/hertzbeat-helm-chart
+++ b/script/helm/hertzbeat-helm-chart
@@ -1 +1 @@
-Subproject commit 2906774fe83b0f1475f8c467fee9f9c331cb36a9
+Subproject commit 4a4fbb796e9485862c10e38b28a43e604d02284f
diff --git a/script/sureness.yml b/script/sureness.yml
index b547db30c4..282e93928a 100644
--- a/script/sureness.yml
+++ b/script/sureness.yml
@@ -66,10 +66,10 @@ resourceRole:
   - /api/bulletin/**===post===[admin,user]
   - /api/bulletin/**===put===[admin,user]
   - /api/bulletin/**===delete===[admin]
-  - /api/sse/**===get===[admin,user]
-  - /api/sse/**===post===[admin,user]
+  - /api/mcp/**===get===[admin]
+  - /api/mcp/**===post===[admin]
   - /api/chat/**===get===[admin,user]
-  - /api/chat/**===post===[admin,user]
+  - /api/chat/**===post===[admin]
   - /api/logs/ingest/**===post===[admin,user]
 
 # config the resource restful api that need bypass auth protection
@@ -114,7 +114,7 @@ excludedResource:
   # h2 database
   - /h2-console/**===*
 
-# account info config
+# account info config refer the 
https://hertzbeat.apache.org/docs/start/account-modify
 # eg: admin has role [admin,user], password is hertzbeat
 # eg: tom has role [user], password is hertzbeat
 # eg: lili has role [guest], plain password is lili, salt is 123, salted 
password is 1A676730B0C7F54654B0E09184448289
@@ -122,16 +122,3 @@ account:
   - appId: admin
     credential: hertzbeat
     role: [admin]
-  - appId: tom
-    credential: hertzbeat
-    role: [user]
-  - appId: guest
-    credential: hertzbeat
-    role: [guest]
-  - appId: lili
-    # credential = MD5(password + salt)
-    # plain password: hertzbeat
-    # attention: digest authentication does not support salted encrypted 
password accounts
-    credential: 94C6B34E7A199A9F9D4E1F208093B489
-    salt: 123
-    role: [user]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to