Skip to content

The game-changer: Because Hoody AI requests flow through HTTP, you can intercept and modify everything using hoody-exec as a MITM (Man-In-The-Middle) proxy.

This isn’t about surveillance. It’s about complete control. When everything is HTTP (as explained in The HTTP Revolution), everything becomes observable, modifiable, and composable. AI requests are no different.

The breakthrough: Intercept, analyze, transform, cache, route, or enhance every AI interaction—all in just a few lines of JavaScript.

The simplicity: Deploy a MITM script once (see Deploying the MITM Script below), then just change the URL in your AI client — the base_url swap shown in the next section is the on-demand toggle, not the whole setup.

Without MITM: https://ai.hoody.icu/api/v1
With MITM: https://your-project-container-exec-1.node-us.containers.hoody.icu/api/v1
Switch on-demand. No code changes. Complete control.

The beauty: You don’t need to change your code. Just change the URL in your AI client settings.

Terminal window
# Normal Hoody AI
curl -X POST "https://{projectId}-{containerId}-workspaces-1.{node}.containers.hoody.icu/api/tasks" \
-d '{
"prompt": "Build an app",
"ai_config": {
"base_url": "https://ai.hoody.icu/api/v1",
"api_key": "container-1",
"model": "anthropic/claude-sonnet-4.5"
}
}'
# With MITM enabled
curl -X POST "https://{projectId}-{containerId}-workspaces-1.{node}.containers.hoody.icu/api/tasks" \
-d '{
"prompt": "Build an app",
"ai_config": {
"base_url": "https://your-project-container-exec-1.node-us.containers.hoody.icu/api/v1",
"api_key": "container-1",
"model": "anthropic/claude-sonnet-4.5"
}
}'

Just change the base_url. Everything else stays the same.

On-demand activation: Want to test with MITM? Change the URL. Want to bypass MITM? Change back. No deployments. No config files. Just URL switching.


Traditional AI integrations are black boxes. You send a prompt, get a response. Everything in between is hidden.

With Hoody’s HTTP architecture:

  • Every AI request is a visible HTTP call
  • Every response flows through your infrastructure
  • Every tool call is JSON you can inspect and modify
  • Every agent decision is an HTTP endpoint you can intercept

This means: You can insert yourself (or your code) anywhere in the AI pipeline. Add logging. Request human approval. Transform prompts. Cache responses. Route to different models. Chain agents together. Replace tool calls. Inject context.

All through simple HTTP interception.

Complete AI Observability:

  • Log every prompt and response for debugging
  • Track token usage per project automatically
  • Analyze AI decision patterns
  • Monitor for prompt injection attempts
  • Build audit trails for compliance

Human-in-the-Loop at Scale:

  • Intercept high-stakes decisions for human approval
  • Pause AI execution for review before deployment
  • Add confirmation steps for sensitive operations
  • Let AI draft, humans decide

Cost Optimization:

  • Compress prompts to reduce token usage (20-40% savings)
  • Cache responses to eliminate duplicate calls (100% on cache hits)
  • Route to cheaper models for simple tasks (40-70% savings)
  • Auto-optimize based on complexity analysis

AI Enhancement:

  • Add context from your knowledge base automatically
  • Inject custom instructions per use case
  • Transform responses to match your style
  • Chain multiple AI calls intelligently

Tool Call Manipulation:

  • Intercept and modify AI tool calls before execution
  • Add safety checks to file operations
  • Reroute dangerous commands to sandbox
  • Replace file paths, command arguments, or entire operations
  • Log all tool usage for audit trails

Agent Orchestration:

  • Cascade AI requests across multiple agent instances
  • Coordinate multi-agent workflows via HTTP
  • Distribute tasks across agent swarms
  • Build self-improving agent networks

Here’s the basic pattern for creating an AI MITM proxy with hoody-exec:

scripts/default/1/api/v1/[...path].js
// This catch-all route handles /api/v1/* (matching OpenAI API structure)
// @mode worker
// @log-level standard
// Handle all /api/v1/* endpoints (chat/completions, embeddings, images, etc.)
const apiPath = metadata.parameters.path.join('/'); // e.g., "chat/completions"
const response = await fetch(`https://ai.hoody.icu/api/v1/${apiPath}`, {
method: req.method,
headers: {
'Authorization': 'Bearer container-1',
'Content-Type': 'application/json'
},
body: req.method === 'POST' ? JSON.stringify(req.body) : undefined
});
const data = await response.json();
// YOUR CUSTOM LOGIC HERE
// - Modify prompts
// - Add context
// - Check cache
// - Log for audit
// - Request human approval
// - Optimize model selection
// - Intercept tool calls
// - Trigger other agents
return res.json(data);

Option 1: Catch-All Route (Recommended - handles all AI endpoints)

/hoody/storage/hoody-exec/scripts/default/1/api/v1/[...path].js

This handles:

  • POST /api/v1/chat/completions
  • POST /api/v1/embeddings
  • GET /api/v1/models
  • Any other OpenAI-compatible endpoint

Option 2: Specific Endpoint (For targeted control)

/hoody/storage/hoody-exec/scripts/default/1/api/v1/chat/completions.js

This only handles POST /api/v1/chat/completions

Accessing your MITM proxy:

https://your-project-container-exec-1.node-us.containers.hoody.icu/api/v1/chat/completions

