@mahilo/openclaw-mahilo
v0.1.5
Published
Ask your contacts from OpenClaw and get attributed answers with boundaries built in.
Maintainers
Readme
Mahilo for OpenClaw
Ask your contacts from OpenClaw and get real answers from people you trust, with attribution and boundaries built in.
Mahilo for OpenClaw turns "ask my contacts" into a native OpenClaw behavior. Instead of trusting public AI noise or repeating the same question across chats, you ask once inside OpenClaw and the plugin uses Mahilo to reach the right contacts, bring back attributed answers from real people you already trust, and honor the sharing boundaries each person has set. OpenClaw stays the conversational surface; Mahilo stays behind the scenes as the trust and control layer for identity, network discovery, server-issued policy bundles, local non-trusted enforcement before transport, and audited review/outcome flows.
Start Here
Choose the path that matches why you're here:
- Guided First Run: the single recommended five-minute path for setup, build-your-circle, ask-around, human approval, and a live Mahilo handoff.
- Ask Your Contacts: get trustworthy answers from your network without leaving OpenClaw.
- Boundaries and Trust: keep your agent helpful without giving up control.
- Build Your Circle: make a small trusted network useful from the first few connections.
- Demo Story Pack: replay the restaurant, weekend-planning, and boundaries launch stories from fixture data.
- Trust and Operations Proof: operator-facing evidence for governance, observability, failure handling, and rollout confidence.
If you want the shortest credible explanation first: Mahilo is the trust and control layer behind the plugin. It knows who is in your network, which agent connection is acting, what can be shared, and whether a request should be allowed, reviewed, or blocked.
Recommended First Run
The single recommended first-run path is Guided First Run. It proves setup, the build-your-circle checkpoint, live connectivity, ask-around orchestration, an in-thread Mahilo handoff, and explicit human approval in one OpenClaw session.
If you only want the raw command/tool sequence, the loop is:
- If you already have a Mahilo API key in plugin config, restart OpenClaw and let the plugin auto-attach the default sender on startup. If you do not, give the agent your one-time invite token (a string starting with
mhinv_) and let the plugin bootstrap automatically via raw HTTP — the agent will register your identity withPOST /api/v1/auth/register, attach the default sender withPOST /api/v1/agents, and save credentials to the local runtime store. No command or manual setup step required. - Run
mahilo statusto confirm connectivity and webhook alignment. - Run
mahilo networkormanage_networkwithaction=listto see whether your circle is ready. - If the network is empty, stay in
manage_networkand useaction=send_requestto invite one trusted person. If they already invited you, useaction=accept, then have them bring their Mahilo plugin online in OpenClaw. - Once one accepted contact has a live agent connection, ask OpenClaw to check with your Mahilo contacts, or call
ask_networkwithaction=ask_around. - Send a sensitive follow-up with
send_messageto prove the live review gate before transport. - Use
set_boundariesto grant a narrow exception, then retry the same send.
Install From npm
@mahilo/openclaw-mahilo is the published Mahilo plugin for OpenClaw. Install it as a normal npm package, register it in openclaw.extensions, and keep runtime settings under plugins.entries.mahilo.config.
npm install @mahilo/openclaw-mahiloThen add the installed package to openclaw.extensions in your OpenClaw runtime config:
{
"openclaw": {
"extensions": ["@mahilo/openclaw-mahilo"]
}
}For a published npm install, point openclaw.extensions at the package name, not dist/index.js. The package already declares its packaged extension entry internally.
Minimal Working OpenClaw Config
Add the Mahilo plugin entry to the same OpenClaw config file:
{
"openclaw": {
"extensions": ["@mahilo/openclaw-mahilo"]
},
"plugins": {
"entries": {
"mahilo": {
"enabled": true,
"config": {}
}
}
}
}By default, the plugin talks to the global Mahilo server at https://mahilo.io.
If you already have a Mahilo API key, add "apiKey": "mhl_...". The plugin will auto-register or repair the default sender on startup. When apiKey is omitted, the plugin bootstraps automatically when the agent is given a one-time invite token (mhinv_...). The agent registers the identity via POST /api/v1/auth/register, attaches the sender via POST /api/v1/agents, and stores the issued credentials in the local runtime store — no manual command needed.
plugins.entries.mahilo.config accepts:
| Field | Purpose | Notes |
| --- | --- | --- |
| baseUrl | Mahilo server base URL override | Defaults to https://mahilo.io; change it only when you intentionally point the plugin at another Mahilo server. |
| apiKey | Existing Mahilo API key | Optional when bootstrapping from an invite token. If present, the plugin uses it to auto-attach or repair the default sender on startup. |
| callbackUrl | Public webhook URL override | Advanced only. Leave it unset unless callback auto-detection is wrong for your deployment. |
| callbackPath | Path appended to auto-detected callback URLs | Defaults to /mahilo/incoming; must start with /. |
| inboundSessionKey | Fallback OpenClaw session for inbound Mahilo messages | Defaults to main. |
| inboundAgentId | Optional agent id paired with inboundSessionKey | Only needed when inbound fallback routing must target a specific agent. |
| localPolicyLLM | Optional local LLM evaluator settings for applicable LLM policies | Supports provider, model, timeout, authProfile, apiKeyEnvVar, and apiKey. |
| promptContextEnabled | Enables native prompt-time Mahilo context injection | Defaults to true; when turned off, the plugin still injects a minimal static browser-access instruction and still does not disable live enforcement. |
| reviewMode | Controls local UX for normal ask outcomes | auto, ask, or manual; defaults to ask. reviewMode=auto does not auto-send degraded local LLM review outcomes. |
| cacheTtlSeconds | TTL for local non-authoritative caches | Defaults to 60. |
Do not add contractVersion, pluginVersion, or callbackSecret to plugin config. Those are server-owned and rejected by the plugin config parser.
For local policy LLM evaluation, inline localPolicyLLM.apiKey is optional, not required. If it is omitted, the plugin checks localPolicyLLM.apiKeyEnvVar, then falls back to the provider-default env var where supported (currently OPENAI_API_KEY for provider=openai). That credential lookup stays local to the plugin/OpenClaw environment. authProfile is only a hint in v1; host auth-profile credential reuse is not wired up yet.
When callbackUrl is omitted, startup auto-registration tries this order:
- the stored callback URL from the last successful Mahilo registration
- the OpenClaw gateway remote URL, if configured
- Tailscale serve/funnel hostname, if enabled
http://localhost:<gateway-port>/mahilo/incomingas a local-only fallback
So normal users do not need to type callbackUrl manually. The override exists for advanced setups only.
When the plugin bootstraps an API key or rotates a callback secret (whether via automatic raw-HTTP bootstrap or the mahilo setup fallback), it stores those server-issued values in a local runtime store under $XDG_CONFIG_HOME/mahilo/openclaw-plugin-runtime.json (or ~/.config/mahilo/openclaw-plugin-runtime.json when XDG_CONFIG_HOME is unset). That keeps server-owned secrets out of plugin config while still avoiding setup retry loops.
Non-Trusted Enforcement At A Glance
In non-trusted mode, the live outbound path is always:
- Fetch a direct-send or group-fanout bundle from Mahilo.
- Evaluate locally with the shared Mahilo policy core.
- Commit the resulting
allow,ask, ordenydecision back to Mahilo. - Transport only committed
allowrecipients. - Report any post-send or post-review outcome against the committed
message_id.
Keep these boundaries in mind:
send_messageaction=contextandaction=previeware advisory or dry-run only. They never authorize transport, consume lifecycle-limited policies, or create an auditable send artifact.- Preview
resolution_idvalues are preview-scoped only. A later live send always fetches a fresh bundle and uses the bundleresolution_idfor commit/send correlation. - Local
askcommits appear inmahilo review. Localdenycommits appear in blocked-event surfaces. Localallowcommits create pending artifacts that later bind to/api/v1/messages/send. - Group sends are per-recipient all the way through. The bundle summary is for plugin UX only; commits, retries, reviews, blocked events, and outcome reports are all recorded per committed member artifact.
If an applicable local LLM policy cannot be evaluated because credentials are missing or the provider returns network, provider, timeout, invalid_response, unknown, or skip, the plugin degrades the decision to ask. Those reason codes use policy.ask.llm.<kind>, stay review_required, and do not auto-send even when reviewMode=auto.
Rollout And Upgrade Rules
- There is no separate
localPolicyEnforcementEnabledflag or preview-only compatibility switch. The only rollout gate is serverTRUSTED_MODE. TRUSTED_MODE=truekeeps the existing trusted/plaintext server-side evaluation path for live sends.TRUSTED_MODE=falsemakes live non-trustedsend_messageandask_networkuse bundle -> local evaluation -> commit -> transport by default as soon as you upgrade and restart.- Existing non-trusted installs should expect stricter live behavior after upgrade: sends that previously depended on advisory preview/context hints may now stop in review or blocked states before transport.
- Before broader rollout with
TRUSTED_MODE=false, confirmmahilo status,mahilo network, and, if any applicable policy usesevaluator="llm", a local key source throughlocalPolicyLLM.apiKey,localPolicyLLM.apiKeyEnvVar, or a provider-default env var such asOPENAI_API_KEY. - Missing local provider credentials do not disable deterministic enforcement. They turn only the affected LLM-backed decisions into
policy.ask.llm.unavailable-stylereview_requiredoutcomes. If that fallback is not acceptable yet, keepTRUSTED_MODE=trueuntil local credentials are staged or the relevant LLM policies are removed.
Commands
The plugin registers these OpenClaw-native commands:
mahilo setupmahilo networkmahilo statusmahilo reviewmahilo reconnect
Minimal Mahilo Surface
The plugin keeps the model-facing surface intentionally small:
send_messageaction=send(default): send a policy-aware message to a user or groupaction=preview: resolve a draft without sending it; dry-run only, not live authorization, and previewresolution_idvalues are never reused for local commit/sendaction=context: fetch compact Mahilo context and prompt guidance for a contact; advisory only
manage_networkaction=list: list contacts, pending requests, sender connections, recent Mahilo activity, and lightweight seven-day product signals from Mahilo/OpenClaw runtime stateaction=send_request,accept,decline: manage Mahilo relationships without a separate tool per server route
browser_accessaction=approve,deny: approve or deny a Mahilo dashboard/browser sign-in code for the already configured account
ask_networkaction=ask_around: fan out one question across all contacts, selected roles, or a named Mahilo group while replies keep flowing back into the same OpenClaw thread
set_boundaries- change sharing boundaries conversationally for opinions/recommendations, availability/schedule, location, health, financial, and contact details
- one-off boundary exceptions still live here, but ongoing boundary changes use the same stable tool instead of exposing policy jargon
- safety-sensitive categories default conservatively: health, financial, and contact details tighten to deny unless you explicitly open them up
Operational and debug workflows stay on commands instead of expanding the tool list.
In non-trusted mode, live send_message and ask_network enforcement comes from server-issued bundles evaluated locally before transport. Prompt context and preview remain advisory/dry-run surfaces. If you preview first, the later live path still fetches a fresh bundle, evaluates locally, commits the decision, and only then transports committed allow recipients.
Default Sender Resolution
Core Mahilo plugin flows no longer require prompt authors or humans to pass senderConnectionId.
When a send, preview, or context-fetch call omits senderConnectionId, the plugin:
- Reads the current user's Mahilo agent connections from
/api/v1/agents - Reuses a cached default sender when one is still fresh under
cacheTtlSeconds - Chooses a default deterministically from active connections in this order:
- server-default or
default-labeled connections openclawframework connections- higher Mahilo connection priority
- lexical fallback by label, then connection id
- server-default or
senderConnectionId and sender_connection_id are still accepted as advanced overrides when you need to force a specific routing path.
Compatibility
- Package name:
@mahilo/openclaw-mahilo - Runtime plugin ID:
mahilo - Stable OpenClaw config entry:
plugins.entries.mahilo.config - Mahilo server contract expected by this package:
1.0.0on/api/v1 - Supported OpenClaw runtime surface: the modern
openclaw/plugin-sdk/coreAPI used by this package (registerTool,registerCommand,registerHook,registerHttpRoute, andruntime.system) - Unsupported combinations:
- OpenClaw runtimes that predate
openclaw/plugin-sdk/coreor only expose legacy plugin APIs - Mahilo server/plugin contract versions other than
1.0.0 - Plugin config that tries to set server-owned keys such as
contractVersion,pluginVersion, orcallbackSecret
- OpenClaw runtimes that predate
First Connectivity Check
After installing the plugin, restart OpenClaw. The plugin bootstraps automatically when the agent encounters a Mahilo tool call without credentials:
- Give the agent your one-time invite token (starts with
mhinv_) and a username. - The agent will register the identity, attach the sender, and save credentials — all without leaving the conversation.
- Run
mahilo statusto confirm connectivity.
A healthy install reports:
Mahilo status: connected; diagnostics snapshot available.If the first probe fails:
- Check the diagnostic message — it tells you whether the runtime store file is missing, malformed, or has a bad server entry.
- Run
mahilo reconnect. - Verify
plugins.entries.mahilo.config.baseUrlstill points to the intended Mahilo server if you overrode the default. - If you preseeded credentials manually, verify
plugins.entries.mahilo.config.apiKeyis valid and has plugin access. - Confirm OpenClaw is reachable through gateway remote or Tailscale and that the webhook route (
callbackPath, default/mahilo/incoming) answersHEADprobes with200.
Fallback: If automatic bootstrap fails, you can still run /mahilo setup {"username":"your_handle","invite_token":"mhinv_..."} as an operator escape hatch.
Upgrade Notes
When moving to a newer published version:
npm install @mahilo/openclaw-mahilo@latestThen restart OpenClaw and rerun mahilo status.
Rollout rule on upgrade: TRUSTED_MODE is the only enablement gate. If it is false, live local enforcement is active immediately after restart and there is no separate plugin flag that preserves the old preview-only non-trusted behavior.
If you are moving from a repo-local install to the published package:
- Replace any absolute plugin checkout path in
openclaw.extensionswith@mahilo/openclaw-mahilo. - Keep the runtime plugin entry name as
mahilo. - Remove any legacy server-owned plugin config keys before restart.
Troubleshooting
baseUrl must be a valid absolute URL: use a full URL such ashttps://mahilo.ioorhttps://mahilo.example, not a relative path.apiKey must be a non-empty string: if you choose to preseed credentials, setplugins.entries.mahilo.config.apiKey; otherwise remove the field entirely and letmahilo setupbootstrap it.unsupported plugin config key(s)orServer-owned/deprecated keys are not allowed in plugin config: remove unknown knobs and legacy keys such ascontractVersion,pluginVersion, andcallbackSecret.unsupported localPolicyLLM config key(s): remove unknown keys from the nested local LLM config block.callbackPath must start with '/': use a route like/mahilo/incoming.promptContextEnabled must be a boolean: set it totrueorfalse, not a string value.reviewMode must be one of: auto, ask, manual: choose one of the supported review modes exactly.localPolicyLLM.timeout must be a positive integer: use a millisecond timeout such as5000.localPolicyLLM.apiKeyEnvVar must be a valid env var name: use a name likeOPENAI_API_KEY.Mahilo setup ... callback step: enable OpenClaw gateway remote or Tailscale exposure so/mahilo/incomingis reachable, then rerunmahilo setup. If you already have a public webhook URL and auto-detection is wrong, setplugins.entries.mahilo.config.callbackUrlas an override.Mahilo status: connectivity checks failed: rerunmahilo setup, then runmahilo reconnectand check server reachability, API key scope, and callback alignment.
Local Development From This Repo
For development against this repo instead of the published npm package:
cd /absolute/path/to/mahilo-2/plugins/openclaw-mahilo
bun install
bun run build
bun run demo:storiesThen point openclaw.extensions at the absolute package directory path instead of @mahilo/openclaw-mahilo.
plugins/openclaw-mahilo/ is the only active development source of truth. Keep myclawd/extensions/mahilo/ frozen except for explicit emergency backports.
Release Maintenance
Package maintainers should use PUBLISH-CHECKLIST.md, RELEASING.md, docs/listing-copy.md, and docs/launch-collateral.md for publish-surface copy, first-announce assets, tarball contents, packed-artifact smoke-test steps, build hooks, and release checklist details.
