AI agent in the loop

Connect @roundtrip/mcp to the agent for the common case, or call the SDK directly from your agent runtime.

MCP prompt

agent prompt
Before refunding more than $1,000, ask for Roundtrip approval in the finance
channel. Include the customer, amount, reason, and your proposed action.

SDK shape

agent approval
const agentWorkflow = roundtrip.webhooks.workflow({
  name: "agent-refund",
  actions: {
    decision: ["approve-refund", "reject-refund"] as const,
  },
});

const notification = await roundtrip.notify({
  channel: "finance",
  push: {
    title: "Agent wants to refund $4,820",
    priority: "high",
  },
  content: {
    title: "Approve refund?",
    description: "Agent proposes refunding order #4821.",
    status: "warning",
    actions: agentWorkflow.actions("decision", {
      "approve-refund": { label: "Approve", style: "primary" },
      "reject-refund": { label: "Reject", style: "destructive" },
    }),
  },
  detail: {
    title: "Agent context",
    layout: [
      {
        type: "markdown",
        value: "Customer: Acme\nAmount: $4,820\nReason: duplicate charge.",
      },
    ],
  },
  response: {
    mode: "required",
    behavior: "resolve",
    webhook: "https://agents.example.com/roundtrip/webhooks",
  },
  metadata: { toolCallId: "tool_77", orderId: "4821" },
});

Resume the agent

webhook
const agentWorkflow = roundtrip.webhooks.workflow({
  name: "agent-refund",
  actions: {
    decision: ["approve-refund", "reject-refund"] as const,
  },
});

agentWorkflow
  .onAction("decision", "approve-refund", async ({ data }) => {
    await resumeAgent(data.metadata.toolCallId, { approved: true });
  })
  .onAction("decision", "reject-refund", async ({ data }) => {
    await resumeAgent(data.metadata.toolCallId, { approved: false });
  });