mirror of
https://github.com/temporal-community/temporal-ai-agent.git
synced 2026-03-15 14:08:08 +01:00
Model Context Protocol (MCP) support with new use case (#42)
* initial mcp * food ordering with mcp * prompt eng * splitting out goals and updating docs * a diff so I can get tests from codex * a diff so I can get tests from codex * oops, missing files * tests, file formatting * readme and setup updates * setup.md link fixes * readme change * readme change * readme change * stripe food setup script * single agent mode default * prompt engineering for better multi agent performance * performance should be greatly improved * Update goals/finance.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update activities/tool_activities.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * co-pilot PR suggested this change, and now fixed it * stronger wording around json format response * formatting * moved docs to dir * moved image assets under docs * cleanup env example, stripe guidance * cleanup --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
1811e4cf59
commit
5d55a9fe80
@@ -2,7 +2,7 @@ import os
|
||||
from typing import List
|
||||
|
||||
import tools.tool_registry as tool_registry
|
||||
from models.tool_definitions import AgentGoal
|
||||
from models.tool_definitions import AgentGoal, MCPServerDefinition
|
||||
|
||||
# Turn on Silly Mode - this should be a description of the persona you'd like the bot to have and can be a single word or a phrase.
|
||||
# Example if you want the bot to be a specific person, like Mario or Christopher Walken, or to describe a specific tone:
|
||||
@@ -311,7 +311,7 @@ goal_fin_check_account_balances = AgentGoal(
|
||||
)
|
||||
|
||||
# this tool checks account balances, and uses ./data/customer_account_data.json as dummy data
|
||||
# it also uses a separate workflow/tool, see ./SETUP.md for details
|
||||
# it also uses a separate workflow/tool, see ./setup.md for details
|
||||
goal_fin_move_money = AgentGoal(
|
||||
id="goal_fin_move_money",
|
||||
category_tag="fin",
|
||||
@@ -351,7 +351,7 @@ goal_fin_move_money = AgentGoal(
|
||||
)
|
||||
|
||||
# this starts a loan approval process
|
||||
# it also uses a separate workflow/tool, see ./SETUP.md for details
|
||||
# it also uses a separate workflow/tool, see ./setup.md for details
|
||||
goal_fin_loan_application = AgentGoal(
|
||||
id="goal_fin_loan_application",
|
||||
category_tag="fin",
|
||||
@@ -455,6 +455,126 @@ goal_ecomm_list_orders = AgentGoal(
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
# ----- MCP Integrations -----
|
||||
goal_mcp_stripe = AgentGoal(
|
||||
id="goal_mcp_stripe",
|
||||
category_tag="mcp-integrations",
|
||||
agent_name="Stripe MCP Agent",
|
||||
agent_friendly_description="Manage Stripe operations via MCP",
|
||||
tools=[], # Will be populated dynamically
|
||||
mcp_server_definition=MCPServerDefinition(
|
||||
name="stripe-mcp",
|
||||
command="npx",
|
||||
args=[
|
||||
"-y",
|
||||
"@stripe/mcp",
|
||||
"--tools=all",
|
||||
f"--api-key={os.getenv('STRIPE_API_KEY')}",
|
||||
],
|
||||
env=None,
|
||||
included_tools=["list_customers", "list_products"],
|
||||
),
|
||||
description="Help manage Stripe operations for customer and product data by using the customers.read and products.read tools.",
|
||||
starter_prompt="Welcome! I can help you read Stripe customer and product information.",
|
||||
example_conversation_history="\n ".join(
|
||||
[
|
||||
"agent: Welcome! I can help you read Stripe customer and product information. What would you like to do first?",
|
||||
"user: what customers are there?",
|
||||
"agent: I'll check for customers now.",
|
||||
"user_confirmed_tool_run: <user clicks confirm on customers.read tool>",
|
||||
'tool_result: { "customers": [{"id": "cus_abc", "name": "Customer A"}, {"id": "cus_xyz", "name": "Customer B"}] }',
|
||||
"agent: I found two customers: Customer A and Customer B. Can I help with anything else?",
|
||||
"user: what products exist?",
|
||||
"agent: Let me get the list of products for you.",
|
||||
"user_confirmed_tool_run: <user clicks confirm on products.read tool>",
|
||||
'tool_result: { "products": [{"id": "prod_123", "name": "Gold Plan"}, {"id": "prod_456", "name": "Silver Plan"}] }',
|
||||
"agent: I found two products: Gold Plan and Silver Plan.",
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
# ----- Food Ordering Goal -----
|
||||
goal_food_ordering = AgentGoal(
|
||||
id="goal_food_ordering",
|
||||
category_tag="food",
|
||||
agent_name="Food Ordering Assistant",
|
||||
agent_friendly_description="Order food from Tony's Pizza Palace using Stripe for payment processing. Browse menu, add items to your order, and check out securely. Please ensure context carries over between tool runs.",
|
||||
tools=[tool_registry.food_add_to_cart_tool],
|
||||
mcp_server_definition=MCPServerDefinition(
|
||||
name="stripe-mcp",
|
||||
command="npx",
|
||||
args=[
|
||||
"-y",
|
||||
"@stripe/mcp",
|
||||
"--tools=all",
|
||||
f"--api-key={os.getenv('STRIPE_API_KEY')}",
|
||||
],
|
||||
env=None,
|
||||
included_tools=[
|
||||
"list_products",
|
||||
"list_prices",
|
||||
"create_customer",
|
||||
"create_invoice",
|
||||
"create_invoice_item",
|
||||
"finalize_invoice",
|
||||
],
|
||||
),
|
||||
description="The user wants to order food from Tony's Pizza Palace. "
|
||||
"First, help the user browse the menu by calling list_products. "
|
||||
"When they express interest in items, get pricing using list_prices. "
|
||||
"Add items to their cart using AddToCart as they decide - the order doesn't matter, multiple items can be added. "
|
||||
"After they're done selecting items, get their customer details and create a Stripe customer. "
|
||||
"For checkout: 1) create_invoice, 2) create_invoice_item for each individual item (IMPORTANT: create_invoice_item does NOT accept quantity parameter - call it once per item, so if user wants 2 pizzas, call create_invoice_item twice with the same price), "
|
||||
"3) finalize_invoice. The finalized invoice will contain a hosted_invoice_url for payment.",
|
||||
starter_prompt=starter_prompt_generic,
|
||||
example_conversation_history="\n ".join(
|
||||
[
|
||||
"user: I want to order food.",
|
||||
"agent: Welcome to Tony's Pizza Palace! I can help you browse our menu, add items to your cart, and process payment. Let me show you what we have available.",
|
||||
"user_confirmed_tool_run: <user clicks confirm on list_products tool with limit=100 and product.metadata.use_case == 'food_ordering_demo'>",
|
||||
'tool_result: {"products": [{"id": "prod_pepperoni", "name": "Pepperoni Pizza", "description": "A timeless classic featuring pepperoni"}, {"id": "prod_margherita", "name": "Margherita Pizza", "description": "Fresh mozzarella and basil"}, {"id": "prod_garlic_bread", "name": "Garlic Bread", "description": "Warm crusty bread with garlic butter"}, {"id": "prod_soda", "name": "Soda", "description": "A large bottle of cola"}]}',
|
||||
"agent: We have Pepperoni Pizza, Margherita Pizza, Garlic Bread, and Soda available. What would you like to order?",
|
||||
"user: I'd like 2 pepperoni pizzas and a soda.",
|
||||
"agent: Excellent! Let me get the pricing for the pepperoni pizzas first so you know the cost.",
|
||||
"user_confirmed_tool_run: <user clicks confirm on list_prices tool with product='prod_pepperoni'>",
|
||||
'tool_result: {"prices": [{"id": "price_pepperoni_large", "product": "prod_pepperoni", "unit_amount": 2299, "currency": "usd"}]}',
|
||||
"agent: Pepperoni Pizza is $22.99 each. Now let me check the soda pricing:",
|
||||
"user_confirmed_tool_run: <user clicks confirm on list_prices tool with product='prod_soda'>",
|
||||
'tool_result: {"prices": [{"id": "price_soda", "product": "prod_soda", "unit_amount": 250, "currency": "usd"}]}',
|
||||
"agent: And Soda is $2.50. So 2 Pepperoni Pizzas ($22.99 each) plus 1 Soda ($2.50) = $48.48 total. What's your email address to add these items to your cart?",
|
||||
"user: jane.smith@example.com",
|
||||
"agent: Perfect! Adding 2 Pepperoni Pizzas to your cart for jane.smith@example.com. Note: I'm using quantity=2 since you want 2 pizzas.",
|
||||
"user_confirmed_tool_run: <user clicks confirm on AddToCart tool with customer_email='jane.smith@example.com', item_name='Pepperoni Pizza', item_price=22.99, quantity=2, stripe_product_id='prod_pepperoni'>",
|
||||
'tool_result: {"status": "success", "message": "Added 2 x Pepperoni Pizza ($22.99) to cart for jane.smith@example.com", "item_added": {"quantity": 2, "name": "Pepperoni Pizza"}}',
|
||||
"agent: Great! Added 2 Pepperoni Pizzas to your cart. Now adding the Soda (quantity=1):",
|
||||
"user_confirmed_tool_run: <user clicks confirm on AddToCart tool with customer_email='jane.smith@example.com', item_name='Soda', item_price=2.50, quantity=1, stripe_product_id='prod_soda'>",
|
||||
'tool_result: {"status": "success", "message": "Added 1 x Soda ($2.50) to cart for jane.smith@example.com", "item_added": {"quantity": 1, "name": "Soda"}}',
|
||||
"agent: Excellent! Your cart now contains: 2 Pepperoni Pizzas ($22.99 each) and 1 Soda ($2.50). Ready to checkout? I'll need your full name.",
|
||||
"user: Yes, let's proceed with payment. My name is Jane Smith.",
|
||||
"agent: Thank you Jane! Creating your Stripe customer profile with name and email.",
|
||||
"user_confirmed_tool_run: <user clicks confirm on create_customer tool with name='Jane Smith' and email='jane.smith@example.com'>",
|
||||
'tool_result: {"customer": {"id": "cus_ExAmPlE12345", "name": "Jane Smith", "email": "jane.smith@example.com"}}',
|
||||
"agent: Customer profile created! Now I'll create a draft invoice for your order.",
|
||||
"user_confirmed_tool_run: <user clicks confirm on create_invoice tool with customer='cus_ExAmPlE12345'>",
|
||||
'tool_result: {"invoice": {"id": "in_InvOicE54321", "status": "draft", "customer": "cus_ExAmPlE12345"}}',
|
||||
"agent: Invoice created! Now adding your first Pepperoni Pizza to the invoice.",
|
||||
"user_confirmed_tool_run: <user clicks confirm on create_invoice_item tool with customer='cus_ExAmPlE12345', invoice='in_InvOicE54321', price='price_pepperoni_large'>",
|
||||
'tool_result: {"status": "success", "invoice_item": {"id": "ii_pizza1"}}',
|
||||
"agent: First pizza added! Now adding your second Pepperoni Pizza to the invoice.",
|
||||
"user_confirmed_tool_run: <user clicks confirm on create_invoice_item tool with customer='cus_ExAmPlE12345', invoice='in_InvOicE54321', price='price_pepperoni_large'>",
|
||||
'tool_result: {"status": "success", "invoice_item": {"id": "ii_pizza2"}}',
|
||||
"agent: Both pizzas added! Now adding your Soda to the invoice.",
|
||||
"user_confirmed_tool_run: <user clicks confirm on create_invoice_item tool with customer='cus_ExAmPlE12345', invoice='in_InvOicE54321', price='price_soda'>",
|
||||
'tool_result: {"status": "success", "invoice_item": {"id": "ii_soda"}}',
|
||||
"agent: All items added to invoice! Now finalizing to generate the payment link.",
|
||||
"user_confirmed_tool_run: <user clicks confirm on finalize_invoice tool with invoice='in_InvOicE54321'>",
|
||||
'tool_result: {"invoice": {"id": "in_InvOicE54321", "status": "open", "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1NBOLuKVZbzw7QA5/test_YWNjdF8xTkJPTHVLVlpienc3UUE1LF9SbGJlZ2xLMjhlc3lxNzFkVVBXbkswOUlFa2Rna1RxLDEzMDAwMTY4Nw0200RKeJRMlw?s=ap", "amount_due": 4848}}',
|
||||
"agent: Perfect! Your order is complete with 2 Pepperoni Pizzas and 1 Soda. Total: $48.48. Pay securely here: https://invoice.stripe.com/i/acct_1NBOLuKVZbzw7QA5/test_YWNjdF8xTkJPTHVLVlpienc3UUE1LF9SbGJlZ2xLMjhlc3lxNzFkVVBXbkswOUlFa2Rna1RxLDEzMDAwMTY4Nw0200RKeJRMlw?s=ap\\n\\nThank you for ordering from Tony's Pizza Palace!",
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
# Add the goals to a list for more generic processing, like listing available agents
|
||||
goal_list: List[AgentGoal] = []
|
||||
goal_list.append(goal_choose_agent_type)
|
||||
@@ -469,19 +589,21 @@ goal_list.append(goal_fin_move_money)
|
||||
goal_list.append(goal_fin_loan_application)
|
||||
goal_list.append(goal_ecomm_list_orders)
|
||||
goal_list.append(goal_ecomm_order_status)
|
||||
goal_list.append(goal_mcp_stripe)
|
||||
goal_list.append(goal_food_ordering)
|
||||
|
||||
|
||||
# for multi-goal, just set list agents as the last tool
|
||||
first_goal_value = os.getenv("AGENT_GOAL")
|
||||
if first_goal_value is None:
|
||||
multi_goal_mode = True # default if unset
|
||||
multi_goal_mode = False # default to single agent mode if unset
|
||||
elif (
|
||||
first_goal_value is not None
|
||||
and first_goal_value.lower() != "goal_choose_agent_type"
|
||||
and first_goal_value.lower() == "goal_choose_agent_type"
|
||||
):
|
||||
multi_goal_mode = False
|
||||
else:
|
||||
multi_goal_mode = True
|
||||
else:
|
||||
multi_goal_mode = False
|
||||
|
||||
if multi_goal_mode:
|
||||
for goal in goal_list:
|
||||
|
||||
Reference in New Issue
Block a user