Python Agent Examples
This guide provides complete, runnable examples for building TraceMem agents in Python. Each example demonstrates a specific pattern for interacting with TraceMem's Agent MCP server.
Prerequisites
- Python 3.8 or higher
requestslibrary:pip install requests- Access to a TraceMem Agent MCP server (default:
https://mcp.tracemem.com) - A valid TraceMem API key
Connection Details
- Endpoint:
https://mcp.tracemem.com(or set viaMCP_AGENT_URLenvironment variable) - Protocol: JSON-RPC 2.0 over HTTP
- Authentication:
Authorization: Agent <your-api-key>header
MCP Client Implementation
First, let's create a reusable MCP client class that handles JSON-RPC 2.0 communication:
import requests
import json
import os
from typing import Dict, Any, Optional
class MCPClient:
"""MCP Client for interacting with TraceMem Agent MCP Server"""
def __init__(self, base_url: str, api_key: str):
self.base_url = base_url
self.api_key = api_key
self.request_id = 0
self.initialized = False
self.session = requests.Session()
self.session.headers.update({
'Authorization': f'Agent {api_key}',
'Content-Type': 'application/json',
})
def _next_id(self) -> int:
"""Get next request ID"""
self.request_id += 1
return self.request_id
def _call(self, method: str, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
"""Make a JSON-RPC call to MCP server"""
request = {
'jsonrpc': '2.0',
'id': self._next_id(),
'method': method,
'params': params or {},
}
try:
response = self.session.post(self.base_url, json=request)
response.raise_for_status()
result = response.json()
if 'error' in result:
error = result['error']
error_msg = f"MCP Error {error.get('code', 'unknown')}: {error.get('message', 'Unknown error')}"
if 'data' in error:
error_msg += f" - {json.dumps(error['data'])}"
raise Exception(error_msg)
return result.get('result', {})
except requests.exceptions.RequestException as e:
raise Exception(f"HTTP Error: {str(e)}")
def initialize(self) -> Dict[str, Any]:
"""Initialize MCP session"""
result = self._call('initialize', {
'protocolVersion': '2024-11-05',
'capabilities': {},
'clientInfo': {
'name': 'tracemem-test-agent',
'version': '1.0.0',
},
})
self.initialized = True
return result
def list_tools(self) -> Dict[str, Any]:
"""List available tools"""
return self._call('tools/list')
def call_tool(self, name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
"""Call a tool"""
if not self.initialized:
self.initialize()
result = self._call('tools/call', {
'name': name,
'arguments': arguments,
})
# Check if the tool result indicates an error
if result.get('isError'):
error_message = 'Tool call failed'
if result.get('content') and len(result['content']) > 0:
content = result['content'][0]
if content.get('type') == 'text' and content.get('text'):
error_message = content['text']
raise Exception(error_message)
# Parse content from tool result
if result.get('content') and len(result['content']) > 0:
content = result['content'][0]
if content.get('type') == 'text' and content.get('text'):
try:
return json.loads(content['text'])
except json.JSONDecodeError:
return {'raw_text': content['text']}
return result
def is_initialized(self) -> bool:
"""Check if client is initialized"""
return self.initialized
Example 1: Read Agent
This example demonstrates reading customer data from a data product.
#!/usr/bin/env python3
"""
Read Test Agent
Tests the read operation on planetscale_read_customer_v1 data product.
This agent:
1. Creates a decision envelope
2. Reads customer data using decision_read
3. Closes the decision envelope
"""
import os
import sys
from mcp_client import MCPClient
def run_read_test():
# Get configuration from environment
mcp_url = os.getenv('MCP_AGENT_URL', 'https://mcp.tracemem.com')
api_key = os.getenv('TRACEMEM_API_KEY')
instance = os.getenv('TRACEMEM_INSTANCE')
actor = os.getenv('TRACEMEM_ACTOR', 'test-read-agent')
customer_id = os.getenv('CUSTOMER_ID', '1003')
if not api_key:
print('ERROR: TRACEMEM_API_KEY environment variable is required', file=sys.stderr)
sys.exit(1)
print('=' * 60)
print('TraceMem MCP - Read Test Agent')
print('=' * 60)
print()
print(f'Connecting to Agent MCP at: {mcp_url}')
if instance:
print(f'Instance: {instance}')
print(f'Actor: {actor}')
print(f'Customer ID: {customer_id}')
print()
client = MCPClient(mcp_url, api_key)
decision_id = None
try:
# Initialize MCP session
print('Initializing MCP session...')
init_result = client.initialize()
server_name = init_result.get('serverInfo', {}).get('name', 'TraceMem Agent MCP')
print(f'✓ Connected to {server_name}')
print()
# Step 1: Create decision envelope
print('Step 1: Creating decision envelope...')
decision = client.call_tool('decision_create', {
'intent': 'test.read.customer',
'automation_mode': 'autonomous',
'instance': instance,
'actor': actor,
'metadata': {
'customer_id': customer_id,
'test_type': 'read',
},
})
decision_id = decision.get('decision_id') or decision.get('id')
if not decision_id:
raise Exception('Failed to get decision_id from decision_create response')
print(f'✓ Decision envelope created: {decision_id}')
print()
# Step 2: Read customer data
print('Step 2: Reading customer data...')
read_result = client.call_tool('decision_read', {
'decision_id': decision_id,
'product': 'planetscale_read_customer_v1',
'purpose': 'web_order',
'query': {
'id': int(customer_id),
},
})
print('✓ Customer data retrieved')
if read_result.get('event_id'):
print(f' Event ID: {read_result["event_id"]}')
if read_result.get('data_ref'):
print(f' Data Reference: {read_result["data_ref"]}')
if read_result.get('records') and len(read_result['records']) > 0:
print(f' Records found: {len(read_result["records"])}')
print(' Customer data:')
print(json.dumps(read_result['records'][0], indent=2))
else:
print(' No records found')
print()
# Step 3: Close decision (commit)
print('Step 3: Committing decision...')
close_result = client.call_tool('decision_close', {
'decision_id': decision_id,
'action': 'commit',
})
print('✓ Decision committed')
if close_result.get('status'):
print(f' Status: {close_result["status"]}')
print()
# Summary
print('=' * 60)
print('Summary')
print('=' * 60)
print(f'Decision ID: {decision_id}')
print('Result: ✓ Read operation completed successfully')
print()
except Exception as error:
print(f'✗ Error: {str(error)}', file=sys.stderr)
import traceback
traceback.print_exc()
# Try to close decision on error
if decision_id:
try:
print('Attempting to abort decision...')
client.call_tool('decision_close', {
'decision_id': decision_id,
'action': 'abort',
'reason': f'Error occurred: {str(error)}',
})
print('✓ Decision aborted')
except Exception as close_error:
print(f'Failed to abort decision: {str(close_error)}', file=sys.stderr)
sys.exit(1)
if __name__ == '__main__':
run_read_test()
Environment Variables
TRACEMEM_API_KEY(required): Your TraceMem agent API keyMCP_AGENT_URL(optional): MCP server URL (default:https://mcp.tracemem.com)TRACEMEM_INSTANCE(optional): Instance identifierTRACEMEM_ACTOR(optional): Actor identifier (default:test-read-agent)CUSTOMER_ID(optional): Customer ID to read (default:1003)
Running the Example
export TRACEMEM_API_KEY="your-api-key"
export CUSTOMER_ID="1"
python test_read_agent.py
Example 2: Insert Agent (with Policy)
This example demonstrates inserting an order with policy evaluation.
#!/usr/bin/env python3
"""
Insert Test Agent (with Policy)
Tests the insert operation on planetscale_insert_order_v1 data product.
This agent:
1. Creates a decision envelope
2. Evaluates discount_cap_v1 policy
3. Inserts an order using decision_write with operation: "insert"
4. Closes the decision envelope
"""
import os
import sys
import json
from mcp_client import MCPClient
def run_insert_test():
# Get configuration from environment
mcp_url = os.getenv('MCP_AGENT_URL', 'https://mcp.tracemem.com')
api_key = os.getenv('TRACEMEM_API_KEY')
instance = os.getenv('TRACEMEM_INSTANCE')
actor = os.getenv('TRACEMEM_ACTOR', 'test-insert-agent')
# Test data - can be overridden via environment variables
customer_id = int(os.getenv('CUSTOMER_ID', '1001'))
product_id = int(os.getenv('PRODUCT_ID', '2'))
quantity = int(os.getenv('QUANTITY', '1'))
total_amount = float(os.getenv('TOTAL_AMOUNT', '99.99'))
order_status = os.getenv('ORDER_STATUS', 'pending')
proposed_discount = float(os.getenv('PROPOSED_DISCOUNT', '0'))
if not api_key:
print('ERROR: TRACEMEM_API_KEY environment variable is required', file=sys.stderr)
sys.exit(1)
print('=' * 60)
print('TraceMem MCP - Insert Test Agent')
print('=' * 60)
print()
print(f'Connecting to Agent MCP at: {mcp_url}')
if instance:
print(f'Instance: {instance}')
print(f'Actor: {actor}')
print('Order Data:')
print(f' Customer ID: {customer_id}')
print(f' Product ID: {product_id}')
print(f' Quantity: {quantity}')
print(f' Total Amount: {total_amount}')
print(f' Order Status: {order_status}')
print(f' Proposed Discount: {proposed_discount}')
print()
client = MCPClient(mcp_url, api_key)
decision_id = None
try:
# Initialize MCP session
print('Initializing MCP session...')
init_result = client.initialize()
server_name = init_result.get('serverInfo', {}).get('name', 'TraceMem Agent MCP')
print(f'✓ Connected to {server_name}')
print()
# Step 1: Create decision envelope
print('Step 1: Creating decision envelope...')
decision = client.call_tool('decision_create', {
'intent': 'test.insert.order',
'automation_mode': 'autonomous',
'instance': instance,
'actor': actor,
'metadata': {
'customer_id': str(customer_id),
'product_id': str(product_id),
'test_type': 'insert',
},
})
decision_id = decision.get('decision_id') or decision.get('id')
if not decision_id:
raise Exception('Failed to get decision_id from decision_create response')
print(f'✓ Decision envelope created: {decision_id}')
print()
# Step 2: Evaluate policy
print('Step 2: Evaluating discount_cap_v1 policy...')
policy_result = client.call_tool('decision_evaluate', {
'decision_id': decision_id,
'policy_id': 'discount_cap_v1',
'inputs': {
'proposed_discount': proposed_discount,
},
})
outcome = policy_result.get('outcome', 'unknown')
print('✓ Policy evaluation completed')
print(f' Policy ID: discount_cap_v1')
print(f' Proposed Discount: {proposed_discount}')
print(f' Outcome: {outcome}')
if policy_result.get('rationale'):
rationale = policy_result['rationale']
if isinstance(rationale, dict):
rationale_message = rationale.get('message', json.dumps(rationale))
else:
rationale_message = rationale
print(f' Rationale: {rationale_message}')
if policy_result.get('event_id'):
print(f' Event ID: {policy_result["event_id"]}')
print()
# Handle policy outcomes
if outcome == 'deny':
raise Exception(f'Policy evaluation denied the operation. Rationale: {policy_result.get("rationale", {}).get("message", "No rationale provided")}')
elif outcome == 'requires_exception':
print('⚠ Policy requires exception/approval, but continuing with test...')
print()
elif outcome != 'allow':
print(f'⚠ Unexpected policy outcome: {outcome}, continuing with test...')
print()
# Step 3: Insert order
print('Step 3: Inserting order...')
write_result = client.call_tool('decision_write', {
'decision_id': decision_id,
'product': 'planetscale_insert_order_v1',
'purpose': 'web_order',
'mutation': {
'operation': 'insert',
'records': [{
'customer_id': customer_id,
'product_id': product_id,
'quantity': quantity,
'total_amount': total_amount,
'order_status': order_status,
}],
},
})
print('✓ Order inserted')
if write_result.get('event_id'):
print(f' Event ID: {write_result["event_id"]}')
if write_result.get('status'):
print(f' Status: {write_result["status"]}')
if write_result.get('created_records') and len(write_result['created_records']) > 0:
print(f' Created {len(write_result["created_records"])} record(s):')
for index, record in enumerate(write_result['created_records']):
print(f' Record {index + 1}:')
print(json.dumps(record, indent=2))
if write_result.get('mutation_summary'):
print(f' Mutation Summary: {json.dumps(write_result["mutation_summary"])}')
print()
# Step 4: Close decision (commit)
print('Step 4: Committing decision...')
close_result = client.call_tool('decision_close', {
'decision_id': decision_id,
'action': 'commit',
})
print('✓ Decision committed')
if close_result.get('status'):
print(f' Status: {close_result["status"]}')
print()
# Summary
print('=' * 60)
print('Summary')
print('=' * 60)
print(f'Decision ID: {decision_id}')
print('Result: ✓ Insert operation completed successfully')
if write_result.get('created_records') and len(write_result['created_records']) > 0:
first_record = write_result['created_records'][0]
if first_record.get('order_id'):
print(f'Created Order ID: {first_record["order_id"]}')
print()
except Exception as error:
print(f'✗ Error: {str(error)}', file=sys.stderr)
import traceback
traceback.print_exc()
# Try to close decision on error
if decision_id:
try:
print('Attempting to abort decision...')
client.call_tool('decision_close', {
'decision_id': decision_id,
'action': 'abort',
'reason': f'Error occurred: {str(error)}',
})
print('✓ Decision aborted')
except Exception as close_error:
print(f'Failed to abort decision: {str(close_error)}', file=sys.stderr)
sys.exit(1)
if __name__ == '__main__':
run_insert_test()
Environment Variables
TRACEMEM_API_KEY(required): Your TraceMem agent API keyMCP_AGENT_URL(optional): MCP server URL (default:https://mcp.tracemem.com)TRACEMEM_INSTANCE(optional): Instance identifierTRACEMEM_ACTOR(optional): Actor identifier (default:test-insert-agent)CUSTOMER_ID(optional): Customer ID for order (default:1001)PRODUCT_ID(optional): Product ID for order (default:2)QUANTITY(optional): Order quantity (default:1)TOTAL_AMOUNT(optional): Order total amount (default:99.99)ORDER_STATUS(optional): Order status (default:pending)PROPOSED_DISCOUNT(optional): Proposed discount for policy evaluation (default:0)
Example 3: Insert Agent (without Policy)
This example demonstrates inserting an order without policy evaluation.
#!/usr/bin/env python3
"""
Insert Test Agent (without Policy)
Tests the insert operation on planetscale_insert_order_no_policy_v1 data product.
This agent:
1. Creates a decision envelope
2. Inserts an order using decision_write with operation: "insert"
3. Closes the decision envelope
"""
import os
import sys
import json
from mcp_client import MCPClient
def run_insert_test():
# Get configuration from environment
mcp_url = os.getenv('MCP_AGENT_URL', 'https://mcp.tracemem.com')
api_key = os.getenv('TRACEMEM_API_KEY')
instance = os.getenv('TRACEMEM_INSTANCE')
actor = os.getenv('TRACEMEM_ACTOR', 'test-insert-agent')
# Test data - can be overridden via environment variables
customer_id = int(os.getenv('CUSTOMER_ID', '1002'))
product_id = int(os.getenv('PRODUCT_ID', '4'))
quantity = int(os.getenv('QUANTITY', '1'))
total_amount = float(os.getenv('TOTAL_AMOUNT', '99.99'))
order_status = os.getenv('ORDER_STATUS', 'pending')
if not api_key:
print('ERROR: TRACEMEM_API_KEY environment variable is required', file=sys.stderr)
sys.exit(1)
print('=' * 60)
print('TraceMem MCP - Insert Test Agent')
print('=' * 60)
print()
print(f'Connecting to Agent MCP at: {mcp_url}')
if instance:
print(f'Instance: {instance}')
print(f'Actor: {actor}')
print('Order Data:')
print(f' Customer ID: {customer_id}')
print(f' Product ID: {product_id}')
print(f' Quantity: {quantity}')
print(f' Total Amount: {total_amount}')
print(f' Order Status: {order_status}')
print()
client = MCPClient(mcp_url, api_key)
decision_id = None
try:
# Initialize MCP session
print('Initializing MCP session...')
init_result = client.initialize()
server_name = init_result.get('serverInfo', {}).get('name', 'TraceMem Agent MCP')
print(f'✓ Connected to {server_name}')
print()
# Step 1: Create decision envelope
print('Step 1: Creating decision envelope...')
decision = client.call_tool('decision_create', {
'intent': 'test.insert.order',
'automation_mode': 'autonomous',
'instance': instance,
'actor': actor,
'metadata': {
'customer_id': str(customer_id),
'product_id': str(product_id),
'test_type': 'insert',
},
})
decision_id = decision.get('decision_id') or decision.get('id')
if not decision_id:
raise Exception('Failed to get decision_id from decision_create response')
print(f'✓ Decision envelope created: {decision_id}')
print()
# Step 2: Insert order
print('Step 2: Inserting order...')
write_result = client.call_tool('decision_write', {
'decision_id': decision_id,
'product': 'planetscale_insert_order_no_policy_v1',
'purpose': 'web_order',
'mutation': {
'operation': 'insert',
'records': [{
'customer_id': customer_id,
'product_id': product_id,
'quantity': quantity,
'total_amount': total_amount,
'order_status': order_status,
}],
},
})
print('✓ Order inserted')
if write_result.get('event_id'):
print(f' Event ID: {write_result["event_id"]}')
if write_result.get('status'):
print(f' Status: {write_result["status"]}')
if write_result.get('created_records') and len(write_result['created_records']) > 0:
print(f' Created {len(write_result["created_records"])} record(s):')
for index, record in enumerate(write_result['created_records']):
print(f' Record {index + 1}:')
# Display key fields prominently
if record.get('order_id') is not None:
print(f' Order ID: {record["order_id"]}')
if record.get('customer_id') is not None:
print(f' Customer ID: {record["customer_id"]}')
if record.get('product_id') is not None:
print(f' Product ID: {record["product_id"]}')
if record.get('quantity') is not None:
print(f' Quantity: {record["quantity"]}')
if record.get('total_amount') is not None:
print(f' Total Amount: {record["total_amount"]}')
if record.get('order_status') is not None:
print(f' Order Status: {record["order_status"]}')
if record.get('order_date') is not None:
print(f' Order Date: {record["order_date"]}')
# Display full record as JSON for complete details
print(' Full Record:')
print(json.dumps(record, indent=4))
else:
print(' ⚠ No created records returned (check if return_created is enabled)')
if write_result.get('mutation_summary'):
print(f' Mutation Summary: {json.dumps(write_result["mutation_summary"])}')
print()
# Step 3: Close decision (commit)
print('Step 3: Committing decision...')
close_result = client.call_tool('decision_close', {
'decision_id': decision_id,
'action': 'commit',
})
print('✓ Decision committed')
if close_result.get('status'):
print(f' Status: {close_result["status"]}')
print()
# Summary
print('=' * 60)
print('Summary')
print('=' * 60)
print(f'Decision ID: {decision_id}')
print('Result: ✓ Insert operation completed successfully')
if write_result.get('created_records') and len(write_result['created_records']) > 0:
first_record = write_result['created_records'][0]
print('Created Record:')
if first_record.get('order_id') is not None:
print(f' Order ID: {first_record["order_id"]}')
if first_record.get('customer_id') is not None:
print(f' Customer ID: {first_record["customer_id"]}')
if first_record.get('product_id') is not None:
print(f' Product ID: {first_record["product_id"]}')
if first_record.get('quantity') is not None:
print(f' Quantity: {first_record["quantity"]}')
if first_record.get('total_amount') is not None:
print(f' Total Amount: {first_record["total_amount"]}')
if first_record.get('order_status') is not None:
print(f' Order Status: {first_record["order_status"]}')
print(f' Full Record: {json.dumps(first_record, indent=2)}')
else:
print('⚠ No created records returned')
print()
except Exception as error:
print(f'✗ Error: {str(error)}', file=sys.stderr)
import traceback
traceback.print_exc()
# Try to close decision on error
if decision_id:
try:
print('Attempting to abort decision...')
client.call_tool('decision_close', {
'decision_id': decision_id,
'action': 'abort',
'reason': f'Error occurred: {str(error)}',
})
print('✓ Decision aborted')
except Exception as close_error:
print(f'Failed to abort decision: {str(close_error)}', file=sys.stderr)
sys.exit(1)
if __name__ == '__main__':
run_insert_test()
Example 4: Update Agent
This example demonstrates updating product stock.
#!/usr/bin/env python3
"""
Update Test Agent
Tests the update operation on planetscale_update_product_stock_v1 data product.
This agent:
1. Creates a decision envelope
2. Updates product stock using decision_write with operation: "update"
3. Closes the decision envelope
"""
import os
import sys
import json
from mcp_client import MCPClient
def run_update_test():
# Get configuration from environment
mcp_url = os.getenv('MCP_AGENT_URL', 'https://mcp.tracemem.com')
api_key = os.getenv('TRACEMEM_API_KEY')
instance = os.getenv('TRACEMEM_INSTANCE')
actor = os.getenv('TRACEMEM_ACTOR', 'test-update-agent')
# Test data - can be overridden via environment variables
product_id = int(os.getenv('PRODUCT_ID', '4'))
stock_quantity = int(os.getenv('STOCK_QUANTITY', '90'))
if not api_key:
print('ERROR: TRACEMEM_API_KEY environment variable is required', file=sys.stderr)
sys.exit(1)
print('=' * 60)
print('TraceMem MCP - Update Test Agent')
print('=' * 60)
print()
print(f'Connecting to Agent MCP at: {mcp_url}')
if instance:
print(f'Instance: {instance}')
print(f'Actor: {actor}')
print('Update Data:')
print(f' Product ID: {product_id}')
print(f' Stock Quantity: {stock_quantity}')
print()
client = MCPClient(mcp_url, api_key)
decision_id = None
try:
# Initialize MCP session
print('Initializing MCP session...')
init_result = client.initialize()
server_name = init_result.get('serverInfo', {}).get('name', 'TraceMem Agent MCP')
print(f'✓ Connected to {server_name}')
print()
# Step 1: Create decision envelope
print('Step 1: Creating decision envelope...')
decision = client.call_tool('decision_create', {
'intent': 'test.update.product.stock',
'automation_mode': 'autonomous',
'instance': instance,
'actor': actor,
'metadata': {
'product_id': str(product_id),
'stock_quantity': str(stock_quantity),
'test_type': 'update',
},
})
decision_id = decision.get('decision_id') or decision.get('id')
if not decision_id:
raise Exception('Failed to get decision_id from decision_create response')
print(f'✓ Decision envelope created: {decision_id}')
print()
# Step 2: Update product stock
print('Step 2: Updating product stock...')
write_result = client.call_tool('decision_write', {
'decision_id': decision_id,
'product': 'planetscale_update_product_stock_v1',
'purpose': 'web_order',
'mutation': {
'operation': 'update',
'records': [{
'product_id': product_id, # Key field for identification
'stock_quantity': stock_quantity, # Field to update
}],
},
})
print('✓ Product stock updated')
if write_result.get('event_id'):
print(f' Event ID: {write_result["event_id"]}')
if write_result.get('status'):
print(f' Status: {write_result["status"]}')
if write_result.get('mutation_summary'):
print(f' Mutation Summary: {json.dumps(write_result["mutation_summary"])}')
print()
# Step 3: Close decision (commit)
print('Step 3: Committing decision...')
close_result = client.call_tool('decision_close', {
'decision_id': decision_id,
'action': 'commit',
})
print('✓ Decision committed')
if close_result.get('status'):
print(f' Status: {close_result["status"]}')
print()
# Summary
print('=' * 60)
print('Summary')
print('=' * 60)
print(f'Decision ID: {decision_id}')
print('Result: ✓ Update operation completed successfully')
print(f'Product ID: {product_id}')
print(f'New Stock Quantity: {stock_quantity}')
print()
except Exception as error:
print(f'✗ Error: {str(error)}', file=sys.stderr)
import traceback
traceback.print_exc()
# Try to close decision on error
if decision_id:
try:
print('Attempting to abort decision...')
client.call_tool('decision_close', {
'decision_id': decision_id,
'action': 'abort',
'reason': f'Error occurred: {str(error)}',
})
print('✓ Decision aborted')
except Exception as close_error:
print(f'Failed to abort decision: {str(close_error)}', file=sys.stderr)
sys.exit(1)
if __name__ == '__main__':
run_update_test()
Environment Variables
TRACEMEM_API_KEY(required): Your TraceMem agent API keyMCP_AGENT_URL(optional): MCP server URL (default:https://mcp.tracemem.com)TRACEMEM_INSTANCE(optional): Instance identifierTRACEMEM_ACTOR(optional): Actor identifier (default:test-update-agent)PRODUCT_ID(optional): Product ID to update (default:4)STOCK_QUANTITY(optional): New stock quantity (default:90)
Example 5: Delete Agent
This example demonstrates deleting a target record.
#!/usr/bin/env python3
"""
Delete Test Agent
Tests the delete operation on planetscale_delete_target_v1 data product.
This agent:
1. Creates a decision envelope
2. Deletes a target record using decision_write with operation: "delete"
3. Closes the decision envelope
"""
import os
import sys
import json
import re
from mcp_client import MCPClient
def run_delete_test():
# Get configuration from environment
mcp_url = os.getenv('MCP_AGENT_URL', 'https://mcp.tracemem.com')
api_key = os.getenv('TRACEMEM_API_KEY')
instance = os.getenv('TRACEMEM_INSTANCE')
actor = os.getenv('TRACEMEM_ACTOR', 'test-delete-agent')
# Test data - target ID must be a UUID
target_id = os.getenv('TARGET_ID', '0cf1e19e-00ed-4a4c-8d82-ee70f590fad8')
if not api_key:
print('ERROR: TRACEMEM_API_KEY environment variable is required', file=sys.stderr)
sys.exit(1)
if not target_id:
print('ERROR: TARGET_ID environment variable is required (must be a UUID)', file=sys.stderr)
print('Example: TARGET_ID=550e8400-e29b-41d4-a716-446655440000', file=sys.stderr)
sys.exit(1)
# Basic UUID format validation
uuid_regex = re.compile(r'^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$', re.IGNORECASE)
if not uuid_regex.match(target_id):
print('ERROR: TARGET_ID must be a valid UUID format', file=sys.stderr)
print(f'Received: {target_id}', file=sys.stderr)
print('Expected format: 550e8400-e29b-41d4-a716-446655440000', file=sys.stderr)
sys.exit(1)
print('=' * 60)
print('TraceMem MCP - Delete Test Agent')
print('=' * 60)
print()
print(f'Connecting to Agent MCP at: {mcp_url}')
if instance:
print(f'Instance: {instance}')
print(f'Actor: {actor}')
print('Delete Data:')
print(f' Target ID: {target_id}')
print()
print('⚠ WARNING: This will delete a record from the database!')
print()
client = MCPClient(mcp_url, api_key)
decision_id = None
try:
# Initialize MCP session
print('Initializing MCP session...')
init_result = client.initialize()
server_name = init_result.get('serverInfo', {}).get('name', 'TraceMem Agent MCP')
print(f'✓ Connected to {server_name}')
print()
# Step 1: Create decision envelope
print('Step 1: Creating decision envelope...')
decision = client.call_tool('decision_create', {
'intent': 'test.delete.target',
'automation_mode': 'autonomous',
'instance': instance,
'actor': actor,
'metadata': {
'target_id': target_id,
'test_type': 'delete',
},
})
decision_id = decision.get('decision_id') or decision.get('id')
if not decision_id:
raise Exception('Failed to get decision_id from decision_create response')
print(f'✓ Decision envelope created: {decision_id}')
print()
# Step 2: Delete target record
print('Step 2: Deleting target record...')
write_result = client.call_tool('decision_write', {
'decision_id': decision_id,
'product': 'planetscale_delete_target_v1',
'purpose': 'delete_target',
'mutation': {
'operation': 'delete',
'records': [{
'id': target_id, # Key field for deletion
}],
},
})
print('✓ Target record deleted')
if write_result.get('event_id'):
print(f' Event ID: {write_result["event_id"]}')
if write_result.get('status'):
print(f' Status: {write_result["status"]}')
if write_result.get('mutation_summary'):
print(f' Mutation Summary: {json.dumps(write_result["mutation_summary"])}')
print()
# Step 3: Close decision (commit)
print('Step 3: Committing decision...')
close_result = client.call_tool('decision_close', {
'decision_id': decision_id,
'action': 'commit',
})
print('✓ Decision committed')
if close_result.get('status'):
print(f' Status: {close_result["status"]}')
print()
# Summary
print('=' * 60)
print('Summary')
print('=' * 60)
print(f'Decision ID: {decision_id}')
print('Result: ✓ Delete operation completed successfully')
print(f'Deleted Target ID: {target_id}')
print()
except Exception as error:
print(f'✗ Error: {str(error)}', file=sys.stderr)
import traceback
traceback.print_exc()
# Try to close decision on error
if decision_id:
try:
print('Attempting to abort decision...')
client.call_tool('decision_close', {
'decision_id': decision_id,
'action': 'abort',
'reason': f'Error occurred: {str(error)}',
})
print('✓ Decision aborted')
except Exception as close_error:
print(f'Failed to abort decision: {str(close_error)}', file=sys.stderr)
sys.exit(1)
if __name__ == '__main__':
run_delete_test()
Environment Variables
TRACEMEM_API_KEY(required): Your TraceMem agent API keyMCP_AGENT_URL(optional): MCP server URL (default:https://mcp.tracemem.com)TRACEMEM_INSTANCE(optional): Instance identifierTRACEMEM_ACTOR(optional): Actor identifier (default:test-delete-agent)TARGET_ID(required): UUID of target record to delete
Common Patterns
Error Handling Best Practices
Always ensure decision envelopes are properly closed, even on errors:
decision_id = None
try:
# Create decision and perform operations
decision = client.call_tool('decision_create', {...})
decision_id = decision.get('decision_id')
# Perform operations...
# Commit on success
client.call_tool('decision_close', {
'decision_id': decision_id,
'action': 'commit',
})
except Exception as error:
# Always abort on error
if decision_id:
try:
client.call_tool('decision_close', {
'decision_id': decision_id,
'action': 'abort',
'reason': f'Error occurred: {str(error)}',
})
except Exception:
pass # Log but don't fail on abort failure
raise
Decision Envelope Lifecycle
Every agent operation should follow this pattern:
- Initialize MCP Session: Connect to the Agent MCP server
- Create Decision Envelope: Open a decision with appropriate intent
- Perform Operations: Read, write, evaluate policies, etc.
- Close Decision: Commit on success, abort on error
Environment Variable Configuration
All examples use environment variables for configuration:
# Required
export TRACEMEM_API_KEY="your-api-key"
# Optional
export MCP_AGENT_URL="https://mcp.tracemem.com"
export TRACEMEM_INSTANCE="my-instance"
export TRACEMEM_ACTOR="my-agent"
Testing Tips
- Start with Read Operations: Test read operations first to verify connectivity
- Use Test Data: Use non-production data products for testing
- Check Decision Traces: Review decision traces in the TraceMem dashboard
- Handle Errors Gracefully: Always implement proper error handling and decision cleanup