Co-authored-by: Antoine <33425718+anth2o@users.noreply.github.com>
Co-authored-by: Bastien <bastien.baret@gmail.com>
Co-authored-by: Clément Sirieix <clement.sirieix@mistral.ai>
Co-authored-by: Kim-Adeline Miguel <51720070+kimadeline@users.noreply.github.com>
Co-authored-by: Mathias Gesbert <mathias.gesbert@mistral.ai>
Co-authored-by: Maxime Dolores <maxime.dolores@ext.mistral.ai>
Co-authored-by: Michel Thomazo <51709227+michelTho@users.noreply.github.com>
Co-authored-by: Nelson PROIA <144663685+Nelson-PROIA@users.noreply.github.com>
Co-authored-by: Pierre Rossinès <pierre.rossines@mistral.ai>
Co-authored-by: Quentin <quentin.torroba@mistral.ai>
Co-authored-by: Robin Gullo <robin.gullo@mistral.ai>
Co-authored-by: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
Clément Drouin 2026-04-28 17:44:07 +02:00 committed by GitHub
parent a83c81ecf5
commit 632ea8c032
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
253 changed files with 13965 additions and 2525 deletions

View file

@ -10,7 +10,8 @@ from unittest.mock import AsyncMock, MagicMock, patch
from pydantic import ValidationError
import pytest
from vibe.core.config import MCPHttp, MCPStdio, MCPStreamableHttp
from tests.stubs.fake_mcp_registry import FakeMCPRegistry
from vibe.core.config import MCPHttp, MCPStdio, MCPStreamableHttp, VibeConfig
from vibe.core.tools.mcp import (
MCPRegistry,
MCPToolResult,
@ -710,3 +711,140 @@ class TestMCPStdioCwd:
)
assert proxy_cls._cwd is None
# ---------------------------------------------------------------------------
# _MCPBase disabled / disabled_tools field tests
# ---------------------------------------------------------------------------
class TestMCPBaseDisableFields:
def test_disabled_defaults_to_false(self):
config = MCPStdio(name="test", transport="stdio", command="python")
assert config.disabled is False
assert config.disabled_tools == []
def test_disabled_true(self):
config = MCPStdio(
name="test", transport="stdio", command="python", disabled=True
)
assert config.disabled is True
def test_disabled_tools_list(self):
config = MCPHttp(
name="test",
transport="http",
url="http://localhost:8080",
disabled_tools=["search", "read"],
)
assert config.disabled_tools == ["search", "read"]
def test_disabled_fields_on_streamable_http(self):
config = MCPStreamableHttp(
name="test",
transport="streamable-http",
url="http://localhost:8080",
disabled=True,
disabled_tools=["write"],
)
assert config.disabled is True
assert config.disabled_tools == ["write"]
# ---------------------------------------------------------------------------
# ToolManager: per-MCP-server disabled / disabled_tools filtering
# ---------------------------------------------------------------------------
from vibe.core.tools.manager import ToolManager
class TestMCPDisableFiltering:
@staticmethod
def _make_config(
mcp_servers: list[MCPHttp | MCPStdio | MCPStreamableHttp] | None = None,
) -> VibeConfig:
return cast(
VibeConfig,
type(
"_Cfg",
(),
{
"mcp_servers": mcp_servers or [],
"connectors": [],
"enabled_tools": [],
"disabled_tools": [],
"tools": {},
"tool_paths": [],
},
)(),
)
def test_disabled_server_excludes_all_tools(self):
srv = MCPHttp(
name="demo", transport="http", url="http://demo:9090", disabled=True
)
registry = FakeMCPRegistry()
remote_a = RemoteTool(name="tool_a", description="A")
remote_b = RemoteTool(name="tool_b", description="B")
proxy_a = create_mcp_http_proxy_tool_class(
url="http://demo:9090", remote=remote_a, alias="demo"
)
proxy_b = create_mcp_http_proxy_tool_class(
url="http://demo:9090", remote=remote_b, alias="demo"
)
registry.set_tools(
[srv], {proxy_a.get_name(): proxy_a, proxy_b.get_name(): proxy_b}
)
config = self._make_config(mcp_servers=[srv])
tm = ToolManager(
config_getter=lambda: config, mcp_registry=registry, connector_registry=None
)
assert "demo_tool_a" not in tm.available_tools
assert "demo_tool_b" not in tm.available_tools
# Still registered (discoverable for UI)
assert "demo_tool_a" in tm.registered_tools
def test_disabled_tools_filters_specific_tools(self):
srv = MCPHttp(
name="demo",
transport="http",
url="http://demo:9090",
disabled_tools=["tool_a"],
)
registry = FakeMCPRegistry()
remote_a = RemoteTool(name="tool_a", description="A")
remote_b = RemoteTool(name="tool_b", description="B")
proxy_a = create_mcp_http_proxy_tool_class(
url="http://demo:9090", remote=remote_a, alias="demo"
)
proxy_b = create_mcp_http_proxy_tool_class(
url="http://demo:9090", remote=remote_b, alias="demo"
)
registry.set_tools(
[srv], {proxy_a.get_name(): proxy_a, proxy_b.get_name(): proxy_b}
)
config = self._make_config(mcp_servers=[srv])
tm = ToolManager(
config_getter=lambda: config, mcp_registry=registry, connector_registry=None
)
assert "demo_tool_a" not in tm.available_tools
assert "demo_tool_b" in tm.available_tools
def test_disabled_false_is_noop(self):
srv = MCPHttp(
name="demo", transport="http", url="http://demo:9090", disabled=False
)
registry = FakeMCPRegistry()
remote = RemoteTool(name="tool_a", description="A")
proxy = create_mcp_http_proxy_tool_class(
url="http://demo:9090", remote=remote, alias="demo"
)
registry.set_tools([srv], {proxy.get_name(): proxy})
config = self._make_config(mcp_servers=[srv])
tm = ToolManager(
config_getter=lambda: config, mcp_registry=registry, connector_registry=None
)
assert "demo_tool_a" in tm.available_tools