mirror of
https://github.com/andrewyng/openworker.git
synced 2026-09-14 08:04:32 +00:00
Remove MCP server: also shut down the live connection and purge OAuth tokens/DCR
This commit is contained in:
@@ -1425,6 +1425,19 @@ class SessionManager:
|
|||||||
self._mcp_auth_hints.discard(name)
|
self._mcp_auth_hints.discard(name)
|
||||||
if self._prefs.get("mcp_last_test", {}).pop(name, None) is not None:
|
if self._prefs.get("mcp_last_test", {}).pop(name, None) is not None:
|
||||||
self._save_prefs()
|
self._save_prefs()
|
||||||
|
# Removing a server must not leave its connection running until the next
|
||||||
|
# restart, nor its OAuth tokens + DCR registration in the secret store —
|
||||||
|
# "Remove" is the user saying this server is GONE (owner review 2026-08-21).
|
||||||
|
# The route runs in a threadpool; the shutdown event belongs to the loop.
|
||||||
|
conn = self.mcp._conns.get(name)
|
||||||
|
if conn is not None:
|
||||||
|
if self._loop is not None:
|
||||||
|
self._loop.call_soon_threadsafe(conn.shutdown.set)
|
||||||
|
else:
|
||||||
|
conn.shutdown.set()
|
||||||
|
from ..mcp import oauth as mcp_oauth
|
||||||
|
|
||||||
|
mcp_oauth.sign_out(name, self.secrets)
|
||||||
return {"ok": ok, "name": name}
|
return {"ok": ok, "name": name}
|
||||||
|
|
||||||
async def mcp_tools(self, name: str) -> dict[str, Any]:
|
async def mcp_tools(self, name: str) -> dict[str, Any]:
|
||||||
|
|||||||
@@ -472,3 +472,27 @@ async def test_verify_tears_down_a_dead_connection_and_reconnects():
|
|||||||
assert out is fresh
|
assert out is fresh
|
||||||
assert dead.shutdown.is_set()
|
assert dead.shutdown.is_set()
|
||||||
assert "srv" not in mgr._conns
|
assert "srv" not in mgr._conns
|
||||||
|
|
||||||
|
|
||||||
|
def test_delete_mcp_shuts_down_connection_and_forgets_tokens(tmp_path):
|
||||||
|
"""Remove server = the server is GONE: live connection told to shut down and
|
||||||
|
the OAuth token/DCR profile purged, not just the config entry deleted."""
|
||||||
|
from types import SimpleNamespace
|
||||||
|
|
||||||
|
from coworker.mcp import oauth as mcp_oauth
|
||||||
|
from coworker.mcp.client import _Conn
|
||||||
|
from coworker.mcp.config import put_global_server
|
||||||
|
from coworker.server import SessionManager
|
||||||
|
|
||||||
|
mgr = SessionManager(data_dir=tmp_path / "data")
|
||||||
|
put_global_server("gone-srv", {"url": "https://x.example/mcp", "auth": "oauth"})
|
||||||
|
mgr.secrets.put(
|
||||||
|
mcp_oauth.PROFILE_PREFIX + "gone-srv", {"tokens": {"access_token": "A"}}
|
||||||
|
)
|
||||||
|
conn = _Conn(SimpleNamespace(), tools=[])
|
||||||
|
mgr.mcp._conns["gone-srv"] = conn
|
||||||
|
|
||||||
|
res = mgr.delete_mcp("gone-srv")
|
||||||
|
assert res["ok"]
|
||||||
|
assert conn.shutdown.is_set()
|
||||||
|
assert mgr.secrets.get(mcp_oauth.PROFILE_PREFIX + "gone-srv") is None
|
||||||
|
|||||||
Reference in New Issue
Block a user