diff --git a/app/services/mcp_client.py b/app/services/mcp_client.py index d4bb49b..06972ad 100644 --- a/app/services/mcp_client.py +++ b/app/services/mcp_client.py @@ -189,7 +189,8 @@ async def _handshake(url: str, headers: dict | None) -> dict: return session -def _server(connector_id: int) -> dict: +def _server(connector_id: int, *, workspace_id: int | None = None, + distribute=None) -> dict: row = get(connector_id) if row is None: raise ValueError("Serveur MCP introuvable") @@ -198,7 +199,8 @@ def _server(connector_id: int) -> dict: if not row["enabled"]: raise ValueError("Serveur MCP désactivé") return {"id": row["id"], "name": row["name"], "url": row["url"], - "headers": _headers(connector_id)} + "headers": _headers(connector_id, workspace_id=workspace_id, + distribute=distribute)} def _normalize(server: dict, raw: list) -> list[dict]: @@ -226,10 +228,16 @@ def _save_tools(connector_id: int, tools: list[dict]) -> None: conn.commit() -async def initialize_and_list(connector_id: int) -> list[dict]: - """Handshake + ``tools/list`` → met à jour le cache de la base.""" - srv = _server(connector_id) - url = _with_secret(srv["url"], connector_id) +async def initialize_and_list(connector_id: int, *, workspace_id: int | None = None, + distribute=None) -> list[dict]: + """Handshake + ``tools/list`` → met à jour le cache de la base. + + Pour un serveur à référence ObsiGate, ``workspace_id`` est obligatoire + (isolation vérifiée avant distribution, voir ``connectors``). + """ + srv = _server(connector_id, workspace_id=workspace_id, distribute=distribute) + url = _with_secret(srv["url"], connector_id, workspace_id=workspace_id, + distribute=distribute) session = await _handshake(url, srv["headers"]) data = await _rpc(url, {"jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {}}, session) @@ -276,14 +284,16 @@ def _content_text(result: dict) -> str: return "\n".join(p for p in parts if p) or json.dumps(result, ensure_ascii=False)[:4000] -async def call_tool(connector_id: int, tool: str, arguments: dict | None = None) -> dict: +async def call_tool(connector_id: int, tool: str, arguments: dict | None = None, *, + workspace_id: int | None = None, distribute=None) -> dict: """``tools/call`` → {status, text} (isError → error, borné à 20 000 car.). Le handshake (avec session éventuelle) précède systématiquement l'appel : c'est la condition T0 des serveurs à session. """ - srv = _server(connector_id) - url = _with_secret(srv["url"], connector_id) + srv = _server(connector_id, workspace_id=workspace_id, distribute=distribute) + url = _with_secret(srv["url"], connector_id, workspace_id=workspace_id, + distribute=distribute) session = await _handshake(url, srv["headers"]) data = await _rpc(url, { "jsonrpc": "2.0", "id": 3, "method": "tools/call",