CrewAI Integration
Protect CrewAI tools with direct Veto API checks.
CrewAI is a Python framework. The local SDK in this repository is the TypeScript veto-sdk, so it does not currently publish veto.integrations.crewai.
Use a guarded BaseTool while a native Python helper is not available.
Guard a CrewAI tool
import httpx
import os
from crewai.tools import BaseTool
from pydantic import BaseModel, Field
async def veto_guard(tool_name: str, args: dict):
response = await httpx.AsyncClient().post(
"https://api.veto.so/v1/validate",
headers={"X-Veto-API-Key": os.environ["VETO_API_KEY"]},
json={"toolName": tool_name, "arguments": args},
timeout=10,
)
response.raise_for_status()
decision = response.json()
if decision["decision"] != "allow":
raise RuntimeError(decision.get("reason") or decision["decision"])
class TransferInput(BaseModel):
amount: float = Field(description="Amount to transfer")
to_account: str = Field(description="Destination account")
class TransferFundsTool(BaseTool):
name: str = "transfer_funds"
description: str = "Transfer money between accounts"
args_schema: type[BaseModel] = TransferInput
async def _arun(self, amount: float, to_account: str) -> str:
await veto_guard(self.name, {
"amount": amount,
"to_account": to_account,
})
return f"Transferred ${amount} to {to_account}"Register tools for Charter
import { Veto } from "veto-sdk";
const veto = await Veto.init();
await veto.registerTools([
{
name: "transfer_funds",
description: "Transfer money between accounts",
parameters: [
{ name: "amount", type: "number", required: true },
{ name: "to_account", type: "string", required: true },
],
},
]);
const res = await fetch("https://api.veto.so/v1/charter/turn", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Veto-API-Key": process.env.VETO_API_KEY!,
},
body: JSON.stringify({
message: "Transfers over $1,000 require finance approval.",
mode: "compile",
surface: "api",
}),
});
const draft = await res.json();Use the returned verification link to approve the policy before it goes live.