How to use:

  1. Deploy the script (see deployment section below)
  2. Change base URL in your AI client:
    • Normal: https://ai.hoody.icu/api/v1
    • With MITM: https://your-project-container-exec-1.node-us.containers.hoody.icu/api/v1
  3. That’s it. All requests now flow through your MITM proxy.

Switch on-demand: Toggle between URLs to enable/disable MITM. No code changes needed.

Prerequisite — container identity token. The examples below use Bearer container-1. Hoody-minted containers are reachable under both a name-derived form (container-<name>) and a numbered form (container-<N>). Replace container-1 with the identifier that matches the container running the script; both forms are equivalent identity tokens, not copyable API keys.

Create your MITM proxy script using the hoody-files API:

Terminal window
# Deploy the catch-all MITM proxy (handles all /api/v1/* endpoints)
curl -X POST "https://your-project-container-files-1.node-us.containers.hoody.icu/hoody/storage/hoody-exec/scripts/default/1/api/v1/%5B...path%5D.js" \
-H "Content-Type: text/plain" \
--data-binary @- << 'EOF'
// File: scripts/default/1/api/v1/[...path].js
// Catch-all MITM proxy for all OpenAI-compatible endpoints
// @mode worker
// @log-level standard
// Handle all /api/v1/* endpoints
const apiPath = metadata.parameters.path.join('/');
const response = await fetch(`https://ai.hoody.icu/api/v1/${apiPath}`, {
method: req.method,
headers: {
'Authorization': 'Bearer container-1',
'Content-Type': 'application/json'
},
body: req.method === 'POST' ? JSON.stringify(req.body) : undefined
});
const data = await response.json();
// YOUR MITM LOGIC HERE
// Example: Log all requests
console.log(`AI Request: ${req.method} /api/v1/${apiPath}`);
console.log(`Model: ${req.body?.model || 'N/A'}`);
console.log(`Tokens: ${data.usage?.total_tokens || 'N/A'}`);
return res.json(data);
EOF

That’s it. Your MITM proxy is now live at:

https://your-project-container-exec-1.node-us.containers.hoody.icu/api/v1/chat/completions
Terminal window
# Create the script using hoody-exec's script management API
curl -X POST "https://your-project-container-exec-1.node-us.containers.hoody.icu/api/v1/exec/scripts/write" \
-H "Content-Type: application/json" \
-d @- << 'EOF'
{
"path": "default/1/api/v1/[...path].js",
"content": "// @mode worker\n// @log-level standard\n\nconst apiPath = metadata.parameters.path.join('/');\n\nconst response = await fetch(`https://ai.hoody.icu/api/v1/${apiPath}`, {\n method: req.method,\n headers: {\n 'Authorization': 'Bearer container-1',\n 'Content-Type': 'application/json'\n },\n body: req.method === 'POST' ? JSON.stringify(req.body) : undefined\n});\n\nconst data = await response.json();\nconsole.log(`AI Request: ${req.method} /api/v1/${apiPath}`);\n\nreturn res.json(data);"
}
EOF
Terminal window
# Test your MITM proxy
curl -X POST "https://your-project-container-exec-1.node-us.containers.hoody.icu/api/v1/chat/completions" \
-H "Authorization: Bearer container-1" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-haiku-4.0",
"messages": [{"role": "user", "content": "Hello!"}]
}'

If you see the response and logs, your MITM is working!



Stop AI from executing high-stakes operations without human approval:

// @mode worker
// @log-level standard
const lastMessage = req.body.messages[req.body.messages.length - 1].content;
// Detect high-stakes operations
const isHighStakes = /deploy|delete|drop|production|payment|transfer/.test(
lastMessage.toLowerCase()
);
if (isHighStakes) {
// Send notification to human via hoody-notifications
await fetch('https://your-project-container-n-1.node-us.containers.hoody.icu/api/notify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
title: '🚨 AI Needs Approval',
message: `High-stakes operation detected:\n${lastMessage}`,
priority: 'urgent',
actions: [
{ label: 'Approve', url: `/api/approve/${requestId}` },
{ label: 'Reject', url: `/api/reject/${requestId}` }
]
})
});
// Store request for approval workflow
const requestId = crypto.randomUUID();
if (!shared.pendingApprovals) shared.pendingApprovals = new Map();
shared.pendingApprovals.set(requestId, req.body);
return res.json({
status: 'pending_approval',
requestId,
message: 'High-stakes operation detected. Awaiting human approval.',
estimatedWait: '2-10 minutes'
});
}
// Normal flow for safe operations
const response = await fetch('https://ai.hoody.icu/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer container-1',
'Content-Type': 'application/json'
},
body: JSON.stringify(req.body)
});
return res.json(await response.json());

The transformation: AI agents can work autonomously 95% of the time. Critical decisions pause for your review. You become the approval layer, not the execution layer.

Real workflow: 47 AI agents working across hundreds of containers. Your job? Answer decision requests. “Deploy to production?” “Delete this database?” “Transfer $10,000?” You confirm. They execute.

The killer feature: AI agents use tool calls to interact with files, execute commands, etc. You can intercept and modify these tool calls before they execute.

Redirect file operations to sandbox:

