Skip to content
Metamynd
Beta Program

Connect your agent to MetaMynd

Give your AI agent a verifiable identity, govern every action it takes with allow / observe / block / escalate policy you control, and watch the whole conversation between your agent and MetaMynd in a tamper-evident log.

How it works

Four steps, one governed loop

Your agent gets an identity and a mandate. A small guard sits in front of its actions and asks MetaMynd to authorize each one. Allowed actions run and are recorded as evidence; risky ones are blocked or escalated to you.

01

Identity

Each agent is issued a verifiable did:hedera whose signing key is embedded in the DID itself.

02

Mandate & policy

You author spend caps, jurisdictions, risk rules and approved tools — no code, editable any time.

03

Authorize gate

Before every action the guard sends a signed request; the gate returns allow, observe, block or escalate.

04

Evidence

Every decision is anchored as tamper-evident, auditor-verifiable evidence.

60-second start

Try it in the sandbox first

No account and no KYB. One command scaffolds a runnable agent wired to a shared sandbox, so you can see a real allow, block and escalate before you connect your own.

sandbox-quickstart.sh
# No account, no KYB — scaffold a governed agent against a shared sandbox
npx create-metamynd-agent --sandbox

# Then run the generated example — watch ALLOW / BLOCK / ESCALATE
npm install && npm start
Connect your agent

Three steps to a governed agent

1

Get beta access

Sign up and log in to the dashboard. During the closed beta there is no KYC/KYB step — a principal (the legal owner your agent acts for) is created and approved automatically, so you can go straight to provisioning. That approval is self-serve, not an identity check, and it is shown as such on your agent's public page; it works for testnet, and mainnet still needs a real verification.

2

Provision your agent

One command scaffolds everything: it logs you in, provisions a verifiable identity (a did:hedera), a spend-capped mandate, a starter SOP and the platform Standards, then writes agent.metamynd.json beside your code. Prefer the UI? Do the same from AgentSafe → Deploy Agent. Prefer your own backend? Call the onboarding API below.

3

Wrap your actions with the guard

Install @metamynd/agentsafe-guard (zero dependencies, Node ≥ 18) and wrap any tool. Before each call the guard asks the MetaMynd gate to authorize the action; it runs only on allow, throws on block, and parks on escalate — the decision is made by your policy, not the model.

provision.sh
# Logs you in, provisions identity + mandate + starter SOP + Standards
# in one call, and writes agent.metamynd.json next to your code.
npx create-metamynd-agent
provision-via-api.sh
# Or provision from your own backend. During the beta, no KYB is
# required — a principal is created and self-approved for you (no identity check runs).
curl -X POST https://metamynd.ai/api/v1/onboarding/agent \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Support Bot", "scope": "flight-purchase" }'

# → 201 { agentDid, agentKey, mandate: { policyId }, sopId,
#         standards: ["eu-ai-act"], bundleUrl, keyVerified: true }
govern-an-action.ts
import { createGuardFromConfig } from "@metamynd/agentsafe-guard";

// Load the config the onboarding call returned (no env vars needed).
const guard = await createGuardFromConfig("./agent.metamynd.json");

// Wrap any action — it runs ONLY if MetaMynd allows it.
const gated = guard.guardTool(
  "flight-purchase",                       // = your mandate scope
  rawBookFlight,                           // your existing handler
  (a) => ({
    amount: a.amount,
    currency: "USD",
    merchant: a.merchant,
    context: { riskLevel: a.riskLevel },   // extra signals your rules can read
  }),
);

// Call the gated action and handle the three outcomes.
try {
  const result = await gated({ amount: 400, merchant: "duffel", riskLevel: "low" });
  // ALLOW → your handler ran, and the decision is recorded as evidence.
} catch (e) {
  const g = e.governance ?? {};            // GovernanceBlocked
  if (g.decision === "escalate") {
    // ESCALATE → parked for the owner: g.escalationId
    // poll: await guard.escalationStatus(g.escalationId)
  } else {
    // BLOCK → g.reasonCode, e.g. "SOP_SPEND_CAP" — the handler never ran
  }
}
Framework guides

Wire it into your framework

The guard wraps any async function, so every framework comes down to one move: register the gated handler instead of the raw one. Pick yours.

OpenClaw

Deterministic, not cooperative: a before_tool_call hook runs after the model picks a tool and BEFORE OpenClaw executes it, authorizes against the gate, and denies anything but allow — OpenClaw fails closed, so the model can't bypass it. A ready-made plugin and skill ship with the beta bundle; ask us and we will send them.

openclaw.ts
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { createGuardFromConfig } from "@metamynd/agentsafe-guard";

const guard = await createGuardFromConfig("./agent.metamynd.json");

export default definePluginEntry({
  id: "agentsafe-governance",
  register(api) {
    api.on("before_tool_call", async ({ toolName, params }) => {
      // Map your consequential tools → gate inputs; unmapped tools run ungoverned.
      if (toolName !== "book_flight") return;
      const v = await guard.authorize({
        action: "flight-purchase",              // = your mandate scope
        amount: Number(params.amount),
        currency: "USD",
        merchant: params.merchant,
        context: { riskLevel: params.riskLevel },
      });
      if (v.decision !== "allow") {
        // throw → OpenClaw fails closed; the tool never runs.
        throw new Error(`AgentSafe DENY ${toolName}: ${v.reasonCode}`);
      }
    });
  },
});
Ask for the OpenClaw plugin →

LangChain (JS)

Wrap the tool's func with guardTool — the tool runs only when the gate allows.

langchain.ts
import { DynamicStructuredTool } from "@langchain/core/tools";

const bookFlight = new DynamicStructuredTool({
  name: "book_flight",
  description: "Book a flight",
  schema,
  func: guard.guardTool("flight-purchase", rawBookFlight,
    (a) => ({ amount: a.amount, currency: "USD", merchant: a.merchant })),
});

OpenAI (Agents SDK / function calling)

Dispatch each tool call to the gated function instead of the raw one.

openai.ts
const tools = {
  book_flight: guard.guardTool("flight-purchase", rawBookFlight,
    (a) => ({ amount: a.amount, currency: "USD", merchant: a.merchant })),
};

// When the model returns a tool call:
const out = await tools[call.function.name](JSON.parse(call.function.arguments));

Vercel AI SDK

Use the gated handler as the tool's execute.

vercel.ts
import { tool } from "ai";
import { z } from "zod";

const bookFlight = tool({
  description: "Book a flight",
  parameters: z.object({ amount: z.number(), merchant: z.string() }),
  execute: guard.guardTool("flight-purchase", rawBookFlight,
    (a) => ({ amount: a.amount, currency: "USD", merchant: a.merchant })),
});

Any Node agent

guardTool wraps any async function — no framework required.

any.ts
const gated = guard.guardTool("flight-purchase", rawFn,
  (a) => ({ amount: a.amount, currency: "USD", merchant: a.merchant }));

// gated(args) → runs on allow · throws on block · waits on escalate

The context object is what your Standards & SOP rules read (jurisdiction, model, tool, PII, risk…). Signed fields (amount, merchant) always win over context, so a forged context key can never slip an action past a rule.

Ready to connect your agent?

Provision an agent, wrap an action, and watch the first allow / observe / block / escalate land in your activity log.