Quick Start Guide
Get up and running with MegaClaw v1.0 in under 5 minutes. Connect your first service and execute your first task via UI, REST API, Webhook, or MCP Server.
Prerequisites
Before you begin, make sure you have:
- ✓ A MegaClaw account (contact your Super Admin)
- ✓ Your tenant URL (e.g.
drx.megaclaw.de) - ✓ Your API key if using REST (format:
mc_xxxx)
✨ New tenant? Start here
Open the ✨ Start tab beside the workflow list. Four questions, and the result is a workflow that runs — with your own services and variables already filled in.
1 · What do you want to automate? 🔔 Alert me when something breaks 📊 Send me a regular report 🔄 Copy things between two systems 🔗 React to something outside ───────────────────────────────── 🤖 Or describe it in your own words
Then: where the data comes from, where the result goes, and when it runs. Each goal produces a different shape:
| Goal | Steps produced |
|---|---|
| 🔔 Alert | read · filter · count · condition · dedup · notify · all-clear branch |
| 📊 Report | read · export as Excel · send with the file named |
| 🔄 Sync | read · split · count · condition · loop · dedup · create · end |
| 🔗 React | read the payload · act · stop (answer sent to caller) |
parallel: 1 (a burst of writes hits the target system's rate limit).No services connected yet? The builder does not stop. It offers to connect one there and then, or continues with a placeholder step so the shape is visible and what is missing is obvious.
Not one of the four shapes? Choose Or describe it in your own words — this hands over to the AI builder.
Step 1 — Log in & explore
- 1
Open your tenant URL
Navigate to your company's MegaClaw URL and log in with your username and password. Ask us for demo access if you want to try it before setting up your own tenant.
- 2
Choose your language
MegaClaw supports English 🇬🇧, German 🇩🇪, Arabic 🇸🇦, and French 🇫🇷 — select from the top navigation bar.
- 3
Go to Integrations or Service Catalog
Click Integrations in the sidebar. Or open Service Catalog for pre-built integrations — connect in 30 seconds with zero tokens.
Step 2 — Add an integration
Option A: Use Service Catalog (Recommended) — Pre-built integrations, no AI generation needed:
Open Service Catalog → Search for "Proxmox" → Click Connect → Enter credentials → Done in 30 seconds
Option B: Describe with AI — Click + New Integration and describe what you want to connect:
Connect to Proxmox VE API using API Token authentication Host: 192.168.1.50 Port: 8006 Node: pve
Step 3 — Run a task
Select your integration from the list, choose a task, and hit Run ▶. Or use REST API, Webhook, or MCP Server:
# Run node_status on Proxmox curl https://api.megaclaw.de/task/run \ -X POST \ -H "X-API-Key: mc_your_key" \ -H "Content-Type: application/json" \ -d '{"service_id":1,"task_id":"node_status","inputs":{}}'
# Same endpoint works from n8n, Zapier, Make, or any HTTP client POST https://api.megaclaw.de/webhook/trigger Header: X-API-Key: mc_your_key Body: {"service_id":1,"task_id":"node_status","inputs":{}}
# Configure Claude Desktop with: { "mcpServers": { "megaclaw": { "url": "https://mcp.megaclaw.de/mcp", "headers": { "X-API-Key": "mc_your_key" } } } } # Then ask Claude: "Show me Proxmox node status"
What's next?
→ Explore all new features (AI Providers, RAG Chat, Webhook, Audit Logs)
→ Full API Reference
→ Browse available integrations
→ Pricing & token system
Major Updates. Live Today.
Multi-AI Provider Support, Service Catalog, RAG Chat, Webhook, Audit Logs, and Flexible Scheduler.
🤖 Multi-AI Provider Support
You now choose your AI engine — MegaClaw supports 4 providers:
📦 Service Catalog
A curated library of pre-built integrations — ready to connect in seconds. No AI generation needed. No tokens consumed. Done in under 30 seconds.
💬 RAG Chat
Most AI chatbots answer general questions. MegaClaw RAG Chat answers questions about YOUR systems. It reads your connected integrations in real time, then suggests exactly what to run — and executes it on your approval.
🧠 RAG AI Agent
Stop searching through documents manually. Start asking questions — and getting real answers. Transform your documents into an intelligent knowledge base.
⚡ How it works:
✅ What makes it different:
- 🤖 Works with Claude, OpenRouter, Ollama, or Azure — your choice
- 🔒 100% self-hosted — your data never leaves your infrastructure
- 🏢 Multi-tenant architecture — each client has isolated data
- 🎯 No hallucinations — AI answers only from YOUR documents
- 📊 Tested on specialized medical & legal documents — accuracy is impressive
- 🆔 UUID accumulation — never overwrites old data, complete history
📚 Document Search
Upload files under Settings → Documents. After that, the chat can answer from them and a workflow step can query them.
Search is by meaning, across languages. A question asked in German finds the answer in an Arabic document that says the same thing — relevant in a product whose users write in three languages.
📚 Documents 🕐 contract.docx waiting ⏳ handbook.pdf 24 / 42 passages ▓▓▓▓▓▓░░░░ 🛑 📄 nc-5218337.pdf 2 passages · 126 KB 🗑️ Documents 2 · Passages 60 · 2.4 MB
Supported formats: PDF, DOCX, TXT, MD. A scanned PDF has no text layer and is rejected with that reason rather than indexed as empty.
Background indexing
The upload returns immediately. Indexing runs in the background — closing the browser, navigating away, or signing out does not interrupt it. Only restarting the scheduler does, and a document caught by that is marked failed with the reason rather than left hanging.
Embedding runs at roughly two seconds per passage on a CPU-only host. A hundred-page document is around 500 passages — twenty minutes of work.
| State | Meaning |
|---|---|
| 🕐 waiting | Uploaded, not started — the scheduler picks it up within 20 seconds |
| ⏳ processing | Being embedded, with a passage count and a progress bar |
| 📄 ready | Searchable |
One document at a time. Two embedding at once would compete for the same Ollama host and finish later than doing them in turn.
The 🛑 button: while waiting, the document is removed immediately. While indexing, the scheduler notices between batches — it stops within about twenty seconds. Cancelling removes the document entirely; there is no half-indexed state left behind.
Limits: 10 MB per file. The file bytes are dropped after indexing finishes — what remains is the text and its vectors. A document that fails keeps its error message and can be deleted; it does not retry on its own.
The rag_query step
{"step": 3, "type": "rag_query", "name": "Ask the handbook", "inputs": {"question": "{{step2.output}}", "top_k": "5", "mode": "answer"}}
| Input | Description |
|---|---|
question | What to ask — references work |
mode | answer for a written answer with sources, chunks for the raw passages |
top_k | How many passages to retrieve (default 5, max 20) |
document_id | Restrict to one document (optional) |
Use answer when the workflow should report what the documents say. Use chunks when a later AI step will summarise or compare the text.
Every answer carries its sources — an answer without a source cannot be checked, so the step always returns both:
Employees are entitled to 30 working days of paid annual leave. 📄 hr_handbook.pdf · page 4 📄 hr_handbook.pdf · page 12
When the documents do not answer
The documents do not answer this. Closest sources: 📄 hr_handbook.pdf · page 7
A similarity score alone is not reliable — an unrelated question scored 0.53 against an invoice in testing. The model is asked to say explicitly when the excerpts do not contain the answer. A workflow that alerts on "the documents do not answer this" is more useful than one that passes a fabricated answer downstream.
Indexing settings — per tenant
Ollama URL http://192.168.1.50:11434 API Key •••• Model bge-m3 dim 1024 [🔌 Test connection] [💾 Save]
These start empty, and uploading is disabled until they are set. A default pointing at MegaClaw's own Ollama would quietly send an on-premise customer's documents to a host they did not choose. Each tenant names their own.
Test connection checks three things at once — the host answers, the model is pulled, and the vector dimension it returns. That last one is why any model works, not just the listed ones: the dimension is measured rather than assumed.
✅ bge-m3 · 1024 dimensions ❌ Model 'xyz' is not on that host. Pull it first: ollama pull xyz
We use bge-m3 because it handles Arabic, German and English in one vector space. Once documents are indexed, the model cannot be changed until every document is deleted — vectors from two different models cannot be compared, and switching silently would return results that look fine and are meaningless.
🔗 Webhook Support (n8n Integration)
One endpoint. Unlimited automation. Trigger any MegaClaw task directly from n8n, Zapier, Make, or any HTTP client.
{ "service_id": 1, "task_id": "node_status", "inputs": {} }
{ "success": true, "output": "CPU: 4.47% · RAM: 61.6%" }
📥 Incoming Webhooks
Until now, reacting to an outside event meant polling: schedule a workflow every 30 minutes, ask ServiceNow whether anything new arrived, act if so. That is 48 calls a day, most finding nothing, and up to 30 minutes of delay.
An incoming webhook inverts it. ServiceNow calls MegaClaw the moment a ticket is created, hands over the ticket, and gets the result back. Triggers are for things that happen; schedules are for things that repeat.
1 · Run a workflow and get its result
curl -X POST 'https://api.megaclaw.de/webhook/workflow/run' \ -H 'X-API-Key: mc_your_key' \ -H 'Content-Type: application/json' \ -d '{"workflow_id": 102, "inputs": {"ticket_id": "INC0012345", "priority": "High"}}'
{ "success": true, "status": "success", "workflow_id": 102, "workflow_name": "Halo PSA → ServiceNow Ticket Sync", "run_id": 592, "output": "Created: INC0010134", "steps_count": 6, "duration_sec": 4.2 }
output is the workflow's own answer — the stop message when it ends with one, otherwise the last successful step's output.
| Parameter | Default | Behaviour |
|---|---|---|
?verbose=true | off | Adds a steps array with every step's name, status, output and error. |
?timeout=60 | 60 s | Maximum 300 s. If the workflow is still running when the timeout passes, returns 202 with the run_id; the result is in the run log. |
2 · A secret URL per workflow
curl -X POST 'https://api.megaclaw.de/hook/wh_...' \ -H 'Content-Type: application/json' \ -d '{"ticket_id": "INC0012345", "priority": "1"}'
No API key. Create the URL in the workflow's 🔗 Webhook panel. The tenant API key runs any workflow and can read or delete every integration — that is far more access than a single trigger needs. A secret URL runs that one workflow and nothing else. Rotating the secret from the same panel invalidates the old URL immediately.
Whatever JSON is posted arrives in the workflow as {{step0.output}}:
{"step": 1, "type": "transform", "transform_type": "json_extract", "inputs": {"source": "{{step0.output}}", "path": "ticket_id"}}
3 · Signature verification
The secret stops someone guessing the URL. It does not stop someone who has seen it — in a proxy log, an error report, a screenshot — from replaying the call. Turn on 🔏 Require a signature in the same panel.
# Compute and send the signature BODY='{"ticket_id":"INC0012345"}' SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | cut -d' ' -f2) curl -X POST "$HOOK_URL" \ -H 'Content-Type: application/json' \ -H "X-MegaClaw-Signature: sha256=$SIG" \ -d "$BODY"
import hmac, hashlib, json, requests body = json.dumps({"ticket_id": "INC0012345"}).encode() sig = hmac.new(SECRET.encode(), body, hashlib.sha256).hexdigest() requests.post(HOOK_URL, data=body, headers={ "Content-Type": "application/json", "X-MegaClaw-Signature": f"sha256={sig}", })
| Request | Response |
|---|---|
| Valid signature | 200 with the result |
| No signature | 401 |
| Valid signature, body changed | 401 — the signature covers the content, not just access |
X-Hub-Signature-256 and X-Signature-256 are also accepted, so GitHub webhooks work without changes.4 · Limits and error codes
| Code | Meaning |
|---|---|
| 200 | Ran successfully, result in the body |
| 202 | Still running past the timeout — run_id returned, result in the run log |
| 401 | Signature missing or wrong |
| 404 | No such hook, or the workflow is inactive — a wrong secret, a disabled workflow and a deleted one all return 404 so a guesser learns nothing |
| 429 | Over 60 calls per minute per workflow |
5 · Worked example — ServiceNow to MegaClaw
- In MegaClaw, open the workflow's 🔗 Webhook panel and create a secret URL.
- In ServiceNow, add a Business Rule on insert for the incident table that POSTs the new record to that URL.
- Step 1 of the workflow reads
{{step0.output}}and extracts the fields it needs. - The workflow runs and ends with a
stopstep whose message becomes theoutputin the response. - ServiceNow gets the answer back in the same call — in seconds, not up to 30 minutes.
📋 Audit Logs
Every action. Every user. Every timestamp. Nothing happens on MegaClaw without being recorded.
🔐 Security
- Login & Logout
- Password changes
- Role changes
- User activation/deactivation
⚡ Operations
- Connect service
- Delete integration
- Run task (with result & duration)
- Failed events filter
⏰ Scheduling
- Scheduled task added
- Scheduled task executed
- Schedule modified/deleted
⏰ Flexible Scheduler
Schedule tasks the way you need:
API Reference
Full REST API + Webhook + MCP Server documentation. Base URL: https://api.megaclaw.de · Webhook: /webhook/trigger · MCP: https://mcp.megaclaw.de/mcp
Authentication
All requests must include your API key in the X-API-Key header.
X-API-Key: mc_your_api_key_here
drx cannot access data from sva.Rate Limits
Endpoints
Returns all connected services for the authenticated tenant.
Execute a task on a connected service. AI generates and runs the code automatically.
curl https://api.megaclaw.de/task/run -X POST -H "X-API-Key: mc_xxxx" -d '{"service_id":1,"task_id":"node_status"}'
Run a workflow by ID and get its result back in the same call. Accepts workflow_id, inputs, optional ?verbose=true and ?timeout (default 60 s, max 300 s). Returns 202 if still running past timeout.
Run one workflow using its secret URL — no API key required. Create the URL in the workflow's Webhook panel. Supports optional HMAC-SHA256 signature via X-MegaClaw-Signature.
Continue a run paused at a wait step. The request body becomes the step's output. Single-use — a second call returns 409.
Webhook endpoint for n8n, Zapier, Make, or any HTTP client. Same payload as /task/run.
Get audit logs for your tenant (admin only). Filter by action type, date range, and user.
Check current token balance for the authenticated tenant.
Get transaction history for token usage and recharge events.
Step 1 of the AI pipeline. Analyze a natural language request and get an execution plan.
Health check. Returns platform status and version. No auth required.
MCP Server Endpoint
Model Context Protocol endpoint for Claude Desktop, Claude Code, and MCP-compatible AI clients.
{ "mcpServers": { "megaclaw": { "url": "https://mcp.megaclaw.de/mcp", "headers": { "X-API-Key": "mc_your_api_key" } } } }
Error Codes
| Status | Meaning |
|---|---|
| 401 | Missing X-API-Key header |
| 403 | Invalid or inactive API key |
| 404 | Service or session not found |
| 429 | Rate limit exceeded (60/min per key or 100/min per IP) |
| 402 | Insufficient tokens — recharge required |
| 500 | Internal execution error |
Integrations Guide
Connect MegaClaw to your existing services. Each integration is added once and reused for unlimited tasks. All credentials are encrypted with AES-256.
🖥️ Proxmox VE
Manage VMs, containers, storage, and nodes via the Proxmox REST API with API Token authentication.
Required credentials
| Field | Description |
|---|---|
| proxmox_host | IP of your Proxmox node |
| proxmox_port | Always 8006 |
| api_token_id | Format: user@realm!tokenname |
| api_token_secret | Token secret UUID |
| node | Node name e.g. pve |
Available tasks
| task_id | Description |
|---|---|
| node_status | CPU, RAM, disk, uptime |
| list_vms | List all virtual machines |
| list_containers | List all LXC containers |
| start_vm / stop_vm | Start or stop a VM by VMID |
| restart_vm | Restart a VM |
| clone_vm | Clone a VM to new VMID |
| snapshot_vm | Create a snapshot |
| list_storage | List storage pools |
| next_vmid | Get next available VMID |
🔵 SAP BTP / HANA
Connect to SAP BTP APIs, SAP HANA on-premise via Cloud Connector, and SAP S/4HANA OData services.
🟣 Odoo
Read and write any Odoo model over the external API — CRM, sales, invoicing, inventory, projects, HR, Helpdesk, and custom modules built for a single customer. Authentication is an Odoo API key, not a password.
Required credentials
| Field | Description |
|---|---|
url | Your Odoo URL, e.g. https://mycompany.odoo.com |
username | The Odoo login (email) |
api_key | Odoo → Preferences → Account Security → New API Key |
database | Optional. Leave empty on *.odoo.com — taken from the URL |
The API key replaces the password everywhere and can be revoked on its own, which a password cannot.
Three layers of access
Most integrations give you a fixed list of actions. A fixed list cannot cover an ERP where every customer has different models.
| Layer | What it gives you |
|---|---|
| 1 · Discovery | list_models and describe_model read the model and field definitions out of the live instance. A custom model built for one customer is queryable without anyone writing an integration for it first. |
| 2 · Generic model access | Search, count, read, create, update, delete and call any method, on any model. This is the whole API surface, not a subset. |
| 3 · Business tasks | The common operations as one-click tasks, so nobody has to type a model name to list their invoices. |
Available tasks
Discovery
| task_id | Description |
|---|---|
check_connection | Server version, database, user, and which Odoo apps are installed |
list_models | List available models, including custom ones |
describe_model | Field names, types, required flags and allowed values for any model |
Generic model access
| task_id | Description |
|---|---|
search_records | Search any model with an Odoo domain, fields, order, limit, offset |
count_records | Count records matching a domain |
get_record | Read one record by id |
create_record | Create a record in any model |
update_record | Update one or more records |
delete_record | Delete records |
call_method | Call any model method, e.g. action_confirm, action_post |
run_query | Model, domain, fields and limit. Superseded by search_records, kept so workflows built before it keep running |
Customers & CRM
| task_id | Description |
|---|---|
list_customers | List customers and contacts |
create_customer | Create a customer with address, VAT number and country |
update_customer | Update a customer's contact details |
list_leads | List CRM leads and opportunities |
create_lead | Create a lead with expected revenue |
Sales
| task_id | Description |
|---|---|
list_sales_orders | List orders by state, customer or date |
create_sales_order | Create an order with line items |
confirm_sales_order | Confirm an order |
Invoicing
| task_id | Description |
|---|---|
list_invoices | List invoices by state, payment state, customer or date |
create_invoice | Create a draft invoice with line items |
post_invoice | Post an invoice and assign its number |
get_invoice_pdf | Retrieve a stored invoice PDF |
Products & inventory
| task_id | Description |
|---|---|
list_products | List products by name or internal reference |
create_product | Create a product or a service |
get_stock | Internal stock per product and location |
Projects & timesheets
| task_id | Description |
|---|---|
list_projects | List projects |
list_project_tasks | List tasks by project, stage or assignee |
create_project_task | Create a task with deadline and assignee |
list_timesheets | Logged hours by date, employee or project, with the total |
People & support
| task_id | Description |
|---|---|
list_employees | List employees by name or department |
list_tickets | List Helpdesk tickets |
create_ticket | Create a Helpdesk ticket |
Purchasing
| task_id | Description |
|---|---|
list_purchase_orders | List purchase orders by state, vendor or date |
Good to know
- Odoo's external API needs a Custom plan. Odoo does not expose the external API on One App Free or Standard plans. On those plans no integration can connect — this is an Odoo licensing decision, not a MegaClaw limitation. Check the plan before planning the integration.
get_invoice_pdfreads a PDF that already exists. Odoo API keys are scoped to the API only, so generating a new PDF needs a password login. Printing or emailing the invoice once from Odoo stores the PDF, and the task reads it over the API from then on.- Tasks follow the installed apps. Helpdesk is Odoo Enterprise only, and timesheet and purchasing tasks need those apps installed. When an app is missing, the task says which app it is instead of returning an error code.
- Tested on Odoo 20. The integration reads field definitions from the live instance rather than assuming a version, which is how it adapts to differences between releases — but 16 to 19 are not yet verified.
Odoo has scheduled removal of its JSON-RPC API for Online 21.1 and self-hosted Odoo 22. The replacement JSON-2 interface is already mapped.
🔄 n8n
Trigger and manage n8n workflows. List, execute, and monitor workflow status via REST API or Webhook.
🐘 PostgreSQL
Execute SQL queries, manage tables, and retrieve data from PostgreSQL databases.
🔒 SSH / Shell
Execute shell commands on remote Linux servers via SSH. Supports password and key-based auth.
🔍 LinkUp Search
Real-time web search. Returns structured results with titles, URLs, and summaries.
🎫 ServiceNow
Manage incidents, problems, change requests, and CMDB via natural language.
📋 Atlassian / Jira
Manage Jira issues and Confluence pages using natural language.
💬 Slack
Send messages, create channels, and manage Slack notifications directly from MegaClaw.
🗄️ Qdrant Vector DB
Perform semantic search, manage collections, and query vectors for AI-powered RAG applications.
🔐 OAuth2 Connect — One Click
Connect any OAuth2 service in one click. No server configuration. No IT tickets. Customers connect themselves.
Supported out of the box:
How it works:
- 1
Settings → Connected Services
Customer opens settings and clicks "Connect New Service"
- 2
Enter Client ID + Secret
Credentials are stored encrypted with AES-256, per-tenant isolated
- 3
Click Connect
Browser OAuth2 login — customer approves access
- 4
Token saved — auto-refreshed forever
MegaClaw handles token refresh automatically. Always authenticated.
Then just type:
→ "Show my Google Calendar for today" → "List my GitHub repos" → "Send a Slack message to #general" → "Create a new email draft in Gmail"
Why this matters:
Every enterprise SaaS supports OAuth2. That means MegaClaw can now connect to virtually any business tool in existence — controlled entirely by the customer, without touching the server. This is self-service enterprise integration.
⏰ Task Scheduler
Run any task or workflow on a schedule. Eleven built-in frequency options, each with timezone support.
| Format | Description |
|---|---|
every_5m / every_15m / every_30m | Short intervals — health checks, sync jobs |
hourly / every_2h / every_6h / every_12h | Medium intervals |
daily@09:30 | Once a day at a fixed time |
weekly@fri@17:00 | One or more days per week |
monthly@1@08:00 | Day 1–28 (short months never skip) |
cron:0 9 * * 1-5 | Full cron expression |
Set the timezone per workflow — Europe/Berlin stays correct through daylight saving changes. Schedules are created from the workflow settings panel, not from the API.
🆔 Task IDs
Every task in MegaClaw has a stable task_id string. Use it in the REST API, Webhook, and MCP to run a specific task without relying on its display name.
curl -X POST https://api.megaclaw.de/task/run \ -H "X-API-Key: mc_your_key" \ -H "Content-Type: application/json" \ -d '{"service_id": 1, "task_id": "node_status", "inputs": {"node": "pve"}}'
Task IDs are listed in the Service Catalog beside each task. They are stable across updates — the display name may change, the ID does not.
📧 Notifications Setup
MegaClaw sends notifications through the services you already have connected — no separate notification provider to configure.
| Channel | How to enable | Used for |
|---|---|---|
| Slack | Connect Slack → set {{tenant.slack_channel}} | Workflow alerts, task results |
| Connect an SMTP or OAuth2 mail service | Reports, summaries, error alerts | |
| Webhook | POST to any URL — n8n, Zapier, Teams | External systems, chat bots |
| Discord | Connect Discord integration → channel webhook | Dev team alerts |
Notifications are workflow steps — a send_message or send_email task at the end of a run. The stop message of a workflow is always recorded in the run log regardless of whether a notification step is present.
🦙 AI Providers
Every tenant chooses its AI engine independently. The choice affects token cost, privacy, and latency — it does not change how workflows are built.
| Provider | Models | Token cost | Notes |
|---|---|---|---|
| Claude (included) | Haiku · Sonnet · Opus | From MegaClaw balance | Default. No setup required. |
| Ollama | Llama 3, Mistral, Phi-3, any GGUF | Zero | Runs on your own hardware. Fully private. |
| OpenRouter | 200+ models | Billed to your key | BYOK — no tokens deducted from balance. |
| Azure OpenAI | GPT-4o, GPT-4, GPT-3.5 | Billed to your key | BYOK — enterprise Microsoft infrastructure. |
Switch provider under Settings → AI Provider. The change takes effect on the next task run. Existing workflows do not need to be edited.
💡 Use Cases
A selection of what MegaClaw customers automate today. Each maps to a ready-made template — open Workflow → Templates, fill in the tenant variables, and the workflow runs.
| Use case | Services | Trigger |
|---|---|---|
| Alert on stopped Proxmox containers | Proxmox + Slack | every_30m |
| ServiceNow → Jira ticket sync | ServiceNow + Atlassian | every_30m |
| Weekly Jira report to Slack | Atlassian + Slack | weekly@mon@08:00 |
| Morning agenda from Google Calendar | Google Calendar + Slack | daily@07:00 |
| New GitHub issues → Discord | GitHub + Discord | every_30m |
| Airtable nightly backup | Airtable + file export | daily@02:00 |
| Website health check + alert | URL Health Check + Slack | every_15m |
| Daily payment summary | Stripe + Email | daily@09:00 |
| SAP BTP incident escalation | SAP + ServiceNow + Slack | Incoming webhook |
| RAG Q&A over connected systems | Qdrant + any AI provider | On demand via chat |
Full Automation Engine
Build complex automations with zero code. AI-native at every step. Competes with n8n and Zapier.
① Visual Workflow Builder
Build complex automations with zero code. Drag, drop, connect — no technical knowledge required.
② Full Control Flow
if/else on every step
auto-stop when conditions fail
reshape data between steps
wait before continuing
define and reuse values
iterate over full lists
halt at the right moment
fail gracefully with retry
📦 Batch Step — Many Items in One Call
{"step": 2, "type": "batch", "name": "In fifties", "inputs": {"source": "{{step1.output}}", "size": "50"}}, {"step": 3, "type": "http_request", "inputs": {"method": "POST", "url": "https://api.example.com/bulk", "body": "{{batch_items}}"}}, {"step": 4, "type": "batch_end", "inputs": {}}
The steps between batch and batch_end run once per slice, not once per item.
| Step | Hands the inner steps | 1000 items becomes |
|---|---|---|
loop | One item | 1000 calls |
batch | A slice of items | 20 calls |
It is not only about speed. Many APIs refuse a thousand requests on a rate limit and accept twenty without complaint — so batching is sometimes the difference between a workflow that works and one that does not.
Use batch when the target takes several records at once: a bulk endpoint, a database insert, a code step that works on a group. Use loop when each item needs its own call — which is most services. Telegram, Slack and Jira all take one message or one issue per request.
What is available inside
| Variable | Value |
|---|---|
{{batch_items}} | The slice as one JSON array — what a bulk endpoint wants |
{{batch_lines}} | The same slice, one item per line |
{{batch_index}} · {{batch_total}} · {{batch_size}} | Where you are |
{{batch_items}} is one value, passed whole to whatever takes it. It is not a list to iterate inside the block.After batch_end:
{{step2.count}} how many items in total
{{step2.batches}} how many calls were made
{{step2.results.0}} the output of the first batchNo item limit by default
batch has no item limit by default; loop caps at 10. A loop makes one call per item, so an unbounded list means an unbounded bill. A batch exists to move everything in few calls — capping it would defeat the point. An overall cap is still available as an optional field.
Limits
- A batch cannot contain a loop or another batch.
- Slice size runs from 1 to 1000; 50 is a reasonable default for most bulk endpoints.
- Every step's per-run limits apply as normal, counted across the batches.
🐍 Code Step — a Python Snippet
{"step": 3, "type": "code", "name": "Open ticket ids", "inputs": {"source": "{{step2.output}}", "code": "result = [x['id'] for x in data if x['status'] == 'open']"}}
Two names are all there is to learn:
| Name | Meaning |
|---|---|
data | The source — parsed from JSON when it is JSON, otherwise the text |
result | Whatever you assign becomes the step's output |
MegaClaw has 22 transforms, and each exists because someone hit a case the others did not cover. The code step is for the next such case: grouping rows, arithmetic across a list, reshaping nested JSON, joining two lists on a key. When a transform fits, use the transform — it reads at a glance and needs no explanation.
It runs in an isolated container with no network at all. Ten-second limit, 256 MB. Available modules: json, re, math, datetime, collections, itertools, statistics, hashlib, base64, urllib.parse, random.
http_request or a service step first, then feed its output into the code step.print() goes to the server log, not the output. Only result becomes {{stepN.output}}. Assign a list or a dict and it comes out as formatted JSON, so the next step can read it.Variables resolve inside the snippet, so {{tenant.company_name}} works in the code itself.
🔍 Compare Step — What Changed Since the Last Run
{"step": 2, "type": "compare", "name": "What changed", "inputs": {"current": "{{step1.output}}", "key": "id", "state_key": "vms"}}
{"first_run": false, "added": [{"id": "vm-104", "status": "running"}], "removed": [{"id": "vm-101", "status": "running"}], "changed": [{"key": "vm-102", "was": {...}, "now": {...}}], "unchanged": 12, "total": 14, "any_change": true}
| Input | Meaning |
|---|---|
key | The field that identifies an item — id, vmid, number |
state_key | A stable name for this comparison |
Without a key, additions and disappearances are still caught; changes are not, because nothing says two versions of a row are the same row. Plain text works as well — one item per line, keyed on the line itself — so it reads what a task prints without a transform in between.
To act on it:
{"step": 3, "type": "condition", "condition": "{{step2.output}} contains \"any_change\": true"}
compare vs dedup_gate
| Step | Answers |
|---|---|
dedup_gate | "Have I already sent this?" — it stops a repeat |
compare | "What is different from last time?" — it names what changed |
A container that was running and has disappeared from the list is invisible to dedup_gate. Nothing arrived to be a duplicate of. compare is the only way to see it, and a disappearance is usually the thing worth knowing.
Two behaviours worth knowing
The first run is quiet. It stores the snapshot and returns first_run: true with nothing added. Reporting every item as new on the first run would alert about a hundred servers that were always there.
Snapshots older than 90 days are dropped.
⏸️ Wait Step — Pause Until Something Outside Answers
{"step": 4, "type": "wait", "name": "Wait for the customer to approve", "inputs": {"timeout_hours": "48", "on_timeout": "fail"}}
The run stops there. The log shows the URL that releases it:
⏸️ Waiting for /resume/wt_...
curl -X POST 'https://api.megaclaw.de/resume/wt_...' \ -H 'Content-Type: application/json' \ -d '{"approved": true, "note": "go ahead"}'
Whatever that call sends becomes the step's output, so the rest of the workflow reads {{step4.output}} like any other step. The steps before the pause are not re-run — they may have created a ticket or sent a message, and doing it twice would be worse than not resuming at all.
Resume URL vs hook URL
| URL | What it does |
|---|---|
| A hook URL | Starts a workflow — same URL every time |
| A resume URL | Continues one paused run — issued for that run, used once |
When the answer never comes
| on_timeout | Behaviour |
|---|---|
fail | Stop the run — the default |
continue | Carry on with no output from this step |
goto_step | Take a different route |
Timeouts run to a maximum of 168 hours — a week. A run parked indefinitely is a row nobody will look at again, and a week is long enough for an approval that goes through a holiday.
The expiry is not passive. The scheduler notices it and resumes the run so the on_timeout route is actually taken; otherwise the escalation branch would never fire. The scheduler sweeps on its own cycle, so a timeout takes effect within a couple of minutes of the deadline, not at the second.
What it is good for
An approval that lives in another system. The workflow posts to a ticketing tool or a chat, then waits. Whoever approves there triggers the resume URL, and the workflow continues with their decision as its input.
A long-running job elsewhere. Kick off a build, a report, a data export; wait; the other system calls back when it is done, and the workflow carries on with the result.
In both cases the alternative is polling every few minutes. A callback is faster and cheaper.
wait is not delay. delay waits a fixed time and continues on its own. wait waits for an event that may never come — which is why it has a timeout and three ways out. A dry run does not pause: it shows what would happen and moves on.Approval by button
The wait step can send its own approval link. The link opens a page with two buttons, so nobody has to run curl.
{"step": 2, "type": "wait", "name": "Wait for the client", "inputs": { "timeout_hours": "48", "on_timeout": "goto_step", "goto_step": "6", "description": "Restart the server {{tenant.proxmox_node}}?", "notify_service_id": "31", "notify_inputs": "{\"chat_id\": \"{{tenant.telegram_chat}}\"}", "notify_message": "A request is waiting for your approval:" }}
The approver receives a message with a link. Opening it shows:
Your approval is needed ┌────────────────────────────────┐ │ Restart the server pve? │ └────────────────────────────────┘ [ Approve ] [ Decline ] Please answer within 47 hours.
Pressing a button sends {"approved": true} or {"approved": false}. That becomes {{step2.output}}, so the workflow branches on it exactly as it would on a curl call.
Why the step sends the link itself
The token does not exist until the run reaches the wait step. A message written in an earlier step would carry an empty link. So the wait step creates the token, then sends.
If the message fails to send — wrong chat id, service down — the run still pauses. The link is in the run log and can be passed on by hand. Failing the step would throw it away.
Why a page and not a link that approves
Telegram, WhatsApp and mail clients fetch a URL before anyone taps it, to build the preview. If opening the link approved, the preview would approve. The decision would be made by software, seconds after the message was sent, and nobody would notice.
So opening the link only shows the choice. The buttons post the decision. It is the same reason a bank never puts "confirm transfer" behind a plain link.
The description field
"description": "Restart the server {{tenant.proxmox_node}}?"
Shown on the page. Without it the approver sees a step name and two buttons, which is not enough to decide on. Variables resolve, so the page can name the thing being acted on.
After the decision
The paused run closes as resumed — not success, not failure. The work continues in a new run that starts at the wait step. The steps before it are not repeated.
| Link state | Response |
|---|---|
| Already used | 409 — a page saying "already answered" |
| Past its deadline | 410 — a page saying it has expired |
Cancelling
A run waiting for an answer appears in the running list with a ⏸️ and a stop button. Cancelling closes the run and voids the link, so a late click cannot resume something that no longer exists.
The orphan cleanup deliberately leaves waiting runs alone — a wait is meant to last. Cancelling is the way to end one that will never be answered.
Delivery goes through whichever service the step names, with the same caveats as any other step. The run pauses either way.
③ AI Agent inside every Workflow
Every step can use Claude, OpenRouter, Ollama, or Azure. The AI reads the previous step's output and acts on it intelligently.
Step 1: HTTP Request → Fetch weather data Step 2: AI Agent (Claude) → "Write a professional Arabic weather report" Step 3: Telegram → Send the report
④ Real Example — Running Today
Set cities → Loop Damascus, Berlin, Paris → Fetch weather for each → Claude writes a professional Arabic report → Telegram delivers it → Every morning at 8AM automatically ☀️
⑤ Import / Export JSON
Share workflows across tenants in one file. The AI Chat builds the JSON for you — just ask.
⑥ Professional Run Logs
- Real duration — see exactly how long each run took
- Filter by status — success, failed, running
- Export CSV — download logs for analysis
- Delete old runs — keep your log clean
⑦ Retry + Timeout per step
The platform retries failed API calls automatically. Configure timeout per step for fine-grained control.
⑧ Incoming Call Log
A tab beside the run logs: 🔗 Incoming calls. Every call that arrived from outside — from a secret URL or through the API — with its status, timing, caller address, and what came back.
✅ 200: 12 🔏 401: 3 🚫 429: 0 ❌ 5xx: 1
🟢 200 · Halo PSA → ServiceNow · 🔗 hook · 9s · 12,510ms
IP 2.208.88.47 · run 596 · sig ✅
🔏 401 · Halo PSA → ServiceNow · 🔗 hook · 2m · 0ms
signature does not match
🔏 401 · Halo PSA → ServiceNow · 🔗 hook · 3m · 0ms
signature header missingA call rejected for a bad signature or over the rate limit creates no run — it left no trace anywhere until now. The run log showed nothing because nothing ran. These are exactly the calls worth seeing. Each entry expands to show the caller's address, the run id, whether the signature checked out, and the full response.
⑨ Version History
Every workflow keeps its last 20 versions. One is saved automatically before each edit — no button to press, nothing to remember.
🕓 History (7)
v7 · 12 steps · before edit
5m ago · alaa · every_30m [🔍 Diff] [↩️]
v6 · 11 steps · before restoring v4
2h ago · alaa [🔍 Diff] [↩️]Diff compares any version with the current one in words, not step numbers:
~ 1. Read payload: renamed ~ 2. Check: condition changed ~ 3. Notify: error handling changed + 4. Export added − 5. Old notify removed
Restore takes one click and a confirmation. Restoring saves the current state as a new version first, so nothing is lost in either direction:
v2 before edit ← you edited v3 before restoring v2 ← you went back, edit was kept v4 before edit ← you edited again v5 before restoring v4 ← you went back again
⑩ Workflow Suggestions
A 💡 panel on each workflow, built from that workflow's own run log.
💡 Suggestions (2) Based on this workflow's own run log over 14 days. Nothing is applied until you say so. 🔴 Step 2 failed 4 times out of 4 S02 always fails — HTTP 404 GET https://httpstat.us/503 → carry on instead of stopping the run [👁️ Preview] [✅ Apply] [✖️ Dismiss] 🔴 Scheduled and sends, with no dedup gate Runs ~336 times a week - a problem that lasts all day alerts on every single run. → add a dedup gate with a one-hour window before the send step
Nothing is applied automatically. Apply loads the change into the editor; saving is still a separate act. A workflow that edits itself is one nobody can reason about afterwards — and the version history means even a saved change can be undone.
What it looks at
| Finding | Reads |
|---|---|
| A step that keeps failing | The run log's per-step status and error |
| A schedule that fires far more often than it acts | Run count against the schedule |
| One step taking most of the token spend | The cost records |
| Scheduled and sending with no dedup gate | The workflow itself |
These are rules, not a model guessing. "This step failed 4 times out of 4" is counting, and it gives the same answer every time.
The fix depends on why the step failed
Slack API rate limit exceeded → retry 3 times, 30 seconds apart channel_not_found → carry on instead of stopping
A rate limit or a timeout will probably succeed on a second attempt. A wrong channel id will not — retrying a permanent failure only fails slower, three times over, and holds the run open while it does.
Preview before applying
Preview shows the change in the same words the version history uses:
~ 2. Post to Slack: retry 3x / 30s + 5. Not more than hourly added
Some findings point at something the panel cannot change — a schedule, a caching setting. Those say so plainly instead of offering an Apply button that would do nothing.
Advanced Workflow Features
Everything that shipped in the last three months and is live on the platform. All of it is available on every plan.
1 · Tenant & System Variables
Write a value once in Settings and use it anywhere in a workflow. A workflow that works for one tenant works for all of them — only the variables differ.
{"inputs": { "channel": "{{tenant.slack_channel}}", "message": "{{tenant.company_name}} report for {{system.today}}" }}
Two kinds, deliberately separate:
| Kind | Set by | Examples |
|---|---|---|
{{tenant.x}} | Tenant, under Settings → Tenant Variables. Any name of lowercase letters, digits and underscores. | sap_mandant, escalation_threshold, report_footer |
{{system.x}} | Platform — always available. | today, now, time, year, month, day, timestamp, tenant, user_id, run_id, workflow |
Variables work in step inputs, conditions, filenames, with filters ({{tenant.project | lower}}), in scheduled runs, single task runs, through the REST API, MCP, and inside the chat.
{{tenant.channel}} to Slack while the run reported success.2 · on_error — What Happens When a Step Fails
Every step has an on_error field. The default is stop. Change it when you need a different behaviour.
{ "step": 4, "type": "service", "task_id": "create_issue", "on_error": {"action": "set_and_continue", "value": "0"} }
| action | Behaviour |
|---|---|
stop | Default. Stops the run and marks it failed. |
continue | Logs the failure and carries on. The step has no output. |
set_and_continue | The given value becomes the step's output. Later steps read it normally. |
goto_step | Jumps to a different step number — for a real alternative route. |
continue and set_and_continue: continue leaves the step with no output, so a later step reading {{step4.output}} also fails. set_and_continue hands it a usable value.goto_step is for a real alternative route — "if Jira is unreachable, open it in ServiceNow instead". A backward jump is capped at three, otherwise a workflow that jumps back to an earlier step loops until the step limit. The value field accepts references: {{"value": "{{tenant.default_owner}}"}}
3 · File Export
Any step's output becomes a downloadable file. The file appears as a download button in the run results.
{ "step": 6, "type": "export_file", "inputs": { "source": "{{step4.output}}", "format": "xlsx", "filename": "incidents-{{system.today}}.xlsx", "title": "Open incidents" } }
| Format | Notes |
|---|---|
csv | UTF-8 with BOM so Excel reads it correctly. |
xlsx | Bold frozen header row, columns sized to content. |
pdf | Landscape, repeating header, cells wrap. |
json | Raw JSON, formatted. |
The step understands three input shapes and picks columns accordingly: a JSON array of objects (keys become headers), numbered pipe-separated lines (1. INC0010080 | High CPU | New — each pipe is a column), or plain lines (one column).
{{stepN.output}} of an export step is the filename, so a later step can reference it: "Report ready: {{step6.output}}".4 · Flexible Scheduling
Eleven schedule forms, each with a timezone:
every_5m every_15m every_30m
hourly every_2h every_6h every_12h
daily@09:30
weekly@fri@17:00
weekly@mon,wed,fri@09:00
monthly@1@08:00 # 1–28 only — short months never skip
cron:0 9 * * 1-5The timezone is chosen per workflow — Europe/Berlin runs at 09:30 local time, including through daylight saving changes.
5 · Parallel Loops
Run loop iterations concurrently instead of one at a time.
{ "step": 3, "type": "loop", "inputs": { "source": "{{step2.output}}", "limit": "20", "parallel": "5" } }
Items run in chunks of up to 10. Output preserves list order regardless of which finished first. Each item gets an isolated context — no leakage of {{stepN.output}} between iterations.
parallel: 1 — a burst of ticket creations hits the target system's rate limit.6 · Sub-workflows
Call one workflow from inside another. The child's steps fold into the parent's log rather than appearing as a separate run.
{ "step": 4, "type": "sub_workflow", "inputs": { "workflow_id": "142", "inputs": "{{step3.output}}", "fail_on_child_error": "true" } }
The payload arrives as {{step0.output}} in the child. Recursion is guarded (A→B→A is detected) and depth is capped at three. The child inherits the parent's remaining budget, not a fresh one.
7 · Dry Run
A third button beside ▶ Run and 🧪 Test. Use it before enabling a schedule on an imported template.
| Step type | Dry run behaviour |
|---|---|
Read steps (list_*, get_*, search_*, GET requests, transforms, conditions) | Execute for real. |
| Write steps (create, update, delete, POST/PATCH/DELETE requests, notifications) | Simulated. Resolved inputs are shown so a wrong reference is visible before it reaches a live system. |
8 · Resume a Failed Run
When a run fails at step 12 of 20, the log offers Resume from step 12 beside Run from start.
set_variable steps before the resume point are re-executed so the context is intact. Skipped steps lose their outputs — the UI says so explicitly.9 · Workflow Health Page
A tab beside the run logs. The key item is the middle one.
- Counts for the last 24 hours — running, succeeded, failed, waiting, cancelled
- Scheduled workflows that are not running as expected — the window is derived from the schedule itself, so an hourly workflow silent for three hours is flagged while a weekly one is not
- Every workflow with its last run, last status and 7-day success rate
10 · Ready-made Templates
Ten workflows that run after filling in the matching variables. Each uses tenant variables for service addresses and values, so it works for any tenant with the right variables defined.
| Template | Default schedule |
|---|---|
| 🩺 Website health check | every 15 minutes |
| 🔔 Proxmox — stopped containers | every 30 minutes |
| 📰 RSS news — no duplicates | daily 08:00 |
| 🔄 ServiceNow → Jira sync | every 30 minutes |
| 📊 Weekly Jira report | Monday 08:00 |
| 💳 Daily payment summary | daily 09:00 |
| 🗂️ Airtable nightly backup | daily 02:00 |
| 🔍 New GitHub issues → Discord | every 30 minutes |
| 📅 Morning agenda | daily 07:00 |
| 🧹 Weekly infrastructure report | Friday 16:00 |
11 · In-Editor Guidance
Three warnings appear while a step is being edited. A summary appears above the builder before saving. Each covers a mistake that produces a workflow which saves, runs, and reports success while being wrong — which is why the warning comes from the editor, not the engine.
While editing a step
⚠️ The previous step returns a JSON array, which is one line - so count_lines answers 1 however many items there are. Use "Count items". ⚠️ Not defined: nope — this step will fail. Add it under Settings. ⚠️ Read by: 6. W06 reads step 5 — with "carry on" this step has no output, so those fail too. Use "use a value and carry on" instead.
Before saving
⚠️ 3 things worth checking • Scheduled and sends, with no dedup gate - a problem that lasts all day will alert on every single run. • A loop at parallel=5 contains a write step - a burst of creates hits the other system's rate limit. Use 1 for writes. • Reference to a step that does not exist: step99 Not errors - the workflow saves and runs. But each of these took a debugging session to find.
These do not block saving and are not validation errors. They are the things that cost someone an afternoon, surfaced at the moment they can still be avoided.
12 · Transforms and Filters
Transform reference for the workflow engine. count and keep_pattern were already in the engine — both are now reachable from the editor's transform list.
count vs count_lines
The single most confusing pair in the product:
| Transform | Counts |
|---|---|
count_lines | Lines in a block of text |
count | Items in a list, however it is formatted |
split_lines returns a JSON array — which is one line. Following it with count_lines answers 1 every time, the condition passes, and an alert says "1 container stopped" when five are. Use count after split_lines.
split_lines — keep_pattern and skip_pattern
{"transform_type": "split_lines", "inputs": {"source": "{{step1.output}}", "keep_pattern": "stopped|failed"}}
keep_pattern keeps only matching lines; skip_pattern drops them. Prefer keep_pattern for filtering — "only the stopped ones" is harder to get backwards than "skip everything that is running". If both are set, keep runs first and skip removes from what is left.
| Transform | What it does | Note |
|---|---|---|
count | Returns how many items regardless of input shape — JSON array elements, rows inside a results/items/data wrapper, or non-empty lines. | Use after split_lines, not count_lines. |
split_lines | Accepts keep_pattern and skip_pattern. keep_pattern keeps only matching lines; if both are set, keep runs first. | Recommend keep_pattern for filters. |
regex_extract_all | Matches line by line. ^ and $ anchor per line. . does not cross a line break. .*stopped.* returns only lines containing "stopped". |
12 · Verified Integrations
Twenty-four integrations are now tested end to end against live systems, not just defined. Each carries a verified badge with the date it was tested. The service catalogue holds 275 services in total.
Newly verified:
| Integration | Tasks |
|---|---|
| Discord | 7 |
| Airtable | 8 |
| Stripe | 10 |
| GitLab | 7 |
| Notion | 7 |
| Atlassian (Jira + Confluence) | 18 |
| Google Calendar | 4 |
| Google Tasks | 5 |
| LinkUp | 3 |
| RSS Feed | 5 |
| Web Scraper | 5 |
| URL Health Check | 5 |
| Odoo | 34 |
Plans, Tokens & Administration
MegaClaw uses a token-based model. Each AI task execution consumes tokens based on complexity. Bring Your Own Key (BYOK): Zero token deduction when using your own API key.
Plans
- 100,000 tokens/month
- Up to 5 integrations
- REST API + MCP + Webhook
- All AI providers + BYOK
- Service Catalog access
- RAG Chat
- Audit Logs (7 days)
- 500,000 tokens/month
- Up to 15 integrations
- REST API + MCP + Webhook
- All AI providers + BYOK
- Full Service Catalog
- RAG Chat + suggestions
- Audit Logs (30 days)
- Token dashboard
- 1,000,000 tokens/month
- Unlimited integrations
- REST API + MCP + Webhook
- All AI providers + BYOK
- Full Service Catalog
- RAG Chat + smart suggestions
- Audit Logs (90 days)
- Proxmox & SAP support
- Priority support
- Email + Telegram alerts
- Unlimited tokens
- Unlimited integrations
- Dedicated infrastructure
- On-premise deployment
- Custom integrations
- Unlimited audit log retention
- SLA + dedicated support
- Ollama private AI included
Token consumption
Tokens are consumed on each AI task execution. Viewing integrations or listing services is free.
Token Dashboard
Real-time usage tracking available in the Admin Panel:
- 📊 Current token balance
- 📈 Transaction history with timestamps
- 📧 Low-balance email alerts (automatically sent at 20%, 10%, and 5%)
- ✅ Recharge confirmation emails
API Key Management
Super Admins and Admins can manage API keys from the UI:
- 🔑 View all tenant API keys
- 🔄 Revoke compromised keys
- ✨ Generate new API keys
- 📝 Audit logging for key actions
Role-Based Access Control
MegaClaw supports four roles with granular permissions:
| Role | Permissions |
|---|---|
| Superadmin | Full system access, manage tenants, add tokens, view all data |
| Admin | Manage integrations, API keys, users within tenant |
| User | Execute tasks, view integrations, personal settings |
| Demo | Read-only access, cannot modify integrations or execute tasks |
🔐 Account Security
Three protections. The first applies to everyone, the second is opt-in per user, the third is for whoever runs the platform.
Sign-in attempt limiting
Five failed attempts, then a fifteen-minute pause.
Attempts are counted by username and by address separately. Limiting only the username would let an attacker lock a real person out of their own account. Limiting only the address would let attempts spread across many addresses walk straight past the cap.
A correct password clears the count. Someone who mistyped four times last month is not one slip away from being locked out today.
Two-factor authentication (TOTP)
Settings → 🔐 Two-factor authentication → Set it up [QR code] → scan with an authenticator app enter the code → eight backup codes
Any standard TOTP authenticator app works.
Optional, and deliberately so. Making it compulsory for a customer's staff turns a security feature into a reason not to adopt the product. It is offered to every user and recommended for admin accounts, where the setup is suggested with a prompt.
For the platform operator
The superadmin account — the one that creates tenants and grants tokens — supports two-factor as well, and the sign-in page shows a notice while it is off.
The superadmin password is stored as a hash and changed from the security page. It is not held in a configuration file.
Managing tokens (Admin)
Super Admins can add tokens from the Admin Panel:
Super Admin → Manage Tenants → Select Company → Add Tokens → Enter amount + plan → Save Token history records: amount, plan, added_by, timestamp System automatically sends: - Confirmation email to tenant admin - Low-balance alerts when threshold reached
💰 Cost Tracking
A 💰 Cost tab beside the workflow list. Where the tokens went, and what they cost. The balance could already say a tenant had used 15 million tokens — it could not say which workflow spent them. That is the question this answers.
💰 Cost — last 30 days
Calls 6 Tokens 37,156 Cost $0.05
≈ €0.05
By workflow
Proxmox CPU Incident — Detect, Remediate 6 calls 37,156 $0.05
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
restart_container: 23,807 · create_incident: 6,962 · container_status: 6,387The per-task breakdown is what makes it usable. In the example above, one task accounts for 64% of the spend. At the workflow level that is invisible — the workflow simply looks expensive.
What gets recorded
Every token spend now carries the work it belongs to:
| Field | Value |
|---|---|
| Workflow & run | Which workflow, which run |
| Task & service | Which step inside it |
| Provider & model | claude / ollama / openrouter, and which model |
| Cost | Computed at the time of use |
Pricing
Cost is estimated from Anthropic's published prices. The model matters more than most people expect — the same request costs five times as much on Opus as on Sonnet. MegaClaw picks a model by the complexity of the request, and this tab is where that choice becomes visible.
| Model | Input | Output |
|---|---|---|
| Opus | $15 / M tokens | $75 / M tokens |
| Sonnet | $3 / M tokens | $15 / M tokens |
| Haiku | $1 / M tokens | $5 / M tokens |
Ollama and BYOK count as zero — this is correct, not missing data:
- Ollama runs on the tenant's own hardware. There is no per-call cost to record.
- BYOK — a tenant's own Anthropic, OpenRouter or Azure key — is billed by that provider directly. MegaClaw never sees that invoice and does not estimate it.
The tab labels the figure as an estimate and shows zero where appropriate, with a note explaining why.
Two uses worth knowing
Finding the expensive step. A workflow that regenerates its code each run costs far more than one whose code is cached. The per-task numbers show which is which.
Answering "what does this cost me". Before this, a tenant on the included Claude key could see a balance going down and nothing else.
Tenant Limits
The platform already documents per-workflow limits (max_steps, max_seconds, max_tokens) — those cap a single run. Tenant limits cap everything the tenant does.
| Caps | Set in | |
|---|---|---|
| Workflow limits | a single run | the workflow's own settings |
| Tenant limits | everything the tenant does | Settings → Tenant Limits |
Five numbers under Settings → Tenant Limits (admin only). Current usage is shown beneath each field — set numbers against what the tenant actually does, not a guess.
Runs / hour 120 Runs / day 2,000 Active workflows 50 Tokens / day 500,000 Export storage 100 MB
Zero means no limit — every field starts at zero, so nothing changes until a number is set.
Warn, or block
🛑 Block runs that exceed a limit [ ]
Off by default. A run over a limit proceeds and a line goes to the server log:
⚠️ [mcg] tenant quota reached — 150 runs in the last hour, limit 120 (warning only; enforcement is off)
On, the run fails immediately and names which limit it hit:
🛑 Tenant quota reached — 150 runs in the last hour, limit 120
FAQ
Can I buy tokens mid-month?
Yes. Contact your administrator or use the Super Admin panel. Unused tokens carry over.
What happens when tokens run out?
Task execution is paused. API calls return 402 Payment Required. Viewing services still works. Email alerts are sent automatically.
Is there a free trial?
New Starter accounts receive 1,000 tokens included. Contact megaclaw@swedan-it.de to get started.
How do I use MCP with Claude?
Add the MCP server configuration to Claude Desktop. See the API Reference for configuration details.
Can I run AI locally?
Yes! MegaClaw supports Ollama for private, local AI execution with zero token consumption.