Files
OpenJarvis/tests/mcp/test_server_upgrade.py
T
Jon Saad-FalconandClaude Opus 4.6 852259f18b Restructure codebase into 5-pillar architecture with MCP tool management, composition layer, and structured learning
Phase 1: Move RoutingContext to core/types.py, add RouterPolicy and QueryAnalyzer ABCs to intelligence/_stubs.py
Phase 2: Move memory backends to tools/storage/, convert memory/ to backward-compat shims
Phase 3: Add MCPToolAdapter, storage MCP tools, upgrade MCP server to spec 2025-11-25
Phase 4: Add SystemBuilder + JarvisSystem composition layer (system.py)
Phase 5: Add InstrumentedEngine for opt-in telemetry, simplify all agents
Phase 6: Add LearningPolicy ABC taxonomy with SFTPolicy, AgentAdvisorPolicy, ICLUpdaterPolicy
Phase 7: Update config schema (ToolsConfig, MCPConfig, TracesConfig, per-pillar learning policies)

Also: update all docs, README (DSPy-inspired), CLAUDE.md, and add logo assets.
1391 tests pass, 32 skipped. Zero new lint errors. Full backward compatibility via shims.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 05:57:13 +00:00

133 lines
4.8 KiB
Python

"""Tests for MCP server upgrade to protocol version 2025-11-25."""
from __future__ import annotations
import pytest
from openjarvis.mcp.protocol import MCPRequest
from openjarvis.mcp.server import MCPServer
from openjarvis.tools.calculator import CalculatorTool
from openjarvis.tools.think import ThinkTool
@pytest.fixture
def server():
return MCPServer([CalculatorTool(), ThinkTool()])
class TestProtocolVersion:
def test_protocol_version_2025(self, server):
assert server.PROTOCOL_VERSION == "2025-11-25"
def test_initialize_returns_2025_version(self, server):
req = MCPRequest(method="initialize", id=1)
resp = server.handle(req)
assert resp.result["protocolVersion"] == "2025-11-25"
class TestServerTitle:
def test_initialize_includes_title(self, server):
req = MCPRequest(method="initialize", id=1)
resp = server.handle(req)
server_info = resp.result["serverInfo"]
assert "title" in server_info
assert server_info["title"] == "OpenJarvis Tool Server"
class TestListChanged:
def test_tools_capability_list_changed_true(self, server):
req = MCPRequest(method="initialize", id=1)
resp = server.handle(req)
caps = resp.result["capabilities"]
assert caps["tools"]["listChanged"] is True
class TestAnnotations:
def test_calculator_has_read_only_annotation(self, server):
req = MCPRequest(method="tools/list", id=1)
resp = server.handle(req)
tools = resp.result["tools"]
calc = next(t for t in tools if t["name"] == "calculator")
assert "annotations" in calc
assert calc["annotations"]["readOnlyHint"] is True
assert calc["annotations"]["destructiveHint"] is False
def test_think_has_read_only_annotation(self, server):
req = MCPRequest(method="tools/list", id=1)
resp = server.handle(req)
tools = resp.result["tools"]
think = next(t for t in tools if t["name"] == "think")
assert "annotations" in think
assert think["annotations"]["readOnlyHint"] is True
class TestAutoDiscovery:
def test_auto_discover_creates_server(self):
"""MCPServer() with no tools arg should auto-discover."""
server = MCPServer()
req = MCPRequest(method="tools/list", id=1)
resp = server.handle(req)
# Should have at least calculator and think (via direct import)
names = {t["name"] for t in resp.result["tools"]}
assert "calculator" in names
assert "think" in names
def test_auto_discover_includes_storage_tools(self):
"""Auto-discovered server should include storage tools."""
server = MCPServer()
req = MCPRequest(method="tools/list", id=1)
resp = server.handle(req)
names = {t["name"] for t in resp.result["tools"]}
assert "memory_store" in names
assert "memory_retrieve" in names
assert "memory_search" in names
assert "memory_index" in names
def test_auto_discover_tool_count(self):
"""Auto-discovered server should have all built-in tools."""
server = MCPServer()
req = MCPRequest(method="tools/list", id=1)
resp = server.handle(req)
# At least: calculator, think, file_read, web_search,
# code_interpreter, memory_store/retrieve/search/index,
# llm, retrieval
assert len(resp.result["tools"]) >= 8
def test_explicit_tools_override_auto_discover(self):
"""Passing explicit tools should NOT auto-discover."""
server = MCPServer([CalculatorTool()])
req = MCPRequest(method="tools/list", id=1)
resp = server.handle(req)
tools = resp.result["tools"]
assert len(tools) == 1
assert tools[0]["name"] == "calculator"
def test_empty_list_means_no_tools(self):
"""Passing empty list should give empty tools (not auto-discover)."""
server = MCPServer([])
req = MCPRequest(method="tools/list", id=1)
resp = server.handle(req)
assert resp.result["tools"] == []
class TestStorageToolAnnotations:
def test_memory_store_destructive(self):
from openjarvis.tools.storage_tools import MemoryStoreTool
server = MCPServer([MemoryStoreTool()])
req = MCPRequest(method="tools/list", id=1)
resp = server.handle(req)
tool = resp.result["tools"][0]
assert tool["annotations"]["destructiveHint"] is True
assert tool["annotations"]["readOnlyHint"] is False
def test_memory_retrieve_read_only(self):
from openjarvis.tools.storage_tools import MemoryRetrieveTool
server = MCPServer([MemoryRetrieveTool()])
req = MCPRequest(method="tools/list", id=1)
resp = server.handle(req)
tool = resp.result["tools"][0]
assert tool["annotations"]["readOnlyHint"] is True
assert tool["annotations"]["destructiveHint"] is False