SDK-First Integration for AI Agent Control
Runplane sits between your agent and execution. Wrap your tools with the SDK, and decisions are enforced at runtime: ALLOW, BLOCK, or REQUIRE_APPROVAL.
How It Works
1. Bring Your Tools
Your existing agent tools
2. Auto-Mapped Actions
Canonical types generated
3. Baseline Policies
Ready-to-use, customizable
4. Wrap with guard()
Enforced at runtime
Installation
npm install @runplane/runplane-sdk
SDK Setup
import { Runplane } from "@runplane/runplane-sdk"
const runplane = new Runplane({
baseUrl: "https://runplane.ai",
apiKey: process.env.RUNPLANE_SYSTEM_KEY,
failMode: "closed" // block if Runplane unreachable
})failMode: "closed" blocks actions if Runplane is unreachable. Use "open" to allow execution if unreachable (not recommended for production).
Wrap Execution with guard()
The guard() method wraps your tool execution. Runplane evaluates the action against your policies and enforces the decision before the callback runs.
await runplane.guard(
"delete_employee", // canonical action type
"hr_system", // target resource or system
{ employeeId: "emp_7421" }, // context for policy evaluation
async () => {
// This callback only runs if ALLOWED or APPROVED
await deleteEmployee("emp_7421")
}
)How guard() works:
- 1. Sends action + context to Runplane for policy evaluation
- 2. Receives decision: ALLOW, BLOCK, or REQUIRE_APPROVAL
- 3. If ALLOW: callback executes immediately
- 4. If BLOCK: callback never runs, throws GuardBlockedError
- 5. If REQUIRE_APPROVAL: waits for human approval, then executes or blocks
Decision States
ALLOWCallback executes immediately. Low risk, policy permits.
BLOCKCallback never runs. Policy violation or excessive risk.
REQUIRE_APPROVALPauses until human approves or denies.
Error Handling
import { GuardBlockedError, GuardDeniedError } from "@runplane/runplane-sdk"
try {
await runplane.guard(
"delete_production_database",
"prod-db",
{ table: "users" },
async () => {
await dropTable("users")
}
)
} catch (error) {
if (error instanceof GuardBlockedError) {
// Policy blocked the action
console.log("Action blocked:", error.reason)
} else if (error instanceof GuardDeniedError) {
// Human denied the approval request
console.log("Approval denied:", error.reason)
}
}Framework Integration
Runplane works with any AI agent framework. Wrap your tool implementations with guard().
LangChain
import { tool } from "@langchain/core/tools"
import { z } from "zod"
const deleteRecordTool = tool(
async ({ recordId }) => {
// Wrap with Runplane guard
await runplane.guard(
"delete_record",
"database",
{ recordId },
async () => {
await db.delete(recordId)
}
)
return "Record deleted"
},
{
name: "delete_record",
description: "Delete a record from the database",
schema: z.object({ recordId: z.string() })
}
)Vercel AI SDK
import { tool } from "ai"
import { z } from "zod"
const sendEmailTool = tool({
description: "Send an email to a user",
parameters: z.object({
to: z.string(),
subject: z.string(),
body: z.string()
}),
execute: async ({ to, subject, body }) => {
// Wrap with Runplane guard
await runplane.guard(
"send_email",
"email_service",
{ to, subject },
async () => {
await sendEmail({ to, subject, body })
}
)
return { sent: true }
}
})Importing Existing Tools
Use the dashboard to import tools from your agent framework. Runplane automatically maps them to canonical action types and applies baseline policies. You remain in control — customize policies for any action type.
Supported import sources:
- LangChain tool definitions
- Vercel AI SDK tools
- OpenAPI specifications
- Manual tool registration
Direct API Access (Advanced)
For environments where the SDK cannot be used, you can call the decision endpoint directly. However, the SDK is the recommended integration path.
curl -X POST https://runplane.ai/api/decide \
-H "Content-Type: application/json" \
-H "Authorization: Bearer RUNPLANE_SYSTEM_KEY" \
-d '{
"actionType": "send_email",
"target": "email_service",
"context": { "recipientCount": 50000 }
}'Response:
{
"decision": "REQUIRE_APPROVAL",
"reason": "Bulk email requires approval",
"requestId": "req_abc123"
}Note: When using the direct API, you are responsible for handling the decision and blocking/allowing execution in your code. The SDK handles this automatically.
Full SDK reference and tool management available in the dashboard after account creation.