OpenClaw extension
Operations
Drop a single TypeScript file into ~/.openclaw/extensions/ to give every OpenClaw agent native myagentmail tools.
OpenClaw loads any .ts file in ~/.openclaw/extensions/ as a tool extension at startup. Below is the full extension that registers four core tools — copy it to ~/.openclaw/extensions/myagentmail.ts and set MYAGENTMAIL_KEY in the OpenClaw env.
// ~/.openclaw/extensions/myagentmail.ts
//
// Native myagentmail tools for OpenClaw agents.
// Set MYAGENTMAIL_KEY in the OpenClaw process env.
import type { ExtensionApi } from "openclaw/extensions";
const API = "https://myagentmail.com/v1";
function key(): string {
const k = process.env.MYAGENTMAIL_KEY || "";
if (!k) throw new Error("MYAGENTMAIL_KEY env var is not set");
return k;
}
async function mam(method: string, path: string, body?: unknown) {
const r = await fetch(`${API}${path}`, {
method,
headers: { "X-API-Key": key(), "Content-Type": "application/json" },
body: body ? JSON.stringify(body) : undefined,
});
if (!r.ok) throw new Error(`mam ${method} ${path} → ${r.status}: ${await r.text()}`);
return r.json();
}
export function register(api: ExtensionApi) {
api.registerTool({
name: "MAM_SEND_EMAIL",
description: "Send an email from a myagentmail inbox. Set verified=true after MX-checking the recipient.",
parameters: {
type: "object",
required: ["inboxId", "to", "subject"],
properties: {
inboxId: { type: "string" },
to: { type: "string", description: "Recipient email or array of emails." },
subject: { type: "string" },
plainBody: { type: "string" },
htmlBody: { type: "string" },
verified: { type: "boolean", default: true },
},
},
async execute(_id, params: any) {
const body = { ...params };
delete body.inboxId;
const result = await mam("POST", `/inboxes/${params.inboxId}/send`, body);
return { content: [{ type: "text", text: JSON.stringify(result) }] };
},
});
api.registerTool({
name: "MAM_LIST_INBOX",
description: "List inbound messages in a myagentmail inbox.",
parameters: {
type: "object",
required: ["inboxId"],
properties: {
inboxId: { type: "string" },
limit: { type: "number", default: 20 },
},
},
async execute(_id, params: any) {
const result = await mam(
"GET",
`/inboxes/${params.inboxId}/messages?direction=inbound&limit=${params.limit ?? 20}`
);
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
},
});
api.registerTool({
name: "MAM_REPLY",
description: "Reply to a myagentmail message in-thread.",
parameters: {
type: "object",
required: ["inboxId", "messageId", "plainBody"],
properties: {
inboxId: { type: "string" },
messageId: { type: "string" },
plainBody: { type: "string" },
},
},
async execute(_id, params: any) {
const result = await mam(
"POST",
`/inboxes/${params.inboxId}/reply/${params.messageId}`,
{ plainBody: params.plainBody }
);
return { content: [{ type: "text", text: JSON.stringify(result) }] };
},
});
api.registerTool({
name: "MAM_CREATE_INBOX",
description: "Provision a new myagentmail inbox.",
parameters: {
type: "object",
properties: {
username: { type: "string" },
displayName: { type: "string" },
},
},
async execute(_id, params: any) {
const result = await mam("POST", "/inboxes", params);
return { content: [{ type: "text", text: JSON.stringify(result) }] };
},
});
}
Restart OpenClaw and the four MAM_* tools become available to every agent. Extend the file with whatever endpoints your agents need — the pattern repeats for every route in the API reference.