TraceMem Integration Guide for AI Agents

This document provides complete context for AI agents to integrate and build with TraceMem. Copy this entire document as context when working with TraceMem.

You can download this file as markdown using this link.

What is TraceMem?

TraceMem is a platform for capturing, organizing, and using "memory" from AI agents and applications across tools and sessions. It provides governed execution boundaries for agent decisions with automatic audit trails, policy enforcement, and human approval workflows.

Core Principle: Agents can request actions, but they never authorize them. TraceMem enforces governance, records evidence, and creates immutable audit trails.

Architecture Overview

TraceMem uses Agent MCP (Model Context Protocol), a JSON-RPC 2.0 server that provides standardized tools for all agent operations.

Connection:

  • Endpoint: https://mcp.tracemem.com
  • Protocol: JSON-RPC 2.0 over HTTP
  • Authentication: Authorization: Agent <api-key> header
  • Content-Type: application/json

Initialization:

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {},
    "clientInfo": {"name": "my-agent", "version": "1.0.0"}
  }
}

Core Concepts

1. Decision Envelopes

Every agent operation must start with a Decision Envelope - an execution boundary that tracks all operations within a decision context.

Required fields:

  • intent (string, required): Structured label describing why this decision exists (e.g., "customer.order.create", "renewal.discount.evaluate")
  • automation_mode (string, required): One of:
    • "propose" - Agent proposes, human decides
    • "approve" - Agent executes after approval
    • "override" - Human overrides policy
    • "autonomous" - Agent executes without human approval

Lifecycle states:

  • open - Envelope created and active
  • needs_approval - Decision requires human approval
  • approved - Required approval has been granted
  • rejected - Required approval was rejected
  • committed - Decision completed successfully (terminal)
  • aborted - Decision intentionally stopped (terminal)
  • failed - Decision could not complete due to error (terminal)

Key principle: Always close decisions explicitly with decision_close (commit or rollback).

2. Data Products

Data Products are the ONLY way agents can read or write data in TraceMem. They are governed, purpose-bound interfaces to data.

Key properties:

  • Each data product supports exactly one operation: read, insert, update, or delete
  • Every access must specify a purpose that's in the data product's allowed_purposes
  • Data products expose only a subset of the source schema
  • All access is logged and auditable
  • Data products are versioned and immutable once published

If you need multiple operations: Create separate data products (e.g., customer_data_read, customer_data_insert).

3. Policies

Policies are deterministic decision rules that determine whether actions are allowed.

Outcomes:

  • allow - Policy permits the action
  • deny - Policy blocks the action
  • requires_exception - Human approval required

Key points:

  • Policies are evaluated at execution time
  • Every evaluation is recorded in the decision trace
  • Policies are versioned and immutable once published
  • Policies never fetch data themselves - they operate on explicit inputs

4. Approvals

When a policy returns requires_exception, agents must request human approval.

Approval lifecycle:

  1. Agent requests approval via decision_request_approval
  2. Approval is delivered through configured integration (Slack, email, webhook)
  3. Agent polls for approval status using decision_get
  4. When approved, agent can proceed with writes
  5. When rejected or expired, agent must abort the decision

5. Decision Traces

Every decision creates an immutable Decision Trace - a permanent, queryable record of:

  • What decision was made
  • What data was accessed (with purposes)
  • Which policies were checked
  • Who approved exceptions
  • What changed as a result

Trace structure:

  1. Decision Envelope - Identity and lifecycle
  2. Decision Events - Append-only timeline (reads, writes, policy evaluations, approvals)
  3. Decision Snapshots - Versions/hashes of policies, schemas, and data products at decision time
  4. Outcome Summary - Final result and metrics

Key principle: Traces are append-only and immutable. They preserve "why this was allowed" even if policies or data products change later.

6. Connectors

Connectors are connections to external data systems (databases, SaaS platforms). Agents never interact with Connectors directly - they access data through Data Products, which use Connectors under the hood.

Complete Agent Workflow

Standard Workflow Pattern

python
# 1. Initialize MCP client
client = MCPClient(api_key="your-api-key")
client.initialize()

decision_id = None
try:
    # 2. Create decision envelope
    decision = client.call_tool("decision_create", {
        "intent": "customer.order.create",
        "automation_mode": "propose",
        "actor": "order-processing-agent"
    })
    decision_id = decision["decision_id"]
    
    # 3. Read data through Data Product
    customer = client.call_tool("decision_read", {
        "decision_id": decision_id,
        "product": "customer_data",  # Data product ID
        "purpose": "order_processing",  # Must be in allowed_purposes
        "query": {"customer_id": "123"}
    })
    
    # 4. Evaluate policy
    policy_result = client.call_tool("decision_evaluate", {
        "decision_id": decision_id,
        "policy_id": "order_limit_v1",
        "inputs": {"order_amount": 1000.00}
    })
    
    outcome = policy_result["outcome"]
    
    # 5. Handle policy outcome
    if outcome == "allow":
        # Write data
        write_result = client.call_tool("decision_write", {
            "decision_id": decision_id,
            "product": "orders",  # Must have insert/update/delete operation enabled
            "purpose": "order_creation",
            "mutation": {
                "operation": "insert",  # or "update" or "delete"
                "records": [{
                    "customer_id": "123",
                    "total": 1000.00
                }]
            }
        })
        
    elif outcome == "requires_exception":
        # Request approval
        approval = client.call_tool("decision_request_approval", {
            "decision_id": decision_id,
            "title": "Order Approval",
            "message": "Customer requesting order above policy limit...",
            "require_rationale": True,
            "expires_in_seconds": 3600
        })
        
        # Poll for approval status
        max_wait = 300  # 5 minutes
        waited = 0
        while waited < max_wait:
            time.sleep(5)
            decision_status = client.call_tool("decision_get", {
                "decision_id": decision_id
            })
            
            status = decision_status["status"]
            if status == "approved":
                # Write data after approval
                client.call_tool("decision_write", {...})
                break
            elif status == "rejected":
                raise Exception("Approval rejected")
            
            waited += 5
        
        if waited >= max_wait:
            raise Exception("Approval timeout")
    
    elif outcome == "deny":
        raise Exception("Action denied by policy")
    
    # 6. Close decision (commit)
    client.call_tool("decision_close", {
        "decision_id": decision_id,
        "action": "commit"
    })
    
except Exception as e:
    # Always close on error (rollback)
    if decision_id:
        client.call_tool("decision_close", {
            "decision_id": decision_id,
            "action": "rollback"
        })
    raise

Available MCP Tools

Decision Lifecycle

  • decision_create - Create a new decision envelope
  • decision_get - Get decision status
  • decision_close - Close decision (commit or rollback)
  • decision_trace - Get complete trace (self-access only)
  • decision_receipt - Get cryptographic receipt

Data Access

  • decision_read - Read data through a Data Product
  • decision_write - Write data through a Data Product (insert/update/delete)

Policy Evaluation

  • decision_evaluate - Evaluate a policy

Approval Workflow

  • decision_request_approval - Request human approval

Context Events

  • decision_add_context - Add context event to trace

Discovery

  • products_list - List available Data Products
  • product_get - Get Data Product details
  • capabilities_get - Get agent capabilities

API Reference

decision_create

Creates a new decision envelope.

Parameters:

  • intent (string, required): Why this decision exists
  • automation_mode (string, required): "propose", "approve", "override", or "autonomous"
  • actor (string, optional): Human-readable actor identifier
  • instance (string, optional): Instance identifier for tracking
  • version (string, optional): SDK/agent version
  • metadata (object, optional): Additional context metadata

Response:

json
{
  "decision_id": "TMEM_abc123...",
  "status": "open",
  "created_at": "2026-01-07T12:00:00Z"
}

decision_read

Reads data through a Data Product.

Parameters:

  • decision_id (string, required): Decision ID from decision_create
  • product (string, required): Data product name
  • purpose (string, required): Why accessing data (must be in allowed_purposes)
  • query (object, optional): Query parameters for filtering
  • allow_multiple (boolean, optional): If false (default), limit to 1 result

Response:

json
{
  "event_id": "evt_...",
  "product": "customer_data",
  "records": [...],
  "summary": {"rows": 1, "fields": [...]}
}

decision_write

Writes data through a Data Product.

Parameters:

  • decision_id (string, required): Decision ID
  • product (string, required): Data product name
  • purpose (string, required): Why writing data
  • mutation (object, required): Mutation structure
    • operation (string, required): "insert", "update", or "delete"
    • records (array, required): Array of records to write
  • idempotency_key (string, optional): Key for idempotent writes

Response:

json
{
  "event_id": "evt_...",
  "status": "executed",
  "mutation_summary": {"targets": 1},
  "created_records": [...]  // Only for insert when return_created is enabled
}

Important: Each data product supports exactly one operation. Use separate products for read, insert, update, and delete.

decision_evaluate

Evaluates a policy.

Parameters:

  • decision_id (string, required): Decision ID
  • policy_id (string, required): Policy identifier
  • inputs (object, required): Policy inputs

Response:

json
{
  "outcome": "allow",  // or "deny" or "requires_exception"
  "rationale": "Policy rationale text",
  "exception_route": {...}  // Only if outcome is "requires_exception"
}

decision_request_approval

Requests human approval.

Parameters:

  • decision_id (string, required): Decision ID
  • title (string, required): Approval request title
  • message (string, required): Approval request message
  • require_rationale (boolean, optional): Whether rationale is required
  • expires_in_seconds (number, optional): Expiration time

Response:

json
{
  "approval_id": "apr_...",
  "status": "requested"
}

Note: Poll for approval status using decision_get until status is "approved" or "rejected".

decision_close

Closes a decision (commit or rollback).

Parameters:

  • decision_id (string, required): Decision ID
  • action (string, required): "commit" or "rollback"

Response:

json
{
  "status": "committed",  // or "aborted"
  "closed_at": "2026-01-07T12:05:00Z"
}

Critical: Always close decisions explicitly. Writes are only permanent when committed.

decision_get

Gets decision status.

Parameters:

  • decision_id (string, required): Decision ID

Response:

json
{
  "decision_id": "TMEM_...",
  "status": "open",  // or "needs_approval", "approved", "committed", etc.
  "created_at": "...",
  "closed_at": null
}

Error Handling

JSON-RPC Error Format

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32600,
    "message": "Invalid Request",
    "data": "decision_id is required"
  }
}

Common Error Codes

  • -32600 Invalid Request - Missing required parameters
  • -32601 Method not found - Unknown tool name
  • -32602 Invalid params - Wrong parameter types
  • -32603 Internal error - Server error

HTTP Status Codes

  • 200 OK - Success (even for JSON-RPC errors)
  • 401 Unauthorized - Invalid API key
  • 403 Forbidden - Permission denied
  • 429 Too Many Requests - Rate limited (includes Retry-After header)

Error Handling Pattern

python
try:
    result = client.call_tool("decision_read", {...})
except Exception as e:
    if "401" in str(e) or "Unauthorized" in str(e):
        # Invalid API key
        raise Exception("Invalid API key")
    elif "403" in str(e) or "Forbidden" in str(e):
        # Permission denied
        raise Exception("Permission denied")
    elif "429" in str(e):
        # Rate limited - retry later
        raise Exception("Rate limited")
    else:
        # Other error
        raise

Best Practices

1. Always Close Decisions

Use try-finally pattern to ensure decisions are always closed:

python
decision_id = None
try:
    decision = client.call_tool("decision_create", {...})
    decision_id = decision["decision_id"]
    # ... perform operations ...
    client.call_tool("decision_close", {"decision_id": decision_id, "action": "commit"})
except Exception as e:
    if decision_id:
        client.call_tool("decision_close", {"decision_id": decision_id, "action": "rollback"})
    raise

2. Use Meaningful Intents

Follow hierarchical naming patterns:

  • customer.order.create
  • renewal.discount.evaluate
  • support.ticket.escalate

3. Specify Explicit Purposes

Use specific purposes for data access:

  • order_processing (not general)
  • fraud_detection (not access)
  • support_triage (not read)

4. Evaluate Policies Before Actions

Always evaluate policies before performing actions:

python
policy_result = client.call_tool("decision_evaluate", {...})
if policy_result["outcome"] == "allow":
    # Proceed with action
elif policy_result["outcome"] == "requires_exception":
    # Request approval
elif policy_result["outcome"] == "deny":
    # Abort decision

5. Handle All Policy Outcomes

Don't assume policies will always return allow. Handle all three outcomes:

  • allow → Proceed
  • requires_exception → Request approval
  • deny → Abort

6. Minimize Data Access

  • Filter by ID when possible
  • Only read what you need
  • Use specific queries, not full table scans

7. Use Idempotency Keys

For writes that may be retried:

python
client.call_tool("decision_write", {
    "decision_id": decision_id,
    "product": "orders",
    "purpose": "order_creation",
    "mutation": {...},
    "idempotency_key": f"order-{customer_id}-{timestamp}"
})

8. Poll for Approvals Correctly

Handle timeouts and rejections:

python
max_wait = 300  # 5 minutes
waited = 0
while waited < max_wait:
    time.sleep(5)
    decision_status = client.call_tool("decision_get", {"decision_id": decision_id})
    status = decision_status["status"]
    if status == "approved":
        break
    elif status == "rejected":
        raise Exception("Approval rejected")
    waited += 5
if waited >= max_wait:
    raise Exception("Approval timeout")

9. Check Data Product Configuration

Before reading/writing, check data product details:

python
product = client.call_tool("product_get", {"product": "customer_data"})
# Check allowed_purposes, exposed schema, allowed operations

10. Store Context Events

Record agent reasoning for auditability:

python
client.call_tool("decision_add_context", {
    "decision_id": decision_id,
    "summary": "Agent determined discount is appropriate based on customer history",
    "payload": {"confidence": 0.95, "reasoning": "..."}
})

Data Product Operations

Critical: Each data product supports exactly one operation. If you need multiple operations, use separate data products.

Read Operation

Data product must have read operation enabled:

python
result = client.call_tool("decision_read", {
    "decision_id": decision_id,
    "product": "customer_data",  # Must have read enabled
    "purpose": "order_processing",
    "query": {"customer_id": "123"}
})

Insert Operation

Data product must have insert operation enabled:

python
result = client.call_tool("decision_write", {
    "decision_id": decision_id,
    "product": "orders",  # Must have insert enabled
    "purpose": "order_creation",
    "mutation": {
        "operation": "insert",
        "records": [{"customer_id": "123", "total": 1000.00}]
    }
})

# If return_created is enabled, created records are returned
if "created_records" in result:
    order_id = result["created_records"][0]["order_id"]

Update Operation

Data product must have update operation enabled:

python
result = client.call_tool("decision_write", {
    "decision_id": decision_id,
    "product": "orders",  # Must have update enabled
    "purpose": "order_fulfillment",
    "mutation": {
        "operation": "update",
        "records": [{"order_id": 12345, "status": "shipped"}]
    }
})

Delete Operation

Data product must have delete operation enabled:

python
result = client.call_tool("decision_write", {
    "decision_id": decision_id,
    "product": "orders",  # Must have delete enabled
    "purpose": "order_cancellation",
    "mutation": {
        "operation": "delete",
        "records": [{"order_id": 12345}]
    }
})

Security Model

Trust Boundaries

TraceMem treats agents as untrusted by default:

  • Agent code is not trusted
  • Agent logic may be buggy, malicious, or misconfigured
  • Agents may attempt unsafe shortcuts

Key guarantee: Agents can request actions, never authorize them.

Authentication

Agents authenticate using Agent API keys:

  • Tenant-scoped
  • Grant access to specific Data Products
  • Provide policy evaluation capabilities
  • Enable approval request channels

Get API key:

  1. Navigate to Settings → Agents in dashboard
  2. Create an agent (if needed)
  3. Create a credential to get an API key
  4. Save securely (shown only once)

Authorization

TraceMem enforces authorization at multiple levels:

  1. API Key Scope - What Data Products the agent can access
  2. Data Product Permissions - What operations are allowed
  3. Purpose Restrictions - What purposes are allowed
  4. Policy Evaluations - Whether actions are allowed
  5. Approval Requirements - Whether human approval is needed

Agents cannot bypass any of these checks.

Rate Limits

  • 100 requests/second per API key
  • 1000 decisions/hour per agent
  • 10 MB maximum request size

Exceeded limits return HTTP 429 with Retry-After header.

Setup Requirements

Before agents can use TraceMem, administrators must set up:

  1. Connector - Connection to data source (database, SaaS)
  2. Data Product - Governed interface to data (with allowed purposes and operations)
  3. Agent - API key for authentication
  4. Integration (optional) - Approval delivery channels (Slack, email, webhook)
  5. Approval Route (optional) - Approval routing configuration
  6. Policy (optional) - Business rules

Agents cannot create or modify these components - they are created by administrators via the dashboard or Admin API.

Mental Models

Decision Envelope

The Decision Envelope is the courtroom.
Evidence (data) is presented.
Rules (policies) are applied.
Judgment (approval or autonomy) is rendered.
The verdict (outcome) is recorded forever.

Data Products

Connectors are the plumbing.
Data Products are the faucets.
Agents turn on the faucets, but they never see the plumbing.
The plumbing knows how to get water from the source.
The faucets control how much water flows and for what purpose.

Decision Traces

The Decision Trace is the courtroom transcript.
Every piece of evidence (data read) is recorded.
Every rule checked (policy evaluation) is documented.
Every judgment (approval) is captured.
The verdict (outcome) is preserved forever.
Years later, you can still read the transcript and understand exactly what happened and why.

Quick Reference

MCP Client Implementation (Python)

python
import requests
import json

class MCPClient:
    def __init__(self, api_key):
        self.base_url = "https://mcp.tracemem.com"
        self.api_key = api_key
        self.session = requests.Session()
        self.session.headers.update({
            "Authorization": f"Agent {api_key}",
            "Content-Type": "application/json"
        })
        self.request_id = 0
    
    def _next_id(self):
        self.request_id += 1
        return self.request_id
    
    def _call(self, method, params=None):
        request = {
            "jsonrpc": "2.0",
            "id": self._next_id(),
            "method": method,
            "params": params or {}
        }
        response = self.session.post(self.base_url, json=request)
        response.raise_for_status()
        result = response.json()
        if "error" in result:
            error = result["error"]
            raise Exception(f"MCP Error {error['code']}: {error['message']}")
        return result.get("result", {})
    
    def initialize(self):
        return self._call("initialize", {
            "protocolVersion": "2024-11-05",
            "capabilities": {},
            "clientInfo": {"name": "my-agent", "version": "1.0.0"}
        })
    
    def call_tool(self, name, arguments):
        result = self._call("tools/call", {
            "name": name,
            "arguments": arguments
        })
        if "content" in result and len(result["content"]) > 0:
            text_content = result["content"][0].get("text", "{}")
            try:
                return json.loads(text_content)
            except json.JSONDecodeError:
                return {"raw_text": text_content}
        return result

Complete Workflow Example

python
import os
import time

# Initialize
mcp_url = os.getenv("MCP_AGENT_URL", "https://mcp.tracemem.com")
api_key = os.getenv("TRACEMEM_API_KEY")
client = MCPClient(mcp_url, api_key)
client.initialize()

decision_id = None
try:
    # Create decision
    decision = client.call_tool("decision_create", {
        "intent": "customer.order.create",
        "automation_mode": "propose"
    })
    decision_id = decision["decision_id"]
    
    # Read data
    customer = client.call_tool("decision_read", {
        "decision_id": decision_id,
        "product": "customer_data",
        "purpose": "order_processing",
        "query": {"customer_id": "123"}
    })
    
    # Evaluate policy
    policy_result = client.call_tool("decision_evaluate", {
        "decision_id": decision_id,
        "policy_id": "order_limit_v1",
        "inputs": {"order_amount": 1000.00}
    })
    
    # Handle outcome
    if policy_result["outcome"] == "allow":
        client.call_tool("decision_write", {
            "decision_id": decision_id,
            "product": "orders",
            "purpose": "order_creation",
            "mutation": {
                "operation": "insert",
                "records": [{"customer_id": "123", "total": 1000.00}]
            }
        })
        client.call_tool("decision_close", {
            "decision_id": decision_id,
            "action": "commit"
        })
    elif policy_result["outcome"] == "requires_exception":
        client.call_tool("decision_request_approval", {
            "decision_id": decision_id,
            "title": "Order Approval",
            "message": "Order above policy limit",
            "expires_in_seconds": 3600
        })
        # Poll for approval...
        client.call_tool("decision_close", {
            "decision_id": decision_id,
            "action": "commit"
        })
    else:
        raise Exception("Action denied")
        
except Exception as e:
    if decision_id:
        client.call_tool("decision_close", {
            "decision_id": decision_id,
            "action": "rollback"
        })
    raise

Summary

TraceMem provides:

  • Governed execution boundaries for agent decisions
  • Automatic audit trails of all operations
  • Policy enforcement with human approval workflows
  • Purpose-bound data access through Data Products
  • Immutable decision traces that preserve "why" forever

Key principles:

  1. Always create a Decision Envelope before any operation
  2. Access data only through Data Products with explicit purposes
  3. Evaluate policies before taking actions
  4. Request approvals when policies require exceptions
  5. Always close decisions explicitly (commit or rollback)
  6. Each data product supports exactly one operation

Remember: Agents can request actions, but they never authorize them. TraceMem enforces governance and creates immutable audit trails.

TraceMem is trace-native infrastructure for AI agents