// @mode worker
const response = await fetch('https://ai.hoody.icu/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer container-1',
'Content-Type': 'application/json'
},
body: JSON.stringify(req.body)
});
const data = await response.json();
// Intercept tool calls before they execute
if (data.choices[0].message.tool_calls) {
data.choices[0].message.tool_calls = data.choices[0].message.tool_calls.map(call => {
// Redirect dangerous file operations to sandbox
if (call.function.name === 'write_file') {
const args = JSON.parse(call.function.arguments);
// Force all writes into /sandbox/ directory
if (!args.path.startsWith('/sandbox/')) {
args.path = '/sandbox' + args.path;
call.function.arguments = JSON.stringify(args);
}
}
// Add safety checks to delete operations
if (call.function.name === 'delete_file') {
const args = JSON.parse(call.function.arguments);
// Prevent deletion of critical files
if (args.path.match(/config|production|\.env|package\.json/)) {
// Replace with confirmation tool
call.function.name = 'confirm_delete';
call.function.arguments = JSON.stringify({
...args,
warning: 'Critical file deletion requires confirmation'
});
}
}
// Intercept command execution
if (call.function.name === 'execute_command') {
const args = JSON.parse(call.function.arguments);
// Block or modify dangerous commands
if (args.command.match(/rm -rf|sudo|chmod 777/)) {
call.function.name = 'blocked_command';
call.function.arguments = JSON.stringify({
original: args.command,
reason: 'Dangerous command intercepted'
});
}
}
return call;
});
}
return res.json(data);

Use cases:

  • AI can code freely, but file writes are automatically sandboxed
  • Dangerous operations require explicit confirmation
  • Critical files are protected from accidental deletion
  • Command injection is prevented

The power: AI operates with full freedom, but you’ve added guardrails that prevent catastrophic mistakes. All done in ~50 lines of code.

The breakthrough: Because every service is HTTP, you can trigger cascades of agents from your MITM proxy.

Multi-agent coordination:

// @mode worker
const response = await fetch('https://ai.hoody.icu/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer container-1',
'Content-Type': 'application/json'
},
body: JSON.stringify(req.body)
});
const data = await response.json();
const aiResponse = data.choices[0].message.content;
// Detect when AI wants to delegate work
if (aiResponse.includes('DELEGATE:')) {
const taskMatch = aiResponse.match(/DELEGATE: (.+)/);
const delegatedTask = taskMatch[1];
// Cascade to another hoody-agent via HTTP
const agentResponse = await fetch(
'https://project-container-workspaces-2.node-us.containers.hoody.icu/api/tasks',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
prompt: delegatedTask,
auto_execute: true,
mode: 'code',
callback_url: 'https://current-container-exec-1.hoody.icu/api/task-complete'
})
}
);
const agentData = await agentResponse.json();
// Modify response to indicate delegation
data.choices[0].message.content =
`Task delegated to Agent-2: ${delegatedTask}\n` +
`Task ID: ${agentData.taskId}\n` +
`Status: In progress...`;
}
// Detect when AI needs specialized capabilities
if (aiResponse.includes('ANALYZE_CODE:')) {
// Trigger code analysis agent
await fetch('https://code-analyzer-agent.hoody.icu/api/tasks', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
prompt: 'Analyze codebase for security issues',
report_to: 'https://current-container-exec-1.hoody.icu/api/analysis-report'
})
});
}
return res.json(data);

What this enables:

  • Agent swarms - One agent spawns/coordinates 10 others
  • Specialized agents - Route tasks to expert agents (code, security, design)
  • Parallel execution - Distribute work across multiple agents simultaneously
  • Self-organizing systems - Agents discover and coordinate with each other

Real scenario: You ask Agent A to “build a complete SaaS app”. Agent A analyzes, then cascades to:

  • Agent B (frontend specialist)
  • Agent C (backend specialist)
  • Agent D (database specialist)
  • Agent E (security auditor)

All coordinating via HTTP. All reporting back. All orchestrated from one MITM script.

Powerful pattern: Pause AI execution until human reviews and approves.

// @mode worker
// @log-level standard
// Initialize shared state
if (!shared.pendingRequests) {
shared.pendingRequests = new Map();
}
if (req.body.urgent === true) {
const requestId = crypto.randomUUID();
// Store request
shared.pendingRequests.set(requestId, {
request: req.body,
timestamp: Date.now(),
status: 'pending'
});
// Notify human via hoody-notifications
await fetch('https://your-project-container-n-1.node-us.containers.hoody.icu/api/notify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
title: '⏸️ AI Awaiting Approval',
message: req.body.messages[req.body.messages.length - 1].content,
priority: 'high',
actions: [
{
label: '✅ Approve',
method: 'POST',
url: `/api/approve?id=${requestId}`
},
{
label: '❌ Reject',
method: 'POST',
url: `/api/reject?id=${requestId}`
}
]
})
});
// Poll for approval (or use webhook callback)
for (let i = 0; i < 300; i++) { // 5 minutes max
await new Promise(resolve => setTimeout(resolve, 1000)); // Wait 1 second
const request = shared.pendingRequests.get(requestId);
if (request.status === 'approved') {
break;
} else if (request.status === 'rejected') {
return res.status(403).json({ error: 'Request rejected by human' });
}
}
// Timeout if no response
if (shared.pendingRequests.get(requestId).status === 'pending') {
return res.status(408).json({ error: 'Approval timeout' });
}
}
// Proceed with AI request
const response = await fetch('https://ai.hoody.icu/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer container-1',
'Content-Type': 'application/json'
},
body: JSON.stringify(req.body)
});
return res.json(await response.json());

