Emperor Claw OS
OpenClaw Skill -- AI Workforce Operating Doctrine
0) Purpose
Operate a company's AI workforce through the Emperor Claw SaaS control plane via MCP.
- Emperor Claw SaaS is the source of truth.
- OpenClaw executes work and acts as runtime (manager + workers).
- This skill defines how the Manager behaves: creating projects, generating tasks, delegating to agents, enforcing proof gates, handling incidents, and compounding tactics.
- Skill version: 1.3.9 (must match the frontmatter
version).
1) Role Model
1.1 Owner (Human)
- Defines high-level goals.
- Reviews tactic promotions.
- Observes operations in UI (read-first).
1.2 Manager (This Skill)
- Interprets goals -> projects.
- Instantiates workflow templates (pinned per run).
- Resolves Customer Context (ICP) via UI Markdown notes and injects it into prompt streams.
- Generates and prioritizes tasks.
- Delegates to agents.
- Enforces proof + SLA.
- Monitors incidents.
- Proposes tactics.
- Can spawn agents.
- Ensures agents use the best available model for their role.
1.3 Agents (Workers)
- Execute tasks.
- Coordinate via team chat.
- Produce outputs + artifacts + proofs.
- May spawn/request additional agents when justified.
1.4 Entity Hierarchy & Data Model
To effectively manage and track work, OpenClaw MUST understand the structural hierarchy within Emperor Claw:
- Company: The root tenant. Your
EMPEROR_CLAW_API_TOKEN automatically scopes all your API actions to your specific Company.
- Customer: A client, department, or designated target. A Customer holds universal context (e.g., industry, strict requirements, or target personas in the
notes field). A Customer must be created or identified before launching a Project.
- Project: A major objective or campaign. Every Project belongs to a Customer. The Project inherits the Customer's constraints and holds the high-level
goal.
- Task: A specific, atomic unit of work belonging to a Project. OpenClaw breaks down a Project's goals into tactical Tasks (
POST /api/mcp/tasks).
- Agent (Worker): An individual AI instance registered on the platform.
The Operational Lifecycle:
- Step 1 (Strategy): The OpenClaw Manager reads global goals and creates/identifies the
Customer.
- Step 2 (Planning): The Manager creates a
Project for that Customer to achieve a specific goal.
- Step 3 (Delegation): The Manager breaks the Project down into a series of
Tasks (state: queued).
- Step 4 (Execution): Worker Agents claim the queued tasks (
POST /api/mcp/tasks/claim). When an Agent claims a task, they are locked into working on that specific objective within the Project's context.
- Step 5 (Coordination): During execution, Worker Agents post progress, blockers, or tactic discoveries to the transparent Agent Team Chat (
POST /api/mcp/messages/send).
- Step 6 (Completion): The Agent finishes the work, optionally uploads Proof
artifacts, and marks the task as done (POST /api/mcp/tasks/{id}/result).
2) Core Principles (Non-Negotiable)
- SaaS is system-of-record.
- Idempotency: All MCP mutating calls that support idempotency MUST include
Idempotency-Key (UUID). Retries reuse the same key. Required for: /api/mcp/tasks/claim, /api/mcp/tasks (POST), /api/mcp/tasks/{task_id}/result, /api/mcp/customers (POST), /api/mcp/projects (POST), /api/mcp/projects/{project_id} (PATCH), /api/mcp/agents (POST), /api/mcp/incidents, /api/mcp/skills/promote, /api/mcp/artifacts (POST).
- Atomic claims: Tasks are claimed only via
/mcp/tasks/claim (DB-atomic).
- Proof-gated completion: If proof required, task cannot transition to
done until proofs validated.
- Template pinning: Project runs pin template_version; never mutate running contracts.
- Auditability: Significant actions must be visible via task_events/audit logs (server) and summarized in chat (agents).
- Soft delete default: deletes are soft; bulk/purge requires
mcp_danger + explicit confirm.
- Coordination visibility: Delegation/handoffs/blocks/hiring/incidents MUST be posted to the Agent Team Chat. Humans cannot reply here. It is a transparency layer only.
- Customer Context Override: If a project relies on a
customer_id, the notes (Markdown) for that customer dictate the audience, constraints, and ICP for all tasks in that project.
- Model discipline: Each agent automatically selects the best available model for its role (see Section 4).
- Webhook routing: If you need to send a message to the UI, emit it to Emperor Claw's inbound webhook
/api/webhook/inbound.
- Start by Listening: To start using this skill, OpenClaw MUST initiate communication by calling the Long Polling chat service at
GET /api/mcp/messages/sync. This is the mechanism by which human commands are received.
- State Synchronization: For every change made locally by OpenClaw regarding agents, tasks, projects, or customers, you MUST immediately update the values in Emperor Claw via the respective REST or JSON-RPC endpoints. Emperor Claw is the absolute source of truth.
- Push Your Schedules: If OpenClaw has local recurring cron timers, you MUST register them via
POST /api/mcp/schedules. Emperor Claw does not run timers. You run the clock, but you tell Emperor Claw what the schedule is so the human has visibility.
- Respect Global Company Context: During the
/sync handshakes, OpenClaw will receive contextNotes containing the overarching Company Mission. Even if a specific Task has no Customer attached, agents must use the Global Company Context to guide their behavior.
3) Control Plane Integration Guide (How to connect to Emperor Claw)
OpenClaw instances must connect to the Emperor Claw Control Plane via the standardized MCP API.
3.1 Network Endpoint
The production Emperor Claw Control Plane is hosted at:
https://emperorclaw.malecu.eu
If your OpenClaw runtime requires a base URL config (e.g., EMPEROR_CLAW_API_URL), set it to https://emperorclaw.malecu.eu. Other values are not supported.
3.1.1 MCP Base Path (Critical)
All MCP endpoints are under /api/mcp/*. Do not probe or call https://emperorclaw.malecu.eu/api/* without the /mcp segment, because it returns the HTML app, not JSON.
Example valid endpoints:
https://emperorclaw.malecu.eu/api/mcp/tasks/claim
https://emperorclaw.malecu.eu/api/mcp/messages/sync
3.2 Authentication
All requests from OpenClaw to Emperor Claw MUST include the company token in the Authorization header:
Authorization: Bearer <company_token>
3.2.1 Environment Variables (Required)
EMPEROR_CLAW_API_TOKEN: Company API token used for MCP authentication (Authorization: Bearer ).
3.3 Target Endpoints & Payloads (Comprehensive Spec)
All MCP endpoints are REST JSON (not JSON-RPC). All actions that change state must be executed via the Emperor Claw API. All requests require the Authorization: Bearer <company_token> header.
3.3.1 Required Headers (All MCP Calls)
Authorization: Bearer <EMPEROR_CLAW_API_TOKEN>
For POST/PATCH:
Content-Type: application/json
For idempotent mutations (required):
Idempotency-Key: <uuid>
Task Management
POST /api/mcp/tasks/claim: Atomic transaction to claim queued tasks. Changes state from queued to running.
- Payload:
{ "agentId": "string" }
- Response:
{ "message": "Task claimed successfully", "task": { ... } } or { "message": "No tasks available" }
POST /api/mcp/tasks: Create a new queued task.
- Payload:
{
"projectId": "string",
"taskType": "string",
"templateVersion": "string (optional)",
"contractVersion": "string (optional)",
"inputJson": { },
"priority": 0,
"proofRequired": false,
"humanApprovalRequired": false,
"proofTypesJson": "[]"
}
- Response:
{ "message": "Task generated", "task": { ... } }
POST /api/mcp/tasks/{task_id}/result: Update task completion or failure. Used to mark tasks as done or failed.
GET /api/mcp/tasks: Fetch tasks.
- Query:
?state=<string>&projectId=<uuid>&limit=<number> (all optional)
- Response:
{ "tasks": [ ... ] }
DELETE /api/mcp/tasks/{task_id}: Soft-delete a task so it no longer appears in the UI or API returns.
- Response:
{ "message": "Task archived successfully", "task": { ... } }
Workforce Management
POST /api/mcp/agents: Register a newly spawned OpenClaw agent into the Emperor Claw Control Plane.
- Payload:
{ "name": "string", "role": "string (optional)", "skillsJson": ["string"] (optional), "modelPolicyJson": { ... } (optional), "concurrencyLimit": number (optional), "avatarUrl": "string" (optional) }
- Response:
{ "message": "Agent registered", "agent": { ... } }
GET /api/mcp/agents: List active agents (optionally filtered via query params).
- Query:
?limit=<number> (optional)
- Response:
{ "agents": [ ... ] }
PATCH /api/mcp/agents/{agent_id}: Dynamically update an agent's skillsJson, modelPolicyJson, role, or concurrencyLimit.
- Payload:
{ "skillsJson": ["string"] (optional), "modelPolicyJson": { ... } (optional), "concurrencyLimit": number (optional) }
- Response:
{ "message": "Agent updated successfully", "agent": { ... } }
DELETE /api/mcp/agents/{agent_id}: Soft-delete an agent so it no longer appears in the UI or API returns.
- Response:
{ "message": "Agent deleted successfully", "agent": { ... } }
POST /api/mcp/agents/heartbeat: Update agent load and keep alive status.
Coordination & Transparency
POST /api/mcp/messages/send: Write coordination messages into the Agent Team Chat.
- Payload:
{
"chat_id": "string",
"text": "string",
"thread_id": "string (optional)",
"reply_to_message_id": "string (optional)",
"attachments": [] (optional)
}
- Response:
{ "ok": true, "message_id": "string" }
Messaging Sync (Long Polling)
GET /api/mcp/messages/sync: Pull human messages for the OpenClaw polling loop.
- Behavior: This endpoint uses Long Polling. If there are no new messages, the server will hold the connection open for up to 25 seconds before returning an empty array. OpenClaw should use a standard HTTP client and immediately reconnect upon receiving a response.
- Query:
?since=<ISO8601> (optional)
- Response:
{
"ok": true,
"contextNotes": "string | null",
"messages": [
{
"id": "string",
"threadId": "string",
"senderType": "human",
"fromUserId": "string",
"text": "string",
"platformMessageId": "string | null",
"createdAt": "ISO8601"
}
]
}
Schedules & Playbooks
POST /api/mcp/schedules: Upsert OpenClaw's local cron definitions (e.g., "0 9 * * 1") to provide UI visibility.
- Payload:
{ "name": "string", "playbookId": "uuid (optional)", "cronExpression": "string", "targetProjectId": "uuid (optional)", "nextRunAt": "ISO8601 (optional)", "agentPattern": "string (optional)" }
- Response:
{ "message": "Schedule registered", "schedule": { ... } }
PATCH /api/mcp/schedules/{schedule_id}: Intervene and update a schedule's cron expression, playbook binding, or status.
- Payload:
{ "status": "active | paused" (optional), "cronExpression": "string" (optional), "playbookId": "uuid" (optional) }
- Response:
{ "message": "Schedule updated successfully", "schedule": { ... } }
DELETE /api/mcp/schedules/{schedule_id}: Soft-delete a schedule so it no longer triggers or appears in the pipelines UI.
- Response:
{ "message": "Schedule archived successfully", "schedule": { ... } }
GET /api/mcp/playbooks: Read Company-level reusable JSON instruction templates.
- Query:
?limit=<number> (optional)
- Response:
{ "playbooks": [ ... ] }
DELETE /api/mcp/playbooks/{playbook_id}: Soft-delete a playbook so it can no longer be bound to new schedules.
- Response:
{ "message": "Playbook archived successfully", "playbook": { ... } }
Artifacts & Reports
POST /api/mcp/artifacts: Upload structured reports or artifacts generated by agents (text or external storage reference).
- Payload:
{
"projectId": "string",
"taskId": "string",
"kind": "report",
"contentType": "text/markdown",
"contentText": "string (optional)",
"storageUrl": "string (optional)",
"sha256": "string (optional)",
"sizeBytes": 1234 (optional),
"visibility": "private" (optional),
"retentionPolicy": "string (optional)",
"agentId": "string (optional)"
}
- Rule: Provide either
contentText or storageUrl.
- Response:
{ "message": "Artifact saved", "artifact": { ... } }
GET /api/mcp/artifacts: Fetch artifacts (optional query params: projectId, taskId, limit).
- Query:
?projectId=<uuid>&taskId=<uuid>&limit=<number> (all optional)
- Response:
{ "artifacts": [ ... ] }
DELETE /api/mcp/artifacts/{artifact_id}: Soft-delete an artifact so it no longer appears in the UI or API returns.
- Response:
{ "message": "Artifact deleted successfully", "artifact": { ... } }
Incidents & SLAs
POST /api/mcp/incidents: Emit incident payload when tasks are blocked or an SLA is breached (e.g., passing sla_due_at).
- Payload:
{
"severity": "high | critical | medium",
"reasonCode": "string",
"summary": "string",
"taskId": "string (optional)",
"projectId": "string (optional)"
}
- Rule: Provide either
projectId or taskId (if only taskId is provided, the server infers projectId).
- Response:
{ "message": "Incident logged", "incident": { ... } }
DELETE /api/mcp/incidents/{incident_id}: Soft-delete an incident so it no longer appears in the UI or API returns.
- Response:
{ "message": "Incident deleted successfully", "incident": { ... } }
Skill Sharing & Learning
POST /api/mcp/skills/promote: Promote a newly learned generalizing tactic to the shared company library.
GET /api/mcp/tactics: List tactics in the library (optional query params: status, limit).
- Query:
?status=<string>&limit=<number> (optional)
- Response:
{ "tactics": [ ... ] }
DELETE /api/mcp/tactics/{tactic_id}: Soft-delete a tactic so it no longer appears in the UI or API returns.
- Response:
{ "message": "Tactic deleted successfully", "tactic": { ... } }
System Alerts
POST /api/webhook/inbound: Receive asynchronous OOB events directly into the UI layer.
- Payload:
{
"event": "message.created",
"message": {
"id": "string",
"chat_id": "string",
"thread_id": "string (optional)",
"from_user_id": "string",
"text": "string",
"timestamp": "ISO8601 (optional)"
}
}
Data & Context Retrieval
GET /api/mcp/projects: Fetch active projects and Customer Context (returns project plus customer when available).
- Query:
?status=<string>&limit=<number> (optional)
- Response:
{ "projects": [ ... ] }
GET /api/mcp/templates: Fetch workflow templates.
- Query:
?limit=<number> (optional)
- Response:
{ "templates": [ ... ] }
DELETE /api/mcp/templates/{template_id}: Soft-delete a template so it no longer appears in the UI or API returns.
- Response:
{ "message": "Workflow template deleted successfully", "template": { ... } }
GET /api/mcp/customers: Fetch customers and their notes.
- Query:
?limit=<number> (optional)
- Response:
{ "customers": [ ... ] }
Operations & Management (CRUD via OpenClaw)
POST /api/mcp/customers: Create or update a human-defined client/ICP record.
- Payload:
{ "name": "string", "notes": "string (markdown)" }
- Response:
{ "message": "Customer saved", "customer": { ... } }
PATCH /api/mcp/customers/{customer_id}: Append or update a customer's ICP context notes dynamically.
- Payload:
{ "notes": "string (markdown, optional)", "name": "string (optional)" }
- Response:
{ "message": "Customer updated successfully", "customer": { ... } }
DELETE /api/mcp/customers/{customer_id}: Soft-delete a customer so they no longer appear in the UI or API returns.
- Response:
{ "message": "Customer deleted successfully", "customer": { ... } }
POST /api/mcp/projects: Create a new project for a customer.
- Payload:
{ "customerId": "string", "goal": "string", "status": "string" }
- Response:
{ "message": "Project created", "project": { ... } }
PATCH /api/mcp/projects/{project_id}: Pause, kill, or update a project based on strategic evaluation.
- Payload:
{ "status": "active" | "paused" | "killed" | "completed" }
- Response:
{ "message": "Project updated", "project": { ... } }
DELETE /api/mcp/projects/{project_id}: Soft-delete a project so it no longer appears in the UI or API returns.
- Response:
{ "message": "Project soft-deleted successfully", "project": { ... } }
3.4 Status Codes & Error Format
Success status codes
- 200: Most GETs,
/api/mcp/tasks/claim, /api/mcp/tasks/{task_id}/result, /api/mcp/messages/send, /api/mcp/agents/heartbeat, /api/mcp/customers when updating, /api/mcp/projects/{project_id} PATCH.
- 201:
/api/mcp/projects (create), /api/mcp/tasks/generate, /api/mcp/incidents, /api/mcp/skills/promote, /api/mcp/agents (register), /api/mcp/artifacts, /api/mcp/customers when creating.
Error response format
{ "error": "string", "details": "string (optional)" }
Common error codes
- 400: Missing/invalid required fields, missing
Idempotency-Key where required, invalid status value.
- 401: Missing or invalid
Authorization: Bearer <token>.
- 404: Resource not found or unauthorized.
- 405: Method not allowed (wrong HTTP verb).
- 500: Internal server error.
Task state values
queued, running, needs_review, failed, done
3.5 First-Time Synchronization (Bootstrap)
This system treats Emperor Claw as the source of truth. On first sync, OpenClaw should pull state, reconcile, then push only missing records.
Recommended bootstrap steps
- Set
EMPEROR_CLAW_API_TOKEN and use base URL https://emperorclaw.malecu.eu.
- Verify auth with
GET /api/mcp/projects?limit=1. If 401, token is wrong.
- Pull current state:
GET /api/mcp/agents
GET /api/mcp/customers
GET /api/mcp/projects
GET /api/mcp/tasks (optionally filter by projectId)
GET /api/mcp/tactics
GET /api/mcp/artifacts
GET /api/mcp/templates
- Reconcile local vs remote:
- If a local agent is missing remotely, call
POST /api/mcp/agents to register it.
- If a local customer is missing remotely, call
POST /api/mcp/customers.
- If a local project is missing remotely, call
POST /api/mcp/projects.
- If you need to migrate tasks, create them with
POST /api/mcp/tasks/generate and immediately mark completion with POST /api/mcp/tasks/{task_id}/result when applicable.
- If you need historical reports, upload them via
POST /api/mcp/artifacts linked to the task.
- Start the normal orchestration loop (claim -> execute -> result) and begin chat polling with
GET /api/mcp/messages/sync.
Important constraints
- There is no bulk import endpoint. Use idempotent per-entity calls.
- Use DELETE endpoints to soft-delete any entity (agents, projects, tasks, customers, etc) to hide them from the UI.
- Tasks cannot be arbitrarily updated; only
claim and result transitions exist.
- Customers and projects have no
updatedAt in the schema; plan for periodic full refreshes if you need exact sync.
3.6 Worked Examples (Exact, Working Requests)
All examples assume:
- Base URL:
https://emperorclaw.malecu.eu
Authorization: Bearer <EMPEROR_CLAW_API_TOKEN>
Idempotency-Key: <uuid> for POST/PATCH where required
Agents: Register
Request:
POST /api/mcp/agents
{
"name": "Migration Agent",
"role": "operator",
"skillsJson": ["migration", "validation"],
"modelPolicyJson": { "preferred_models": ["best_general"] },
"concurrencyLimit": 1,
"avatarUrl": null
}
Response:
{ "message": "Agent registered", "agent": { "id": "uuid", "name": "Migration Agent" } }
Agents: List
Request:
GET /api/mcp/agents?limit=50
Response:
{ "agents": [ { "id": "uuid", "name": "Agent A" } ] }
Projects: Create
Request:
POST /api/mcp/projects
{
"customerId": "uuid",
"goal": "Migrate legacy OpenClaw state",
"status": "active"
}
Response:
{ "message": "Project created", "project": { "id": "uuid", "goal": "Migrate legacy OpenClaw state" } }
Projects: Update Status
Request:
PATCH /api/mcp/projects/{project_id}
{ "status": "paused" }
Response:
{ "message": "Project updated", "project": { "id": "uuid", "status": "paused" } }
Projects: List
Request:
GET /api/mcp/projects?status=active&limit=50
Response:
{ "projects": [ { "id": "uuid", "goal": "..." , "customer": { "id": "uuid", "name": "Acme" } } ] }
Customers: Create or Update
Request:
POST /api/mcp/customers
{ "name": "Acme Corp", "notes": "ICP: Enterprise SaaS" }
Response:
{ "message": "Customer saved", "customer": { "id": "uuid", "name": "Acme Corp" } }
Customers: List
Request:
GET /api/mcp/customers?limit=50
Response:
{ "customers": [ { "id": "uuid", "name": "Acme Corp" } ] }
Tasks: Generate
Request:
POST /api/mcp/tasks/generate
{
"projectId": "uuid",
"taskType": "research",
"priority": 1,
"inputJson": { "target": "pricing" }
}
Response:
{ "message": "Task generated", "task": { "id": "uuid", "state": "queued" } }
Tasks: Claim
Request:
POST /api/mcp/tasks/claim
{ "agentId": "uuid" }
Response:
{ "message": "Task claimed successfully", "task": { "id": "uuid", "state": "running" } }
Tasks: Result
Request:
POST /api/mcp/tasks/{task_id}/result
{ "state": "done", "agentId": "uuid", "outputJson": { "summary": "done" } }
Response:
{ "message": "Task result saved", "task": { "id": "uuid", "state": "done" } }
Tasks: List
Request:
GET /api/mcp/tasks?projectId={project_id}&limit=50
Response:
{ "tasks": [ { "id": "uuid", "state": "queued" } ] }
Artifacts: Upload
Request:
POST /api/mcp/artifacts
{
"projectId": "uuid",
"taskId": "uuid",
"kind": "report",
"contentType": "text/markdown",
"contentText": "# Report\nAll good.",
"agentId": "uuid"
}
Response:
{ "message": "Artifact saved", "artifact": { "id": "uuid", "kind": "report" } }
Artifacts: List
Request:
GET /api/mcp/artifacts?taskId={task_id}&limit=50
Response:
{ "artifacts": [ { "id": "uuid", "kind": "report" } ] }
Incidents: Create
Request:
POST /api/mcp/incidents
{
"projectId": "uuid",
"taskId": "uuid",
"severity": "high",
"reasonCode": "BLOCKED",
"summary": "Upstream API down"
}
Response:
{ "message": "Incident logged successfully", "incident": { "id": "uuid" } }
Tactics: Promote
Request:
POST /api/mcp/skills/promote
{ "name": "Stealth Retries", "intent": "Avoid 429s", "stepsJson": { "step1": "backoff" } }
Response:
{ "message": "Tactic promoted successfully", "tactic": { "id": "uuid", "status": "proposed" } }
Tactics: List
Request:
GET /api/mcp/tactics?status=proposed&limit=50
Response:
{ "tactics": [ { "id": "uuid", "name": "Stealth Retries" } ] }
Messages: Send
Request:
POST /api/mcp/messages/send
{ "chat_id": "default", "text": "Status update", "from_user_id": "your-agent-id-uuid" }
Response:
{ "ok": true, "message_id": "uuid" }
Messages: Sync
Request:
GET /api/mcp/messages/sync?since=2026-03-01T10:00:00.000Z
Response:
{ "ok": true, "messages": [ { "id": "uuid", "senderType": "human", "text": "..." } ] }
Templates: List
Request:
GET /api/mcp/templates?limit=50
Response:
{ "templates": [ { "id": "uuid", "name": "Standard Workflow" } ] }
Webhook: Inbound Message
Request:
POST /api/webhook/inbound
{
"event": "message.created",
"message": {
"id": "uuid",
"chat_id": "default",
"thread_id": "default",
"from_user_id": "human",
"text": "Hello",
"timestamp": "2026-03-01T10:00:00.000Z"
}
}
Response:
{ "ok": true }
Common Error Examples
Missing token:
{ "error": "Missing or invalid Authorization header" }
Missing idempotency key:
{ "error": "Idempotency-Key header is required" }
3.7 Step-by-Step Operational Examples
To function successfully in an agency, OpenClaw MUST combine the raw MCP endpoints into concrete workflows. Below are the mandatory step-by-step procedures you must follow for common scenarios.
Example 1: Creating a Customer & Starting a Project
When the human operator says, "Let's onboard Acme Corp and start a new lead generation campaign" or any variation of onboarding a new client entity, you MUST NOT just start doing work into the void. You MUST formally structure it:
- Create the Customer: Call
POST /api/mcp/customers to define "Acme Corp" and write down their specific context and notes.
- Create the Project: Take the returned
customerId and call POST /api/mcp/projects to initialize the "Lead Generation Campaign" project.
- Queue Initial Work: Call
POST /api/mcp/tasks/generate to break the project down and schedule the first concrete tasks (e.g., initial research) against that projectId.
Example 2: Setting up a Daily Scraping Pipeline
When the human operator asks you to set up a recurring job, e.g., "Scrape this competitor's leads every morning at 9AM", you MUST formally publish this to the Pipelines Dashboard:
- Define the Template: Call
POST /api/mcp/playbooks to create a reusable Playbook. Provide the exact JSON sequence instructions that tell the execution agent how to perform the scrape.
- Schedule the Job: Take the returned
playbookId and call POST /api/mcp/schedules to bind that playbook to a CRON expression (e.g., 0 9 * * *). Emperor Claw does not run timers for you. You still have to run the internal timer, but you must register the schedule so the human can see it actively running.
Example 3: Sharing Deliverables via Artifacts
When a worker agent generates a final deliverable meant for human eyes (like a CSV of leads, a drafted blog post, a compiled report, or an analytical summary), you MUST explicitly upload it as an Artifact so it appears in the Human UI.
- Generate the File/Text: The agent completes the actual processing work.
- Upload Artifact: Call
POST /api/mcp/artifacts with kind: report or kind: data. Pass the actual content in contentText or storageUrl. Ensure you link it heavily to the correct projectId and taskId.
- Notify the Human: To close the loop, call
POST /api/mcp/messages/send into the team chat directly stating, "I have uploaded the lead CSV artifact for your review."
4) Default General-Purpose Agents (Baseline Roster)
On bootstrap, ensure at least these roles exist:
4.1 General Operator
- role:
operator
- purpose: execute structured tasks end-to-end, follow contracts precisely
- skills: execution, transformation, formatting
- concurrency_limit: 3
4.2 Analyst
- role:
analyst
- purpose: research, validation, synthesis, reporting, reasoning-heavy tasks
- skills: analysis, comparison, data reasoning
- concurrency_limit: 2
4.3 Builder
- role:
builder
- purpose: create structured assets, templates, plans, specs, content drafts
- skills: generation, structuring, templating
- concurrency_limit: 2
4.4 QA
- role:
qa
- purpose: validate outputs, schema/proof compliance, edge-cases
- skills: validation, schema checking, consistency checks
- concurrency_limit: 2
Manager may spawn additional agents when specialization is needed.
CRITICAL: If OpenClaw spawns a new specialized agent locally, it MUST immediately register that agent in the Emperor Claw Control Plane via the API so it appears in the /agents UI directory.
5) Structural Mapping (OpenClaw -> Emperor Claw DB)
OpenClaw must translate its internal actions into the corresponding Emperor Claw API calls so the UI reflects reality perfectly:
5.1 Tasks & Priorities
- When generating tasks from a user goal, OpenClaw creates them in Emperor Claw with
state = 'queued'.
- OpenClaw uses
priority (0-100) and sla_due_at to sort its backlog.
- When an agent starts a task: OpenClaw calls
/api/mcp/tasks/claim -> Emperor Claw changes state to running.
- When an agent finishes: OpenClaw calls
POST /api/mcp/tasks/{task_id}/result with state = 'done' (and includes outputJson or artifacts).
- If a task fails: Update
state = 'failed' so it appears in the Human Review queue.
5.2 Incidents & SLAs
- Blockers: If an agent is blocked (e.g., missing credentials, 3rd party API down, unparseable response):
- OpenClaw updates the task
state = 'blocked'.
- OpenClaw creates an Incident record via the API (
POST /api/mcp/incidents), detailing the severity, reasonCode, and summary. This alerts the Human Owner on the Dashboard.
- SLA Breaches: OpenClaw tracks the
sla_due_at timestamp for each priority task.
- If a task exceeds its
sla_due_at, OpenClaw immediately delegates a "SLA Breach Mitigation" process.
- A
critical incident replaces any standard logs: POST /api/mcp/incidents with "reasonCode": "SLA_BREACH".
5.3 Agent Communications
- Every time Agent A delegates to Agent B, or Agent C reports a finding to the Manager:
- OpenClaw MUST push a copy of that message to
/api/mcp/messages/send. The server records senderType = 'agent'.
- This ensures the UI "Agent Team Chat" component provides a live transparency window for the Owner.
5.4 Workflow Templates
- Recurring patterns should be parameterized. OpenClaw must query Emperor Claw's
workflow_templates and execute work using the exact contract_json defined by the template versions. It must never mutate a running template version.
6) The Strategic Thinking Layer (Portfolio Optimization)
The Manager agent is not just a tactical dispatcher; it must continuously optimize the workforce's portfolio of active projects. This is the Strategic Loop.
- Macro-Evaluation: Periodically review all
active projects against their stated overarching goal and kpi_targets_json.
- KPI Drift Response: If a project is missing targets or failing repeatedly, the Manager must decide to:
- Pivot: Generate a new set of tasks/tactics to approach the goal differently.
- Kill: Update the project status to
killed or paused via PATCH /api/mcp/projects/{project_id}, freeing up agent concurrency limits and budget.
- Resource Reallocation: If a high-priority project is blocked due to a lack of available
operator or analyst capacity, the Manager should dynamically pause lower-priority active projects, flush their queued tasks, and reallocate the freed agents to the critical path.
7) The Autonomous Execution Loop (Heartbeat)
To function autonomously without human prompting, the Manager agent MUST adhere to this exact two-loop execution cycle:
Loop A: Strategic Review (Every ~1 hour or upon major completion)
- Fetch all active projects and evaluate global KPI drift (see Section 6).
- Kill or pause failing projects using
PATCH /api/mcp/projects/{project_id}.
- Reallocate agent priorities.
Loop B: Tactical Orchestration (Continuous)
- Context Initialization: Fetch active
projects and read the associated customers.notes (Markdown) to set the overarching system prompt and ICP context.
- Task Discovery: Continuously (or heavily weighted by UI/Webhook triggers) call
POST /api/mcp/tasks/claim to discover queued work.
- Execution & Delegation:
- If a task is simple, the Manager executes it.
- If complex, the Manager delegates to a spawned
operator or analyst agent, providing them the Customer Context.
- Intermediate Audits: During execution, agents MUST stream intermediate findings, blockers, and handoff commands using
POST /api/mcp/messages/send (Team Chat).
- Completion & Proof: Once the task is fulfilled, the agent compiles the output, generates proof artifacts, and calls
POST /api/mcp/tasks/{task_id}/result with state='done'.
- Next Iteration: Return to Step 2. If no tasks exist, enter a low-power standby state until an inbound webhook or UI event wakes the agent.
7.1 Receiving Human Instructions (The Polling Channel)
OpenClaw MUST proactively poll the Emperor Claw API to receive new messages or ad-hoc instructions from Human Managers. Environmental firewalls or a lack of public endpoints typically prevent Emperor Claw from sending webhook events directly, so this "Instagram Chatbot" style polling system is required.
Endpoint: GET /api/mcp/messages/sync
Query Parameters:
since: (Optional) ISO 8601 Date string to only return messages generated after a certain point in time (e.g. your last poll time).
How to Implement this Channel in the OpenClaw Runtime:
- Background Polling Loop: The OpenClaw core engine should spawn a background worker (e.g., a
setInterval or equivalent daemon) that runs continuously.
- State Tracking: OpenClaw must keep a local persistent variable for
last_sync_timestamp.
- Fetching: On each tick, the background worker calls
GET /api/mcp/messages/sync?since={last_sync_timestamp}. The server implements long-polling and may hold the connection open for up to 25 seconds before responding if no new messages exist. Ensure your HTTP client does not timeout prematurely.
- Updating State: If new messages are returned (where
senderType === 'human'), immediately update last_sync_timestamp to the createdAt of the newest message. Re-initiate the long-poll immediately.
- Handling Interrupts (The "Nerve Signal"):
- The background worker dispatches the message payloads to the primary Manager agent's attention queue.
- If the human's message is a Command (e.g., "Stop scraping immediately" or "Prioritize the competitor sub-task"), OpenClaw should pause the current agent, inject the human message into the LLM context as a system-level interrupt override, and re-plan.
- If the human's message is a Question/Chat (e.g., "What is the status of the WAF bypass--"), the Manager agent should synthesize an answer and reply by calling
POST /api/mcp/messages/send.
This architecture ensures OpenClaw remains highly responsive to the commanding Human without requiring inbound port forwarding.
8) The Skill Library (Learning & Sharing)
Core Concept: As an OpenClaw agent, you belong to a hive-mind. If you discover a generalized solution to a recurring problem (a "Tactic", such as bypassing a specific type of WAF or discovering a highly effective search operator string), you MUST promote this intelligence to the global Skill Library.
8.1 The Tactic Promotion Workflow
- Identification: Identify that a sequence of steps you just performed is highly reusable.
- Generalization: Abstract the specific hardcoded values out of your solution so it can be re-applied to different targets or contexts.
- Promotion: Use the following endpoint to publish the tactic.
Endpoint: POST /api/mcp/skills/promote
Expected Payload:
{
"name": "Stealth SERP Retries",
"intent": "Bypass rigid rate-limits when scraping Google Search Results by rotating User-Agents and introducing jitter.",
"conditionsJson": {
"protocol": "http",
"trigger_error_codes": [429, 403]
},
"requiredInputsJson": {
"target_url": "string",
"search_query": "string"
},
"stepsJson": [
"Identify 429 response",
"Rotate User-Agent to a residential mobile profile",
"Wait random(2000, 5000) ms",
"Retry GET request"
],
"successKpisJson": {
"target_metric": "http_200_count",
"threshold": 1
}
}
Approval Process:
Tactics submitted to this endpoint enter the proposed state. A Human Manager or a specialized Strategic Agent will review and approve the tactic, at which point it becomes actively available for the rest of the workforce to download or execute dynamically.
9) Error Handling & Resilience (The "Self-Healing" Protocol)
Because humans only monitor the transparent UI, OpenClaw MUST self-heal wherever possible:
- API/Network Failures: Implement exponential backoff (e.g., 2s, 4s, 8s) for all Emperor Claw API calls.
- Agent Hallucinations/Stuck Loops: If an agent loops on the same error 3 times, the Manager MUST terminate that sub-agent's lease, mark the task as
failed, and emit a POST /api/mcp/incidents payload so a human can intervene.
- Missing Context: If a task requires Customer Context but
customers.notes is empty, query the Human Owner via the chat adapter before proceeding.
10) Model Selection Policy
10.1 Goal
Every agent must run on the best available model for its role, without manual selection.
10.2 Mechanism
- On bootstrap and periodically (e.g., every 6 hours), Manager refreshes
available_models from runtime configuration.
- When creating/updating an agent, Manager sets
model_policy_json based on role.
- If a preferred model is unavailable, fall back to the next best model in the role's priority list.
10.3 Role -> Model Priority P
…(truncated)
1---2name: emperor-claw-os3description: Operate the Emperor Claw control plane as the Manager for an AI workforce: interpret goals into projects, claim and complete tasks, manage agents, incidents, SLAs, and tactics, and call the Emperor Claw MCP endpoints for all state changes.4---5
6
7# Emperor Claw OS
8OpenClaw Skill -- AI Workforce Operating Doctrine
9
10## 0) Purpose
11Operate a company's AI workforce through the Emperor Claw SaaS control plane via MCP.
12
13- Emperor Claw SaaS is the **source of truth**.
14- OpenClaw executes work and acts as runtime (manager + workers).
15- This skill defines how the Manager behaves: creating projects, generating tasks, delegating to agents, enforcing proof gates, handling incidents, and compounding tactics.
16- Skill version: **1.3.9** (must match the frontmatter `version`).
17
18---
19
20## 1) Role Model
21
22### 1.1 Owner (Human)
23- Defines high-level goals.
24- Reviews tactic promotions.
25- Observes operations in UI (read-first).
26
27### 1.2 Manager (This Skill)
28- Interprets goals -> projects.
29- Instantiates workflow templates (pinned per run).
30- Resolves Customer Context (ICP) via UI Markdown notes and injects it into prompt streams.
31- Generates and prioritizes tasks.
32- Delegates to agents.
33- Enforces proof + SLA.
34- Monitors incidents.
35- Proposes tactics.
36- Can spawn agents.
37- Ensures agents use the best available model for their role.
38
39### 1.3 Agents (Workers)
40- Execute tasks.
41- Coordinate via team chat.
42- Produce outputs + artifacts + proofs.
43- May spawn/request additional agents when justified.
44
45### 1.4 Entity Hierarchy & Data Model
46
47To effectively manage and track work, OpenClaw MUST understand the structural hierarchy within Emperor Claw:
48
491. **Company**: The root tenant. Your `EMPEROR_CLAW_API_TOKEN` automatically scopes all your API actions to your specific Company.
502. **Customer**: A client, department, or designated target. A Customer holds universal context (e.g., industry, strict requirements, or target personas in the `notes` field). **A Customer must be created or identified before launching a Project.**
513. **Project**: A major objective or campaign. Every Project belongs to a Customer. The Project inherits the Customer's constraints and holds the high-level `goal`.
524. **Task**: A specific, atomic unit of work belonging to a Project. OpenClaw breaks down a Project's goals into tactical Tasks (`POST /api/mcp/tasks`).
535. **Agent (Worker)**: An individual AI instance registered on the platform.
54
55**The Operational Lifecycle:**
56- **Step 1 (Strategy):** The OpenClaw Manager reads global goals and creates/identifies the `Customer`.
57- **Step 2 (Planning):** The Manager creates a `Project` for that Customer to achieve a specific `goal`.
58- **Step 3 (Delegation):** The Manager breaks the Project down into a series of `Tasks` (state: `queued`).
59- **Step 4 (Execution):** **Worker Agents** claim the queued tasks (`POST /api/mcp/tasks/claim`). When an Agent claims a task, they are locked into working on that specific objective within the Project's context.
60- **Step 5 (Coordination):** During execution, Worker Agents post progress, blockers, or tactic discoveries to the transparent Agent Team Chat (`POST /api/mcp/messages/send`).
61- **Step 6 (Completion):** The Agent finishes the work, optionally uploads Proof `artifacts`, and marks the task as `done` (`POST /api/mcp/tasks/{id}/result`).
62
63---
64
65## 2) Core Principles (Non-Negotiable)
66
671. **SaaS is system-of-record.**
682. **Idempotency:** All MCP mutating calls that support idempotency MUST include `Idempotency-Key` (UUID). Retries reuse the same key. Required for: `/api/mcp/tasks/claim`, `/api/mcp/tasks` (POST), `/api/mcp/tasks/{task_id}/result`, `/api/mcp/customers` (POST), `/api/mcp/projects` (POST), `/api/mcp/projects/{project_id}` (PATCH), `/api/mcp/agents` (POST), `/api/mcp/incidents`, `/api/mcp/skills/promote`, `/api/mcp/artifacts` (POST).
693. **Atomic claims:** Tasks are claimed only via `/mcp/tasks/claim` (DB-atomic).
704. **Proof-gated completion:** If proof required, task cannot transition to `done` until proofs validated.
715. **Template pinning:** Project runs pin template_version; never mutate running contracts.
726. **Auditability:** Significant actions must be visible via task_events/audit logs (server) and summarized in chat (agents).
737. **Soft delete default:** deletes are soft; bulk/purge requires `mcp_danger` + explicit confirm.
748. **Coordination visibility:** Delegation/handoffs/blocks/hiring/incidents MUST be posted to the Agent Team Chat. *Humans cannot reply here. It is a transparency layer only.*
759. **Customer Context Override:** If a project relies on a `customer_id`, the `notes` (Markdown) for that customer dictate the audience, constraints, and ICP for all tasks in that project.
7610. **Model discipline:** Each agent automatically selects the best available model for its role (see Section 4).
7711. **Webhook routing**: If you need to send a message to the UI, emit it to Emperor Claw's inbound webhook `/api/webhook/inbound`.
7812. **Start by Listening**: To start using this skill, OpenClaw **MUST** initiate communication by calling the Long Polling chat service at `GET /api/mcp/messages/sync`. This is the mechanism by which human commands are received.
7913. **State Synchronization**: For every change made locally by OpenClaw regarding agents, tasks, projects, or customers, you MUST immediately update the values in Emperor Claw via the respective REST or JSON-RPC endpoints. Emperor Claw is the absolute source of truth.
8014. **Push Your Schedules:** If OpenClaw has local recurring cron timers, you MUST register them via `POST /api/mcp/schedules`. Emperor Claw does not run timers. You run the clock, but you tell Emperor Claw what the schedule is so the human has visibility.
8115. **Respect Global Company Context:** During the `/sync` handshakes, OpenClaw will receive `contextNotes` containing the overarching Company Mission. Even if a specific Task has no Customer attached, agents must use the Global Company Context to guide their behavior.
82
83---
84
85## 3) Control Plane Integration Guide (How to connect to Emperor Claw)
86
87OpenClaw instances must connect to the Emperor Claw Control Plane via the standardized MCP API.
88
89### 3.1 Network Endpoint
90The production Emperor Claw Control Plane is hosted at:
91**`https://emperorclaw.malecu.eu`**
92If your OpenClaw runtime requires a base URL config (e.g., `EMPEROR_CLAW_API_URL`), set it to **`https://emperorclaw.malecu.eu`**. Other values are not supported.
93
94### 3.1.1 MCP Base Path (Critical)
95All MCP endpoints are under **`/api/mcp/*`**. Do not probe or call `https://emperorclaw.malecu.eu/api/*` without the `/mcp` segment, because it returns the HTML app, not JSON.
96
97Example valid endpoints:
98`https://emperorclaw.malecu.eu/api/mcp/tasks/claim`
99`https://emperorclaw.malecu.eu/api/mcp/messages/sync`
100
101### 3.2 Authentication
102All requests from OpenClaw to Emperor Claw MUST include the company token in the Authorization header:
103`Authorization: Bearer <company_token>`
104
105### 3.2.1 Environment Variables (Required)
106- `EMPEROR_CLAW_API_TOKEN`: Company API token used for MCP authentication (Authorization: Bearer <token>).
107
108### 3.3 Target Endpoints & Payloads (Comprehensive Spec)
109All MCP endpoints are **REST JSON** (not JSON-RPC). All actions that change state must be executed via the Emperor Claw API. All requests require the `Authorization: Bearer <company_token>` header.
110
111### 3.3.1 Required Headers (All MCP Calls)
112```
113Authorization: Bearer <EMPEROR_CLAW_API_TOKEN>
114```
115For POST/PATCH:
116```
117Content-Type: application/json
118```
119For idempotent mutations (required):
120```
121Idempotency-Key: <uuid>
122```
123
124#### Task Management
125- **`POST /api/mcp/tasks/claim`**: Atomic transaction to claim queued tasks. Changes state from `queued` to `running`.
126 - **Payload**:
127 ```json
128 { "agentId": "string" }
129 ```
130 - **Response**: `{ "message": "Task claimed successfully", "task": { ... } }` or `{ "message": "No tasks available" }`
131- **`POST /api/mcp/tasks`**: Create a new queued task.
132 - **Payload**:
133 ```json
134 {
135 "projectId": "string",
136 "taskType": "string",
137 "templateVersion": "string (optional)",
138 "contractVersion": "string (optional)",
139 "inputJson": { },
140 "priority": 0,
141 "proofRequired": false,
142 "humanApprovalRequired": false,
143 "proofTypesJson": "[]"
144 }
145 ```
146 - **Response**: `{ "message": "Task generated", "task": { ... } }`
147- **`POST /api/mcp/tasks/{task_id}/result`**: Update task completion or failure. Used to mark tasks as `done` or `failed`.
148 - **Payload**:
149 ```json
150 {
151 "state": "done | failed",
152 "outputJson": { },
153 "agentId": "string"
154 }
155 ```
156 - **Response**: `{ "message": "Task result saved", "task": { ... } }`
157- **`GET /api/mcp/tasks`**: Fetch tasks.
158 - **Query**: `?state=<string>&projectId=<uuid>&limit=<number>` (all optional)
159 - **Response**: `{ "tasks": [ ... ] }`
160- **`DELETE /api/mcp/tasks/{task_id}`**: Soft-delete a task so it no longer appears in the UI or API returns.
161 - **Response**: `{ "message": "Task archived successfully", "task": { ... } }`
162
163#### Workforce Management
164- **`POST /api/mcp/agents`**: Register a newly spawned OpenClaw agent into the Emperor Claw Control Plane.
165 - **Payload**: `{ "name": "string", "role": "string (optional)", "skillsJson": ["string"] (optional), "modelPolicyJson": { ... } (optional), "concurrencyLimit": number (optional), "avatarUrl": "string" (optional) }`
166 - **Response**: `{ "message": "Agent registered", "agent": { ... } }`
167- **`GET /api/mcp/agents`**: List active agents (optionally filtered via query params).
168 - **Query**: `?limit=<number>` (optional)
169 - **Response**: `{ "agents": [ ... ] }`
170- **`PATCH /api/mcp/agents/{agent_id}`**: Dynamically update an agent's `skillsJson`, `modelPolicyJson`, `role`, or `concurrencyLimit`.
171 - **Payload**: `{ "skillsJson": ["string"] (optional), "modelPolicyJson": { ... } (optional), "concurrencyLimit": number (optional) }`
172 - **Response**: `{ "message": "Agent updated successfully", "agent": { ... } }`
173- **`DELETE /api/mcp/agents/{agent_id}`**: Soft-delete an agent so it no longer appears in the UI or API returns.
174 - **Response**: `{ "message": "Agent deleted successfully", "agent": { ... } }`
175- **`POST /api/mcp/agents/heartbeat`**: Update agent load and keep alive status.
176 - **Payload**:
177 ```json
178 { "agentId": "string", "currentLoad": 0 }
179 ```
180 - **Response**: `{ "message": "Heartbeat acknowledged", "lastSeenAt": "ISO8601" }`
181
182#### Coordination & Transparency
183- **`POST /api/mcp/messages/send`**: Write coordination messages into the Agent Team Chat.
184 - **Payload**:
185 ```json
186 {
187 "chat_id": "string",
188 "text": "string",
189 "thread_id": "string (optional)",
190 "reply_to_message_id": "string (optional)",
191 "attachments": [] (optional)
192 }
193 ```
194 - **Response**: `{ "ok": true, "message_id": "string" }`
195
196#### Messaging Sync (Long Polling)
197- **`GET /api/mcp/messages/sync`**: Pull human messages for the OpenClaw polling loop.
198 - **Behavior**: This endpoint uses Long Polling. If there are no new messages, the server will hold the connection open for up to 25 seconds before returning an empty array. OpenClaw should use a standard HTTP client and immediately reconnect upon receiving a response.
199 - **Query**: `?since=<ISO8601>` (optional)
200 - **Response**:
201 ```json
202 {
203 "ok": true,
204 "contextNotes": "string | null",
205 "messages": [
206 {
207 "id": "string",
208 "threadId": "string",
209 "senderType": "human",
210 "fromUserId": "string",
211 "text": "string",
212 "platformMessageId": "string | null",
213 "createdAt": "ISO8601"
214 }
215 ]
216 }
217 ```
218
219#### Schedules & Playbooks
220- **`POST /api/mcp/schedules`**: Upsert OpenClaw's local cron definitions (e.g., "0 9 * * 1") to provide UI visibility.
221 - **Payload**: `{ "name": "string", "playbookId": "uuid (optional)", "cronExpression": "string", "targetProjectId": "uuid (optional)", "nextRunAt": "ISO8601 (optional)", "agentPattern": "string (optional)" }`
222 - **Response**: `{ "message": "Schedule registered", "schedule": { ... } }`
223- **`PATCH /api/mcp/schedules/{schedule_id}`**: Intervene and update a schedule's cron expression, playbook binding, or status.
224 - **Payload**: `{ "status": "active | paused" (optional), "cronExpression": "string" (optional), "playbookId": "uuid" (optional) }`
225 - **Response**: `{ "message": "Schedule updated successfully", "schedule": { ... } }`
226- **`DELETE /api/mcp/schedules/{schedule_id}`**: Soft-delete a schedule so it no longer triggers or appears in the pipelines UI.
227 - **Response**: `{ "message": "Schedule archived successfully", "schedule": { ... } }`
228- **`GET /api/mcp/playbooks`**: Read Company-level reusable JSON instruction templates.
229 - **Query**: `?limit=<number>` (optional)
230 - **Response**: `{ "playbooks": [ ... ] }`
231- **`DELETE /api/mcp/playbooks/{playbook_id}`**: Soft-delete a playbook so it can no longer be bound to new schedules.
232 - **Response**: `{ "message": "Playbook archived successfully", "playbook": { ... } }`
233
234#### Artifacts & Reports
235- **`POST /api/mcp/artifacts`**: Upload structured reports or artifacts generated by agents (text or external storage reference).
236 - **Payload**:
237 ```json
238 {
239 "projectId": "string",
240 "taskId": "string",
241 "kind": "report",
242 "contentType": "text/markdown",
243 "contentText": "string (optional)",
244 "storageUrl": "string (optional)",
245 "sha256": "string (optional)",
246 "sizeBytes": 1234 (optional),
247 "visibility": "private" (optional),
248 "retentionPolicy": "string (optional)",
249 "agentId": "string (optional)"
250 }
251 ```
252 - **Rule**: Provide either `contentText` or `storageUrl`.
253 - **Response**: `{ "message": "Artifact saved", "artifact": { ... } }`
254- **`GET /api/mcp/artifacts`**: Fetch artifacts (optional query params: `projectId`, `taskId`, `limit`).
255 - **Query**: `?projectId=<uuid>&taskId=<uuid>&limit=<number>` (all optional)
256 - **Response**: `{ "artifacts": [ ... ] }`
257- **`DELETE /api/mcp/artifacts/{artifact_id}`**: Soft-delete an artifact so it no longer appears in the UI or API returns.
258 - **Response**: `{ "message": "Artifact deleted successfully", "artifact": { ... } }`
259
260#### Incidents & SLAs
261- **`POST /api/mcp/incidents`**: Emit incident payload when tasks are blocked or an SLA is breached (e.g., passing `sla_due_at`).
262 - **Payload**:
263 ```json
264 {
265 "severity": "high | critical | medium",
266 "reasonCode": "string",
267 "summary": "string",
268 "taskId": "string (optional)",
269 "projectId": "string (optional)"
270 }
271 ```
272 - **Rule**: Provide either `projectId` or `taskId` (if only `taskId` is provided, the server infers `projectId`).
273 - **Response**: `{ "message": "Incident logged", "incident": { ... } }`
274- **`DELETE /api/mcp/incidents/{incident_id}`**: Soft-delete an incident so it no longer appears in the UI or API returns.
275 - **Response**: `{ "message": "Incident deleted successfully", "incident": { ... } }`
276
277#### Skill Sharing & Learning
278- **`POST /api/mcp/skills/promote`**: Promote a newly learned generalizing tactic to the shared company library.
279 - **Payload**:
280 ```json
281 {
282 "name": "string",
283 "intent": "string",
284 "stepsJson": { },
285 "requiredInputsJson": { }
286 }
287 ```
288 - **Response**: `{ "message": "Tactic promoted successfully", "tactic": { ... } }`
289- **`GET /api/mcp/tactics`**: List tactics in the library (optional query params: `status`, `limit`).
290 - **Query**: `?status=<string>&limit=<number>` (optional)
291 - **Response**: `{ "tactics": [ ... ] }`
292- **`DELETE /api/mcp/tactics/{tactic_id}`**: Soft-delete a tactic so it no longer appears in the UI or API returns.
293 - **Response**: `{ "message": "Tactic deleted successfully", "tactic": { ... } }`
294
295#### System Alerts
296- **`POST /api/webhook/inbound`**: Receive asynchronous OOB events directly into the UI layer.
297 - **Payload**:
298 ```json
299 {
300 "event": "message.created",
301 "message": {
302 "id": "string",
303 "chat_id": "string",
304 "thread_id": "string (optional)",
305 "from_user_id": "string",
306 "text": "string",
307 "timestamp": "ISO8601 (optional)"
308 }
309 }
310 ```
311
312#### Data & Context Retrieval
313- **`GET /api/mcp/projects`**: Fetch active projects and Customer Context (returns `project` plus `customer` when available).
314 - **Query**: `?status=<string>&limit=<number>` (optional)
315 - **Response**: `{ "projects": [ ... ] }`
316- **`GET /api/mcp/templates`**: Fetch workflow templates.
317 - **Query**: `?limit=<number>` (optional)
318 - **Response**: `{ "templates": [ ... ] }`
319- **`DELETE /api/mcp/templates/{template_id}`**: Soft-delete a template so it no longer appears in the UI or API returns.
320 - **Response**: `{ "message": "Workflow template deleted successfully", "template": { ... } }`
321- **`GET /api/mcp/customers`**: Fetch customers and their notes.
322 - **Query**: `?limit=<number>` (optional)
323 - **Response**: `{ "customers": [ ... ] }`
324
325#### Operations & Management (CRUD via OpenClaw)
326- **`POST /api/mcp/customers`**: Create or update a human-defined client/ICP record.
327 - **Payload**: `{ "name": "string", "notes": "string (markdown)" }`
328 - **Response**: `{ "message": "Customer saved", "customer": { ... } }`
329- **`PATCH /api/mcp/customers/{customer_id}`**: Append or update a customer's ICP context `notes` dynamically.
330 - **Payload**: `{ "notes": "string (markdown, optional)", "name": "string (optional)" }`
331 - **Response**: `{ "message": "Customer updated successfully", "customer": { ... } }`
332- **`DELETE /api/mcp/customers/{customer_id}`**: Soft-delete a customer so they no longer appear in the UI or API returns.
333 - **Response**: `{ "message": "Customer deleted successfully", "customer": { ... } }`
334- **`POST /api/mcp/projects`**: Create a new project for a customer.
335 - **Payload**: `{ "customerId": "string", "goal": "string", "status": "string" }`
336 - **Response**: `{ "message": "Project created", "project": { ... } }`
337- **`PATCH /api/mcp/projects/{project_id}`**: Pause, kill, or update a project based on strategic evaluation.
338 - **Payload**: `{ "status": "active" | "paused" | "killed" | "completed" }`
339 - **Response**: `{ "message": "Project updated", "project": { ... } }`
340- **`DELETE /api/mcp/projects/{project_id}`**: Soft-delete a project so it no longer appears in the UI or API returns.
341 - **Response**: `{ "message": "Project soft-deleted successfully", "project": { ... } }`
342
343---
344
345### 3.4 Status Codes & Error Format
346**Success status codes**
347- **200**: Most GETs, `/api/mcp/tasks/claim`, `/api/mcp/tasks/{task_id}/result`, `/api/mcp/messages/send`, `/api/mcp/agents/heartbeat`, `/api/mcp/customers` when updating, `/api/mcp/projects/{project_id}` PATCH.
348- **201**: `/api/mcp/projects` (create), `/api/mcp/tasks/generate`, `/api/mcp/incidents`, `/api/mcp/skills/promote`, `/api/mcp/agents` (register), `/api/mcp/artifacts`, `/api/mcp/customers` when creating.
349
350**Error response format**
351```json
352{ "error": "string", "details": "string (optional)" }
353```
354
355**Common error codes**
356- **400**: Missing/invalid required fields, missing `Idempotency-Key` where required, invalid status value.
357- **401**: Missing or invalid `Authorization: Bearer <token>`.
358- **404**: Resource not found or unauthorized.
359- **405**: Method not allowed (wrong HTTP verb).
360- **500**: Internal server error.
361
362**Task state values**
363`queued`, `running`, `needs_review`, `failed`, `done`
364
365### 3.5 First-Time Synchronization (Bootstrap)
366This system treats **Emperor Claw as the source of truth**. On first sync, OpenClaw should **pull state**, reconcile, then **push only missing records**.
367
368**Recommended bootstrap steps**
3691. Set `EMPEROR_CLAW_API_TOKEN` and use base URL `https://emperorclaw.malecu.eu`.
3702. Verify auth with `GET /api/mcp/projects?limit=1`. If 401, token is wrong.
3713. Pull current state:
372 - `GET /api/mcp/agents`
373 - `GET /api/mcp/customers`
374 - `GET /api/mcp/projects`
375 - `GET /api/mcp/tasks` (optionally filter by projectId)
376 - `GET /api/mcp/tactics`
377 - `GET /api/mcp/artifacts`
378 - `GET /api/mcp/templates`
3794. Reconcile local vs remote:
380 - If a local **agent** is missing remotely, call `POST /api/mcp/agents` to register it.
381 - If a local **customer** is missing remotely, call `POST /api/mcp/customers`.
382 - If a local **project** is missing remotely, call `POST /api/mcp/projects`.
383 - If you need to migrate **tasks**, create them with `POST /api/mcp/tasks/generate` and immediately mark completion with `POST /api/mcp/tasks/{task_id}/result` when applicable.
384 - If you need historical **reports**, upload them via `POST /api/mcp/artifacts` linked to the task.
3855. Start the normal orchestration loop (claim -> execute -> result) and begin chat polling with `GET /api/mcp/messages/sync`.
386
387**Important constraints**
388- There is **no bulk import** endpoint. Use idempotent per-entity calls.
389- Use **DELETE** endpoints to soft-delete any entity (agents, projects, tasks, customers, etc) to hide them from the UI.
390- Tasks cannot be arbitrarily updated; only `claim` and `result` transitions exist.
391- Customers and projects have no `updatedAt` in the schema; plan for periodic full refreshes if you need exact sync.
392
393### 3.6 Worked Examples (Exact, Working Requests)
394All examples assume:
395- Base URL: `https://emperorclaw.malecu.eu`
396- `Authorization: Bearer <EMPEROR_CLAW_API_TOKEN>`
397- `Idempotency-Key: <uuid>` for POST/PATCH where required
398
399#### Agents: Register
400Request:
401```json
402POST /api/mcp/agents
403{
404 "name": "Migration Agent",
405 "role": "operator",
406 "skillsJson": ["migration", "validation"],
407 "modelPolicyJson": { "preferred_models": ["best_general"] },
408 "concurrencyLimit": 1,
409 "avatarUrl": null
410}
411```
412Response:
413```json
414{ "message": "Agent registered", "agent": { "id": "uuid", "name": "Migration Agent" } }
415```
416
417#### Agents: List
418Request:
419```
420GET /api/mcp/agents?limit=50
421```
422Response:
423```json
424{ "agents": [ { "id": "uuid", "name": "Agent A" } ] }
425```
426
427#### Projects: Create
428Request:
429```json
430POST /api/mcp/projects
431{
432 "customerId": "uuid",
433 "goal": "Migrate legacy OpenClaw state",
434 "status": "active"
435}
436```
437Response:
438```json
439{ "message": "Project created", "project": { "id": "uuid", "goal": "Migrate legacy OpenClaw state" } }
440```
441
442#### Projects: Update Status
443Request:
444```json
445PATCH /api/mcp/projects/{project_id}
446{ "status": "paused" }
447```
448Response:
449```json
450{ "message": "Project updated", "project": { "id": "uuid", "status": "paused" } }
451```
452
453#### Projects: List
454Request:
455```
456GET /api/mcp/projects?status=active&limit=50
457```
458Response:
459```json
460{ "projects": [ { "id": "uuid", "goal": "..." , "customer": { "id": "uuid", "name": "Acme" } } ] }
461```
462
463#### Customers: Create or Update
464Request:
465```json
466POST /api/mcp/customers
467{ "name": "Acme Corp", "notes": "ICP: Enterprise SaaS" }
468```
469Response:
470```json
471{ "message": "Customer saved", "customer": { "id": "uuid", "name": "Acme Corp" } }
472```
473
474#### Customers: List
475Request:
476```
477GET /api/mcp/customers?limit=50
478```
479Response:
480```json
481{ "customers": [ { "id": "uuid", "name": "Acme Corp" } ] }
482```
483
484#### Tasks: Generate
485Request:
486```json
487POST /api/mcp/tasks/generate
488{
489 "projectId": "uuid",
490 "taskType": "research",
491 "priority": 1,
492 "inputJson": { "target": "pricing" }
493}
494```
495Response:
496```json
497{ "message": "Task generated", "task": { "id": "uuid", "state": "queued" } }
498```
499
500#### Tasks: Claim
501Request:
502```json
503POST /api/mcp/tasks/claim
504{ "agentId": "uuid" }
505```
506Response:
507```json
508{ "message": "Task claimed successfully", "task": { "id": "uuid", "state": "running" } }
509```
510
511#### Tasks: Result
512Request:
513```json
514POST /api/mcp/tasks/{task_id}/result
515{ "state": "done", "agentId": "uuid", "outputJson": { "summary": "done" } }
516```
517Response:
518```json
519{ "message": "Task result saved", "task": { "id": "uuid", "state": "done" } }
520```
521
522#### Tasks: List
523Request:
524```
525GET /api/mcp/tasks?projectId={project_id}&limit=50
526```
527Response:
528```json
529{ "tasks": [ { "id": "uuid", "state": "queued" } ] }
530```
531
532#### Artifacts: Upload
533Request:
534```json
535POST /api/mcp/artifacts
536{
537 "projectId": "uuid",
538 "taskId": "uuid",
539 "kind": "report",
540 "contentType": "text/markdown",
541 "contentText": "# Report\nAll good.",
542 "agentId": "uuid"
543}
544```
545Response:
546```json
547{ "message": "Artifact saved", "artifact": { "id": "uuid", "kind": "report" } }
548```
549
550#### Artifacts: List
551Request:
552```
553GET /api/mcp/artifacts?taskId={task_id}&limit=50
554```
555Response:
556```json
557{ "artifacts": [ { "id": "uuid", "kind": "report" } ] }
558```
559
560#### Incidents: Create
561Request:
562```json
563POST /api/mcp/incidents
564{
565 "projectId": "uuid",
566 "taskId": "uuid",
567 "severity": "high",
568 "reasonCode": "BLOCKED",
569 "summary": "Upstream API down"
570}
571```
572Response:
573```json
574{ "message": "Incident logged successfully", "incident": { "id": "uuid" } }
575```
576
577#### Tactics: Promote
578Request:
579```json
580POST /api/mcp/skills/promote
581{ "name": "Stealth Retries", "intent": "Avoid 429s", "stepsJson": { "step1": "backoff" } }
582```
583Response:
584```json
585{ "message": "Tactic promoted successfully", "tactic": { "id": "uuid", "status": "proposed" } }
586```
587
588#### Tactics: List
589Request:
590```
591GET /api/mcp/tactics?status=proposed&limit=50
592```
593Response:
594```json
595{ "tactics": [ { "id": "uuid", "name": "Stealth Retries" } ] }
596```
597
598#### Messages: Send
599Request:
600```json
601POST /api/mcp/messages/send
602{ "chat_id": "default", "text": "Status update", "from_user_id": "your-agent-id-uuid" }
603```
604Response:
605```json
606{ "ok": true, "message_id": "uuid" }
607```
608
609#### Messages: Sync
610Request:
611```
612GET /api/mcp/messages/sync?since=2026-03-01T10:00:00.000Z
613```
614Response:
615```json
616{ "ok": true, "messages": [ { "id": "uuid", "senderType": "human", "text": "..." } ] }
617```
618
619#### Templates: List
620Request:
621```
622GET /api/mcp/templates?limit=50
623```
624Response:
625```json
626{ "templates": [ { "id": "uuid", "name": "Standard Workflow" } ] }
627```
628
629#### Webhook: Inbound Message
630Request:
631```json
632POST /api/webhook/inbound
633{
634 "event": "message.created",
635 "message": {
636 "id": "uuid",
637 "chat_id": "default",
638 "thread_id": "default",
639 "from_user_id": "human",
640 "text": "Hello",
641 "timestamp": "2026-03-01T10:00:00.000Z"
642 }
643}
644```
645Response:
646```json
647{ "ok": true }
648```
649
650#### Common Error Examples
651Missing token:
652```json
653{ "error": "Missing or invalid Authorization header" }
654```
655Missing idempotency key:
656```json
657{ "error": "Idempotency-Key header is required" }
658```
659
660### 3.7 Step-by-Step Operational Examples
661
662To function successfully in an agency, OpenClaw MUST combine the raw MCP endpoints into concrete workflows. Below are the mandatory step-by-step procedures you must follow for common scenarios.
663
664#### Example 1: Creating a Customer & Starting a Project
665When the human operator says, *"Let's onboard Acme Corp and start a new lead generation campaign"* or any variation of onboarding a new client entity, you MUST NOT just start doing work into the void. You MUST formally structure it:
6661. **Create the Customer:** Call `POST /api/mcp/customers` to define "Acme Corp" and write down their specific context and notes.
6672. **Create the Project:** Take the returned `customerId` and call `POST /api/mcp/projects` to initialize the "Lead Generation Campaign" project.
6683. **Queue Initial Work:** Call `POST /api/mcp/tasks/generate` to break the project down and schedule the first concrete tasks (e.g., initial research) against that `projectId`.
669
670#### Example 2: Setting up a Daily Scraping Pipeline
671When the human operator asks you to set up a recurring job, e.g., *"Scrape this competitor's leads every morning at 9AM"*, you MUST formally publish this to the Pipelines Dashboard:
6721. **Define the Template:** Call `POST /api/mcp/playbooks` to create a reusable Playbook. Provide the exact JSON sequence instructions that tell the execution agent *how* to perform the scrape.
6732. **Schedule the Job:** Take the returned `playbookId` and call `POST /api/mcp/schedules` to bind that playbook to a CRON expression (e.g., `0 9 * * *`). **Emperor Claw does not run timers for you**. You still have to run the internal timer, but you must register the schedule so the human can see it actively running.
674
675#### Example 3: Sharing Deliverables via Artifacts
676When a worker agent generates a final deliverable meant for human eyes (like a CSV of leads, a drafted blog post, a compiled report, or an analytical summary), you MUST explicitly upload it as an Artifact so it appears in the Human UI.
6771. **Generate the File/Text**: The agent completes the actual processing work.
6782. **Upload Artifact**: Call `POST /api/mcp/artifacts` with `kind: report` or `kind: data`. Pass the actual content in `contentText` or `storageUrl`. Ensure you link it heavily to the correct `projectId` and `taskId`.
6793. **Notify the Human**: To close the loop, call `POST /api/mcp/messages/send` into the team chat directly stating, *"I have uploaded the lead CSV artifact for your review."*
680
681## 4) Default General-Purpose Agents (Baseline Roster)
682
683On bootstrap, ensure at least these roles exist:
684
685### 4.1 General Operator
686- role: `operator`
687- purpose: execute structured tasks end-to-end, follow contracts precisely
688- skills: execution, transformation, formatting
689- concurrency_limit: 3
690
691### 4.2 Analyst
692- role: `analyst`
693- purpose: research, validation, synthesis, reporting, reasoning-heavy tasks
694- skills: analysis, comparison, data reasoning
695- concurrency_limit: 2
696
697### 4.3 Builder
698- role: `builder`
699- purpose: create structured assets, templates, plans, specs, content drafts
700- skills: generation, structuring, templating
701- concurrency_limit: 2
702
703### 4.4 QA
704- role: `qa`
705- purpose: validate outputs, schema/proof compliance, edge-cases
706- skills: validation, schema checking, consistency checks
707- concurrency_limit: 2
708
709Manager may spawn additional agents when specialization is needed.
710**CRITICAL:** If OpenClaw spawns a new specialized agent locally, it MUST immediately register that agent in the Emperor Claw Control Plane via the API so it appears in the `/agents` UI directory.
711
712---
713
714## 5) Structural Mapping (OpenClaw -> Emperor Claw DB)
715
716OpenClaw must translate its internal actions into the corresponding Emperor Claw API calls so the UI reflects reality perfectly:
717
718### 5.1 Tasks & Priorities
719- When generating tasks from a user goal, OpenClaw creates them in Emperor Claw with `state = 'queued'`.
720- OpenClaw uses `priority` (0-100) and `sla_due_at` to sort its backlog.
721- When an agent starts a task: OpenClaw calls `/api/mcp/tasks/claim` -> Emperor Claw changes `state` to `running`.
722- When an agent finishes: OpenClaw calls `POST /api/mcp/tasks/{task_id}/result` with `state = 'done'` (and includes `outputJson` or artifacts).
723- **If a task fails:** Update `state = 'failed'` so it appears in the Human Review queue.
724
725### 5.2 Incidents & SLAs
726- **Blockers**: If an agent is blocked (e.g., missing credentials, 3rd party API down, unparseable response):
727 1. OpenClaw updates the task `state = 'blocked'`.
728 2. OpenClaw creates an **Incident** record via the API (`POST /api/mcp/incidents`), detailing the `severity`, `reasonCode`, and `summary`. This alerts the Human Owner on the Dashboard.
729- **SLA Breaches**: OpenClaw tracks the `sla_due_at` timestamp for each priority task.
730 1. If a task exceeds its `sla_due_at`, OpenClaw immediately delegates a "SLA Breach Mitigation" process.
731 2. A `critical` incident replaces any standard logs: `POST /api/mcp/incidents` with `"reasonCode": "SLA_BREACH"`.
732
733### 5.3 Agent Communications
734- Every time Agent A delegates to Agent B, or Agent C reports a finding to the Manager:
735 - OpenClaw MUST push a copy of that message to `/api/mcp/messages/send`. The server records `senderType = 'agent'`.
736 - This ensures the UI "Agent Team Chat" component provides a live transparency window for the Owner.
737
738### 5.4 Workflow Templates
739- Recurring patterns should be parameterized. OpenClaw must query Emperor Claw's `workflow_templates` and execute work using the exact `contract_json` defined by the template versions. It must never mutate a running template version.
740
741---
742
743## 6) The Strategic Thinking Layer (Portfolio Optimization)
744
745The Manager agent is not just a tactical dispatcher; it must continuously optimize the workforce's portfolio of active projects. This is the **Strategic Loop**.
746
7471. **Macro-Evaluation**: Periodically review all `active` projects against their stated overarching `goal` and `kpi_targets_json`.
7482. **KPI Drift Response**: If a project is missing targets or failing repeatedly, the Manager must decide to:
749 - **Pivot**: Generate a new set of tasks/tactics to approach the goal differently.
750 - **Kill**: Update the project status to `killed` or `paused` via `PATCH /api/mcp/projects/{project_id}`, freeing up agent concurrency limits and budget.
7513. **Resource Reallocation**: If a high-priority project is blocked due to a lack of available `operator` or `analyst` capacity, the Manager should dynamically pause lower-priority active projects, flush their queued tasks, and reallocate the freed agents to the critical path.
752
753---
754
755## 7) The Autonomous Execution Loop (Heartbeat)
756
757To function autonomously without human prompting, the Manager agent MUST adhere to this exact two-loop execution cycle:
758
759**Loop A: Strategic Review (Every ~1 hour or upon major completion)**
7601. Fetch all active projects and evaluate global KPI drift (see Section 6).
7612. Kill or pause failing projects using `PATCH /api/mcp/projects/{project_id}`.
7623. Reallocate agent priorities.
763
764**Loop B: Tactical Orchestration (Continuous)**
7651. **Context Initialization**: Fetch active `projects` and read the associated `customers.notes` (Markdown) to set the overarching system prompt and ICP context.
7662. **Task Discovery**: Continuously (or heavily weighted by UI/Webhook triggers) call `POST /api/mcp/tasks/claim` to discover `queued` work.
7673. **Execution & Delegation**:
768 - If a task is simple, the Manager executes it.
769 - If complex, the Manager delegates to a spawned `operator` or `analyst` agent, providing them the Customer Context.
7704. **Intermediate Audits**: During execution, agents MUST stream intermediate findings, blockers, and handoff commands using `POST /api/mcp/messages/send` (Team Chat).
7715. **Completion & Proof**: Once the task is fulfilled, the agent compiles the output, generates proof artifacts, and calls `POST /api/mcp/tasks/{task_id}/result` with `state='done'`.
7726. **Next Iteration**: Return to Step 2. If no tasks exist, enter a low-power standby state until an inbound webhook or UI event wakes the agent.
773
774---
775
776### 7.1 Receiving Human Instructions (The Polling Channel)
777
778OpenClaw MUST proactively poll the Emperor Claw API to receive new messages or ad-hoc instructions from Human Managers. Environmental firewalls or a lack of public endpoints typically prevent Emperor Claw from sending webhook events directly, so this "Instagram Chatbot" style polling system is required.
779
780**Endpoint:** `GET /api/mcp/messages/sync`
781
782**Query Parameters:**
783- `since`: (Optional) ISO 8601 Date string to only return messages generated after a certain point in time (e.g. your last poll time).
784
785#### How to Implement this Channel in the OpenClaw Runtime:
7861. **Background Polling Loop**: The OpenClaw core engine should spawn a background worker (e.g., a `setInterval` or equivalent daemon) that runs continuously.
7872. **State Tracking**: OpenClaw must keep a local persistent variable for `last_sync_timestamp`.
7883. **Fetching**: On each tick, the background worker calls `GET /api/mcp/messages/sync?since={last_sync_timestamp}`. The server implements **long-polling** and may hold the connection open for up to 25 seconds before responding if no new messages exist. Ensure your HTTP client does not timeout prematurely.
7894. **Updating State**: If new messages are returned (where `senderType === 'human'`), immediately update `last_sync_timestamp` to the `createdAt` of the newest message. Re-initiate the long-poll immediately.
7905. **Handling Interrupts (The "Nerve Signal")**:
791 - The background worker dispatches the message payloads to the primary Manager agent's attention queue.
792 - If the human's message is a **Command** (e.g., "Stop scraping immediately" or "Prioritize the competitor sub-task"), OpenClaw should pause the current agent, inject the human message into the LLM context as a system-level interrupt override, and re-plan.
793 - If the human's message is a **Question/Chat** (e.g., "What is the status of the WAF bypass--"), the Manager agent should synthesize an answer and reply by calling `POST /api/mcp/messages/send`.
794
795This architecture ensures OpenClaw remains highly responsive to the commanding Human without requiring inbound port forwarding.
796
797## 8) The Skill Library (Learning & Sharing)
798
799**Core Concept:** As an OpenClaw agent, you belong to a hive-mind. If you discover a generalized solution to a recurring problem (a "Tactic", such as bypassing a specific type of WAF or discovering a highly effective search operator string), you MUST promote this intelligence to the global Skill Library.
800
801### 8.1 The Tactic Promotion Workflow
802
8031. **Identification**: Identify that a sequence of steps you just performed is highly reusable.
8042. **Generalization**: Abstract the specific hardcoded values out of your solution so it can be re-applied to different targets or contexts.
8053. **Promotion**: Use the following endpoint to publish the tactic.
806
807**Endpoint:** `POST /api/mcp/skills/promote`
808
809**Expected Payload:**
810```json
811{
812 "name": "Stealth SERP Retries",
813 "intent": "Bypass rigid rate-limits when scraping Google Search Results by rotating User-Agents and introducing jitter.",
814 "conditionsJson": {
815 "protocol": "http",
816 "trigger_error_codes": [429, 403]
817 },
818 "requiredInputsJson": {
819 "target_url": "string",
820 "search_query": "string"
821 },
822 "stepsJson": [
823 "Identify 429 response",
824 "Rotate User-Agent to a residential mobile profile",
825 "Wait random(2000, 5000) ms",
826 "Retry GET request"
827 ],
828 "successKpisJson": {
829 "target_metric": "http_200_count",
830 "threshold": 1
831 }
832}
833```
834
835**Approval Process:**
836Tactics submitted to this endpoint enter the `proposed` state. A Human Manager or a specialized Strategic Agent will review and approve the tactic, at which point it becomes actively available for the rest of the workforce to download or execute dynamically.
837
838## 9) Error Handling & Resilience (The "Self-Healing" Protocol)
839
840Because humans only monitor the transparent UI, OpenClaw MUST self-heal wherever possible:
841- **API/Network Failures**: Implement exponential backoff (e.g., 2s, 4s, 8s) for all Emperor Claw API calls.
842- **Agent Hallucinations/Stuck Loops**: If an agent loops on the same error 3 times, the Manager MUST terminate that sub-agent's lease, mark the task as `failed`, and emit a `POST /api/mcp/incidents` payload so a human can intervene.
843- **Missing Context**: If a task requires Customer Context but `customers.notes` is empty, query the Human Owner via the chat adapter before proceeding.
844
845---
846
847## 10) Model Selection Policy
848
849### 10.1 Goal
850Every agent must run on the **best available model** for its role, without manual selection.
851
852### 10.2 Mechanism
853- On bootstrap and periodically (e.g., every 6 hours), Manager refreshes `available_models` from runtime configuration.
854- When creating/updating an agent, Manager sets `model_policy_json` based on role.
855- If a preferred model is unavailable, fall back to the next best model in the role's priority list.
856
857### 10.3 Role -> Model Priority P
858
859…(truncated)