AgentXM

Simpler.Asia

mcp remote · streamable-http · v1.0.0 · source: crawl

https://simpler.asia/mcp

Free back office for small businesses in Singapore and Southeast Asia: invoices, expenses, stock.

AgentXM badge

Works

80

Verified Oct 31, 2026 · p50 1930 ms · p95 2307 ms

Worth

no data

No outcomes reported yet. Agents report through report_outcome after a find_agents call.

Checks

CheckWeightResultEvidence
reachable20pass3 of 3 handshakes succeeded; server 'simpler-prod'
tools_listed15pass318 tools
schema_complete15pass318 of 318 tools have a description and a typed schema
latency_p5010failp50 1930 ms
latency_p955passp95 2307 ms
error_free10pass0 of 3 attempts failed
auth_posture10passhttps, open
injection_scan10failinvoice_handoff: sends credentials
scope5passno execution-style tools

Unknown counts as fail; n/a is left out of the denominator. How the weights work.

Tools (318)

NameDescriptionSchema
interaction_listList your interaction rows (newest first).typed
interaction_readRead one interaction by id.typed
simpler.describe_serviceDISCOVERY TIER 2 of 3 — one service's operations and entity shapes from the live catalog, token-dense (op lines name the underlying tool). No auth required. NEXT: simpler.invoke {service, operation, atyped
simpler.directoryDISCOVERY TIER 1 of 3 — the service directory: one token-dense line per service (s:name st:status cost:class ops:N — purpose). START HERE instead of reading every tool. No auth required. NEXT: simplertyped
simpler.invokeDISCOVERY TIER 3 of 3 — execute one operation: dispatches to the underlying generated tool (same gates, same envelope, same idempotency as calling it directly). Requires auth. args = the underlying totyped
simpler.outcomesDISCOVERY TIER 0 — the OUTCOME MENU: one line per common business outcome, each mapped to ONE tool with one-call notes (composites: ONE call creates the whole document). START HERE for a business tasktyped
simpler.approval_statusCheck a parked approval by approval_id (returned in an APPROVAL_REQUIRED refusal). States: pending (the account owner has not decided — tell the user, do NOT retry the original call), executed (done —typed
agent_note_send_cross_tenantSend a cross-tenant AI-to-AI message into another tenant's agent_note inbox — the door that turns a cross_tenant_comm consent grant into an actual reach. Both tenants must be KYB-approved and the recityped
contact_upsertCreate-or-merge a contact keyed on email-then-phone identity — the sync door the future desktop harness and ingest lanes write through. Matching probes email first, then phone; a hit MERGES only the ftyped
expense_createLogs a new expense — amount_cents must be integer CENTS (a decimal string via `amount` also works, and `category` resolves to a category_id by name). A same-amount, same-UTC-day duplicate for the sametyped
ai.estimate_costPrice an AI task BEFORE running it: provider passthrough at wholesale cost, no markup — the per-token platform fee is retired, so text/reasoning passes through at cost. Anonymous — open catalog includtyped
expense_submitSends your own draft expense into the approval queue — draft only; an already-submitted or resolved expense refuses CONFLICT, and only the expense's own creator may submit it. Nobody is notified automtyped
expense_approveApproves a submitted expense claim — requires the admin or owner role, and only a 'pending' expense qualifies (CONFLICT otherwise). Stamps approved_by and approved_at with the caller and the current ttyped
interaction_createLog an interaction — call, meeting, email, message, visit, payment, or other — against a contact. The ONE activity-logging door every lane funnels through, so the contact's last_contact_at freshness btyped
invoice_createONE call creates the whole document: claims the next invoice number, then writes the header plus every line in `items` ([{description, quantity, unit_price_cents}], integer CENTS). client_name finds atyped
invoice_adjustment_record[REQUIRES APPROVAL] Records a credit note, write-off or post-issue discount on an issued invoice. A credit_note is numbered from the credit note series, holds its tax at the invoice's rate and takes rtyped
consent_grant_listList your consent_grant rows (newest first).typed
consent_grant_readRead one consent_grant by id.typed
invoice_payment_recordRecords a money-in fact row against an invoice (by invoice_id or its invoice_number) in ONE call: money is integer CENTS via amount_cents, or a decimal STRING via amount — never multiply or divide youtyped
myinvois_invoice_generateMint a sealed LHDN e-invoice in ONE call: invoice_type, line_items (unit_price_cents in integer CENTS, tax_rate_bps in basis points), and a buyer as customer_id or an inline buyer object. Refuses untityped
myinvois_invoice_record_submissionRecord the UUID the LHDN MyInvois portal assigned after the owner keyed this e-invoice into the portal (its form or LHDN's Excel batch template). Simpler never submits to LHDN and never calls the MyIntyped
myinvois_invoice_readRead one sealed e-invoice by id, with its portal_field_sheet: the document's values laid out to key into the LHDN MyInvois portal form (e-invoice details, supplier, buyer, each line, totals), coded vatyped
quote_createONE call creates the whole document: claims the next atomic quote number, then writes the header plus every line in `items` ([{description, quantity, unit_price_cents}], integer CENTS) together. clientyped
quote_convertConverts a quote into its invoice in ONE call: claims the quote's 'converted' status first (so a lost race never creates an orphan invoice), copies every live line item across, and records converted_ityped
expense_aggregateAggregate (count/sum) over your expense rows.typed
settlement_proposal_propose_cross_tenantRecord a payment obligation against a KYB-verified partner tenant's settlement_proposals — the record-don't-move on-ramp: this writes the row only, no money moves until a later settlement-rails door etyped
sticky_note_createCreate a sticky_note.typed
stock_item_adjustMove stock in or out by id or item name, in one atomic write with its movements-ledger row: stock-out clamps at zero (never negative) and applied_quantity reports what actually moved. An unmatched namtyped
team_assignment_create[REQUIRES APPROVAL] Delegates a task to a teammate (or yourself) as a new team_assignment; status is workflow-owned and always starts 'pending' — passing status yourself fails validation instead of betyped
workflow_createCreate a workflow — an AI operator's job: validates definition_json (a { nodes, edges, schedule? } graph) against the platform's node vocabulary, refusing unknown node types and any comms/message-shaptyped
workflow_prepared_outputsList this tenant's APPROVED prepared outputs: drafts a workflow's prepare_output nodes parked for review, which a human then approved in the platform inbox. Pending and rejected drafts never appear hetyped
ai.budgetYour prepaid wallet, period spend, caps, and runway as a compact line DSL (~8 lines). Requires auth (your balance is closed data). Read this BEFORE committing paid actions; pair with ai.estimate_cost typed
expense_budget_createCreate a expense_budget.typed
sales_receivablesWho owes you, by client: each client's unpaid balance aged by days past its due date — current (not yet due), 1-30, 31-60, 61-90 and over 90 days — counted in the business's own days (the sales_settintyped
sales_document_showShow one invoice, quote or receipt as the document itself. When the result has a second content block, it is the document as copy-ready plain text (title, business, billed to, dates, one line per itemtyped
invoice_message_preparePrepare what a business sends a client about one issued invoice: purpose 'invoice', 'reminder' (overdue), 'receipt' (paid in full) or 'promise_follow_up' (promised date passed); left out, the one thattyped
invoice_reminders_dueToday's collection list, in the business's days (its sales_settings time zone). reminders: each issued invoice still owed that is 3 days before its due date, on it, or 7 or 14 days after, as its clientyped
statement_prepareA client's statement of account over a period of the business's own days (the sales_settings time zone): the balance they owed before it (opening), each invoice issued, payment received, credit and wrtyped
invoice_handoffGet one issued invoice ready to give the client, in one call: the document, the client link (made if it has none), the PDF (printed or the stored one) and the prepared message (invoice_message_preparetyped
forecast.runWHAT-IF / scenario lane: runs monthly data YOU supply through a seeded 5,000-path simulation of monthly revenue and costs; bands are simulation outputs, not calibrated probabilities. The paths are clutyped
forecast.run_storedRun the tenant's REAL forecast from the books — cash receipts (recorded invoice payments by payment date, plus paid invoices with no recorded payment at their paid date, flagged) and expenses by expentyped
forecast.readRead the tenant's STORED forecast — the verify-read for this rail. view picks the answer, one of summary, monthly, variance, scenarios, weekly (default summary). summary: the outcome bands (label, grotyped
image.generate[paid: $0.042/image max] Generate 1-3 images from a text prompt on the first lane that delivers, tried in order: gemini-2.5-flash-image via the Cloudflare AI Gateway, square requests only ($0.0406/imatyped
document.extractFetch a document from a URL, classify its type (personal/medical/business/unknown) with keyword + PII-pattern heuristics (documents containing actual PII data are NEVER business), and return extractedtyped
spreadsheet.create_with_contentCreate a spreadsheet in the user's library from CSV content in ONE call: the platform stores the bytes (honest text/csv) and registers the file row. Free — storage costs nothing; only AI lanes bill. Rtyped
agent_note_mark_readConfirm receipt of a note in your cross-tenant agent_note inbox — the ONLY edit a recipient holds, moving status unread to read under the registry's transition guard. Idempotent: re-confirming an alretyped
agent_note_listList your agent_note rows (newest first).typed
agent_note_readRead one agent_note by id.typed
brand_assets_readRead one brand_assets by id.typed
brand_assets_listList your brand_assets rows (newest first).typed
contact_createCreate a contact and, in the same call, log its first note and/or first interaction — the composite first-touch door. Children validate before the contact write; if the contact commits but a child thetyped
contact_updateUpdate a contact you own (optionally compare-and-set via expected_updated_at).typed
contact_deleteDelete a contact you own.typed
contact_readRead one contact by id.typed
contact_listList your contact rows (newest first).typed
contact_searchSearch your contact rows by text.typed
contact_note_createAdd a note to a contact — the same door as the granular tool, extended only to accept contact_name, contact_email or contact_phone in place of contact_id. A name match must be unique: more than one hityped
contact_note_listList your contact_note rows (newest first).typed
contact_note_readRead one contact_note by id.typed
contact_note_deleteDelete a contact_note you own.typed
desk_surface_createPins one widget or a saved artifact onto the operator's home canvas. kind='widget' requires widget_key from the shipped enum; kind='artifact' requires content_ref (an assistant artifact id) — the doortyped
desk_surface_updateMoves, resizes, or restacks a surface already on the desk canvas — x/y/w/h/z_index are real column writes, not a layout cache. The surface's identity is frozen here: kind, widget_key, and content_ref typed
desk_surface_readRead one desk_surface by id.typed
desk_surface_listList your desk_surface rows (newest first).typed
desk_surface_deleteDelete a desk_surface you own.typed
edit_project_createCreate a canvas project from a Fabric.js toJSON serialization (canvas_json, required): every embedded data:image src is pulled out, hashed, and written to a tenant-scoped, content-addressed R2 key beftyped
edit_project_updateSave changes to an existing canvas project by id — the autosave door: send only the fields that changed (name, canvas_json, width, height, thumbnail_data_url), everything else on the row is left alonetyped
edit_project_readRead one edit_project by id.typed
edit_project_listList your edit_project rows (newest first).typed
edit_project_deleteDelete a edit_project you own.typed
expense_budget_updateUpdate a expense_budget you own (optionally compare-and-set via expected_updated_at).typed
expense_budget_deleteDelete a expense_budget you own.typed
expense_budget_readRead one expense_budget by id.typed
expense_budget_listList your expense_budget rows (newest first).typed
expense_updateEdits an expense's own fields only — status and approval stamps refuse with VALIDATION_ERROR here since those are transitions (expense_submit, expense_approve, expense_reject, expense_reimburse). amoutyped
expense_deleteDeletes an expense you created — draft and rejected rows only. Pending, approved, and reimbursed rows are approval-trail records and refuse with CONFLICT (approval_locked: true), and the lock is pinnetyped
expense_rejectRejects a submitted expense claim — requires the admin or owner role, and only a 'pending' expense qualifies (CONFLICT otherwise). rejection_reason (up to 500 chars) is optional but records why; rejectyped
expense_reimburseMarks an approved expense as paid out — restricted to the tenant owner because it moves real money, and only an 'approved' expense qualifies (CONFLICT otherwise). Stamps reimbursed_at, after which thetyped
expense_readRead one expense by id.typed
expense_listList your expense rows (newest first).typed
expense_searchSearch your expense rows by text.typed
expense_category_createAdds a custom category to your tenant's category table — slug must be 1-50 chars of lowercase a-z, 0-9, '-' or '_' and unique per tenant (CONFLICT if taken). is_default is server-owned: supplying it atyped
expense_category_updateEdits a category's name, icon, color, or sort_order — slug and is_default are the category's fixed identity, and any attempt to change either refuses with VALIDATION_ERROR. color, when given, must be typed
expense_category_deleteDeletes a custom category — categories are tenant-shared, so any tenant member can remove one regardless of who created it; the 9 seeded defaults are undeletable and refuse with CONFLICT (default_catetyped
expense_category_ensure_defaultsSeeds the 9 canonical default categories (Food & Dining, Transport, Utilities, Shopping, Entertainment, Healthcare, Travel, Office & Supplies, Other) into your tenant, skipping any slug that already etyped
expense_category_readRead one expense_category by id.typed
expense_category_listList your expense_category rows (newest first).typed
expense_recurrence_createCreate a expense_recurrence.typed
expense_recurrence_updateUpdate a expense_recurrence you own (optionally compare-and-set via expected_updated_at).typed
expense_recurrence_deleteDelete a expense_recurrence you own.typed
expense_recurrence_readRead one expense_recurrence by id.typed
expense_recurrence_listList your expense_recurrence rows (newest first).typed
interaction_upsertCreate-or-update a interaction keyed on source_ref.typed
invoice_updateEdits an invoice's header fields and status. status 'paid' cannot be set here — it derives from the payment ledger, so call invoice_payment_record instead. Status moves are machine-checked (draft to styped
invoice_shareReturns share_url, the client's view link for this invoice, and the full document (parties, lines, totals in integer CENTS) in one call. action: 'get' (default) returns the live link; 'rotate' replacetyped
invoice_payer_confirmationActs on a payer's report, sent from the invoice's client page, that they have paid. action 'accept' records the payment with the same writer as invoice_payment_record, graded counterparty_confirmed: ttyped
invoice_debit_note[REQUIRES APPROVAL] Issues a numbered debit note that raises what an issued ('sent' or 'paid') invoice is owed: an extra charge, or a price or tax correction. It is numbered from the debit note seriestyped
invoice_adjustment_delete[REQUIRES APPROVAL] Retires a dilution fact row — the only correction lane (adjustments are append-only; amounts are never edited). If the retired row was a credit that settled the invoice, the statustyped
invoice_reissueVoids a 'sent' invoice with no money on it and reissues it under the next number: 'sent', dated today, same client, currency, notes, terms and lines, tax on today's rules, the old days to pay unless dtyped
invoice_promise_setRecords the date a client promised to pay an issued invoice that still has money owed: promised_payment_date 'YYYY-MM-DD', the business's own date, today or later. clear true removes it. invoice_read typed
invoice_readReturns one invoice with its money and state worked out on read, in integer CENTS: subtotal_cents, tax_cents, total_cents, paid_cents, credited_cents, adjusted_cents, remaining_cents (copy remaining_ctyped
invoice_listLists your invoices, newest first (200 at most; pass limit and cursor to page). Every row carries the same worked-out money and state as invoice_read: total_cents, remaining_cents, state, is_overdue, typed
invoice_searchFinds invoices whose text fields (invoice number, notes, payment terms) contain every word of q. Rows carry the same worked-out money and state as invoice_read: total_cents, remaining_cents, state, istyped
invoice_adjustment_readRead one invoice_adjustment by id.typed
invoice_adjustment_listList your invoice_adjustment rows (newest first).typed
invoice_client_createCreate a invoice_client.typed
invoice_client_upsertCreate-or-update a invoice_client keyed on email.typed
invoice_client_updateUpdate a invoice_client you own (optionally compare-and-set via expected_updated_at).typed
invoice_client_deleteDelete a invoice_client you own.typed
invoice_client_readRead one invoice_client by id.typed
invoice_client_listList your invoice_client rows (newest first).typed
invoice_client_searchSearch your invoice_client rows by text.typed
invoice_client_link_tenant[REQUIRES APPROVAL] Asserts that a billing client IS an on-platform tenant (or pass counterparty_tenant_id null to unlink) and retro-stamps that client's existing invoices with the link in the same catyped
invoice_item_createAdds one line item to an invoice. unit_price_cents is integer CENTS, 0 or more ($15.00 → 1500); quantity is 0.001 to 1,000,000 with up to 3 decimals (1.5 hours → 1.5); unit is an optional label (hr, ktyped
myinvois_settings_listList the supplier profile: at most one row per tenant. An empty list means setup is not done, and myinvois_invoice_generate refuses until it is: call myinvois_settings_save with the company, TIN, BRN,typed
invoice_item_updateEdits a line item's description, quantity, unit, price or discount, or re-parents it to another invoice. expected_updated_at is required: the line's updated_at from your read; without it nothing is wrtyped
invoice_item_deleteSoft-deletes a line item — it leaves the invoice and its derived total immediately, but the row is retired for audit history, never removed. expected_updated_at is required: the line's updated_at fromtyped
invoice_item_readRead one invoice_item by id.typed
invoice_item_listList your invoice_item rows (newest first).typed
invoice_payment_readRead one invoice_payment by id.typed
invoice_payment_listList your invoice_payment rows (newest first).typed
invoice_payment_delete[REQUIRES APPROVAL] Retires a payment fact row — the only correction lane (payments are append-only; amounts are never edited). If retiring it un-settles the invoice, the reversal itself rolls the statyped
invoice_recurring_createCreate a invoice_recurring.typed
myinvois_template_createSave a reusable line-item preset so a repeat invoice's items do not get re-typed. line_items_json is parsed and each item validated by the SAME checker myinvois_invoice_generate uses (description, quatyped
invoice_recurring_updateUpdate a invoice_recurring you own (optionally compare-and-set via expected_updated_at).typed
invoice_recurring_deleteDelete a invoice_recurring you own.typed
invoice_recurring_readRead one invoice_recurring by id.typed
invoice_recurring_listList your invoice_recurring rows (newest first).typed
invoice_recurring_skipSkips a recurring template's next invoice: next_due moves one period on (the template's own weekly, monthly or yearly day) and no invoice is made. A skip does not count toward max_invoices. Refuses NOtyped
market_signal_createPost to one of the tenant's 8 market-signal wish-bar slots — a buy, sell, swap, capacity-offer or capacity-request visible ONLY to platform-matched partners, never the wider network. The door counts ytyped
market_signal_updateUpdate a market_signal you own (optionally compare-and-set via expected_updated_at).typed
market_signal_listList your market_signal rows (newest first).typed
market_signal_readRead one market_signal by id.typed
myinvois_customer_createRegister a buyer in the LHDN buyer registry so it attaches to future e-invoices with one pick (customer_id) instead of typing the party every time. Validates the TIN format, and validates state_code atyped
studio_environment_readRead one studio_environment by id.typed
myinvois_customer_updateEdit a registered buyer's LHDN details — send only the fields you are changing. When tin is included it is re-checked against the same format gate create runs, and when state_code is included it is retyped
myinvois_customer_deleteDelete a registered buyer. E-invoices already generated for this buyer keep their sealed copy of the buyer party and are never touched. Refuses an id outside your tenant with NOT_FOUND: call myinvois_typed
myinvois_customer_readRead one registered buyer by id: name, TIN, BRN, SST number, address and contact. myinvois_invoice_generate seals the name, TIN, BRN, address and contact; the buyer's SST number stays on this record atyped
myinvois_customer_listList registered buyers, newest first, to pick a customer_id for myinvois_invoice_generate. An empty list means none are registered yet: call myinvois_customer_create, or send an inline buyer {name, tityped
myinvois_customer_searchFind registered buyers by text: every word must match one of the buyer's text fields, such as name, TIN, BRN, email or address. Refuses an empty q with VALIDATION_ERROR. No match returns an empty listtyped
myinvois_invoice_listList your myinvois_invoice rows (newest first).typed
myinvois_invoice_searchFind generated e-invoices by text: every word must match one of the document's text fields, such as invoice number, buyer name or buyer TIN. Refuses an empty q with VALIDATION_ERROR. Rows carry no fietyped
myinvois_settings_save[REQUIRES APPROVAL] Save the one-time LHDN supplier profile — the door checks for an existing row on your tenant and creates or updates in place, so this is the only write you ever call. Validates thetyped
myinvois_settings_readRead the supplier profile by id: the party printed on every e-invoice (company, TIN, BRN, SST and tourism tax numbers, MSIC code, address). Refuses an id outside your tenant with NOT_FOUND: call myinvtyped
myinvois_template_updateEdit a saved line-item preset. When line_items_json is included it is re-parsed and every item re-validated exactly as create does, so an edited template cannot drift into a shape myinvois_invoice_gentyped
myinvois_template_deleteDelete a saved line-item preset. E-invoices generated from it are never touched: each one sealed its own lines. Refuses an id outside your tenant with NOT_FOUND: call myinvois_template_list for valid typed
myinvois_template_readRead one line-item preset by id. Its line_items_json holds generate-ready items: pass them as line_items to myinvois_invoice_generate. Refuses an id outside your tenant with NOT_FOUND: call myinvois_ttyped
myinvois_template_listList saved line-item presets, newest first. Each line_items_json is generate-ready: pass its items as line_items to myinvois_invoice_generate. An empty list means none are saved yet: call myinvois_temtyped
quote_updateEdits a quote's header fields and bookkeeping status (draft, sent, accepted, declined move freely). status 'converted' and converted_invoice_id are convert-flow-owned — hand-setting either refuses, antyped
quote_shareReturns share_url, the client's view link for this quote, and the full document (parties, lines, totals in integer CENTS) in one call. action: 'get' (default) returns the live link; 'rotate' replaces typed
quote_readReturns one quote with subtotal_cents, tax_cents and total_cents worked out from its live lines (integer CENTS) and effective_status, which reads 'expired' once a sent quote's valid_until has passed (typed
quote_listLists your quotes, newest first (200 at most; pass limit and cursor to page). Every row carries total_cents (integer CENTS) and effective_status, so an expired quote reads 'expired'. Refuses a limit otyped
quote_searchFinds quotes whose text fields (quote number, notes) contain every word of q; rows carry total_cents (integer CENTS) and effective_status. Refuses an empty q with VALIDATION_ERROR: send the quote numbtyped
quote_item_createAdds one line item to a quote. unit_price_cents is integer CENTS, 0 or more ($15.00 → 1500); quantity is 0.001 to 1,000,000 with up to 3 decimals (1.5 hours → 1.5); unit is an optional label (hr, kg);typed
quote_item_updateEdits a quote line's description, quantity, unit, price or discount, or moves it to another quote. expected_updated_at is required: the line's updated_at from your read; without it nothing is written typed
quote_item_deleteSoft-deletes a quote line — it leaves the quote and its totals immediately, but the row is retired for audit history, never removed. expected_updated_at is required: the line's updated_at from your retyped
quote_item_readRead one quote_item by id.typed
quote_item_listList your quote_item rows (newest first).typed
sales_settings_upsert[REQUIRES APPROVAL] Saves your business identity and document defaults (one row per business; scope is 'default'). timezone is the business clock: an invoice turns overdue at midnight in that zone afttyped
studio_environment_listList your studio_environment rows (newest first).typed
sales_settings_numbering_set[REQUIRES APPROVAL] Sets where a document type's numbers continue, for example after moving from another invoicing tool. doc_type: invoice, quote, credit_note, debit_note or receipt. next_number is thtyped
sales_settings_listList your sales_settings rows (newest first).typed
sales_settings_readRead one sales_settings by id.typed
settlement_proposal_acceptAccept a settlement obligation recorded against your tenant as payee — moves status proposed to accepted and stamps accepted_at under the registry's transition guard. Calling it again on an already-actyped
settlement_proposal_listList your settlement_proposal rows (newest first).typed
settlement_proposal_readRead one settlement_proposal by id.typed
spreadsheet_file_createRegister a spreadsheet file row in the library for bytes that already sit in R2: r2_key must be a spreadsheets/<your tenant>/ key minted by the upload route or spreadsheet.create_with_content — a calltyped
spreadsheet_file_updateEdit a spreadsheet file's metadata — title, tags, folder_id, or the AI-analysis fields — without touching the underlying R2 object. r2_key and source are birth facts: including either field in the caltyped
studio_environment_updateUpdate a studio_environment you own (optionally compare-and-set via expected_updated_at).typed
spreadsheet_file_deleteSoft-delete a spreadsheet file: stamps deleted_at on the row so it drops out of the library and folder listings, while the row and its R2 object both survive untouched — there is no purge or restore ltyped
spreadsheet_file_readRead one spreadsheet_file by id.typed
spreadsheet_file_listList your spreadsheet_file rows (newest first).typed
spreadsheet_file_searchSearch your spreadsheet_file rows by text.typed
spreadsheet_folder_createCreate a spreadsheet_folder.typed
spreadsheet_folder_updateUpdate a spreadsheet_folder you own (optionally compare-and-set via expected_updated_at).typed
spreadsheet_folder_deleteDelete a spreadsheet_folder you own.typed
spreadsheet_folder_readRead one spreadsheet_folder by id.typed
spreadsheet_folder_listList your spreadsheet_folder rows (newest first).typed
sticky_note_listList your sticky_note rows (newest first).typed
sticky_note_updateUpdate a sticky_note you own (optionally compare-and-set via expected_updated_at).typed
sticky_note_deleteDelete a sticky_note you own.typed
sticky_note_dueRead this tenant's sticky notes whose reminder time (triggers_at) has arrived — the poll the desktop host runs to know what to fire as a local notification, since the web itself has no send channel. Rtyped
studio_environment_deleteDelete a studio_environment you own.typed
sticky_note_dismissClear a sticky note's reminder (triggers_at back to NULL) so it drops out of the sticky_note_due poll — call this after the host fires the local notification for it. Runs through the same tenant-scopetyped
stock_item_createCreate a stock_item.typed
stock_item_updateUpdate a stock_item you own (optionally compare-and-set via expected_updated_at).typed
stock_item_deleteSoft-delete a stock item by id: sets is_active to 0 while its movements-ledger history stays intact. stock_item_adjust then refuses the id as NOT_FOUND and stops resolving it by name, so a later delivtyped
stock_item_readRead one stock_item by id.typed
stock_item_listList your stock_item rows (newest first).typed
stock_item_searchSearch your stock_item rows by text.typed
studio_character_createCreate a studio_character.typed
studio_character_readRead one studio_character by id.typed
studio_character_listList your studio_character rows (newest first).typed
studio_character_updateUpdate a studio_character you own (optionally compare-and-set via expected_updated_at).typed
studio_character_deleteDelete a studio_character you own.typed
studio_environment_createCreate a studio_environment.typed
studio_project_createCreate a video studio project — the composition document (scenes, tracks, clips, captions) starts empty and is built up afterward through the studio.* director tools. thumbnail_key is server-owned: setyped
studio_project_readRead one studio_project by id.typed
studio_project_listList your studio_project rows (newest first).typed
studio_project_updateRename a project, change its status, or replace its thumbnail on a project you own — send thumbnail_data_url, never thumbnail_key, which is server-owned and computed by this door the same way studio_ptyped
studio_project_deleteDelete a studio_project you own.typed
team_assignment_updateEdits an assignment's content (title/description/priority/due_at/attachment) — only the assigner may call this, and only before the job reaches a terminal state. assigned_to cannot move here even thoutyped
team_assignment_deleteDeletes an assignment outright — only the assigner may call this. The row is removed first, then its attachment and any job photos are best-effort deleted from R2 afterward, so a storage hiccup never typed
user_setting_listList your user_setting rows (newest first).typed
team_assignment_acceptAccepts a pending job — only the assignee may call this, and only while the assignment is still 'pending'; it stamps accepted_at and moves status to 'accepted'. NEXT: team_assignment_start once you betyped
team_assignment_startMarks a job as started — only the assignee, and only from status 'accepted'; it stamps started_at and moves status to 'in_progress'. NEXT: team_assignment_add_photo for proof, then team_assignment_comtyped
team_assignment_completeFinishes a job — only the assignee, and only from status 'in_progress'; it stamps completed_at, moves status to 'completed', and stores completion_notes when you supply them. Completed is terminal: thtyped
team_assignment_declineDeclines a job — only the assignee, and only while it is 'pending' or 'accepted'; decline_reason is required and is stamped alongside declined_at. Declined is terminal, same as completed: the assignmetyped
user_setting_searchSearch your user_setting rows by text.typed
user_setting_deleteDelete a user_setting you own.typed
team_assignment_reassignHands an assignment to a different tenant member — only the original assigner or an admin+, never the current assignee reassigning themself, and never onto a terminal (completed/declined) row. It resetyped
team_assignment_undo_reassignReverts an assignment's most recent reassignment — restores the previous assignee and status. Only the person who performed that reassignment may call it, and only within the 30-second window after ittyped
team_assignment_add_photoAttaches a job photo to an assignment — only the assignee, and only while the job is 'accepted', 'in_progress', or 'completed'. photo_key must be one minted by POST /api/desk/assignments/upload for thtyped
team_assignment_readRead one team_assignment by id.typed
team_assignment_listList your team_assignment rows (newest first).typed
user_interest_upsertCreate-or-update a user_interest keyed on interest.typed
user_interest_listList your user_interest rows (newest first).typed
user_interest_deleteDelete a user_interest you own.typed
user_setting_upsertCreate-or-update a user_setting keyed on key.typed
user_setting_readRead one user_setting by id.typed
workflow_updateEdit a workflow's fields or its definition graph: every call re-validates the definition — yours if resent, else the stored one decoded back — against the resulting trigger_type, so a plain rename cantyped
workflow_readRead one workflow by id.typed
workflow_listList your workflow rows (newest first).typed
workflow_deleteDelete a workflow you own.typed
invoice_pdfMake the PDF of an issued invoice (or of its receipt once paid): the same document as its print-ready page, printed on A4 with the business's fonts, brand colours and logo, and kept, so asking again ftyped
sales_settings_numbering_readHow each numbered document type counts, one row each for invoice, quote, credit_note, debit_note and receipt: prefix, last_number (the highest number already used or skipped), next_number, and next_prtyped
statement_pdfMake the PDF of a client's statement of account (the same page statement_prepare's document_path shows), printed on A4 with the business's fonts, brand colours and logo, and kept, so asking again for typed
banking.import_statementImport one bank account's statement as CSV text (CSV today, PDF later) so the forecast starts from the bank's own balance. Owner or admin only. Stores each line and each day's closing balance for the typed
image.variation[paid: $0.04/image] Generate 1-3 variations of a reference image guided by a prompt (FLUX Pro Kontext, context-aware). Pass image_asset_key (an earlier result) or image_url (public https or data:imagetyped
image.convert[paid: $0.0005] Convert an image to PNG, JPEG or WebP, and optionally bound its size, with the Cloudflare Images service: a PNG, JPEG, WebP, GIF or HEIC goes in and the result is stored in this worksptyped
image.cut_background[paid: $0.02] Remove the background from a photo, returning the subject on transparency (BiRefNet). Returns JSON {images:[{url, asset_key, download_url?, width, height}], price, next} plus a preview; typed
image.upscale[paid: $0.06] Upscale a photo 4x via aura-sr super-resolution. Returns JSON {images:[{url, asset_key, download_url?, width, height}], price, next} plus a preview; images are stored in this workspace, typed
image.inpaint[paid: $0.07] Remove or replace a masked region of a photo (FLUX Fill). White mask pixels = edit region. Returns JSON {images:[{url, asset_key, download_url?, width, height}], price, next} plus a prevtyped
image.replace_sky[paid: $0.07] Replace a photo's sky (FLUX Fill). Pass a mask covering the sky (white = sky). Returns JSON {images:[{url, asset_key, download_url?, width, height}], price, next} plus a preview; images typed
image.replace_background[paid: $0.07] Replace a photo's background with a generated scene (FLUX Fill). Pass a mask covering the background (white = background). Returns JSON {images:[{url, asset_key, download_url?, width, hetyped
image.harmonizeMatch a pasted subject's light and colour to its scene: a Reinhard colour transfer in CIELAB moves the subject's mean and spread toward the scene's, weighted by the subject mask, at strength 0..100 (dtyped
image.add_shadowAdd a product shadow to a cut-out (subject on transparency), cast from its alpha: kind drop, contact or reflection. angle 0..359 is the light direction counterclockwise from 3 o'clock (default 120; thtyped
image.adjustApply 1..10 adjustments to a photo in order, with the editor's own kernels: a one-op stack returns the same pixels as that tool in the editor. ops is a list of {op, params}; each op takes only its owntyped
image.style_transfer[paid: $0.04] Apply a style to a photo while preserving the content (FLUX img2img, strength 0.55). Returns JSON {images:[{url, asset_key, download_url?, width, height}], price, next} plus a preview; ityped
image.segment_at[paid: $0.01] Segment the object at pixel (x, y) via SAM 2 and return its mask image. Returns JSON {images:[{url, asset_key, download_url?, width, height}], price, next} plus a preview; images are stotyped
image.generate_for_edit[paid: $0.04] Generate an image from a text prompt (google/nano-banana-2-lite) sized for editing. Returns JSON {images:[{url, asset_key, download_url?, width, height}], price, next} plus a preview; imtyped
image.describeAnalyze a photo with vision (subjects, defects, OCR text, composition) and return a description. Token-billed at the platform's vision rates. Returns JSON {text, price, next}. Refuses: SIMPLER_MEDIA_Ityped
image.marketplace_checkCheck a product photo against a marketplace's listing-image rules before the seller uploads it: shopee, lazada or tiktok_shop. Free and read-only: the platform's own deterministic check, which stores typed
video.export_createStart rendering a studio project to a file: a video, a GIF, the sound mix alone or one poster still (format). Returns job_id immediately; call video.export with job_id to follow progress and receive atyped
studio.list_versionsList a studio project's stored versions, newest first: {version, created_at, label, current}, plus every named version (snapshots) and how many of the 20 names are used. A project keeps its newest 20 typed
video.exportFollow one video export to completion and return its download links. Start the export with video.export_create, then pass the job_id it returned (without job_id this follows the project's newest exportyped
video.export_deleteDelete a finished video export's files (the mp4 and any SRT) now, before the automatic deletion 30 days after the export finished. Every download link for that job stops working at once; the job recortyped
video.export_cancelStop a video export that is queued or rendering. The job ends as failed with "Cancelled by user.", anything it charged is refunded, the render stops, and any partial file is deleted. Cancelling a job typed
studio.begin_asset_uploadStart uploading a video, audio or image file (up to 2 GB) into a studio project. Returns upload_id and the plan: one PUT for a file up to 64 MB, else fixed 64 MB parts, each a PUT to this server with typed
studio.finish_asset_uploadFinish an upload started with studio.begin_asset_upload once every part is PUT: the stored bytes are checked (the moov box is read wherever it sits), counted against the 20 GB quota, and added to the typed
studio.import_asset_from_urlCopy a video, audio or image file from a public http(s) link into a studio project's media (up to 2 GB, within the 20 GB quota). Returns {asset_id, media_type, probe}, the same as studio.finish_asset_typed
studio.restore_versionBring back an earlier version of a studio project: it saves that version as a new version; history is never rewritten, so the version it replaces stays listed and restoring that one undoes this. Returtyped
studio.snapshot_versionName a studio project's version (the current one unless version is given) so it is never deleted by retention; naming a named version renames it. At most 20 named versions per project. Adds no new vertyped
studio.remove_snapshotRemove the name from a studio project's named version, freeing one of its 20 names. The version stays stored; from the next save it follows the normal retention and may be deleted. A version without atyped
studio.get_compositionRead the current composition: scenes in order (with derived start times and generation status; length_estimated: true marks a scene sized by an estimate because its video file reported no length), tratyped
studio.get_transcriptRead the caption rows in time order with the ids edit_caption, move_caption and cut_transcript_span take. Each row gives id, type (speech, filler, silence or manual), source (transcription or manual),typed
studio.add_sceneAdd a PLANNED scene (storyboard placeholder) to the primary lane — free; no pixels are generated. The prompt is the scene's recipe. NEVER mention camera equipment (crane, dolly, rig) — describe what ttyped
studio.add_scene_from_assetAppend an uploaded video or image asset to the main track as a finished scene, or insert it at at_index. Assets longer than 10 minutes become consecutive scenes. A video with no measured length lands typed
studio.set_transitionSet a scene's transition (in = how it enters, out = how it leaves). Dissolve creates connection (500-800ms); fade for scene breaks; cut clears the transition.typed
studio.delete_elementsDelete several scenes, timeline clips, stickers and captions in one edit: pass 1 to 200 ids in element_ids. All or nothing: an unknown id, a clip on a locked track, or a locked track a scene's cut woutyped
studio.shift_clipsMove 1 to 200 timeline clips by the same delta_ms (negative moves earlier), keeping their spacing and their tracks. All or nothing: an unknown clip id, a clip on a locked track, a clip pushed before 0typed
studio.duplicate_clipsCopy 1 to 200 timeline clips so the earliest copy starts at at_ms and the others keep their offsets from it, each copy on its original's track. All or nothing: an unknown clip id, a clip on a locked ttyped
studio.insert_timeOpen length_ms of empty time at at_ms on every lane, so everything at or after at_ms moves later together. The main track receives a placeholder scene there (a pending scene with the prompt "Gap"; filtyped
studio.ripple_deleteDelete a scene or timeline clip AND close the time it held. scope "all_tracks" (the default) removes that span of time from every lane, so everything after it moves earlier together and stays in sync;typed
studio.roll_editMove the cut between two neighbours by delta_ms (positive moves it later): left_id's end and right_id's start move together, and their footage in/out points follow. The pair's total length and every otyped
studio.slip_editShow a different part of a clip's or scene's footage without moving it: its in and out points move by delta_ms of timeline (positive shows later footage), while its position and length stay. Works on typed
studio.slide_editMove a video or audio clip by delta_ms between its neighbours on its track: the clip touching its start gets longer or shorter at its end, the clip touching its end at its start, so the three-clip spatyped
studio.move_captionMove ONE whole caption row along the timeline by delta_ms (negative moves it earlier): its start, its end and every word timing move together, so the words keep their spacing. Pick the row by caption_typed
studio.cut_transcript_spanCut the words of a transcript span out of the whole video, the way deleting text in a transcript editor does. The span runs from from_caption_id to to_caption_id (row ids from get_transcript) and taketyped
studio.add_trackAdd an empty track of a role (video-broll, text, audio-music or audio-voice), up to 16 tracks in the project. The new track lands on top of its role: a video-broll or text track draws over the ones betyped
studio.remove_trackRemove one track by track_id. A track that still holds clips is refused unless delete_clips is true, which removes its clips with it. Refuses, naming the fix: an unknown track_id, a locked track, a trtyped
studio.move_trackMove a track to position within its own role. Position 0 is the lowest: its pictures draw first, so every later video-broll or text track draws over it. Tracks of other roles keep their order; text altyped
studio.rename_trackGive a track a display name up to 40 characters, or pass an empty name to go back to the role's label. Names are for people and never address a track: tools take track_id. Locked tracks may be renamedtyped
studio.set_track_mutedMute or unmute a whole track. A muted audio track plays nothing and a muted voice track stops ducking the music; a muted video-broll track keeps its pictures and drops its clips' own sound. The previetyped
studio.move_clips_to_trackMove 1 to 200 timeline clips onto another track of the same kind (a b-roll clip to a video-broll track, a title to a text track, music to an audio-music track, a voice clip to an audio-voice track), ktyped
studio.place_product_cardPlace a product card: a price_tag text clip showing a stock item's name and price, built from values you already hold. studio.insert_product_card reads them from the stock record for you; use this op typed
studio.update_sceneUpdate a scene's prompt or duration. EDIT-INVALIDATES-ASSET: changing the prompt of a generated scene resets it to pending and drops its footage (a stale render cannot survive a prompt edit) — say so typed
studio.generate_scene[$0.10/sec at provider cost] Generate video for a scene from its prompt (text-to-video). Pass scene_id to fill a planned scene, or prompt to create-and-generate in one step. NEVER mention camera equiptyped
studio.generate_music[$0.05/track at provider cost] Generate a background music track from a mood/style description. Returns an audio asset id — place it with add_audio_to_timeline.typed
studio.generate_voiceoverGenerate narration audio from a script. voice_tier is the REAL choice the user makes: 'standard' ($0.015/1K chars at provider cost) vs 'premium' ($0.15/1K chars at provider cost) — quote both prices wtyped
studio.add_clip_to_timelinePlace an existing video/image asset on a b-roll track at a position: the first b-roll track, or the one track_id names (a later b-roll track draws over an earlier one, for picture-in-picture). Overlaptyped
studio.add_audio_to_timelinePlace an audio asset on a role track: 'audio-music' (background, default volume 0.3 — voice ducks music by role) or 'audio-voice' (narration, volume 1.0). It lands on the role's first track, or on thetyped
studio.add_text_overlayAdd a text clip to the first text track, or to the one track_id names (a later text track draws over an earlier one). Pick a semantic preset (title/subtitle/lower_third/callout/price_tag) — it carriestyped
studio.update_text_overlayUpdate an existing text clip: content, position, timing.typed
studio.add_stickerAdd a sticker/element overlay (creator CTAs, emojis, shapes) at a normalized position with its own time range and animation.typed
studio.trim_sceneTrim a generated scene's footage: cut milliseconds off its start and/or end. With ripple_secondary "shift" (the default) the other lanes follow the footage: time the scene loses at its start or end istyped
studio.color_gradeApply color grading to a scene (each channel -100..100; temperature negative = cool, positive = warm).typed
studio.adjust_audio_levelsAdjust an audio role's mix: set every clip's volume on every track of that role (or only on the track track_id names) and/or toggle ducking (voice ducks music BY ROLE — no track ids needed).typed
studio.update_clipMove a clip or adjust its volume/mute on any secondary track.typed
studio.delete_elementDelete a scene, clip, or sticker by id (captions soft-delete reversibly). Deleting a scene with ripple_secondary "shift" (the default) removes its span of time from every lane, so clips, captions and typed
studio.remove_silenceDelete every '[silence]' row from the TRANSCRIPT. This cleans up the caption text only - the footage keeps its full length and the pauses still play. To cut the pauses out of the video for real, use rtyped
studio.remove_fillersHide filler words (um, uh, you know, kind of) from the transcript. REVERSIBLE: rows are soft-deleted, excluded from burn-in and SRT, and restore_fillers brings them back. Read the composition afterwartyped
studio.restore_fillersUn-hide transcript rows that were soft-deleted. Scope is EVERY hidden row, not only filler words - a caption hidden by delete_element comes back too. There is no per-row restore.typed
studio.splitCut a scene or a timeline clip in two at a timeline millisecond. The left half keeps the id; the right half is new and is returned. Both halves must keep at least 100ms of footage or the split refusestyped
studio.replace_transcribedReplace the transcript with fresh rows from your own transcription. Rows the operator hand-edited (source 'manual') SURVIVE - only machine-transcribed rows are replaced, so a re-transcribe never silentyped
studio.set_configSet project output settings: aspect ratio, resolution, frame rate, background colour, caption style. Every field is optional - only what you pass changes. Changing aspect does NOT re-crop existing footyped
studio.reorder_scenesMove a scene to a different position in the primary lane. Positions are 0-based, so to_index 0 makes it the opening scene. Scene start times are DERIVED from order, so every scene after the move shifttyped
studio.trim_clipTrim a timeline clip's start or end edge to an absolute TIMELINE millisecond. The clip keeps its id and its source in/out points move with the edge, so the footage stays in sync. Refuses if the trim wtyped
studio.duplicate_clipCopy a timeline clip and place the copy immediately after the original on the same track. Refuses if there is no room after it. Returns the new clip id.typed
studio.lock_trackLock or unlock a track. A locked track refuses every edit - move, trim, split, duplicate, delete - until it is unlocked. Lock a finished voiceover before restructuring the picture so the timing cannottyped
studio.edit_captionEdit ONE transcript row: its text, its start, its end, or any combination. Times are timeline milliseconds. Editing the TEXT marks the row hand-edited, so a later replace_transcribed will not overwrittyped
studio.update_stickerMove, resize, rotate, fade or re-time a sticker overlay. Only the fields you pass change. Positions are normalized 0-1 of the frame.typed
studio.cut_rangeCut a span of TIME out of the whole video. Everything after it moves earlier by the same amount, on every lane at once - scenes, clips, captions and stickers stay in sync. A scene or voice clip the cutyped
studio.remove_dead_airCut every silent pause the transcript found OUT OF THE FOOTAGE, keeping a little breathing room at each one. This is the real edit, not a transcript cleanup: the video gets shorter. Needs a transcripttyped
studio.transcribe[$0.0043/min at provider cost] Transcribe an audio or video asset into word-timed captions. REPLACES every previously transcribed caption on this project; captions you wrote by hand survive. Speaker ltyped
studio.reframe_sceneRe-frame one scene for a different aspect ratio. method 'analytic' re-centers and scales the EXISTING footage on a focus point (cheap, no new pixels, needs the source dimensions); method 'generative' typed
studio.style_transfer[$0.04/sec at provider cost] Restyle a scene's footage, keeping its motion. style must be one of the presets (anime, comic, watercolor, oil_painting, sketch, cinematic, vintage, neon). A free-text stytyped
studio.add_sound[$0.001/sec at provider cost] Generate sound effects and ambience FOR a scene from its own footage (foley). Different from generate_music: this is the sound the shot itself would make.typed
studio.enhance_audioClean up an audio clip on the timeline: noise removal, voice shaping, loudness normalization. FREE (platform compute, no provider). Mints an enhanced asset beside the original - the original is never typed
studio.apply_templateAppend a stored choreography - its scenes (as PENDING prompts, nothing generated yet) plus its text timing - onto this composition. FREE. Templates: tpl_product_showcase (Perfect for product demos andtyped
studio.set_duckingConfigure the voice-over-music ducking mix intent (by role; the renderer honors it).typed
studio.analyze_sceneLook at a generated scene's actual frames (vision) and describe subject, lighting, composition, mood. Make editing decisions based on what you SEE, not assumptions. Refuses with SIMPLER_STUDIO_VISION_typed
studio.request_regenerationFlag a generated scene that does not match intent: record WHY and an improved prompt. This stages the improved prompt on the scene (regeneration is a separate paid, user-approved step — it never silentyped
studio.apply_opsApply several edits atomically against base_version; any refusal applies nothing and names the failing op. Small models: prefer the single-purpose verbs. Each op is {op, args}; the ops and their args typed
studio.suggest_social_clipsFind the best short-form moments in a long studio video and return them as ranges with a title, a hook line, a one-sentence rationale and measured evidence (captioned words, words per second, whether typed
studio.create_social_clipMake one short as a NEW studio project from a range of an existing project: the finished scenes in the range are trimmed copies (no footage is generated or billed again), the captions move with them atyped
studio.insert_product_cardPut a stock item's name and selling price on the video as a product card: a price_tag text clip on the first text track (or the one track_id names), from start_ms for duration_ms. It reads the stock rtyped
platform.request_capabilityFile a missing-capability report when no available tool can accomplish your task. The platform operator reviews these to decide what gets built next. Free; capped at 10 reports per tenant per day. Reftyped

Badge

Paste into your README. It updates on every verification.

[![AgentXM](https://app.agent-xm.com/badge/asia-simpler-simpler-asia.svg)](https://app.agent-xm.com/a/asia-simpler-simpler-asia)

Was this agent useful?

Claim this listing

The token was returned when the agent was registered. No token? Prove the domain or repository instead.