The workflow:

  1. AI agent wants to deploy to production
  2. MITM detects high-stakes operation
  3. Notification sent to your phone/desktop
  4. AI request pauses (stalls)
  5. You review and approve/reject
  6. AI continues or stops based on your decision

This is human-in-the-loop at scale. 47 agents working, you approve the 2-3 critical decisions per hour.

The most powerful pattern: Completely replace what AI tools do.

Example: Reroute all file writes to version control:

// @mode worker
const response = await fetch('https://ai.hoody.icu/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer container-1',
'Content-Type': 'application/json'
},
body: JSON.stringify(req.body)
});
const data = await response.json();
// Intercept and replace tool calls
if (data.choices[0].message.tool_calls) {
for (const call of data.choices[0].message.tool_calls) {
// Replace write_file with version-controlled write
if (call.function.name === 'write_file') {
const args = JSON.parse(call.function.arguments);
// Create git commit for this change
await fetch('https://your-project-container-terminal-1.node-us.containers.hoody.icu/api/v1/terminal/execute?terminal_id=1', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
command: `git add ${args.path} && git commit -m "AI: ${args.description || 'auto-save'}"`
})
});
// Modify the tool call to include git metadata
call.function.arguments = JSON.stringify({
...args,
git_tracked: true,
commit_message: `AI: ${args.description || 'auto-save'}`
});
}
// Replace read_file to inject AI-generated documentation
if (call.function.name === 'read_file') {
const args = JSON.parse(call.function.arguments);
// Read actual file via hoody-files
const fileResponse = await fetch(
`https://your-project-container-files-1.node-us.containers.hoody.icu${args.path}`,
{ method: 'GET' }
);
const fileContent = await fileResponse.text();
// Ask AI to add inline documentation
const docResponse = await fetch('https://ai.hoody.icu/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer container-1',
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'anthropic/claude-haiku-4.0',
messages: [{
role: 'user',
content: `Add inline documentation to this code:\n${fileContent}`
}]
})
});
const documented = await docResponse.json();
// Return documented version instead
call.function.arguments = JSON.stringify({
...args,
enhanced: true,
content: documented.choices[0].message.content
});
}
}
}
return res.json(data);

What you’ve done:

  • Every file write is now automatically version controlled
  • Every file read is enhanced with AI-generated documentation
  • AI sees improved code context automatically
  • You have full audit trail of all changes

The magic: AI doesn’t know you’re intercepting. It just works with better data and safer operations.

6. Cost Optimization: Intelligent Model Routing

Section titled “6. Cost Optimization: Intelligent Model Routing”

Save 40-70% by routing to cheaper models automatically:

// @mode worker
const lastMessage = req.body.messages[req.body.messages.length - 1].content;
// Analyze complexity
const wordCount = lastMessage.split(/\s+/).length;
const hasCode = /```|function|class|import|async|await/.test(lastMessage);
const hasMultiStep = /step|then|after|finally|workflow/.test(lastMessage);
const isDeployment = /deploy|production|release/.test(lastMessage);
// Intelligent model selection
let selectedModel = req.body.model;
if (isDeployment) {
// Critical operations get best model
selectedModel = 'anthropic/claude-opus-4.1';
} else if (wordCount < 50 && !hasCode && !hasMultiStep) {
// Simple question → cheapest model
selectedModel = 'anthropic/claude-haiku-4.0'; // $0.25/M tokens
} else if (hasCode || hasMultiStep) {
// Complex reasoning → balanced model
selectedModel = 'anthropic/claude-sonnet-4.5'; // $3.00/M tokens
} else {
// General tasks → fast model
selectedModel = 'openai/gpt-4o'; // $2.50/M tokens
}
const response = await fetch('https://ai.hoody.icu/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer container-1',
'Content-Type': 'application/json'
},
body: JSON.stringify({
...req.body,
model: selectedModel // Override with optimal model
})
});
return res.json(await response.json());

Savings: 40-70% by automatically using cheaper models when appropriate. AI quality doesn’t suffer—simple tasks don’t need expensive models.

Auto-enhance AI with your company knowledge:

// @mode worker
// Modules auto-installed on first require
const { createClient } = require('@supabase/supabase-js');
const supabase = createClient(
process.env.SUPABASE_URL,
process.env.SUPABASE_KEY
);
const userPrompt = req.body.messages[req.body.messages.length - 1].content;
// Semantic search in your knowledge base
const { data: context } = await supabase
.from('documentation')
.select('content, source, relevance')
.textSearch('content', userPrompt)
.order('relevance', { ascending: false })
.limit(3);
// Inject context into system prompt
const enhancedMessages = [
{
role: 'system',
content: `You have access to our internal knowledge base. Relevant context for this request:\n\n${
context.map(c => `**${c.source}**:\n${c.content}`).join('\n\n')
}\n\nUse this context to provide accurate, company-specific answers.`
},
...req.body.messages
];
const response = await fetch('https://ai.hoody.icu/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer container-1',
'Content-Type': 'application/json'
},
body: JSON.stringify({
...req.body,
messages: enhancedMessages
})
});
return res.json(await response.json());

The result: AI always has access to your latest documentation, internal wikis, company policies, and codebase context—automatically. No manual RAG setup. Just HTTP interception.

Eliminate duplicate AI calls:

// @mode worker
const { createClient } = require('@supabase/supabase-js');
const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY);
// Create cache key from request
const cacheKey = JSON.stringify({
model: req.body.model,
messages: req.body.messages
});
// Check cache (using hoody-sqlite for persistence)
const { data: cached } = await supabase
.from('ai_cache')
.select('response')
.eq('cache_key', cacheKey)
.single();
if (cached) {
return res.json({
...cached.response,
cached: true,
savings: '100% (from cache)'
});
}
// Call AI
const response = await fetch('https://ai.hoody.icu/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer container-1',
'Content-Type': 'application/json'
},
body: JSON.stringify(req.body)
});
const data = await response.json();
// Store in cache
await supabase
.from('ai_cache')
.insert({
cache_key: cacheKey,
response: data,
created_at: new Date().toISOString()
});
return res.json(data);

Savings: 100% cost reduction on cache hits. Perfect for:

  • Repeated questions (documentation, support)
  • Code reviews (similar code patterns)
  • Content generation (similar prompts)

Reduce token usage 20-40%:

// @mode worker
function compressPrompt(text) {
return text
.replace(/\s+/g, ' ') // Normalize whitespace
.replace(/\b(the|a|an)\b/gi, '') // Remove articles
.replace(/\b(please|kindly|could you)\b/gi, '') // Remove pleasantries
.trim();
}
// Compress verbose prompts
const compressedMessages = req.body.messages.map(msg => ({
...msg,
content: compressPrompt(msg.content)
}));
const response = await fetch('https://ai.hoody.icu/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer container-1',
'Content-Type': 'application/json'
},
body: JSON.stringify({
...req.body,
messages: compressedMessages
})
});
return res.json(await response.json());

Savings: 20-40% on verbose inputs without losing semantic meaning.


Build audit trails automatically:

// @mode worker
const { createClient } = require('@supabase/supabase-js');
const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY);
const requestId = crypto.randomUUID();
const startTime = Date.now();
// Log request
await supabase.from('ai_logs').insert({
request_id: requestId,
container: metadata.subdomain,
model: req.body.model,
prompt: req.body.messages[req.body.messages.length - 1].content,
timestamp: new Date().toISOString()
});
// Make AI request
const response = await fetch('https://ai.hoody.icu/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer container-1',
'Content-Type': 'application/json'
},
body: JSON.stringify(req.body)
});
const data = await response.json();
const duration = Date.now() - startTime;
// Log response
await supabase.from('ai_logs').update({
response: data.choices[0].message.content,
tokens_used: data.usage?.total_tokens,
duration_ms: duration,
cost: (data.usage?.total_tokens || 0) * 0.000003 // Example cost calculation
}).eq('request_id', requestId);
return res.json(data);

You now have:

  • Complete audit trail of all AI interactions
  • Token usage per container/project
  • Cost tracking automatically
  • Performance metrics
  • Compliance documentation

Use Hoody AI, fallback to your own keys:

// @mode worker
// Try Hoody AI first
let response = await fetch('https://ai.hoody.icu/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer container-1',
'Content-Type': 'application/json'
},
body: JSON.stringify(req.body)
});
// Fallback to direct OpenAI if Hoody AI fails
if (!response.ok && response.status >= 500) {
response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.OPENAI_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(req.body)
});
}
// Fallback to Anthropic if OpenAI fails
if (!response.ok && response.status >= 500) {
response = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'x-api-key': process.env.ANTHROPIC_KEY,
'anthropic-version': '2023-06-01',
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: req.body.model.replace('anthropic/', ''),
max_tokens: req.body.max_tokens || 1024,
messages: req.body.messages
})
});
}
return res.json(await response.json());

Resilience: Automatic failover across providers. Zero downtime.

AI generates code, you automatically add explanations:

// @mode worker
const response = await fetch('https://ai.hoody.icu/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer container-1',
'Content-Type': 'application/json'
},
body: JSON.stringify(req.body)
});
const data = await response.json();
let content = data.choices[0].message.content;
// Detect code blocks
if (content.includes('```')) {
// Ask another AI to explain the code
const explanation = await fetch('https://ai.hoody.icu/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer container-1',
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'anthropic/claude-haiku-4.0', // Cheap model for simple task
messages: [{
role: 'user',
content: `Explain this code in simple terms:\n${content}`
}]
})
});
const explainData = await explanation.json();
// Append explanation
content += '\n\n**How this works:**\n' + explainData.choices[0].message.content;
data.choices[0].message.content = content;
}
return data;

Cool integration: Get instant notifications on your phone/desktop about AI activity using hoody-notifications:

// @mode worker
const response = await fetch('https://ai.hoody.icu/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer container-1',
'Content-Type': 'application/json'
},
body: JSON.stringify(req.body)
});
const data = await response.json();
// Detect significant events
const aiResponse = data.choices[0].message.content;
const isCodeGeneration = aiResponse.includes('```') && aiResponse.length > 500;
const isError = data.error || data.choices[0].finish_reason === 'error';
if (isCodeGeneration) {
// Notify about large code generation
await fetch('https://your-project-container-n-1.node-us.containers.hoody.icu/api/notify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
title: '🤖 AI Generated Code',
message: `AI just wrote ${aiResponse.length} characters of code`,
priority: 'normal',
icon: 'code'
})
});
}
if (isError) {
// Alert about AI errors
await fetch('https://your-project-container-n-1.node-us.containers.hoody.icu/api/notify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
title: '⚠️ AI Request Failed',
message: data.error?.message || 'Unknown error',
priority: 'high',
icon: 'warning'
})
});
}
// Track token usage and alert on threshold
if (data.usage?.total_tokens > 50000) {
await fetch('https://your-project-container-n-1.node-us.containers.hoody.icu/api/notify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
title: '💰 High Token Usage',
message: `Request used ${data.usage.total_tokens} tokens`,
priority: 'normal'
})
});
}
return res.json(data);

