From 511ad0542bb71610b45fe259b361b428a09b6613 Mon Sep 17 00:00:00 2001 From: Tomasz Wyderka Date: Sat, 27 Dec 2025 20:16:57 +0100 Subject: [PATCH] Add open_dashboard MCP tool for on-demand dashboard opening This provides an alternative for users who want to disable automatic browser opening (web_dashboard_open_on_launch: False) but still have easy access to the dashboard through AI assistance. Changes: - Add OpenDashboardTool in config_tools.py - Add open_dashboard() and get_dashboard_url() methods to SerenaAgent - Store dashboard URL in _dashboard_url field - Update documentation with new tool and configuration option - Update config template comment to mention the tool Closes #875 --- docs/01-about/035_tools.md | 1 + docs/02-usage/060_dashboard.md | 9 ++++++ src/serena/agent.py | 29 +++++++++++++++++++ .../resources/serena_config.template.yml | 3 +- src/serena/tools/config_tools.py | 13 +++++++++ 5 files changed, 54 insertions(+), 1 deletion(-) diff --git a/docs/01-about/035_tools.md b/docs/01-about/035_tools.md index 55ff8bf2..23662750 100644 --- a/docs/01-about/035_tools.md +++ b/docs/01-about/035_tools.md @@ -28,6 +28,7 @@ Note that in most configurations, only a subset of these tools will be enabled s * `list_dir`: Lists files and directories in the given directory (optionally with recursion). * `list_memories`: Lists memories in Serena's project-specific memory store. * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building). +* `open_dashboard`: Opens the Serena web dashboard in the default web browser. * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with th e necessary context). * `read_file`: Reads a file within the project directory. diff --git a/docs/02-usage/060_dashboard.md b/docs/02-usage/060_dashboard.md index 73376926..0a7a462a 100644 --- a/docs/02-usage/060_dashboard.md +++ b/docs/02-usage/060_dashboard.md @@ -20,3 +20,12 @@ Serena comes with built-in tools for monitoring and managing the current session Both can be configured in Serena's [configuration](050_configuration) file (`serena_config.yml`). If enabled, they will automatically be opened as soon as the Serena agent/MCP server is started. + +## Disabling Automatic Browser Opening + +If you prefer not to have the dashboard open automatically (e.g., to avoid focus stealing), you can disable it +by setting `web_dashboard_open_on_launch: False` in your `serena_config.yml`. + +When automatic opening is disabled, you can still access the dashboard by: +* Navigating directly to `http://localhost:24282/dashboard/index.html` in your browser +* Asking the AI to use the `open_dashboard` tool, which will open the dashboard in your default browser diff --git a/src/serena/agent.py b/src/serena/agent.py index 02d44079..7f0c0e9c 100644 --- a/src/serena/agent.py +++ b/src/serena/agent.py @@ -189,6 +189,9 @@ class SerenaAgent: # project-specific instances, which will be initialized upon project activation self._active_project: Project | None = None + # dashboard URL (set when dashboard is started) + self._dashboard_url: str | None = None + # adjust log level serena_log_level = self.serena_config.log_level if Logger.root.level != serena_log_level: @@ -292,6 +295,7 @@ class SerenaAgent: if dashboard_host == "0.0.0.0": dashboard_host = "localhost" dashboard_url = f"http://{dashboard_host}:{port}/dashboard/index.html" + self._dashboard_url = dashboard_url log.info("Serena web dashboard started at %s", dashboard_url) if self.serena_config.web_dashboard_open_on_launch: if not system_has_usable_display(): @@ -405,6 +409,31 @@ class SerenaAgent: # open the dashboard URL in the default web browser webbrowser.open(url) + def get_dashboard_url(self) -> str | None: + """ + :return: the URL of the web dashboard, or None if the dashboard is not running + """ + return self._dashboard_url + + def open_dashboard(self) -> str: + """ + Opens the Serena web dashboard in the default web browser. + + :return: a message indicating success or failure + """ + if self._dashboard_url is None: + return "Error: The web dashboard is not running. Enable it in the Serena configuration." + + if not system_has_usable_display(): + return f"Error: No usable display detected. You can open the dashboard manually at: {self._dashboard_url}" + + # open the dashboard URL in the default web browser (using a separate process to control + # output redirection) + process = multiprocessing.Process(target=self._open_dashboard, args=(self._dashboard_url,)) + process.start() + process.join(timeout=1) + return f"Dashboard opened in the default web browser: {self._dashboard_url}" + def get_project_root(self) -> str: """ :return: the root directory of the active project (if any); raises a ValueError if there is no active project diff --git a/src/serena/resources/serena_config.template.yml b/src/serena/resources/serena_config.template.yml index d197991d..9465961c 100644 --- a/src/serena/resources/serena_config.template.yml +++ b/src/serena/resources/serena_config.template.yml @@ -35,7 +35,8 @@ web_dashboard_listen_address: 127.0.0.1 web_dashboard_open_on_launch: True # whether to open a browser window with the web dashboard when Serena starts (provided that web_dashboard # is enabled). If set to False, you can still open the dashboard manually by navigating to -# http://localhost:24282/dashboard/ in your web browser (24282 = 0x5EDA, SErena DAshboard). +# http://localhost:24282/dashboard/ in your web browser (24282 = 0x5EDA, SErena DAshboard), +# or by asking the AI to use the open_dashboard tool. # If you have multiple instances running, a higher port will be used; try port 24283, 24284, etc. log_level: 20 diff --git a/src/serena/tools/config_tools.py b/src/serena/tools/config_tools.py index 45ca01c7..265bb2f3 100644 --- a/src/serena/tools/config_tools.py +++ b/src/serena/tools/config_tools.py @@ -2,6 +2,19 @@ from serena.config.context_mode import SerenaAgentMode from serena.tools import Tool, ToolMarkerDoesNotRequireActiveProject, ToolMarkerOptional +class OpenDashboardTool(Tool, ToolMarkerDoesNotRequireActiveProject): + """ + Opens the Serena web dashboard in the default web browser. + The dashboard provides logs, session information, and tool usage statistics. + """ + + def apply(self) -> str: + """ + Opens the Serena web dashboard in the default web browser. + """ + return self.agent.open_dashboard() + + class ActivateProjectTool(Tool, ToolMarkerDoesNotRequireActiveProject): """ Activates a project based on the project name or path.