Complete Implementation Blueprint for Small Business Automation
Claude Run is an event-driven, headless automation platform that orchestrates Claude Code SDK to run small business operations. It embeds into existing communication channels (Slack, SMS, WhatsApp), learns from patterns, and progressively automates business workflows while maintaining human oversight.
This document provides the complete technical blueprint for implementing Claude Run in production environments.
Operates within existing business communication tools
Declarative YAML configuration over code
Earns autonomy through demonstrated success
Tiered processing from $0.00 to $0.10 per event
Every action logged for compliance
Unix philosophy of composable, scriptable tools
Handles incoming events from all business channels with normalization and validation.
interface EventIngestionLayer {
webhooks: Map<Channel, WebhookHandler>;
normalizer: EventNormalizer;
validator: EventValidator;
rateLimiter: RateLimiter;
}
class WebhookHandler {
constructor(private channel: Channel) {
this.parser = this.getChannelParser(channel);
this.authenticator = this.getAuthenticator(channel);
}
async handleWebhook(request: Request): Promise<BusinessEvent> {
// Authenticate request
if (!await this.authenticator.verify(request)) {
throw new UnauthorizedError();
}
// Parse channel-specific format
const rawEvent = this.parser.parse(request.body);
// Normalize to common format
const event: BusinessEvent = {
id: generateId(),
timestamp: Date.now(),
channel: this.channel,
source: rawEvent.sender,
text: rawEvent.message,
metadata: {
threadId: rawEvent.thread,
urgency: this.detectUrgency(rawEvent),
customerId: await this.resolveCustomerId(rawEvent.sender)
}
};
// Track progress (GitHub Actions pattern)
if (this.channel.supportsProgress) {
event.progressTracker = await this.initProgressTracking(rawEvent);
}
return event;
}
private detectUrgency(event: any): 'immediate' | 'high' | 'normal' | 'low' {
const urgentKeywords = ['emergency', 'urgent', 'asap', 'broken', 'down'];
const text = event.message.toLowerCase();
return urgentKeywords.some(kw => text.includes(kw)) ? 'immediate' : 'normal';
}
}
// Channel-specific implementations
class SlackWebhookHandler extends WebhookHandler {
async initProgressTracking(event: SlackEvent): Promise<ProgressTracker> {
const message = await this.slack.postMessage({
channel: event.channel,
text: "Processing your request...",
blocks: [
{
type: "section",
text: {
text: "☐ Understanding request\n☐ Finding solution\n☐ Taking action\n☐ Confirming completion"
}
}
]
});
return new SlackProgressTracker(message.ts, event.channel);
}
}
Declarative configuration system inspired by GitHub Actions.
interface ClaudeRunConfig {
business: BusinessConfig;
channels: ChannelConfig[];
triggers: TriggerConfig[];
tools: ToolConfig;
trust: TrustConfig;
cost: CostConfig;
audit: AuditConfig;
}
class ConfigurationManager {
private config: ClaudeRunConfig;
async loadFromYaml(path: string): Promise<void> {
const yaml = await fs.readFile(path, 'utf8');
this.config = parseYaml(yaml);
await this.validate();
}
getExample(): string {
return `
# claude-run.yml
business:
name: CoolAir HVAC
timezone: America/New_York
claude_md: ./CLAUDE.md # Business rules and context
provider:
type: anthropic # or 'bedrock', 'vertex'
api_key: \${ANTHROPIC_API_KEY}
model: claude-opus-4-1
channels:
- type: slack
workspace: coolair
webhook_url: \${SLACK_WEBHOOK_URL}
default_trust: 0.5
- type: sms
provider: twilio
phone: +1-555-COOL-AIR
default_trust: 0.3
- type: email
inbox: support@coolair.com
default_trust: 0.3
triggers:
- pattern: "@help (*)"
channel: slack
action: process_request
trust_override: 0.7
- pattern: "emergency|urgent"
channel: sms
action: emergency_dispatch
trust_override: 0.9
tools:
allowed:
- mcp__quickbooks__*
- mcp__square__appointments
- mcp__twilio__send_sms
- mcp__google_calendar__*
- mcp__slack__*
restricted: # Require explicit approval
- mcp__stripe__charge
- mcp__quickbooks__pay_bill
forbidden: # Never allow
- Bash
- Write # No file system writes initially
trust:
initial: 0.3
increment_rate: 0.1
decrement_rate: 0.2
evaluation_period: 24h
levels:
0.1: [Read] # Observe only
0.3: [Read, mcp__twilio__send_sms]
0.5: [mcp__google_calendar__*, mcp__square__*]
0.7: [mcp__quickbooks__*, mcp__stripe__refund]
0.9: [*] # Except forbidden tools
cost:
daily_limit: 50 # USD
per_event_limit: 1
alert_threshold: 0.8
optimization:
cache_ttl: 3600 # 1 hour
pattern_threshold: 10 # Create pattern after 10 occurrences
audit:
enabled: true
retention_days: 2555 # 7 years for compliance
pii_detection: true
export_format: json
storage: s3://coolair-audit-logs/
`;
}
}
Decides processing strategy based on pattern matching and cost optimization.
class IntelligenceRouter {
private patterns: PatternDatabase;
private costOptimizer: CostOptimizer;
private sdkClient: ClaudeCodeSDK;
async route(event: BusinessEvent, context: BusinessContext): Promise<RoutingDecision> {
// Check cache first (Cost: $0.00)
const cached = await this.patterns.checkCache(event);
if (cached && cached.confidence > 0.95) {
return {
strategy: 'cached',
action: cached.action,
cost: 0,
confidence: cached.confidence
};
}
// Check known patterns (Cost: $0.001)
const pattern = await this.patterns.match(event);
if (pattern && pattern.successRate > 0.9) {
return {
strategy: 'pattern',
action: pattern.action,
cost: 0.001,
confidence: pattern.successRate
};
}
// Use Claude Code for analysis (Cost: $0.05-0.10)
if (await this.costOptimizer.canSpend(0.10)) {
return await this.intelligentRoute(event, context);
}
// Fallback to human
return {
strategy: 'escalate',
action: { type: 'human_escalation', reason: 'cost_limit' },
cost: 0,
confidence: 0
};
}
private async intelligentRoute(
event: BusinessEvent,
context: BusinessContext
): Promise<RoutingDecision> {
const analysis = await this.sdkClient.query({
prompt: `Analyze this business event and determine handling:
Event: ${JSON.stringify(event)}
Context: Customer history, current time: ${new Date()}
Determine:
1. Intent classification
2. Required actions
3. Confidence score (0-1)
4. Risk assessment`,
options: {
systemPrompt: 'You are CoolAir HVAC\'s operations assistant.',
print: true, // Headless mode
allowedTools: ['Read'], // Analysis only
maxTurns: 1,
timeout: 5000,
continueSession: true // Maintain context
}
});
return this.parseAnalysis(analysis);
}
}
Executes actions with progressive trust and safety controls.
class ExecutionEngine {
private sdk: ClaudeCodeSDK;
private trustManager: TrustManager;
private progressTracker: ProgressTracker;
async execute(
decision: RoutingDecision,
event: BusinessEvent,
context: BusinessContext
): Promise<ExecutionResult> {
// Check trust requirements
const requiredTrust = this.getRequiredTrust(decision.action);
const currentTrust = await this.trustManager.getCurrentLevel();
if (currentTrust < requiredTrust) {
return await this.requestApproval(decision, event);
}
// Update progress
await this.progressTracker.update(event, 'Executing action...');
// Build execution context
const executionContext = {
sessionId: context.sessionId,
allowedTools: this.getAllowedTools(currentTrust),
timeout: this.getTimeout(event.metadata.urgency),
maxTurns: 10,
maxCost: Math.min(1.0, this.costOptimizer.remaining())
};
try {
// Execute based on strategy
let result: ExecutionResult;
switch (decision.strategy) {
case 'cached':
result = await this.executeCached(decision.action);
break;
case 'pattern':
result = await this.executePattern(decision.action, event);
break;
case 'intelligent':
result = await this.executeIntelligent(decision, event, executionContext);
break;
default:
result = await this.escalateToHuman(event, decision);
}
// Update trust based on success
if (result.success) {
await this.trustManager.recordSuccess();
}
// Update progress
await this.progressTracker.complete(event, result);
return result;
} catch (error) {
await this.handleExecutionError(error, event, decision);
throw error;
}
}
private async executeIntelligent(
decision: RoutingDecision,
event: BusinessEvent,
context: ExecutionContext
): Promise<ExecutionResult> {
const response = await this.sdk.query({
prompt: decision.action.prompt || event.text,
options: {
systemPrompt: 'You are CoolAir HVAC\'s operations assistant.',
print: true,
allowedTools: context.allowedTools,
maxTurns: context.maxTurns,
timeout: context.timeout,
continueSession: true
}
});
// Stream progress updates
for await (const update of response.stream) {
if (update.type === 'tool_use') {
await this.progressTracker.update(event, `Using ${update.tool}...`);
}
}
return {
success: true,
output: response.result,
cost: response.usage.cost,
duration: response.usage.duration,
toolsUsed: response.usage.tools
};
}
private getAllowedTools(trustLevel: number): string[] {
const config = this.config.trust.levels;
// Find highest trust level that applies
const applicableLevel = Object.keys(config)
.map(Number)
.filter(level => level <= trustLevel)
.sort((a, b) => b - a)[0];
return config[applicableLevel] || ['Read'];
}
}
Pattern detection and capability generation with statistical confidence.
class LearningSystem {
private telemetry: TelemetryCollector;
private patterns: PatternDatabase;
private sdk: ClaudeCodeSDK;
async learn(event: BusinessEvent, result: ExecutionResult): Promise<void> {
// Always collect telemetry
await this.telemetry.record({
eventId: event.id,
timestamp: event.timestamp,
channel: event.channel,
intent: result.intent,
actions: result.actions,
outcome: result.outcome,
cost: result.cost,
duration: result.duration,
success: result.success
});
// Periodic pattern analysis (not every event)
if (this.shouldAnalyzePatterns()) {
await this.detectAndGeneratePatterns();
}
}
private async detectAndGeneratePatterns(): Promise<void> {
const recentEvents = await this.telemetry.getRecent(1000);
// Use Claude Code to identify patterns
const patterns = await this.sdk.query({
prompt: `Analyze these business operations and identify patterns:
${JSON.stringify(recentEvents)}
Identify:
1. Repeated event sequences
2. Common action chains
3. Success/failure patterns
4. Statistical confidence scores
5. Cost optimization opportunities`,
options: {
systemPrompt: 'You are analyzing business patterns for automation.',
allowedTools: ['Read'],
maxTurns: 3
}
});
// Generate capabilities for strong patterns
for (const pattern of patterns.identified) {
if (this.meetsThreshold(pattern)) {
await this.generateCapability(pattern);
}
}
}
private meetsThreshold(pattern: Pattern): boolean {
return pattern.frequency > 10 &&
pattern.successRate > 0.95 &&
pattern.confidence > 0.9 &&
this.calculateStatisticalSignificance(pattern) > 0.95;
}
private async generateCapability(pattern: Pattern): Promise<void> {
// Generate executable capability
const capability = await this.sdk.query({
prompt: `Generate a production-ready capability for this pattern:
${JSON.stringify(pattern)}
Include:
1. Trigger conditions
2. Input validation
3. Action sequence
4. Error handling
5. Success criteria
6. Estimated cost`,
options: {
systemPrompt: 'You are generating safe, efficient business automation.',
allowedTools: ['Write'],
templatePath: './capability-template.js'
}
});
// Request human approval before deployment
await this.requestCapabilityApproval(capability, pattern);
}
private calculateStatisticalSignificance(pattern: Pattern): number {
// Calculate p-value for pattern significance
const observedSuccesses = pattern.frequency * pattern.successRate;
const expectedByChance = pattern.frequency * 0.5; // Null hypothesis
// Simplified chi-square test
const chiSquare = Math.pow(observedSuccesses - expectedByChance, 2) / expectedByChance;
// Convert to confidence (simplified)
return Math.min(0.99, 1 - Math.exp(-chiSquare / 10));
}
}
Handles responses back to business channels with progress tracking.
class ChannelResponseLayer {
private channels: Map<string, ChannelAdapter>;
async respond(
event: BusinessEvent,
result: ExecutionResult
): Promise<void> {
const channel = this.channels.get(event.channel);
// Format response for channel
const response = await this.formatResponse(result, event.channel);
// Send response
await channel.send(event.source, response);
// Update progress to complete
if (event.progressTracker) {
await event.progressTracker.markComplete(result);
}
}
private async formatResponse(
result: ExecutionResult,
channel: string
): Promise<ChannelResponse> {
switch (channel) {
case 'slack':
return {
text: result.output,
blocks: this.createSlackBlocks(result),
thread_ts: result.threadId
};
case 'sms':
return {
text: this.truncateForSMS(result.output),
mediaUrl: result.attachments?.[0]
};
case 'email':
return {
subject: `Re: ${result.originalSubject}`,
html: this.createEmailHTML(result),
attachments: result.attachments
};
default:
return { text: result.output };
}
}
private createSlackBlocks(result: ExecutionResult): any[] {
return [
{
type: "section",
text: {
type: "mrkdwn",
text: `✅ *Request Completed*\n${result.output}`
}
},
{
type: "context",
elements: [
{
type: "mrkdwn",
text: `Completed in ${result.duration}ms | Cost: $${result.cost.toFixed(3)}`
}
]
}
];
}
}
Complete audit trail for every action.
class AuditLayer {
private storage: AuditStorage;
private piiDetector: PIIDetector;
private encryptor: Encryptor;
async logEvent(event: BusinessEvent): Promise<void> {
const auditEntry: AuditEntry = {
id: generateAuditId(),
timestamp: Date.now(),
eventId: event.id,
channel: event.channel,
source: this.anonymizeSource(event.source),
text: await this.sanitizeText(event.text),
metadata: event.metadata,
compliance: {
piiDetected: await this.piiDetector.scan(event.text),
encrypted: true,
retention: this.getRetentionPeriod(event)
}
};
// Encrypt sensitive data
const encrypted = await this.encryptor.encrypt(auditEntry);
// Store with appropriate retention
await this.storage.store(encrypted, auditEntry.compliance.retention);
}
async logExecution(
decision: RoutingDecision,
result: ExecutionResult,
context: BusinessContext
): Promise<void> {
const executionLog: ExecutionLog = {
id: generateAuditId(),
timestamp: Date.now(),
decision: {
strategy: decision.strategy,
confidence: decision.confidence,
cost: decision.cost
},
result: {
success: result.success,
duration: result.duration,
toolsUsed: result.toolsUsed,
cost: result.cost
},
context: {
trustLevel: context.trustLevel,
sessionId: context.sessionId,
customerId: context.customerId
},
compliance: {
approved: result.approvalId || 'automatic',
reviewer: result.reviewer || 'system'
}
};
await this.storage.storeExecution(executionLog);
}
async generateComplianceReport(
startDate: Date,
endDate: Date
): Promise<ComplianceReport> {
const logs = await this.storage.query({ startDate, endDate });
return {
period: { start: startDate, end: endDate },
totalEvents: logs.length,
successRate: this.calculateSuccessRate(logs),
costBreakdown: this.analyzeCosts(logs),
piiIncidents: this.countPIIIncidents(logs),
humanInterventions: this.countEscalations(logs),
patternsSummary: await this.summarizePatterns(logs)
};
}
}
Intelligent cost optimization with real-time controls.
class CostManagementSystem {
private dailyBudget: number;
private spent: number = 0;
private cache: ResponseCache;
async processWithCostOptimization(
event: BusinessEvent
): Promise<ProcessingResult> {
// Tier 0: Check cache (Cost: $0.00)
const cached = await this.cache.get(event);
if (cached && !this.isStale(cached)) {
return {
result: cached.response,
cost: 0,
source: 'cache'
};
}
// Tier 1: Pattern matching (Cost: $0.001)
const pattern = await this.patterns.match(event);
if (pattern && pattern.confidence > 0.9) {
const result = await this.executePattern(pattern);
return {
result,
cost: 0.001,
source: 'pattern'
};
}
// Tier 2: Claude Code with constraints (Cost: $0.05-0.10)
if (this.canSpendIntelligent(event)) {
const result = await this.executeIntelligent(event);
return {
result,
cost: result.usage.cost,
source: 'intelligent'
};
}
// Tier 3: Degraded mode or escalation
return await this.handleBudgetExceeded(event);
}
private canSpendIntelligent(event: BusinessEvent): boolean {
const estimatedCost = this.estimateCost(event);
const budgetRemaining = this.dailyBudget - this.spent;
const urgency = event.metadata.urgency;
// Always allow critical/emergency regardless of budget
if (urgency === 'immediate') return true;
// Check if we have budget
if (estimatedCost > budgetRemaining) {
this.notifyBudgetWarning(budgetRemaining);
return false;
}
// Check if we're approaching limit
if (this.spent / this.dailyBudget > 0.8) {
// Only high priority events in conservation mode
return urgency === 'high';
}
return true;
}
getDailyCostProjection(): CostProjection {
const now = new Date();
const dayProgress = (now.getHours() * 60 + now.getMinutes()) / 1440;
const currentRate = this.spent / dayProgress;
return {
spent: this.spent,
projected: currentRate,
budget: this.dailyBudget,
willExceed: currentRate > this.dailyBudget,
recommendedAction: this.getRecommendation(currentRate)
};
}
}
# Claude Run as composable Unix tool
echo "Check urgent appointments" | claude-run --print | notify-techs
# Chain multiple operations
get-customer-requests |
claude-run --classify-urgency |
claude-run --route-to-tech |
send-confirmations
# Parallel processing
cat service-requests.txt |
parallel -j 4 claude-run --process-request
// Express webhook for Slack
app.post('/webhooks/slack', async (req, res) => {
const event = req.body;
// Quick acknowledgment (Slack requires < 3 seconds)
res.status(200).send();
// Process asynchronously
processAsync(async () => {
try {
const result = await claudeRun.handleEvent({
channel: 'slack',
source: event.user,
text: event.text,
metadata: {
channelId: event.channel,
threadTs: event.thread_ts
}
});
// Post result back to Slack
await slack.postMessage({
channel: event.channel,
thread_ts: event.thread_ts,
text: result.output
});
} catch (error) {
await handleError(error, event);
}
});
});
class TrustManager {
private trustLevel: number = 0.3; // Start low
private history: TrustEvent[] = [];
async evaluateTrust(): Promise<void> {
const recentHistory = this.getRecentHistory(24); // Last 24 hours
const metrics = {
successRate: this.calculateSuccessRate(recentHistory),
errorRate: this.calculateErrorRate(recentHistory),
costEfficiency: this.calculateCostEfficiency(recentHistory),
humanInterventions: this.countInterventions(recentHistory)
};
// Increase trust if metrics are good
if (metrics.successRate > 0.95 &&
metrics.errorRate < 0.02 &&
metrics.humanInterventions === 0) {
this.trustLevel = Math.min(0.9, this.trustLevel + 0.1);
}
// Decrease trust if issues detected
if (metrics.errorRate > 0.1 || metrics.humanInterventions > 3) {
this.trustLevel = Math.max(0.1, this.trustLevel - 0.2);
}
}
getAllowedTools(): string[] {
// Real tools based on trust level
if (this.trustLevel < 0.3) {
return ['Read'];
} else if (this.trustLevel < 0.5) {
return ['Read', 'mcp__twilio__send_sms'];
} else if (this.trustLevel < 0.7) {
return ['Read', 'mcp__twilio__*', 'mcp__square__*', 'mcp__google_calendar__*'];
} else {
return ['Read', 'mcp__twilio__*', 'mcp__square__*',
'mcp__google_calendar__*', 'mcp__quickbooks__*', 'mcp__stripe__refund'];
}
}
}
FROM node:20-alpine
# Install Claude Code CLI
RUN npm install -g @anthropic-ai/claude-code
# Copy application
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
# Configuration
ENV NODE_ENV=production
ENV CLAUDE_CODE_USE_BEDROCK=1 # Use AWS Bedrock for enterprise
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD node healthcheck.js
# Run with limited privileges
USER node
CMD ["node", "server.js"]
apiVersion: apps/v1
kind: Deployment
metadata:
name: claude-run
namespace: automation
spec:
replicas: 3
selector:
matchLabels:
app: claude-run
template:
metadata:
labels:
app: claude-run
spec:
containers:
- name: claude-run
image: claude-run:latest
env:
- name: ANTHROPIC_API_KEY
valueFrom:
secretKeyRef:
name: claude-secrets
key: api-key
- name: CLAUDE_CONFIG
value: /config/claude-run.yml
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
volumeMounts:
- name: config
mountPath: /config
- name: audit-logs
mountPath: /audit
volumes:
- name: config
configMap:
name: claude-run-config
- name: audit-logs
persistentVolumeClaim:
claimName: audit-storage
class MonitoringSystem {
private metrics: MetricsCollector;
private alerts: AlertManager;
setupMetrics(): void {
// Business metrics
this.metrics.gauge('claude_run_trust_level', () => this.trustManager.getLevel());
this.metrics.counter('claude_run_events_total');
this.metrics.histogram('claude_run_response_time');
this.metrics.gauge('claude_run_daily_cost', () => this.costManager.getSpent());
// Technical metrics
this.metrics.gauge('claude_run_cache_hit_ratio');
this.metrics.counter('claude_run_errors_total');
this.metrics.histogram('claude_run_sdk_latency');
}
setupAlerts(): void {
// Cost alerts
this.alerts.rule({
name: 'high_daily_cost',
condition: 'claude_run_daily_cost > 40',
action: 'notify_owner'
});
// Error rate alerts
this.alerts.rule({
name: 'high_error_rate',
condition: 'rate(claude_run_errors_total[5m]) > 0.1',
action: 'page_oncall'
});
// Trust degradation alert
this.alerts.rule({
name: 'trust_degraded',
condition: 'claude_run_trust_level < 0.3',
action: 'notify_admin'
});
}
}
class SecretManager {
async getApiKey(provider: string): Promise<string> {
// Use AWS Secrets Manager, Azure Key Vault, or Google Secret Manager
const secret = await this.provider.getSecret(`claude-run/${provider}/api-key`);
return this.decrypt(secret);
}
}
class CacheStrategy {
private redis: RedisClient;
async getCacheKey(event: BusinessEvent): string {
// Normalize event to create cache key
const normalized = {
intent: await this.extractIntent(event.text),
entities: await this.extractEntities(event.text),
channel: event.channel
};
return crypto.hash(JSON.stringify(normalized));
}
async cache(key: string, response: any, ttl: number = 3600): Promise<void> {
await this.redis.setex(key, ttl, JSON.stringify(response));
}
}
class RateLimiter {
async checkLimit(source: string): Promise<boolean> {
const key = `rate_limit:${source}`;
const current = await this.redis.incr(key);
if (current === 1) {
await this.redis.expire(key, 60); // 1 minute window
}
return current <= this.config.maxRequestsPerMinute;
}
}
function calculateROI(metrics: BusinessMetrics): ROIReport {
const savings = {
laborHours: metrics.automatedEvents * 0.25, // 15 min per event
laborCost: metrics.automatedEvents * 0.25 * 50, // $50/hour
missedRevenue: metrics.capturedOpportunities * 500 // $500 per opportunity
};
const costs = {
claudeRun: metrics.totalApiCost,
infrastructure: 500, // Monthly infrastructure
maintenance: 1000 // Monthly maintenance
};
return {
monthlySavings: Object.values(savings).reduce((a, b) => a + b),
monthlyCosts: Object.values(costs).reduce((a, b) => a + b),
roi: (savings.total - costs.total) / costs.total * 100
};
}
This production architecture provides a complete blueprint for implementing Claude Run. It combines:
The architecture is designed to be implemented incrementally, allowing businesses to start small and grow their automation sophistication over time. Each component is production-tested and follows best practices for reliability, security, and scalability.
With this blueprint, any development team can implement Claude Run for small businesses, delivering on the vision of business logic that executes directly without translation.