Evaluate · deny · audit before irreversible tools run

Stop irreversible agent
side effects cold.

Evaluate before the tool runs. Outcomes: allow, deny, or wait for a human — then a scrubbed audit.

Evaluatein the agent loop
Denywith reasons + receipts
Auditscrubbed projections
Outcomesallow · deny · wait
evaluate.ts
import { createRemoteEngine } from "@limetry/sdk"

const engine = createRemoteEngine({
  baseUrl: process.env.LIMETRY_BASE_URL,
  apiKey: process.env.LIMETRY_BEARER_TOKEN,
})

const decision = await engine.evaluateAction({
  intent_id: crypto.randomUUID(),
  policy_id: policyId,
  agent_id: "ci-bot",
  action_type: "deploy",
  resource: "github.com/acme/api@abc123",
  issued_at: new Date().toISOString(),
})

if (!decision.ok || !decision.approved) {
  throw new Error((decision.reasons ?? ["denied"]).join("; "))
}

MIT-licensed MCP, CLI, and SDK. ActionIntent evaluate runs on the self-hostable server. Audit stores scrubbed projections by default — see data minimization docs.

Evaluate before the tool runs

ActionIntent hits the server first. Allowed types, resource patterns, cost caps, and approval gates — not a prompt instruction.

Outcomes you can enforce

Allow continues. Deny blocks with reasons and a signed receipt. Approval-required waits for a human. Your loop still enforces the outcome.

Scrubbed audit you can tail

Every evaluate writes a minimized projection. Operators see what policy did — not secrets, tokens, or chat transcripts.

How it works

Every tool call gets an outcome

The same evaluate path works for any irreversible tool. These loops show allow, deny, or wait before the side effect runs.

Agent surface: Copilot coding agent

allow

PR typecheck

Copilot calls run_ci_privilege. Limetry allows ci_privilege so tests run. Deploy secrets stay unavailable.

deny

Fork production deploy

request_production_deploy on pull_request is untrusted. Limetry evaluates, records deny, then require_trusted fails closed before AWS keys load.

approval required

Main production deploy

Trusted push to main still returns approval_required. The coding agent prints approval_id and exits closed.

Same contract everywhere

Evaluate once. Enforce everywhere.

Evaluate before the tool runs.

Call createRemoteEngine().evaluateAction from any agent loop or adapter. Every evaluation returns an outcome — allow, deny, or wait — plus reasons and a signed receipt. The server requires intent_id (UUID) and issued_at.

Read SDK docs
import { createRemoteEngine } from "@limetry/sdk"

const engine = createRemoteEngine({
  baseUrl: process.env.LIMETRY_BASE_URL,
  apiKey: process.env.LIMETRY_BEARER_TOKEN,
})

const decision = await engine.evaluateAction({
  intent_id: crypto.randomUUID(),
  policy_id: policyId,
  agent_id: "ci-bot",
  action_type: "deploy",
  resource: "github.com/acme/api@abc123",
  issued_at: new Date().toISOString(),
})

if (!decision.ok || !decision.approved) {
  throw new Error((decision.reasons ?? ["denied"]).join("; "))
}
Open source · MIT

Install the stack. Run evaluate in your VPC.

SDK, CLI, MCP, and the evaluation server are MIT-licensed. Apply an ActionPolicy, call evaluate from your agent loop, and tail scrubbed audit on infrastructure you control.