Skip to content

Integrate

Wrap the agent you already built. Do not re-platform it.

You already built an agent that does the work and then stalls at sign-off. Keep it where it is. Point the SDK at your self-hosted MakerChecker and wrap the tools it already calls, same names, same schemas. A denied action throws before the tool runs, and every call is signed into the audit. Typed connectors ship for LangChain and the Claude Agent SDK. CrewAI, LlamaIndex, and AutoGen connect through the generic SDK wrapper, and we never imply a typed connector we do not ship.

The connectors

Two typed connectors. One generic wrapper for everything else.

The honest version: LangChain and the Claude Agent SDK have typed connectors. CrewAI, LlamaIndex, AutoGen, and any other callable go through the generic SDK wrapper. Same governance, same audit; the difference is only how tightly it slots into your framework's types.

Typed connector

LangChain

governLangChainTool and governToolkit take a real LangChain tool and return one with the same name, description, and schema. The LLM tool spec is byte-for-byte identical, so it drops into the same ToolNode or agent executor with no other change.

Typed connector

Claude Agent SDK

governClaudeTool returns a normal SdkMcpToolDefinition with the name, description, and input schema preserved. Drop it into createSdkMcpServer alongside your ungoverned tools and the agent invokes it through the SDK as normal.

Generic SDK wrapper

CrewAI, LlamaIndex, AutoGen

There is no typed connector for these. They go through the generic SDK wrapper: governedTool in TypeScript or governed_tool in Python wraps any async callable that takes a plain-object input. The framework stays the executor; the wrapper adds check, run, record around the call.

Generic SDK wrapper

Any callable

A raw HTTP call, a database write, or a bare function works the same way. If there is no dedicated connector for your stack, the generic wrapper covers it, and it is what the LangChain and Claude connectors are built on.

Whatever the framework, the wrapper does the same three things in order, inside the tool call: check the proposal against the agent's role and grants, run the original tool if the check passes, and record the outcome to the audit chain. A denied check throws before the tool body ever runs.

The same pattern, both surfaces

A typed connector and the generic wrapper, in a few lines each.

The package names are real; the SDK and connectors live in the open-source repository. Both paths open a proxy session, wrap a tool, and let the agent call it normally.

Typed · LangChain

LangChain connector

import { createClient } from "@makerchecker/sdk";
import { governLangChainTool } from "@makerchecker/connector-langchain";
// Point at your own self-hosted MakerChecker.
const mc = createClient({ baseUrl: process.env.MAKERCHECKER_URL });
const { session } = await mc.proxy.openSession({ label: "pv-run" });
// Typed connector: name, description, and schema are preserved, so the
// governed tool drops into the same ToolNode or agent executor.
const assessSeriousness = governLangChainTool(
mc,
{ sessionId: session.id, agentName: "pv-processor", skillRef: "seriousness-assess@1" },
rawAssessSeriousness,
);
// The agent calls it normally. A denied action throws before it runs,
// and every call is signed into the audit chain.
await assessSeriousness.invoke({ case: "P-4003" });

Generic wrapper · CrewAI, LlamaIndex, AutoGen

generic SDK wrapper

from makerchecker import create_client, governed_tool, GovernanceDeniedError
mc = create_client(base_url=os.environ["MAKERCHECKER_URL"])
session = mc.proxy.open_session(label="pv-run")["session"]
# Generic SDK wrapper: CrewAI, LlamaIndex, AutoGen, or a bare function.
# There is no typed connector for these, and we never imply one.
triage = governed_tool(
mc, session["id"], "pv-processor", "case-triage@1", raw_triage,
)
# check -> deny raises GovernanceDeniedError before the function runs
# -> run -> record the outcome to the audit chain.
try:
triage({"case": "P-4001"})
except GovernanceDeniedError as err:
# err.code is machine-readable; err.reason is the human sentence.
route_to_human(err.reason)

Two integration models

Proxy sessions to wrap. Flows to gate.

Most teams start by wrapping the tools their agent already calls. When a high-risk step needs a named human to sign, a flow makes that sign-off a first-class, audited step instead of an out-of-band approval.

Proxy sessions

Wrap the tools your agent already calls.

A session ties a run of governed calls together in the audit. You open one, wrap and invoke tools against it, then close it. Each call is checked and recorded, and a high-risk action is denied before the tool runs. The fastest path, and where most teams start.

Run the quickstart →

Flows

Make the sign-off a first-class step.

Define the workflow in MakerChecker, with approval gates where a high-risk step waits for a named human to sign. The sign-off becomes an audited step in the run rather than an approval that happens somewhere off the record. Publishing a flow without the gate on a high-risk step is rejected by construction.

See a gated run verify →

skill_not_granted

The skill is not granted to the role, or not at this version. Deny by default.

sod_violation

Acting would break segregation of duties. The agent that processed a case cannot sign it off.

high_risk_requires_gate

The action is high-risk. Through the proxy it is denied; in a flow it waits at an approval gate.

A denial is a recorded event. The check is appended to the audit chain before the error is thrown, so a refused action leaves the same tamper-evident trace as an allowed one.

Where it runs

On your infrastructure, air-gapped if you need it.

You point the SDK at a control plane you run yourself, inside your perimeter, on your own Postgres. It can run fully disconnected, and it is open source, so the team that has to approve the integration reads every line before anything touches a real action.

Typed connectors
LangChain, Claude Agent SDK
Generic wrapper
CrewAI, LlamaIndex, AutoGen
Languages
TypeScript and Python
Models
Proxy sessions and flows
Runs on
Your infrastructure
On deny
Throws before the tool runs

Self-hosted · open source · the agent you already built, behind a gate it cannot talk its way past.

See it for yourself

Wrap your stalled agent. Ship it behind the gate.

One command starts the demo: an agent stopped from signing off its own work, and the signed evidence file an inspector can check for themselves.

Designed against the rules your auditors already enforce.