Implement and configure the Story agent
Task 1: Implement the Story Agent
Section titled “Task 1: Implement the Story Agent”The Story Agent is a Strands agent generated with --protocol=ag-ui in Module 1, so the UI can stream from it over the Agent-User Interaction protocol via CopilotKit. It uses the Inventory MCP Server to manage the player’s items, and already persists conversation history via the session.py the generator provisioned in Module 1 — deployed, that’s Strands’ built-in S3SessionManager writing into the same S3 bucket the Game API’s queryActions reads from, so the browser can rebuild transcripts on revisit.
Agent implementation
Section titled “Agent implementation”Update agent.py in packages/story/dungeon_adventure_story/agent:
from contextlib import contextmanager
from dungeon_adventure_agent_connection import InventoryMcpServerClientStrands, log_model_errors, log_tool_errorsfrom strands import Agentfrom strands.hooks import HookCallback, HookProvider
AGENT_HOOKS: list[HookProvider | HookCallback] = [log_model_errors, log_tool_errors]
@contextmanagerdef get_agent(): inventory_mcp_server = InventoryMcpServerClientStrands.create() with ( inventory_mcp_server, ): yield Agent( system_prompt="""You are running a text adventure game for a lone adventurer. When a new storybegins, the first user message will tell you the player's name and the genre(one of 'medieval', 'zombie', 'superhero'). Greet the player by name, set thescene in the chosen genre, and populate their inventory with a few startingitems. On subsequent turns, advance the story in response to the player'sactions and keep item state in sync with the narrative.Use the tools to manage the player's inventory as items are obtained or lost.Item names in the inventory must be Title Case — match them exactly.Only use list-inventory-items if you are unsure of the exact item name before modifying it.IMPORTANT: Only call ONE tool per response turn. Never batch multiple tool calls in a single turn.Ensure you specify a suitable emoji when adding items if available.Items should be a key part of the narrative.Keep responses under 100 words.""", tools=[*inventory_mcp_server.list_tools_sync()], hooks=AGENT_HOOKS, )from contextlib import contextmanager
from dungeon_adventure_agent_connection import InventoryMcpServerClientStrands, log_model_errors, log_tool_errorsfrom strands import Agent, toolfrom strands import Agentfrom strands.hooks import HookCallback, HookProviderfrom strands_tools import current_time
@tooldef subtract(a: int, b: int) -> int: return a - b
AGENT_HOOKS: list[HookProvider | HookCallback] = [log_model_errors, log_tool_errors]
@contextmanagerdef get_agent(): inventory_mcp_server = InventoryMcpServerClientStrands.create() with ( inventory_mcp_server, ): yield Agent( name="StoryAgent", description="StoryAgent Strands Agent", system_prompt="""You are a mathematical wizard.Use your tools for mathematical tasks.Refer to tools as your 'spellbook'.You are running a text adventure game for a lone adventurer. When a new storybegins, the first user message will tell you the player's name and the genre(one of 'medieval', 'zombie', 'superhero'). Greet the player by name, set thescene in the chosen genre, and populate their inventory with a few startingitems. On subsequent turns, advance the story in response to the player'sactions and keep item state in sync with the narrative.Use the tools to manage the player's inventory as items are obtained or lost.Item names in the inventory must be Title Case — match them exactly.Only use list-inventory-items if you are unsure of the exact item name before modifying it.IMPORTANT: Only call ONE tool per response turn. Never batch multiple tool calls in a single turn.Ensure you specify a suitable emoji when adding items if available.Items should be a key part of the narrative.Keep responses under 100 words.""", tools=[subtract, current_time, *inventory_mcp_server.list_tools_sync()], tools=[*inventory_mcp_server.list_tools_sync()], hooks=AGENT_HOOKS, )agent.py drops the sample subtract tool and swaps the system prompt for a dungeon-master one that invites the first user message to state the player’s name and genre, and uses the Inventory MCP Server’s tools. main.py needs no changes here — session management was already wired up when the agent was generated.
Task 2: Test your Agent locally
Section titled “Task 2: Test your Agent locally”Build the code
Section titled “Build the code”To build the code:
pnpm buildyarn buildnpm run buildbun buildChat with your Agent
Section titled “Chat with your Agent”The generated agent-chat target opens an interactive REPL against your agent. It runs standalone and connects to your locally-running agent, so first start the agent’s local server in one terminal:
pnpm nx agent-dev storyyarn nx agent-dev storynpx nx agent-dev storybunx nx agent-dev storyThen, in a second terminal, start the chat:
pnpm nx agent-chat storyyarn nx agent-chat storynpx nx agent-chat storybunx nx agent-chat storyYour first message should tell the agent your hero’s name and the genre (for example: My name is Alice. Start my zombie adventure.) and the story will stream back.
Congratulations. You have built and tested your first Strands Agent locally! 🎉🎉🎉