Real-world scenarios:

  • Get notified when AI generates large amounts of code
  • Alert on AI errors or rate limits
  • Track high token usage in real-time
  • Monitor AI agent activity from your phone
  • Know immediately when critical operations complete

The power: Your entire AI infrastructure sends alerts to your real devices. Stay informed without actively monitoring.

Store all AI interactions in a database using Bun’s built-in SQLite and /hoody/databases/ for automatic safety:

// @mode worker
// Use Bun's built-in sqlite3 (no npm install needed with Bun)
const { Database } = require('bun:sqlite');
// Database in /hoody/databases/ = automatic concurrent-write safety
// Thanks to SQLite Drive FUSE mount - prevents corruption from concurrent writes
const db = new Database('/hoody/databases/ai-history.db');
// Create table on first run
if (!shared.initialized) {
db.run(`
CREATE TABLE IF NOT EXISTS prompts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp TEXT NOT NULL,
container TEXT,
model TEXT,
prompt TEXT,
response TEXT,
tokens INTEGER,
cost REAL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`);
db.run('CREATE INDEX IF NOT EXISTS idx_timestamp ON prompts(timestamp DESC)');
db.run('CREATE INDEX IF NOT EXISTS idx_model ON prompts(model)');
db.run('CREATE INDEX IF NOT EXISTS idx_container ON prompts(container)');
shared.initialized = true;
}
// Make AI request
const response = await fetch('https://ai.hoody.icu/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer container-1',
'Content-Type': 'application/json'
},
body: JSON.stringify(req.body)
});
const data = await response.json();
// Store complete interaction in database (concurrent-write safe)
db.run(`
INSERT INTO prompts (timestamp, container, model, prompt, response, tokens, cost)
VALUES (?, ?, ?, ?, ?, ?, ?)
`, [
new Date().toISOString(),
metadata.subdomain || 'default',
req.body.model,
req.body.messages[req.body.messages.length - 1].content,
data.choices[0].message.content,
data.usage?.total_tokens || 0,
(data.usage?.total_tokens || 0) * 0.000003 // Example cost calc
]);
return res.json(data);

Why /hoody/databases/ is critical here:

  • Multiple containers can log simultaneously without corruption
  • AI agents making parallel requests all write safely
  • FUSE mount coordinates writes automatically
  • Zero locking errors even under heavy concurrent load

See: SQLite Drive for full details on concurrent-write safety.

Query your AI history:

Terminal window
# View recent prompts
bun -e 'const db = require("bun:sqlite").Database("/hoody/databases/ai-history.db");
console.log(db.query("SELECT model, prompt, tokens FROM prompts ORDER BY created_at DESC LIMIT 10").all())'
# Total tokens used per model
bun -e 'const db = require("bun:sqlite").Database("/hoody/databases/ai-history.db");
console.log(db.query("SELECT model, SUM(tokens) as total FROM prompts GROUP BY model").all())'
# Most expensive queries
bun -e 'const db = require("bun:sqlite").Database("/hoody/databases/ai-history.db");
console.log(db.query("SELECT prompt, cost FROM prompts ORDER BY cost DESC LIMIT 5").all())'
# Usage by container
bun -e 'const db = require("bun:sqlite").Database("/hoody/databases/ai-history.db");
console.log(db.query("SELECT container, COUNT(*) as requests, SUM(tokens) as tokens FROM prompts GROUP BY container").all())'

Use cases:

  • Audit trails - Complete record of all AI interactions
  • Cost analytics - Track spending by model, container, time period
  • Pattern analysis - Identify frequently repeated prompts for caching
  • Debugging - Review exact prompts/responses when issues occur
  • Compliance - Maintain detailed logs for regulatory requirements
  • RAG data - Use your prompt history as training data for fine-tuning

Critical freedom: It’s YOUR infrastructure. Route to whoever you want.

// @mode worker
// Route to OpenAI directly
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.OPENAI_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(req.body)
});
return res.json(await response.json());
// Or use any other provider:
// - Anthropic directly
// - Together AI
// - Your own self-hosted models (Ollama, LM Studio)
// - Multiple providers with custom routing logic

You decide:

  • Which provider for which tasks
  • When to use Hoody AI vs your own keys
  • How to distribute load
  • Where costs should go

The only rule: It’s HTTP. Route however you want.


Let AI generate entire applications, but with guardrails:

// Sandbox all AI file operations
if (call.function.name === 'write_file') {
args.path = '/sandbox' + args.path;
}
// Block dangerous commands
if (call.function.name === 'execute_command') {
if (args.command.match(/rm -rf|sudo|chmod 777/)) {
return blocked();
}
}

Each customer gets MITM’d AI access:

const customer = getCustomerFromContainer(metadata.subdomain);
// Customer-specific quota enforcement
if (customer.tokensUsedToday > customer.quota) {
return res.status(429).json({ error: 'Quota exceeded' });
}
// Customer-specific model restrictions
if (!customer.allowedModels.includes(req.body.model)) {
req.body.model = customer.defaultModel;
}

