Go Agent Examples
This guide provides complete, runnable examples for building TraceMem agents in Go. Each example demonstrates a specific pattern for interacting with TraceMem's Agent MCP server.
Prerequisites
- Go 1.21 or higher
- Standard library only (no external dependencies required)
- 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 that handles JSON-RPC 2.0 communication:
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
// JsonRpcRequest represents a JSON-RPC 2.0 request
type JsonRpcRequest struct {
JsonRpc string `json:"jsonrpc"`
ID int `json:"id"`
Method string `json:"method"`
Params map[string]interface{} `json:"params,omitempty"`
}
// JsonRpcResponse represents a JSON-RPC 2.0 response
type JsonRpcResponse struct {
JsonRpc string `json:"jsonrpc"`
ID int `json:"id"`
Result map[string]interface{} `json:"result,omitempty"`
Error *JsonRpcError `json:"error,omitempty"`
}
// JsonRpcError represents a JSON-RPC 2.0 error
type JsonRpcError struct {
Code int `json:"code"`
Message string `json:"message"`
Data map[string]interface{} `json:"data,omitempty"`
}
// ToolContent represents MCP tool call result content
type ToolContent struct {
Type string `json:"type"`
Text string `json:"text,omitempty"`
}
// ToolCallResult represents MCP tool call result
type ToolCallResult struct {
Content []ToolContent `json:"content"`
IsError bool `json:"isError,omitempty"`
}
// MCPClient handles communication with TraceMem Agent MCP Server
type MCPClient struct {
baseURL string
apiKey string
httpClient *http.Client
requestID int
initialized bool
}
// NewMCPClient creates a new MCP client
func NewMCPClient(baseURL, apiKey string) *MCPClient {
return &MCPClient{
baseURL: baseURL,
apiKey: apiKey,
httpClient: &http.Client{},
requestID: 0,
}
}
// nextID returns the next request ID
func (c *MCPClient) nextID() int {
c.requestID++
return c.requestID
}
// call makes a JSON-RPC call to the MCP server
func (c *MCPClient) call(method string, params map[string]interface{}) (map[string]interface{}, error) {
request := JsonRpcRequest{
JsonRpc: "2.0",
ID: c.nextID(),
Method: method,
Params: params,
}
jsonData, err := json.Marshal(request)
if err != nil {
return nil, fmt.Errorf("failed to marshal request: %w", err)
}
req, err := http.NewRequest("POST", c.baseURL, bytes.NewBuffer(jsonData))
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("Authorization", fmt.Sprintf("Agent %s", c.apiKey))
req.Header.Set("Content-Type", "application/json")
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("HTTP error: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response: %w", err)
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("HTTP error %d: %s", resp.StatusCode, string(body))
}
var jsonResp JsonRpcResponse
if err := json.Unmarshal(body, &jsonResp); err != nil {
return nil, fmt.Errorf("failed to unmarshal response: %w", err)
}
if jsonResp.Error != nil {
errorMsg := fmt.Sprintf("MCP Error %d: %s", jsonResp.Error.Code, jsonResp.Error.Message)
if jsonResp.Error.Data != nil {
dataJSON, _ := json.Marshal(jsonResp.Error.Data)
errorMsg += fmt.Sprintf(" - %s", string(dataJSON))
}
return nil, fmt.Errorf(errorMsg)
}
if jsonResp.Result == nil {
return make(map[string]interface{}), nil
}
return jsonResp.Result, nil
}
// Initialize initializes the MCP session
func (c *MCPClient) Initialize() (map[string]interface{}, error) {
params := map[string]interface{}{
"protocolVersion": "2024-11-05",
"capabilities": map[string]interface{}{},
"clientInfo": map[string]interface{}{
"name": "tracemem-test-agent",
"version": "1.0.0",
},
}
result, err := c.call("initialize", params)
if err != nil {
return nil, err
}
c.initialized = true
return result, nil
}
// ListTools lists available tools
func (c *MCPClient) ListTools() (map[string]interface{}, error) {
return c.call("tools/list", nil)
}
// CallTool calls a tool
func (c *MCPClient) CallTool(name string, arguments map[string]interface{}) (map[string]interface{}, error) {
if !c.initialized {
if _, err := c.Initialize(); err != nil {
return nil, err
}
}
params := map[string]interface{}{
"name": name,
"arguments": arguments,
}
result, err := c.call("tools/call", params)
if err != nil {
return nil, err
}
// Check if the tool result indicates an error
if isError, ok := result["isError"].(bool); ok && isError {
errorMessage := "Tool call failed"
if content, ok := result["content"].([]interface{}); ok && len(content) > 0 {
if contentMap, ok := content[0].(map[string]interface{}); ok {
if text, ok := contentMap["text"].(string); ok {
errorMessage = text
}
}
}
return nil, fmt.Errorf(errorMessage)
}
// Parse content from tool result
if content, ok := result["content"].([]interface{}); ok && len(content) > 0 {
if contentMap, ok := content[0].(map[string]interface{}); ok {
if text, ok := contentMap["text"].(string); ok {
var parsed map[string]interface{}
if err := json.Unmarshal([]byte(text), &parsed); err == nil {
return parsed, nil
}
return map[string]interface{}{"raw_text": text}, nil
}
}
}
return result, nil
}
// IsInitialized checks if the client is initialized
func (c *MCPClient) IsInitialized() bool {
return c.initialized
}
Example 1: Read Agent
This example demonstrates reading customer data from a data product.
package main
import (
"encoding/json"
"fmt"
"os"
"strconv"
)
func runReadTest() error {
// Get configuration from environment
mcpURL := getEnv("MCP_AGENT_URL", "https://mcp.tracemem.com")
apiKey := os.Getenv("TRACEMEM_API_KEY")
instance := os.Getenv("TRACEMEM_INSTANCE")
actor := getEnv("TRACEMEM_ACTOR", "test-read-agent")
customerID := getEnv("CUSTOMER_ID", "1003")
if apiKey == "" {
return fmt.Errorf("ERROR: TRACEMEM_API_KEY environment variable is required")
}
fmt.Println(strings.Repeat("=", 60))
fmt.Println("TraceMem MCP - Read Test Agent")
fmt.Println(strings.Repeat("=", 60))
fmt.Println()
fmt.Printf("Connecting to Agent MCP at: %s\n", mcpURL)
if instance != "" {
fmt.Printf("Instance: %s\n", instance)
}
fmt.Printf("Actor: %s\n", actor)
fmt.Printf("Customer ID: %s\n", customerID)
fmt.Println()
client := NewMCPClient(mcpURL, apiKey)
var decisionID string
defer func() {
if decisionID != "" {
// Try to close decision on error
if r := recover(); r != nil {
fmt.Println("Attempting to abort decision...")
_, err := client.CallTool("decision_close", map[string]interface{}{
"decision_id": decisionID,
"action": "abort",
"reason": fmt.Sprintf("Error occurred: %v", r),
})
if err != nil {
fmt.Printf("Failed to abort decision: %v\n", err)
} else {
fmt.Println("✓ Decision aborted")
}
}
}
}()
// Initialize MCP session
fmt.Println("Initializing MCP session...")
initResult, err := client.Initialize()
if err != nil {
return fmt.Errorf("failed to initialize: %w", err)
}
serverInfo, _ := initResult["serverInfo"].(map[string]interface{})
serverName := "TraceMem Agent MCP"
if name, ok := serverInfo["name"].(string); ok {
serverName = name
}
fmt.Printf("✓ Connected to %s\n", serverName)
fmt.Println()
// Step 1: Create decision envelope
fmt.Println("Step 1: Creating decision envelope...")
decision, err := client.CallTool("decision_create", map[string]interface{}{
"intent": "test.read.customer",
"automation_mode": "autonomous",
"instance": instance,
"actor": actor,
"metadata": map[string]interface{}{
"customer_id": customerID,
"test_type": "read",
},
})
if err != nil {
return fmt.Errorf("failed to create decision: %w", err)
}
decisionID, _ = decision["decision_id"].(string)
if decisionID == "" {
decisionID, _ = decision["id"].(string)
}
if decisionID == "" {
return fmt.Errorf("failed to get decision_id from decision_create response")
}
fmt.Printf("✓ Decision envelope created: %s\n", decisionID)
fmt.Println()
// Step 2: Read customer data
fmt.Println("Step 2: Reading customer data...")
customerIDInt, _ := strconv.Atoi(customerID)
readResult, err := client.CallTool("decision_read", map[string]interface{}{
"decision_id": decisionID,
"product": "planetscale_read_customer_v1",
"purpose": "web_order",
"query": map[string]interface{}{
"id": customerIDInt,
},
})
if err != nil {
return fmt.Errorf("failed to read customer data: %w", err)
}
fmt.Println("✓ Customer data retrieved")
if eventID, ok := readResult["event_id"].(string); ok {
fmt.Printf(" Event ID: %s\n", eventID)
}
if dataRef, ok := readResult["data_ref"].(string); ok {
fmt.Printf(" Data Reference: %s\n", dataRef)
}
if records, ok := readResult["records"].([]interface{}); ok && len(records) > 0 {
fmt.Printf(" Records found: %d\n", len(records))
fmt.Println(" Customer data:")
recordJSON, _ := json.MarshalIndent(records[0], "", " ")
fmt.Println(string(recordJSON))
} else {
fmt.Println(" No records found")
}
fmt.Println()
// Step 3: Close decision (commit)
fmt.Println("Step 3: Committing decision...")
closeResult, err := client.CallTool("decision_close", map[string]interface{}{
"decision_id": decisionID,
"action": "commit",
})
if err != nil {
return fmt.Errorf("failed to close decision: %w", err)
}
fmt.Println("✓ Decision committed")
if status, ok := closeResult["status"].(string); ok {
fmt.Printf(" Status: %s\n", status)
}
fmt.Println()
// Summary
fmt.Println(strings.Repeat("=", 60))
fmt.Println("Summary")
fmt.Println(strings.Repeat("=", 60))
fmt.Printf("Decision ID: %s\n", decisionID)
fmt.Println("Result: ✓ Read operation completed successfully")
fmt.Println()
return nil
}
func getEnv(key, defaultValue string) string {
if value := os.Getenv(key); value != "" {
return value
}
return defaultValue
}
func main() {
if err := runReadTest(); err != nil {
fmt.Fprintf(os.Stderr, "✗ Error: %v\n", err)
os.Exit(1)
}
}
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"
go run test_read_agent.go
Example 2: Insert Agent (with Policy)
This example demonstrates inserting an order with policy evaluation.
package main
import (
"encoding/json"
"fmt"
"os"
"strconv"
"strings"
)
func runInsertTest() error {
// Get configuration from environment
mcpURL := getEnv("MCP_AGENT_URL", "https://mcp.tracemem.com")
apiKey := os.Getenv("TRACEMEM_API_KEY")
instance := os.Getenv("TRACEMEM_INSTANCE")
actor := getEnv("TRACEMEM_ACTOR", "test-insert-agent")
// Test data - can be overridden via environment variables
customerID, _ := strconv.Atoi(getEnv("CUSTOMER_ID", "1001"))
productID, _ := strconv.Atoi(getEnv("PRODUCT_ID", "2"))
quantity, _ := strconv.Atoi(getEnv("QUANTITY", "1"))
totalAmount, _ := strconv.ParseFloat(getEnv("TOTAL_AMOUNT", "99.99"), 64)
orderStatus := getEnv("ORDER_STATUS", "pending")
proposedDiscount, _ := strconv.ParseFloat(getEnv("PROPOSED_DISCOUNT", "0"), 64)
if apiKey == "" {
return fmt.Errorf("ERROR: TRACEMEM_API_KEY environment variable is required")
}
fmt.Println(strings.Repeat("=", 60))
fmt.Println("TraceMem MCP - Insert Test Agent")
fmt.Println(strings.Repeat("=", 60))
fmt.Println()
fmt.Printf("Connecting to Agent MCP at: %s\n", mcpURL)
if instance != "" {
fmt.Printf("Instance: %s\n", instance)
}
fmt.Printf("Actor: %s\n", actor)
fmt.Println("Order Data:")
fmt.Printf(" Customer ID: %d\n", customerID)
fmt.Printf(" Product ID: %d\n", productID)
fmt.Printf(" Quantity: %d\n", quantity)
fmt.Printf(" Total Amount: %.2f\n", totalAmount)
fmt.Printf(" Order Status: %s\n", orderStatus)
fmt.Printf(" Proposed Discount: %.2f\n", proposedDiscount)
fmt.Println()
client := NewMCPClient(mcpURL, apiKey)
var decisionID string
defer func() {
if decisionID != "" {
if r := recover(); r != nil {
fmt.Println("Attempting to abort decision...")
_, err := client.CallTool("decision_close", map[string]interface{}{
"decision_id": decisionID,
"action": "abort",
"reason": fmt.Sprintf("Error occurred: %v", r),
})
if err != nil {
fmt.Printf("Failed to abort decision: %v\n", err)
} else {
fmt.Println("✓ Decision aborted")
}
}
}
}()
// Initialize MCP session
fmt.Println("Initializing MCP session...")
initResult, err := client.Initialize()
if err != nil {
return fmt.Errorf("failed to initialize: %w", err)
}
serverInfo, _ := initResult["serverInfo"].(map[string]interface{})
serverName := "TraceMem Agent MCP"
if name, ok := serverInfo["name"].(string); ok {
serverName = name
}
fmt.Printf("✓ Connected to %s\n", serverName)
fmt.Println()
// Step 1: Create decision envelope
fmt.Println("Step 1: Creating decision envelope...")
decision, err := client.CallTool("decision_create", map[string]interface{}{
"intent": "test.insert.order",
"automation_mode": "autonomous",
"instance": instance,
"actor": actor,
"metadata": map[string]interface{}{
"customer_id": strconv.Itoa(customerID),
"product_id": strconv.Itoa(productID),
"test_type": "insert",
},
})
if err != nil {
return fmt.Errorf("failed to create decision: %w", err)
}
decisionID, _ = decision["decision_id"].(string)
if decisionID == "" {
decisionID, _ = decision["id"].(string)
}
if decisionID == "" {
return fmt.Errorf("failed to get decision_id from decision_create response")
}
fmt.Printf("✓ Decision envelope created: %s\n", decisionID)
fmt.Println()
// Step 2: Evaluate policy
fmt.Println("Step 2: Evaluating discount_cap_v1 policy...")
policyResult, err := client.CallTool("decision_evaluate", map[string]interface{}{
"decision_id": decisionID,
"policy_id": "discount_cap_v1",
"inputs": map[string]interface{}{
"proposed_discount": proposedDiscount,
},
})
if err != nil {
return fmt.Errorf("failed to evaluate policy: %w", err)
}
outcome, _ := policyResult["outcome"].(string)
if outcome == "" {
outcome = "unknown"
}
fmt.Println("✓ Policy evaluation completed")
fmt.Printf(" Policy ID: discount_cap_v1\n")
fmt.Printf(" Proposed Discount: %.2f\n", proposedDiscount)
fmt.Printf(" Outcome: %s\n", outcome)
if rationale, ok := policyResult["rationale"].(map[string]interface{}); ok {
if msg, ok := rationale["message"].(string); ok {
fmt.Printf(" Rationale: %s\n", msg)
} else {
rationaleJSON, _ := json.Marshal(rationale)
fmt.Printf(" Rationale: %s\n", string(rationaleJSON))
}
} else if rationale, ok := policyResult["rationale"].(string); ok {
fmt.Printf(" Rationale: %s\n", rationale)
}
if eventID, ok := policyResult["event_id"].(string); ok {
fmt.Printf(" Event ID: %s\n", eventID)
}
fmt.Println()
// Handle policy outcomes
if outcome == "deny" {
rationaleMsg := "No rationale provided"
if rationale, ok := policyResult["rationale"].(map[string]interface{}); ok {
if msg, ok := rationale["message"].(string); ok {
rationaleMsg = msg
}
}
return fmt.Errorf("policy evaluation denied the operation. Rationale: %s", rationaleMsg)
} else if outcome == "requires_exception" {
fmt.Println("⚠ Policy requires exception/approval, but continuing with test...")
fmt.Println()
} else if outcome != "allow" {
fmt.Printf("⚠ Unexpected policy outcome: %s, continuing with test...\n", outcome)
fmt.Println()
}
// Step 3: Insert order
fmt.Println("Step 3: Inserting order...")
writeResult, err := client.CallTool("decision_write", map[string]interface{}{
"decision_id": decisionID,
"product": "planetscale_insert_order_v1",
"purpose": "web_order",
"mutation": map[string]interface{}{
"operation": "insert",
"records": []map[string]interface{}{
{
"customer_id": customerID,
"product_id": productID,
"quantity": quantity,
"total_amount": totalAmount,
"order_status": orderStatus,
},
},
},
})
if err != nil {
return fmt.Errorf("failed to write: %w", err)
}
fmt.Println("✓ Order inserted")
if eventID, ok := writeResult["event_id"].(string); ok {
fmt.Printf(" Event ID: %s\n", eventID)
}
if status, ok := writeResult["status"].(string); ok {
fmt.Printf(" Status: %s\n", status)
}
if createdRecords, ok := writeResult["created_records"].([]interface{}); ok && len(createdRecords) > 0 {
fmt.Printf(" Created %d record(s):\n", len(createdRecords))
for i, record := range createdRecords {
fmt.Printf(" Record %d:\n", i+1)
recordJSON, _ := json.MarshalIndent(record, "", " ")
fmt.Println(string(recordJSON))
}
}
if mutationSummary, ok := writeResult["mutation_summary"].(map[string]interface{}); ok {
mutationJSON, _ := json.Marshal(mutationSummary)
fmt.Printf(" Mutation Summary: %s\n", string(mutationJSON))
}
fmt.Println()
// Step 4: Close decision (commit)
fmt.Println("Step 4: Committing decision...")
closeResult, err := client.CallTool("decision_close", map[string]interface{}{
"decision_id": decisionID,
"action": "commit",
})
if err != nil {
return fmt.Errorf("failed to close decision: %w", err)
}
fmt.Println("✓ Decision committed")
if status, ok := closeResult["status"].(string); ok {
fmt.Printf(" Status: %s\n", status)
}
fmt.Println()
// Summary
fmt.Println(strings.Repeat("=", 60))
fmt.Println("Summary")
fmt.Println(strings.Repeat("=", 60))
fmt.Printf("Decision ID: %s\n", decisionID)
fmt.Println("Result: ✓ Insert operation completed successfully")
if createdRecords, ok := writeResult["created_records"].([]interface{}); ok && len(createdRecords) > 0 {
if firstRecord, ok := createdRecords[0].(map[string]interface{}); ok {
if orderID, ok := firstRecord["order_id"].(float64); ok {
fmt.Printf("Created Order ID: %.0f\n", orderID)
}
}
}
fmt.Println()
return nil
}
func getEnv(key, defaultValue string) string {
if value := os.Getenv(key); value != "" {
return value
}
return defaultValue
}
func main() {
if err := runInsertTest(); err != nil {
fmt.Fprintf(os.Stderr, "✗ Error: %v\n", err)
os.Exit(1)
}
}
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. The code structure is similar to Example 2, but without the policy evaluation step. The key difference is using planetscale_insert_order_no_policy_v1 as the product and skipping the decision_evaluate call.
Example 4: Update Agent
This example demonstrates updating product stock.
package main
import (
"encoding/json"
"fmt"
"os"
"strconv"
"strings"
)
func runUpdateTest() error {
// Get configuration from environment
mcpURL := getEnv("MCP_AGENT_URL", "https://mcp.tracemem.com")
apiKey := os.Getenv("TRACEMEM_API_KEY")
instance := os.Getenv("TRACEMEM_INSTANCE")
actor := getEnv("TRACEMEM_ACTOR", "test-update-agent")
// Test data
productID, _ := strconv.Atoi(getEnv("PRODUCT_ID", "4"))
stockQuantity, _ := strconv.Atoi(getEnv("STOCK_QUANTITY", "90"))
if apiKey == "" {
return fmt.Errorf("ERROR: TRACEMEM_API_KEY environment variable is required")
}
fmt.Println(strings.Repeat("=", 60))
fmt.Println("TraceMem MCP - Update Test Agent")
fmt.Println(strings.Repeat("=", 60))
fmt.Println()
fmt.Printf("Connecting to Agent MCP at: %s\n", mcpURL)
if instance != "" {
fmt.Printf("Instance: %s\n", instance)
}
fmt.Printf("Actor: %s\n", actor)
fmt.Println("Update Data:")
fmt.Printf(" Product ID: %d\n", productID)
fmt.Printf(" Stock Quantity: %d\n", stockQuantity)
fmt.Println()
client := NewMCPClient(mcpURL, apiKey)
var decisionID string
defer func() {
if decisionID != "" {
if r := recover(); r != nil {
fmt.Println("Attempting to abort decision...")
_, err := client.CallTool("decision_close", map[string]interface{}{
"decision_id": decisionID,
"action": "abort",
"reason": fmt.Sprintf("Error occurred: %v", r),
})
if err != nil {
fmt.Printf("Failed to abort decision: %v\n", err)
} else {
fmt.Println("✓ Decision aborted")
}
}
}
}()
// Initialize and create decision (similar pattern as above)
// ... (implementation follows same pattern as read/insert examples)
// Step 2: Update product stock
fmt.Println("Step 2: Updating product stock...")
writeResult, err := client.CallTool("decision_write", map[string]interface{}{
"decision_id": decisionID,
"product": "planetscale_update_product_stock_v1",
"purpose": "web_order",
"mutation": map[string]interface{}{
"operation": "update",
"records": []map[string]interface{}{
{
"product_id": productID, // Key field for identification
"stock_quantity": stockQuantity, // Field to update
},
},
},
})
if err != nil {
return fmt.Errorf("failed to update: %w", err)
}
fmt.Println("✓ Product stock updated")
// ... (output handling similar to insert example)
return nil
}
func getEnv(key, defaultValue string) string {
if value := os.Getenv(key); value != "" {
return value
}
return defaultValue
}
func main() {
if err := runUpdateTest(); err != nil {
fmt.Fprintf(os.Stderr, "✗ Error: %v\n", err)
os.Exit(1)
}
}
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.
package main
import (
"encoding/json"
"fmt"
"os"
"regexp"
"strings"
)
func runDeleteTest() error {
// Get configuration from environment
mcpURL := getEnv("MCP_AGENT_URL", "https://mcp.tracemem.com")
apiKey := os.Getenv("TRACEMEM_API_KEY")
instance := os.Getenv("TRACEMEM_INSTANCE")
actor := getEnv("TRACEMEM_ACTOR", "test-delete-agent")
targetID := getEnv("TARGET_ID", "0cf1e19e-00ed-4a4c-8d82-ee70f590fad8")
if apiKey == "" {
return fmt.Errorf("ERROR: TRACEMEM_API_KEY environment variable is required")
}
if targetID == "" {
return fmt.Errorf("ERROR: TARGET_ID environment variable is required (must be a UUID)")
}
// Basic UUID format validation
uuidRegex := regexp.MustCompile(`^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`)
if !uuidRegex.MatchString(targetID) {
return fmt.Errorf("ERROR: TARGET_ID must be a valid UUID format. Received: %s", targetID)
}
fmt.Println(strings.Repeat("=", 60))
fmt.Println("TraceMem MCP - Delete Test Agent")
fmt.Println(strings.Repeat("=", 60))
fmt.Println()
fmt.Printf("Connecting to Agent MCP at: %s\n", mcpURL)
if instance != "" {
fmt.Printf("Instance: %s\n", instance)
}
fmt.Printf("Actor: %s\n", actor)
fmt.Println("Delete Data:")
fmt.Printf(" Target ID: %s\n", targetID)
fmt.Println()
fmt.Println("⚠ WARNING: This will delete a record from the database!")
fmt.Println()
client := NewMCPClient(mcpURL, apiKey)
var decisionID string
defer func() {
if decisionID != "" {
if r := recover(); r != nil {
fmt.Println("Attempting to abort decision...")
_, err := client.CallTool("decision_close", map[string]interface{}{
"decision_id": decisionID,
"action": "abort",
"reason": fmt.Sprintf("Error occurred: %v", r),
})
if err != nil {
fmt.Printf("Failed to abort decision: %v\n", err)
} else {
fmt.Println("✓ Decision aborted")
}
}
}
}()
// Initialize and create decision (similar pattern as above)
// ... (implementation follows same pattern)
// Step 2: Delete target record
fmt.Println("Step 2: Deleting target record...")
writeResult, err := client.CallTool("decision_write", map[string]interface{}{
"decision_id": decisionID,
"product": "planetscale_delete_target_v1",
"purpose": "delete_target",
"mutation": map[string]interface{}{
"operation": "delete",
"records": []map[string]interface{}{
{
"id": targetID, // Key field for deletion
},
},
},
})
if err != nil {
return fmt.Errorf("failed to delete: %w", err)
}
fmt.Println("✓ Target record deleted")
// ... (output handling)
return nil
}
func getEnv(key, defaultValue string) string {
if value := os.Getenv(key); value != "" {
return value
}
return defaultValue
}
func main() {
if err := runDeleteTest(); err != nil {
fmt.Fprintf(os.Stderr, "✗ Error: %v\n", err)
os.Exit(1)
}
}
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:
decisionID := ""
defer func() {
if decisionID != "" {
if r := recover(); r != nil {
fmt.Println("Attempting to abort decision...")
_, err := client.CallTool("decision_close", map[string]interface{}{
"decision_id": decisionID,
"action": "abort",
"reason": fmt.Sprintf("Error occurred: %v", r),
})
if err != nil {
fmt.Printf("Failed to abort decision: %v\n", err)
}
}
}
}()
// Create decision and perform operations
decision, err := client.CallTool("decision_create", {...})
if err != nil {
return err
}
decisionID = decision["decision_id"].(string)
// Perform operations...
// Commit on success
_, err = client.CallTool("decision_close", map[string]interface{}{
"decision_id": decisionID,
"action": "commit",
})
if err != nil {
return err
}
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