diff --git a/src/strands/mcp/__init__.py b/src/strands/mcp/__init__.py new file mode 100644 index 000000000..8d2c1daa2 --- /dev/null +++ b/src/strands/mcp/__init__.py @@ -0,0 +1,14 @@ +"""Model Context Protocol (MCP) integration. + +This package provides integration with the Model Context Protocol (MCP), allowing agents to use tools provided by MCP +servers. + +- Docs: https://www.anthropic.com/news/model-context-protocol +""" + +from .mcp_agent_tool import MCPAgentTool +from .mcp_client import MCPClient, ToolFilters +from .mcp_tasks import TasksConfig +from .mcp_types import MCPTransport + +__all__ = ["MCPAgentTool", "MCPClient", "MCPTransport", "TasksConfig", "ToolFilters"] diff --git a/src/strands/tools/mcp/mcp_agent_tool.py b/src/strands/mcp/mcp_agent_tool.py similarity index 97% rename from src/strands/tools/mcp/mcp_agent_tool.py rename to src/strands/mcp/mcp_agent_tool.py index bedd93f24..5ae4d2c9e 100644 --- a/src/strands/tools/mcp/mcp_agent_tool.py +++ b/src/strands/mcp/mcp_agent_tool.py @@ -12,8 +12,8 @@ from mcp.types import Tool as MCPTool from typing_extensions import override -from ...types._events import ToolResultEvent -from ...types.tools import AgentTool, ToolGenerator, ToolSpec, ToolUse +from ..types._events import ToolResultEvent +from ..types.tools import AgentTool, ToolGenerator, ToolSpec, ToolUse if TYPE_CHECKING: from .mcp_client import MCPClient diff --git a/src/strands/tools/mcp/mcp_client.py b/src/strands/mcp/mcp_client.py similarity index 99% rename from src/strands/tools/mcp/mcp_client.py rename to src/strands/mcp/mcp_client.py index 2ac632925..1665f5bf5 100644 --- a/src/strands/tools/mcp/mcp_client.py +++ b/src/strands/mcp/mcp_client.py @@ -44,11 +44,11 @@ from pydantic import AnyUrl from typing_extensions import Protocol, TypedDict -from ...types import PaginatedList -from ...types.exceptions import MCPClientInitializationError, ToolProviderException -from ...types.media import ImageFormat -from ...types.tools import AgentTool, ToolResultContent, ToolResultStatus -from ..tool_provider import ToolProvider +from ..tools.tool_provider import ToolProvider +from ..types import PaginatedList +from ..types.exceptions import MCPClientInitializationError, ToolProviderException +from ..types.media import ImageFormat +from ..types.tools import AgentTool, ToolResultContent, ToolResultStatus from .mcp_agent_tool import MCPAgentTool from .mcp_instrumentation import mcp_instrumentation from .mcp_tasks import DEFAULT_TASK_CONFIG, DEFAULT_TASK_POLL_TIMEOUT, DEFAULT_TASK_TTL, TasksConfig diff --git a/src/strands/tools/mcp/mcp_instrumentation.py b/src/strands/mcp/mcp_instrumentation.py similarity index 100% rename from src/strands/tools/mcp/mcp_instrumentation.py rename to src/strands/mcp/mcp_instrumentation.py diff --git a/src/strands/tools/mcp/mcp_tasks.py b/src/strands/mcp/mcp_tasks.py similarity index 100% rename from src/strands/tools/mcp/mcp_tasks.py rename to src/strands/mcp/mcp_tasks.py diff --git a/src/strands/tools/mcp/mcp_types.py b/src/strands/mcp/mcp_types.py similarity index 98% rename from src/strands/tools/mcp/mcp_types.py rename to src/strands/mcp/mcp_types.py index 09feb624f..e80ef2fd4 100644 --- a/src/strands/tools/mcp/mcp_types.py +++ b/src/strands/mcp/mcp_types.py @@ -9,7 +9,7 @@ from mcp.shared.message import SessionMessage from typing_extensions import NotRequired -from ...types.tools import ToolResult +from ..types.tools import ToolResult """ MCPTransport defines the interface for MCP transport implementations. This abstracts diff --git a/src/strands/tools/mcp/__init__.py b/src/strands/tools/mcp/__init__.py index 8d2c1daa2..0edd82125 100644 --- a/src/strands/tools/mcp/__init__.py +++ b/src/strands/tools/mcp/__init__.py @@ -1,14 +1,27 @@ -"""Model Context Protocol (MCP) integration. +"""Deprecated: MCP integration has moved to ``strands.mcp``. -This package provides integration with the Model Context Protocol (MCP), allowing agents to use tools provided by MCP -servers. - -- Docs: https://www.anthropic.com/news/model-context-protocol +This module re-exports the public API from its new location and emits a +``DeprecationWarning`` at import time. Legacy submodule paths such as +``strands.tools.mcp.mcp_client`` continue to resolve to the canonical +modules under ``strands.mcp`` via ``sys.modules`` aliasing. Update +imports to ``strands.mcp``; this alias will be removed in a future +release. """ -from .mcp_agent_tool import MCPAgentTool -from .mcp_client import MCPClient, ToolFilters -from .mcp_tasks import TasksConfig -from .mcp_types import MCPTransport +import sys as _sys +import warnings as _warnings + +from strands import mcp as _mcp +from strands.mcp import MCPAgentTool, MCPClient, MCPTransport, TasksConfig, ToolFilters + +for _submod_name in ("mcp_agent_tool", "mcp_client", "mcp_instrumentation", "mcp_tasks", "mcp_types"): + _sys.modules[f"strands.tools.mcp.{_submod_name}"] = getattr(_mcp, _submod_name) + +_warnings.warn( + "strands.tools.mcp has moved to strands.mcp. " + "Import from strands.mcp instead; strands.tools.mcp will be removed in a future release.", + DeprecationWarning, + stacklevel=2, +) __all__ = ["MCPAgentTool", "MCPClient", "MCPTransport", "TasksConfig", "ToolFilters"] diff --git a/tests/strands/mcp/__init__.py b/tests/strands/mcp/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/strands/mcp/test_canonical_import_path.py b/tests/strands/mcp/test_canonical_import_path.py new file mode 100644 index 000000000..0194d3bee --- /dev/null +++ b/tests/strands/mcp/test_canonical_import_path.py @@ -0,0 +1,25 @@ +"""Tests for the canonical ``strands.mcp`` import path. + +The implementation currently lives in ``strands.tools.mcp``. This test +locks in the contract that ``strands.mcp`` re-exports the same objects so +that users can migrate imports ahead of the follow-up refactor that +moves the implementation. +""" + + +def test_strands_mcp_reexports_public_api() -> None: + import strands.mcp as new + import strands.tools.mcp as old + + assert new.MCPClient is old.MCPClient + assert new.MCPAgentTool is old.MCPAgentTool + assert new.MCPTransport is old.MCPTransport + assert new.TasksConfig is old.TasksConfig + assert new.ToolFilters is old.ToolFilters + + +def test_strands_mcp_all_matches_tools_mcp_all() -> None: + import strands.mcp as new + import strands.tools.mcp as old + + assert sorted(new.__all__) == sorted(old.__all__)