Different MITM rules per environment:

// Development: Log everything, use cheap models
if (metadata.execId === 'dev') {
console.log('Request:', req.body);
req.body.model = 'anthropic/claude-haiku-4.0';
}
// Production: Route to best model, alert on errors
if (metadata.execId === 'prod') {
req.body.model = 'anthropic/claude-opus-4.1';
// monitorForErrors() implementation
}

Don’t try to do everything in one script. Chain multiple MITM proxies:

App → MITM Layer 1 (logging) → MITM Layer 2 (caching) → MITM Layer 3 (model routing) → Hoody AI

Each layer does one thing well. Composable intelligence.

Store caches, approval requests, logs in hoody-sqlite:

// Persistent cache across restarts
await fetch('https://your-project-container-sqlite-1.node-us.containers.hoody.icu/api/v1/sqlite/kv/batch/set', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
items: [{ key: cacheKey, value: aiResponse }]
})
});

Your MITM proxy adds latency. Measure it:

const start = Date.now();
const response = await fetch('https://ai.hoody.icu/api/v1/chat/completions', { /* ... */ });
const latency = Date.now() - start;
if (latency > 1000) {
console.warn('MITM proxy slow:', latency, 'ms');
}

Day 1: Just log requests
Day 2: Add caching
Day 3: Add model routing
Day 4: Add human approval for high-stakes
Day 5: Add agent cascade

Build incrementally. Each layer adds value.


Problem: Requests bypass your proxy

Solution: Ensure apps point to your hoody-exec endpoint:

https://your-project-container-exec-1.node-us.containers.hoody.icu/api/v1
NOT: https://ai.hoody.icu/api/v1

Problem: Modifications to tool_calls don’t take effect

Solution: Return the modified data BEFORE the tool executes:

// ✅ Correct: Modify in response, before tool execution
data.choices[0].message.tool_calls = modified;
return res.json(data);
// ❌ Wrong: Trying to modify after execution

Problem: Cached responses are stale

Solution: Add cache invalidation:

const cacheKey = `${model}:${JSON.stringify(messages)}:${Math.floor(Date.now() / 3600000)}`;
// Key changes every hour, auto-invalidates

Problem: Stalled requests timeout before human responds

Solution: Increase timeout or implement webhook callback:

// Webhook approach (better):
// 1. Store request
// 2. Send notification with callback URL
// 3. Return immediately with "pending" status
// 4. Human approves via webhook
// 5. Agent polls or receives event

You don’t have to write a proxy to intercept AI. The hoody-agent (hoody-workspaces) ships with a declarative rule engine that lets you observe, modify, and control every AI interaction — without writing a single line of JavaScript.

The hoody-exec approach above is powerful when you need full programmatic control. But most MITM use cases — prompt guardrails, cost tracking, safety alerts, context injection — follow a pattern. Define an event, specify a filter, pick an action. That pattern is now a first-class JSON configuration.

The rule engine runs inside hoody-agent itself. It hooks directly into the session lifecycle. No proxy. No URL change. No latency. Rules fire at the exact moment an event occurs — synchronously for in-flight modifications, asynchronously for notifications and logging.


Every AI interaction passes through a pipeline of 7 event types, split into two categories:

Async events — fire after the fact, cannot modify anything:

EventWhen It Fires
session.createdA new AI session starts
session.idleSession transitions from busy to idle (task complete)
session.errorSession encounters an error

Sync events — fire in real-time, can modify in-flight data:

EventWhen It Fires
chat.messageA message is sent or received
tool.execute.beforeRight before a tool executes (bash, write, read, etc.)
tool.execute.afterRight after a tool finishes executing
chat.system.transformSystem prompt is being assembled (you can rewrite it)

This is not a simplified abstraction. These hooks run at the same level as the AI engine itself. When a chat.system.transform rule appends to the system prompt, that modification is what the LLM actually sees. When a tool.execute.before rule fires, the tool has not executed yet — you can alert, log, or inject context before it does.


Each rule triggers exactly one action:

ActionWhat It Does
shellExecute a shell command with full MITM context as environment variables ($MITM_SESSION_ID, $MITM_TOOL_NAME, $MITM_TOOL_INPUT, etc.)
webhookSend an HTTP POST/GET to any URL with structured event data (session, tool, tags, timestamp)
notificationPush a notification to the session — visible in hoody-agent’s UI, forwardable to phone/watch/browser via hoody-notifications
messageInject a message into the AI session (the agent sees it as if the user said it)
prompt-injectModify the system prompt or user message — prepend or append content before the LLM processes it

Shell actions receive the full context as environment variables: MITM_SESSION_ID, MITM_SESSION_TITLE, MITM_TAGS, MITM_EVENT, MITM_DIRECTORY, MITM_PROJECT_ID, MITM_TOOL_NAME, MITM_TOOL_INPUT, MITM_TOOL_OUTPUT, MITM_MESSAGE_ROLE, MITM_MESSAGE_CONTENT, MITM_ERROR_MESSAGE. Your script can read any of them.

Webhook actions automatically serialize the event context as JSON: { event, sessionID, sessionTitle, tags, directory, timestamp, toolName, messageRole }. Point it at Slack, PagerDuty, your own API — anything that accepts HTTP.


Rules don’t have to fire on everything. Each rule can be scoped with precision:

