When to embed Duvo vs. build the capability yourself
| Embed Duvo when… | Build natively when… |
|---|---|
| The task already exists as a configured Duvo Agent | The task is simple and doesn’t need connections or HITL |
| The task involves approvals, sensitive systems, or audit needs | Latency is critical and a Run round-trip isn’t acceptable |
| Non-developers need to maintain the task’s AOP | You want full control over the execution environment |
| The task spans multiple Connections (Gmail + Sheets + Slack…) | The task has no human-in-the-loop requirement |
- An editor-agent reviews a document and delegates any compliance action to a Duvo Agent.
- A customer copilot triages a request and hands a regulated branch (refund, escalation) to Duvo, where a human can approve it.
- An internal AI workbench catalogs Duvo Agents as named skills and routes work to them by category.
How it works
Your agent connects to the Duvo MCP server (https://api.duvo.ai/v2/mcp). Every Duvo Public API endpoint is auto-exposed as an MCP tool. Your agent calls those tools to start Runs, poll for completion, respond to human-in-the-loop requests, and collect results — all through a standard MCP interface.
Scoping which Agents your agent can call
The Duvo MCP server exposes tools for the full Public API. Your agent can calllistAgents to discover all Agents visible to its API key, then filter by name or ID to invoke specific ones.
Narrowing scope with API keys:
Each API key is scoped to a team and inherits the permissions of the user who created it. To limit a parent agent to a subset of Agents, create a dedicated Duvo user with access only to the relevant Agents and generate an API key for that user. This prevents the parent agent from accidentally discovering or starting Agents it shouldn’t touch.
Discovering Agents at startup:
How an Agent appears as a tool
When your agent callslistAgents, each Agent is returned with metadata your agent can use to decide which one to invoke. Here is a trimmed example of the response (additional fields omitted for brevity):
id, name, and latest_build.revision_description. The name and description come from what was entered in the Duvo dashboard — edit them there to make the Agent self-describing for your agent.
Tips for writing agent-friendly Agent metadata:
- Name: use a verb phrase — “Process Refund Request”, “Triage Support Ticket”, “Update Inventory Record”.
- Revision description (
latest_build.revision_description): explain the input the Agent expects and the output it produces — “Takes a customer complaint email body. Returns a triage decision (escalate / auto-resolve / needs-more-info) with a one-sentence rationale.”
Invocation patterns
All Run endpoints are on the base URLhttps://api.duvo.ai/v2. Starting a Run is team-scoped (POST /teams/{team_id}/runs); reading and responding to a Run is addressed by run_id.
Synchronous (poll until done)
Start a Run, then pollgetRun until the status is completed, failed, or stopped. Suitable for short-running Agents (under a few minutes).
Asynchronous with a webhook
Provide awebhook_url when starting the Run. Duvo POSTs to that URL on state changes (run_completed, run_failed, run_interrupted) and when the Agent needs input (human_request), so your agent doesn’t have to poll. Filter on the payload’s event field for the case you care about.
HITL handoff
When Duvo reaches a step that requires human approval, the Run’s status changes towaiting. If your parent agent is polling, it detects this status and can either:
- Forward the request to a human — surface the
titleanddescriptionfromgetRun’spending_human_requestfield in your agent’s own UI or chat thread, then relay the human’s answer back viarespondToHumanRequest. - Respond programmatically — if your agent has enough context to make the decision itself, it can call
respondToHumanRequestdirectly without surfacing it to a human.
Trust and guardrails
What the parent agent can’t do:- The parent agent operates under the permissions of its API key. It cannot bypass Connection-level authorization — if the Agent uses a Gmail Connection that the API key’s user can’t access, the Run will fail with a permissions error.
- The parent agent cannot modify the Agent’s AOP or Connections through an MCP tool call without the corresponding write endpoints, which should be locked down for service accounts.
End-to-end example: email triage with a human approval gate
A parent agent monitors an inbound email queue. When it receives a complaint that touches a financial policy, it delegates to a Duvo Agent, waits for a human to approve the proposed response, then sends the final email.- The parent agent starts a Run on the “Complaint Triage” Agent with the raw email body.
- Duvo’s Agent reads the complaint, connects to the order system via its configured Connection, drafts a refund proposal, and pauses — asking an operator to approve before sending.
- The parent agent detects
waiting, fetches the HITL request, and surfaces the draft to an on-call operator (via a chat message, Slack notification, or UI). - The operator approves or rejects. The parent agent relays that decision back to Duvo.
- Duvo sends the approved response and marks the Run
completed. - The parent agent reads the final result and continues its own workflow.
Related
- The Duvo MCP server — how to configure authentication and connect any MCP-compatible host
- Connect a custom MCP to Duvo — the inverse direction: bring your own tools into Duvo Agents
- Running Agents via API — full API reference for Runs, messages, and HITL responses
- Guardrails for High-Risk Automations — risk framework for delegating irreversible actions
- Audit Log and Activity Tracking — how to trace which agent started which Run