Tools
A tool is a callable the model can invoke during a turn to do real work. Morpheus
uses the native strands-agents tool format: decorated functions passed straight
into an agent’s tools list.
Tool implementations live in morpheus-llm so the
Lambdas and the runtime share them. agentcore/tools/ is a re-export layer:
# agentcore/tools/__init__.py
from morpheus_llm.tools import (
add_numbers, create_agentcore_browser, create_hubspot_mcp, create_tavily_mcp,
)
Defining a tool
The @tool decorator from strands derives everything from the function itself: the
docstring becomes the description (including the Args: block, which the model sees),
and type annotations become the input schema. No separate schema object.
from strands import tool
@tool
def multiply(a: float, b: float) -> float:
"""Multiply two numbers together.
Args:
a: First operand
b: Second operand
Returns:
The product of a and b
"""
return a * b
The decorated function is a Strands-native tool object and can be passed directly to
ClaudeAgentService.
Local tools
| Tool | Signature | Purpose |
|---|---|---|
|
|
Demonstration tool, also used as a smoke test in |
Vended Strands tools
From strands-agents-tools, wired into dialler_agent:
| Tool | Import | Capability |
|---|---|---|
|
|
Read and write files on the container filesystem |
|
|
Execute shell commands |
|
|
Arbitrary HTTP requests |
|
|
Execute Python with state persistence across calls |
|
|
MCP tools
Model Context Protocol servers appear to the agent as tools. Both integrations are
factory functions, not module-level objects, because MCPClient transports hold an
open HTTP session and cannot be reused across agent invocations.
create_hubspot_mcp()
create_hubspot_mcp(*, client_id: str, client_secret: str, refresh_token: str) -> MCPClient
Connects to the HubSpot Remote MCP server at https://mcp.hubspot.com/ over
Streamable HTTP. The OAuth refresh token is exchanged for an access token by
refresh_hubspot_access_token() and cached with @lru_cache(maxsize=4) keyed on the
credential triple, so the OAuth round-trip happens once per container.
Two transport details:
-
The underlying
httpxtransport is wrapped in_RetryOn429Transport, which retries HTTP 429 up to 4 times with exponential backoff (1 s base, capped at 30 s per sleep), honouringRetry-Afterwhen present. -
terminate_on_close=False, because HubSpot’s MCP server does not implement the DELETE session-termination endpoint and returns 405 if it is called.
Capabilities the server advertises: contact search and retrieval, call and activity history, task management, company and deal lookups.
create_tavily_mcp()
create_tavily_mcp(*, api_key: str) -> MCPClient
Connects to https://mcp.tavily.com/mcp/ with the API key in the query string. Two
tools reach the agent:
-
tavily-search— web search with optional domain filtering, topic selection (generalornews), and result-depth control. -
tavily-extract— clean article content from one or more URLs.
Used by the enrichment agent in enrichment-scorer, not by the runtime’s
dialler_agent. See Seller enrichment.
create_agentcore_browser()
create_agentcore_browser(region=None, session_timeout=3600, identifier=None) -> Any
A fully managed cloud Chrome session through Bedrock AgentCore Browser — navigate,
fill forms, extract content, click. Requires the optional extras
(pip install morpheus-llm[browser]: strands-agents-tools, playwright,
nest-asyncio); a missing dependency raises ImportError with the install command.
Not currently wired into any agent.
Credentials
Every factory takes credentials as explicit keyword arguments. Libraries never read
os.environ. The caller fetches them:
config = load_config() # or load_secrets() in a Lambda
tools = lambda: [
create_hubspot_mcp(
client_id=config.hubspot_client_id,
client_secret=config.hubspot_client_secret,
refresh_token=config.hubspot_refresh_token,
),
create_tavily_mcp(api_key=config.tavily_api_key),
]
This makes credential provenance visible at the call site and keeps the library testable without environment manipulation.
Adding a tool
-
Create
libs/morpheus-llm/morpheus_llm/tools/builtin/<name>.py. -
Decorate with
@toolfromstrands; write a precise docstring. -
Export it from
morpheus_llm/tools/init.py. -
For an MCP tool, write a factory taking credentials as keyword-only arguments.
-
Pass it into an agent’s
toolslist — alambdaif it is stateful. -
Re-export from
agentcore/tools/init.pyif the runtime needs it.
Guidelines
-
snake_casenames. Models handleget_contact_by_phonebetter thangetContactByPhone. -
Precise docstrings. The
Args:descriptions are surfaced to the model. Be specific about inputs, outputs, and side effects. -
Return strings. Tool results go back to the model as text; return a JSON string for structured data rather than a raw object.
-
Handle errors inside the tool. Catch exceptions and return an error string so the model can reason about the failure and retry, rather than raising and aborting the turn.
-
Never hold state at module level. Anything with a connection — an
MCPClient, a browser session — must be created per invocation via a factory.