FilterWhat It Does
TagsOnly fire for sessions with specific tags (e.g., prod, dev, experimental)
Tool nameOnly fire for a specific tool (bash, write, read, glob, etc.)
RoleOnly fire for user or assistant messages
Content matchRegex pattern tested against message content (e.g., deploy.*prod)
CooldownMinimum milliseconds between firings per session — prevents rapid re-triggering
EnabledToggle rules on/off without deleting them

Tags are set per-session. When you create a session in hoody-agent’s UI or via the API, you assign tags like prod, dev, or api-mode. Rules filter against those tags. A rule with tags: ["prod"] never fires on a dev session. A rule with no tags fires on everything.


Rules live under the mitm key in your hoody.json, hoody.jsonc, or .hoody.json config file (any config file hoody-agent reads). You can also manage them through the Settings > MITM Rules panel in hoody-agent’s web UI — add, edit, toggle, and test rules visually.

The schema is straightforward:

{
"mitm": {
"tags": [
{ "id": "prod", "label": "Production", "color": "red" },
{ "id": "dev", "label": "Development", "color": "blue" },
{ "id": "api-mode", "label": "API Mode", "color": "purple" }
],
"rules": [
{
"id": "rule-1",
"name": "My Rule",
"enabled": true,
"description": "What this rule does",
"trigger": {
"event": "chat.message",
"tags": ["prod"],
"toolName": "bash",
"role": "user",
"contentMatch": "deploy.*prod"
},
"action": {
"type": "webhook",
"url": "https://hooks.slack.com/...",
"method": "POST"
},
"cooldownMs": 5000
}
]
}
}

Every field in trigger except event is optional. An empty tags array means “all sessions.” An omitted toolName means “all tools.” You layer filters to narrow scope as much or as little as you need.


These are copy-paste ready. Drop them into your mitm.rules array and they work.

A safety guardrail that appends a critical instruction to every system prompt — but only for production sessions. The LLM sees this instruction on every single request.

The agent literally cannot avoid this instruction. It is part of the system prompt. Every response, every tool call, every decision passes through this guardrail. No amount of prompt engineering by the AI can override it — because it is injected after the prompt is assembled.

Track every tool call across all sessions. This webhook fires after every tool execution, sending the session ID, tool name, and event details to your cost tracking endpoint. Know exactly which agents are burning through your budget.

The webhook body automatically includes { event, sessionID, sessionTitle, tags, directory, timestamp, toolName }. No custom serialization needed. Point it at any analytics endpoint and start aggregating.

3. Human-in-the-Loop for Production Deploys

Section titled “3. Human-in-the-Loop for Production Deploys”

When the AI mentions deploying to production — in any message, from any session tagged prod — you get a notification on your phone. The regex catches variations like “deploy to prod,” “production push,” “pushing to production,” etc.

The 30-second cooldown prevents notification spam if the conversation keeps referencing production deployments. You get one alert, you check it, you decide.

For sessions tagged api-mode, prepend a strict formatting instruction to the system prompt. The AI will respond in structured JSON — every time, without reminders.

This is how you turn a general-purpose AI agent into a structured API backend. Tag a session as api-mode, and the system prompt is automatically rewritten. No code changes to your application.

When any session hits an error — any session, regardless of tags — fire a webhook to your incident tracking system. PagerDuty, Slack, Opsgenie, a custom endpoint, whatever accepts HTTP.

Empty tags array means all sessions. The 10-second cooldown prevents a single flapping session from flooding your incident system. The webhook payload includes the error message in the event context.

6. Inject Context Based on What the Agent Is Doing

Section titled “6. Inject Context Based on What the Agent Is Doing”

When the agent is about to run a bash command in a dev session, append infrastructure context to the user message. The agent knows where PostgreSQL and Redis are without you telling it every time.

The 60-second cooldown is key here. You don’t want this context injected before every single bash command — just once per minute at most. The agent gets the reminder when it needs it, without being spammed.

Every time the agent reads a file, log it. This shell action appends the tool input (which includes the file path) to an access log. Full audit trail of every file the AI touched.

The shell command has access to $MITM_SESSION_ID, $MITM_TOOL_INPUT, $MITM_TOOL_OUTPUT, $MITM_TOOL_NAME, $MITM_DIRECTORY, and every other context variable. Write to a log, pipe to jq, post to an API with curl — your shell, your rules.


Between the hoody-exec proxy approach (earlier in this page) and the built-in rule engine, you have two complementary systems:

Capabilityhoody-exec ProxyRule Engine
SetupWrite JavaScript, deploy as exec script, change AI URLAdd JSON to config file or use Settings UI
LatencyAdds network hop (proxy is a separate process)Zero — runs inside hoody-agent’s process
FlexibilityUnlimited — full programmatic controlStructured — 7 events, 5 actions, declarative filters
Best forCustom caching, model routing, response transformation, multi-tenant quotasGuardrails, monitoring, alerts, context injection, audit logs
Requires codeYes (JavaScript)No (JSON configuration)

Use the rule engine for the 80% of cases that follow a pattern. Use hoody-exec for the 20% that need full programmatic control. Use both together when you need guardrails AND custom logic.

This is what happens when AI is just HTTP. Every request, every response, every tool call, every system prompt — observable, modifiable, controllable. Per agent, per session, per tool call, per message. No other platform gives you this level of introspection into AI behavior, because no other platform built AI as an HTTP-native service from day one.


Start MITM’ing: