M
megent/docs
v0.1.0PythonTypeScriptSoonMIT License

Megent SDK
Documentation

A policy runtime that controls what AI agents can do. Intercept tool calls, enforce YAML rules, and mask PII — across every major agentic framework.

Overview

Megent sits between your orchestration layer and your AI agents, intercepting every tool call before it executes. You define rules in a simple YAML file — Megent enforces them at runtime, masking PII in outputs, blocking dangerous operations, and logging every decision to a structured audit trail.

LLM / Orchestrator

Megent Runtime

Tool Function

policy.yaml defines rules · runtime enforces · audit.log records all decisions

🛡

Deny-by-default

Block any tool call not explicitly allowed.

🔏

PII Masking

Strip sensitive fields from tool outputs.

📋

Audit Trail

Structured JSON log of every decision.

🔗

Any Framework

Python, TS, LangChain, CrewAI, OpenAI.

🎯

Glob Matching

Match tools with patterns like delete_*.

🪪

JWT Identity

Per-agent passports with scoped permissions.

Installation

pip · npm

Megent provides first-class packages for Python and TypeScript. Pick whichever matches your agent stack.

Python
pip install megent
TypeScript / NodeSoon
Coming soon

Recommended: use a virtual environment

Run python -m venv .venv && source .venv/bin/activate before pip installing to keep your project dependencies isolated.

Quick Start

Two lines to initialize, one decorator to enforce. Here's everything you need to get running:

main.py
import megent
      from any_agent_sdk import AgentToolkit

      # Load your policy file
      mgnt = megent.init(policy="policy.yaml")


      # Decorate your own tools
      @mgnt.guard
      def get_user(user_id: str):
        return {"id": user_id, "email": "alice@acme.com"}


      # Or wrap a third-party agent or toolkit
      safe_agent = mgnt.wrap(AgentToolkit())

Policy YAML

core

All rules live in a single YAML file. Rules are evaluated top-to-bottom — the first match wins and evaluation stops.

policy.yaml
version: "1.0"
agent: production-agent

rules:
  - id: block-delete
    description: No agent may delete any resource
    match:
      tool: "delete_*"
    action: deny

  - id: restrict-payments
    description: Payment tools require human-in-the-loop
    match:
      tool: "transfer_*"
    action: deny
    reason: "Payment actions require human approval"

  - id: mask-pii
    description: Strip PII from all tool outputs
    match:
      tool: "*"
    action: mask
    fields:
      - email
      - phone
      - ssn
      - credit_card
      - ip_address

  - id: allow-reads
    description: Read operations are permitted
    match:
      tool: "get_*"
    action: allow
Rule Schema
id *stringUnique identifier referenced in audit logs and error messages.
descriptionstringHuman-readable explanation of what this rule does.
match.tool *globTool name glob. Supports * wildcard. e.g. delete_*, get_user, *
action *enumOne of: allow · deny · mask
fieldsstring[]For mask: field names to redact from the tool output.
reasonstringFor deny: custom message included in MegentDenyError.

Actions

Every rule must declare one of three actions. Actions determine what the runtime does when a tool call matches.

allow

The tool call is permitted to execute normally. Execution passes through to the underlying function.

- id: allow-reads
  match:
    tool: "get_*"
  action: allow
deny

The tool call is blocked before execution. A MegentDenyError is raised with an optional reason. The function is never called.

- id: block-delete
  match:
    tool: "delete_*"
  action: deny
  reason: "Deletion requires human approval"
mask

The tool call executes, but specified fields in the return value are redacted. Runs after the function returns, before the result reaches the LLM.

- id: mask-pii
  match:
    tool: "*"
  action: mask
  fields: [email, phone, ssn]

PII Masking

automatic

The mask action walks the return value recursively and replaces any matching key with ***.

masking-demo.py
# policy.yaml
- id: mask-pii
  match:
    tool: "*"
  action: mask
  fields: [email, phone, ssn, credit_card]

# agent.py
@mgnt.guard
def get_user(user_id: str):
    return {
        "id": user_id,
        "name": "Alice Smith",       # ← untouched
        "email": "alice@acme.com",   # ← masked
        "phone": "555-0192",         # ← masked
    "ssn": "123-45-6789",        # ← masked
    }

result = get_user("u_001")
# → {
#     "id":    "u_001",
#     "name":  "Alice Smith",
#     "email": "***",
#     "phone": "***",
#     "ssn":   "***"
#   }

Recursive masking

Megent walks nested dicts and lists to any depth. You don't need to specify the path — just the field name.

Framework Examples

5 SDKs

The same policy.yaml enforces your rules across every major framework. Switch tabs to see the full example for each SDK.

Install
terminal
pip install megent
Full example
agent.py
import megent

mgnt = megent.init(policy="policy.yaml")

@mgnt.guard
def get_user(user_id: str):
    return {
        "id": user_id,
        "email": "alice@acme.com",
        "phone": "555-0192",
        "ssn": "123-45-6789",
    }

@mgnt.guard
def delete_user(user_id: str):
    # ✗ blocked by policy — matches delete_*
    return {"deleted": user_id}

@mgnt.guard
def transfer_funds(amount: float, to: str):
    # ✗ blocked by policy — restrict-payments rule
    return {"transferred": amount, "to": to}

if __name__ == "__main__":
    # ✓ Allowed — PII masked in return value
    print(get_user("u_001"))
    # → {"id": "u_001", "email": "***", "phone": "***", "ssn": "***"}

    # ✗ Denied — rule: block-delete
    delete_user("u_001")
    # → MegentDenyError: 'block-delete' denied call: delete_user

    # ✗ Denied — rule: restrict-payments
    transfer_funds(500.00, "bob")
    # → MegentDenyError: Payment actions require human approval

Audit Logs

auto-generated

Every intercepted tool call is appended to audit.logas newline-delimited JSON. No configuration required — it's on by default.

audit.log
{"ts":"2026-03-30T09:00:01Z","agent":"production-agent","tool":"get_user","action":"allow","rule":"allow-reads","masked_fields":["email","phone","ssn"],"duration_ms":4}
{"ts":"2026-03-30T09:00:02Z","agent":"production-agent","tool":"delete_user","action":"deny","rule":"block-delete","reason":"No agent may delete any resource","duration_ms":0}
{"ts":"2026-03-30T09:00:03Z","agent":"production-agent","tool":"transfer_funds","action":"deny","rule":"restrict-payments","reason":"Payment actions require human approval","duration_ms":0}
Log Fields
tsISO 8601Timestamp of the intercepted call.
agentstringAgent ID from policy.yaml or JWT.
toolstringName of the function that was called.
actionenumOutcome: allow · deny · mask
rulestringID of the rule that matched.
reasonstringDenial message if set in the rule.
masked_fieldsstring[]Fields redacted in output, if action is mask.
duration_msnumberMilliseconds from intercept to return.

JWT Identity

coming soon

Issue each agent a signed JWT passport with scoped tool permissions. Megent validates the token on every call and enforces per-agent rules.

jwt-demo.py
# Issue a scoped passport for a specific agent
token = mgnt.issue_passport(
    agent_id="data-analyst-v2",
    scopes=["get_*", "list_*"],   # only these tools are allowed
    expires_in=3600,               # 1-hour TTL
)

# Agent initializes with its passport
mgnt_agent = megent.init(
    policy="policy.yaml",
    jwt=token,                     # validated on every call
)

@mgnt_agent.guard
def get_transactions(account_id: str):
    ...  # ✓ in passport scopes

@mgnt_agent.guard
def delete_account(account_id: str):
    ...  # ✗ not in passport scopes → MegentDenyError

In development — v0.2.0

JWT identity is on the roadmap. The API shown is a preview and may change before release.

M

Ready to control your agents?

Open source · MIT licensed · Works with any LLM framework