Intent Plans
Understanding plan structure, lifecycle, and validation
Intent Plans
An Intent Plan is a structured document that declares all actions an agent intends to execute. Think of it as a "pre-approved checklist" that gets cryptographically signed.
What is an Intent Plan?
An intent plan is:
- Declarative: States what to do, not how
- LLM-Generated: Created dynamically by the agent's reasoning
- Immutable: Cannot be changed once signed
- Verifiable: Cryptographically bound to execution
Plan Structure
Basic Plan Format
{
"steps": [
{
"action": "fetch_data",
"mcp": "data-mcp",
"description": "Get user data from database"
},
{
"action": "analyze",
"mcp": "analytics-mcp",
"description": "Calculate risk score"
}
]
}Plan with Metadata
{
"steps": [
{
"action": "process_payment",
"mcp": "finance-mcp",
"description": "Process customer payment",
"metadata": {
"priority": "high",
"timeout_seconds": 30
}
}
],
"metadata": {
"purpose": "payment_processing",
"version": "1.2.0",
"tags": ["finance", "critical"]
}
}Plan Templates vs LLM Generation
Primary: LLM-Generated Plans (Recommended)
# Agent uses LLM to generate plan from natural language
captured = client.capture_plan(
llm="gpt-4",
prompt="Fetch user data, calculate credit score, and store result"
)
# LLM autonomously decides which MCPs and actions to useBenefits:
- Maximum flexibility
- Agent autonomy
- Adapts to context
- Natural language interface
Alternative: Plan Templates (Fixed Structure)
# For debugging, testing, or strict workflows
plan_template = {
"steps": [
{"action": "fetch_data", "mcp": "data-mcp"},
{"action": "analyze", "mcp": "analytics-mcp"}
]
}
captured = client.capture_plan(
llm="gpt-4",
prompt="Execute predefined workflow",
plan=plan_template # Use fixed structure
)Use Cases:
- Testing and debugging
- Regulatory compliance (fixed workflows)
- Performance-critical scenarios (skip LLM planning)
- Template-based execution
Note: Plan templates are more restrictive than LLM-generated plans. They're useful for specific scenarios but sacrifice agent flexibility.
Plan Validation
When you submit a plan, ArmorIQ validates:
1. Structure Validation
Checks:
- Required fields present (
action,mcp) - Field types correct (strings, objects)
- No malformed JSON
- Valid step ordering
Example Error:
{
"error": "InvalidPlanError",
"message": "Step 2 missing required field: 'action'",
"details": {
"step_index": 2,
"missing_fields": ["action"]
}
}2. MCP Validation
Checks:
- MCP exists in registry
- Action is supported by MCP
- Action schema matches
- MCP is accessible to user/agent
Example Error:
{
"error": "InvalidMCPError",
"message": "MCP 'unknown-mcp' not found in registry",
"details": {
"requested_mcp": "unknown-mcp",
"available_mcps": ["data-mcp", "analytics-mcp", "finance-mcp"]
}
}Plan Lifecycle
Phase 1: Capture
captured_plan = client.capture_plan(
llm="gpt-4",
prompt="Fetch and analyze data"
)What Happens:
- Prompt sent to ArmorIQ
- Plan generated (by LLM or template)
- Structure validated
- Plan stored with unique ID
- PlanCapture object returned
Phase 2: Canonicalization
token = client.get_intent_token(captured_plan)What Happens:
- Plan converted to canonical form (CSRG)
- Deterministic hash generated
- Hash signs the token
- Token includes plan hash + policy + expiration
Canonical Form (CSRG):
{
"nodes": [
{"id": "n1", "action": "fetch_data", "mcp": "data-mcp"},
{"id": "n2", "action": "analyze", "mcp": "analytics-mcp"}
],
"edges": [
{"from": "n1", "to": "n2"}
]
}Phase 3: Verification
result = client.invoke(
mcp="data-mcp",
action="fetch_data",
intent_token=token
)What Happens:
- Proxy receives request
- Token signature verified
- Plan hash extracted
- Action checked against plan
- If match: request forwarded to MCP
- If mismatch: request rejected
Phase 4: Audit
Automatically Logged:
- Plan creation time
- Token generation time
- All action invocations
- Success/failure status
- Execution times
Plan Examples
Example 1: Data Pipeline
# Natural language prompt
captured = client.capture_plan(
llm="gpt-4",
prompt="Fetch customer data, validate it, and store in warehouse"
)
# Generated plan:
{
"steps": [
{"action": "fetch_customers", "mcp": "data-mcp"},
{"action": "validate_schema", "mcp": "validation-mcp"},
{"action": "store_data", "mcp": "warehouse-mcp"}
]
}Example 2: Financial Analysis
# Natural language prompt
captured = client.capture_plan(
llm="gpt-4",
prompt="Analyze Q4 revenue, compare with forecast, generate report"
)
# Generated plan:
{
"steps": [
{"action": "fetch_revenue", "mcp": "finance-mcp"},
{"action": "fetch_forecast", "mcp": "finance-mcp"},
{"action": "compare_metrics", "mcp": "analytics-mcp"},
{"action": "generate_report", "mcp": "reporting-mcp"}
]
}Example 3: Multi-Service Orchestration
# Complex workflow
captured = client.capture_plan(
llm="gpt-4",
prompt="Get user profile, check permissions, fetch data, apply transformations, send notification"
)
# Generated plan:
{
"steps": [
{"action": "get_profile", "mcp": "auth-mcp"},
{"action": "check_permissions", "mcp": "auth-mcp"},
{"action": "fetch_data", "mcp": "data-mcp"},
{"action": "transform", "mcp": "etl-mcp"},
{"action": "send_notification", "mcp": "notification-mcp"}
]
}Best Practices
1. Use Descriptive Prompts
# ✓ Good: Specific and clear
prompt = "Fetch sales data for 2024, calculate YoY growth, and generate PDF report"
# ✗ Bad: Vague
prompt = "Do some data stuff"2. Include Context in Metadata
captured = client.capture_plan(
llm="gpt-4",
prompt="Process refund",
metadata={
"transaction_id": "txn_123",
"reason": "customer_request",
"priority": "high"
}
)3. Validate Plans Before Execution
try:
captured = client.capture_plan(llm="gpt-4", prompt=user_input)
print(f"Plan has {len(captured.plan['steps'])} steps")
# Review plan before getting token
for step in captured.plan['steps']:
print(f"- {step['mcp']}/{step['action']}")
# Proceed if plan looks good
token = client.get_intent_token(captured)
except InvalidPlanError as e:
print(f"Plan validation failed: {e}")4. Use Plan Templates for Critical Workflows
# For regulatory compliance or safety-critical operations
compliance_template = {
"steps": [
{"action": "verify_identity", "mcp": "kyc-mcp"},
{"action": "check_sanctions", "mcp": "compliance-mcp"},
{"action": "approve_transaction", "mcp": "approval-mcp"}
]
}
captured = client.capture_plan(
llm="gpt-4",
prompt="Execute compliance workflow",
plan=compliance_template
)Common Issues
Issue: Plan Too Large
Problem: Plan has > 100 steps, causing timeouts
Solution: Break into multiple plans
# Split large workflows
plan1 = client.capture_plan(llm="gpt-4", prompt="Fetch and validate data")
plan2 = client.capture_plan(llm="gpt-4", prompt="Transform and load data")Issue: Action Not in Registry
Problem: MCP or action doesn't exist
Solution: Check available MCPs first
# Verify MCP exists
available_mcps = client.list_mcps()
print(available_mcps)Issue: Plan Hash Mismatch
Problem: Token verification fails
Solution: Don't modify captured plan after getting token
# ✓ Good
captured = client.capture_plan(...)
token = client.get_intent_token(captured)
client.invoke(..., intent_token=token)
# ✗ Bad: Modifying plan
captured = client.capture_plan(...)
captured.plan['steps'].append(...) # Don't do this!
token = client.get_intent_token(captured) # Hash won't matchNext Steps
- Token Lifecycle - How tokens work
- Security Model - Verification details
- Policy Management - Control execution