oto_apps
Apps: screens people build on the platform — dashboards, review queues. Before building or changing one, read the guide: oto_guide op=read slug=build-apps. An app is a manifest (the tables, fields and agents it touches) plus HTML that runs sandboxed and talks to the platform through its window bridge. Not a memory page. An app has its OWN owner and shares, like a table: a new one belongs to you, in your active organization, private unless the org shares new apps by default; share or transfer it with oto_resource (resource_type=app). Projects only FILE apps (shown on the project page), they give no access.
op=list (no project: your active org's apps; project_ids: those filed there; cards, no HTML) / get (app_id; with manifest, HTML and rev) / create (title, manifest, html, optional thumbnail, optional project_id to file it) / read_file (app_id, file_id: a file a person dropped in the app, for the run they started — PDF text, a sheet as CSV, text inline, plus a signed link to the original) / put_file (app_id, name, content or content_base64, media_type: hand a RESULT file back to the app, for the person whose run this is — they get it with oto.files() / oto.download; PDF, Word, Excel, text, CSV, JSON, 20 MB) / update (app_id, any of those; pass expected_rev from get → 409 if it changed) / patch (app_id, edits: exact find → replace in the HTML, each find unique, all or nothing; returns rev, replaced and warnings, never the HTML — prefer it to update for any change smaller than the whole page) / archive / unarchive / revisions / restore (revision_id) / file / unfile (app_id, project_id) / validate (manifest, and app_id for an existing app, optional html: the problems a create would refuse, nothing written). create, update, patch, restore and validate also return warnings: oto.rows / oto.aggregate calls that sort, filter, group or measure on a field the manifest doesn't declare (_created_at / _updated_at are always sortable and filterable) — the open app would refuse them, so fix them first. Every declared table and agent must be within YOUR reach and in the app's organization: otherwise 400 invalid_manifest, each problem listed.
In the HTML, window.oto: rows(table, {filter, orderBy, limit}) / aggregate(table, {groupBy, metrics, filter}) / set(table, rowId, field, value) / add(table, values) / upload(file) → {id, name, mediaType, size} (manifest files: true; PDF, Word, Excel, text, CSV, JSON; 20 MB a file, 1 GB per viewer per app, kept 30 days) / files() → each with origin upload or agent / download(fileId) (opens the viewer's own file) / runAgent(agent, {input, files: [ids]}) → {jobId} — the run gets each file's text and reads it in full with op=read_file / job(jobId) / runs(agent) / go(route). A click in the app does NOT approve anything: every set, add, upload and runAgent is shown by the HOST screen (outside the app) with what it writes, and runs only once the viewer confirms there — cancelled, it rejects. Ask for one gesture at a time, from a click. One run of an agent waits at a time (run_already_queued): collect files, then one runAgent with files: [...].
Tool call template
Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {
"op": "<op>"
},
"name": "oto_apps"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| op | Yes | ||
| _org | No | ||
| html | No | ||
| name | No | put_file: the file's name, with its extension (`summary.csv`, `report.docx`). | |
| edits | No | patch: exact replacements in the app's HTML, applied in order, all or nothing — `[{"find": "…", "replace": "…"}]`; `find` must appear exactly once (or pass `"all": true`). | |
| title | No | ||
| app_id | No | ||
| content | No | put_file: the file's TEXT (CSV, Markdown, text, JSON). Exactly one of `content` or `content_base64`. | |
| file_id | No | read_file: a file a person dropped in the app (its id comes with the run's input). | |
| archived | No | ||
| manifest | No | ||
| thumbnail | No | ||
| media_type | No | put_file: its type (`text/csv`, `application/pdf`…); judged on the bytes anyway. | |
| project_id | No | create: also file the new app in this project. file / unfile: the project. list: only the apps filed in it. | |
| project_ids | No | list: only the apps filed in these projects (at most 200). Without any project: the apps of your active organization. | |
| revision_id | No | ||
| expected_rev | No | ||
| content_base64 | No | put_file: the file's bytes in base64 (PDF, Word, Excel). | |
| clear_thumbnail | No |