mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-12 22:14:54 +00:00
Fix MCP server lifecycle issue
In HTTP/SSE mode, a client disconnection triggered a partial agent shutdown (project deactivation, dashboard manager & GUI viewer shutdown)
This commit is contained in:
1 parent
65474d3d3b
commit
a1d874b29e
3 files changed
+27
-7
No files matched your search
+2
-1
@@ -7,7 +7,8 @@ Status of the `main` branch. Changes prior to the next official version change w
|
||||
Instead, they can define `added_modes` to add modes on top of base and default modes.
|
||||
See updated [documentation on modes](https://oraios.github.io/serena/02-usage/050_configuration.html#modes).
|
||||
- Serena's default configuration now uses `interactive` and `editing` as `base_modes` instead of as `default_modes`.
|
||||
- Fixed path validation in `search_for_pattern` tool (thanks to [@dodge1218](https://github.com/dodge1218) for the report)
|
||||
- Fixed path validation in `search_for_pattern` tool (thanks to [@dodge1218](https://github.com/dodge1218) for the report)
|
||||
- Fix: In HTTP/SSE mode, a client disconnection triggered a partial agent shutdown (project deactivation, dashboard manager & GUI viewer shutdown)
|
||||
|
||||
* JetBrains:
|
||||
- Add new tools:
|
||||
|
||||
+1
-1
@@ -362,7 +362,7 @@ class TopLevelCommands(AutoRegisteringGroup):
|
||||
if default_modes or added_modes:
|
||||
mode_selection_def = ModeSelectionDefinitionWithAddedModes(default_modes=default_modes or None, added_modes=added_modes or None)
|
||||
|
||||
factory = SerenaMCPFactory(context=context, project=project_file, memory_log_handler=memory_log_handler)
|
||||
factory = SerenaMCPFactory(transport=transport, context=context, project=project_file, memory_log_handler=memory_log_handler)
|
||||
server = factory.create_mcp_server(
|
||||
host=host,
|
||||
port=port,
|
||||
|
||||
+24
-5
@@ -52,14 +52,22 @@ class SerenaMCPFactory:
|
||||
Factory for the creation of the Serena MCP server with an associated SerenaAgent.
|
||||
"""
|
||||
|
||||
def __init__(self, context: str = DEFAULT_CONTEXT, project: str | None = None, memory_log_handler: MemoryLogHandler | None = None):
|
||||
def __init__(
|
||||
self,
|
||||
transport: Literal["stdio", "sse", "streamable-http"],
|
||||
context: str = DEFAULT_CONTEXT,
|
||||
project: str | None = None,
|
||||
memory_log_handler: MemoryLogHandler | None = None,
|
||||
):
|
||||
"""
|
||||
:param transport: The transport to use for the MCP server.
|
||||
:param context: The context name or path to context file
|
||||
:param project: Either an absolute path to the project directory or a name of an already registered project.
|
||||
If the project passed here hasn't been registered yet, it will be registered automatically and can be activated by its name
|
||||
afterward.
|
||||
:param memory_log_handler: the in-memory log handler to use for the agent's logging
|
||||
"""
|
||||
self.transport = transport
|
||||
self.context = SerenaAgentContext.load(context)
|
||||
self.project = project
|
||||
self.agent: SerenaAgent | None = None
|
||||
@@ -342,16 +350,27 @@ class SerenaMCPFactory:
|
||||
|
||||
@asynccontextmanager
|
||||
async def server_lifespan(self, mcp_server: FastMCP) -> AsyncIterator[None]:
|
||||
"""Manage server startup and shutdown lifecycle."""
|
||||
"""
|
||||
Manages the lifespan of MCP server instances and performs necessary setup and teardown.
|
||||
For stdio transport, there is a single server instance.
|
||||
For other transports, this is called once per connection!
|
||||
|
||||
:param mcp_server: the MCP server instance to configure
|
||||
"""
|
||||
openai_tool_compatible = self.context.name in ["chatgpt", "codex", "oaicompat-agent"]
|
||||
self._set_mcp_tools(mcp_server, openai_tool_compatible=openai_tool_compatible)
|
||||
log.info("MCP server lifetime setup complete")
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
log.info("MCP server shutting down")
|
||||
if self.agent is not None:
|
||||
self.agent.on_shutdown()
|
||||
# Shut down the server if we are running in stdio mode.
|
||||
# For other transports, we do nothing; the singleton agent instance remains active.
|
||||
if self.transport == "stdio":
|
||||
log.info("MCP server shutting down")
|
||||
if self.agent is not None:
|
||||
self.agent.on_shutdown()
|
||||
else:
|
||||
log.info("Client disconnected")
|
||||
|
||||
def _get_initial_instructions(self) -> str:
|
||||
assert self.agent is not None
|
||||
|
||||
Reference in new issue
Block a user