Turn your SaaS API into tools AI agents can use
Import your OpenAPI document and Riviera serves the operations it can call as tools agents can use, with no MCP server to build or run. See how agents use each tool, and improve what they read without redeploying your backend.
Riviera editing the create_invoice tool of a sample project, Acme API. Your server describes the tool as “Creates an invoice.” with no parameter descriptions. The draft agents will read has a fuller description and a description for each parameter. For the request “Bill customer cus_8Hq2 for the March retainer”, the model picked record_charge on Production, which fails, and create_invoice on the draft, which passes.
6 tools
- create_invoiceDraft
- get_invoice
- list_customersDraft
- record_chargeDraft
- refund_payment
- void_invoiceOff
What agents read
Description
Your server saysCreates an invoice.
Parameters
The wrong tool call doesn’t throw an error. It just does the wrong thing.
Agents don’t know your product. For every request, they read the name and a short description of each tool, pick the one that sounds closest and fill in the inputs as best they can. When they get it wrong, nothing breaks. The call goes through, your customer gets the wrong result, and to them it’s your product that failed.
- You find out from a support ticket.
- Your logs show a successful call. They don’t show it was the wrong one.
- A one-line fix is a full release.
- Tool descriptions live next to the code that runs them, so changing a sentence means a PR, a review and a deploy of your server.
- You can’t tell if the fix worked.
- Wording that helps one request can break another, and today the only way to check is to ship it and wait.
Know which tool the agent will choose before you ship
Today you ship a new description and hope. Write down the requests your customers actually make, and the tool that should handle each one. Riviera runs them against a real model, on what agents read today and on your draft, side by side. You see that 2 of 5 fail today and all 5 pass with your edit, before anything changes for a single user.
Sample eval results for Acme API. Production passes 3 of 5 evals. The draft passes 5 of 5.
- Production
- 60%
- Draft
- 100%
- Bill a customerBill customer cus_8Hq2 for the March retainer, 4,200 dollars, due in 14 days.Expected: create_invoiceProductionFailDraftPass
- Record a bank transferNorthwind paid invoice 2041 by bank transfer, mark it as received.Expected: record_chargeProductionFailDraftPass
- Find a customer by nameWhat is the customer id for Northwind Traders?Expected: list_customersProductionPassDraftPass
- Look up one invoiceShow me invoice 2041.Expected: get_invoiceProductionPassDraftPass
- Refund part of a paymentRefund 40 dollars of payment pay_31Xc.Expected: refund_paymentProductionPassDraftPass
Every plan includes model test runs each month: 200 on Free, 2,000 on Pro. A run is one request checked against one version.
Ship a better description without shipping your backend
A sentence shouldn’t need a deploy. Edits stay in a draft, so agents keep reading what works until you’re ready. Publishing creates a new version with no PR, no build and no change to your server. Every published version is kept exactly as it was, so when something goes wrong you know precisely what agents were reading at the time.
Review of the changes waiting to be published for Acme API. Three tools changed since Production v12. The description of record_charge changes from “Records a charge.” to a fuller one that says not to use it to bill a customer.
record_chargeDescription edited
create_invoiceDescription and 3 parameters edited. Input schema changed
Input schema
Production (v12)
{
"type": "object",
"properties": {
"customerId": {
"type": "string"
},
"lineItems": {
"type": "array"
},
"dueDate": {
"type": "string"
}
},
"required": [
"customerId",
"lineItems"
]
}Draft
{
"type": "object",
"properties": {
"customerId": {
"type": "string",
"description": "Customer to bill. Get the id from list_customers."
},
"lineItems": {
"type": "array",
"description": "One item per billable line. Amounts are in cents."
},
"dueDate": {
"type": "string",
"description": "Due date, YYYY-MM-DD. Defaults to 30 days."
}
},
"required": [
"customerId",
"lineItems"
]
}list_customersDescription edited
Review every change before agents see it.
See what agents actually did, not just that the request succeeded
Every call shows the tool the agent chose, the version it was reading, how long it took and, when it failed, where: bad arguments, an error from your server, a timeout or authorization. So you can tell a tool agents misunderstood from a backend that broke, and know what to fix next.
Sample tool-call activity for Acme API over 7 days: 4,678 calls, 98.8% successful, 57 failed, 214 milliseconds on average. The recent calls include one failed refund_payment call with the error “payment pay_31Xc is already fully refunded”.
- Tool calls
- 4,678
- Success rate
- 98.8%
- Failed calls
- 57
- Avg duration
- 214ms
| Timestamp | Tool | Status | Duration |
|---|---|---|---|
| 3/18/2026, 2:41:07 PM | create_invoice | Success | 412ms |
| 3/18/2026, 2:41:05 PM | list_customers | Success | 89ms |
| 3/18/2026, 2:38:52 PM | refund_payment | Error: payment pay_31Xc is already fully refunded | 131ms |
| 3/18/2026, 2:36:20 PM | get_invoice | Success | 96ms |
| 3/18/2026, 2:35:44 PM | get_invoice | Success | 102ms |
| 3/18/2026, 2:31:09 PM | record_charge | Success | 240ms |
Every miss becomes a test
Found a call that went wrong? Add what the user was asking for and it becomes a test in your set, linked to that call. Fix the description, check it against the test, and publish. The mistake stays in your tests, ready for the next change.
Start from what you already have
Bring your API or the MCP server you already run. Both become a Riviera project with the same building, testing, versions and visibility.
- Import an API
- Operations Riviera can call exactly as your document describes become tools agents can call, and the import tells you what to change for the rest. Nothing to build or host. See what converts or read the import documentation.
- Connect your MCP
- Keep the server you have. Riviera adds the layer around it.
Give agents a version of your product they get right
Import an OpenAPI document or connect your MCP. No changes to your backend. Free for one project and 10,000 tool calls a month.