Classification: Internal-Only
Curated input/output notes for the most-used tools. The authoritative, complete list of tool names and effects is the generated Tool catalog (built from libs/typescript/mcp-tool); if this page and the catalog disagree, the catalog wins. Tool names and input parameter names were checked against the catalog and the tools’ input schemas; output descriptions are hand-written and may lag the code.
Every tool below is scoped to your own organization and checked against your own BonsAI permissions — the same rules the web app enforces. entity_id (and any other id) has to be one you already have access to; list_entities is usually the first call in any conversation.
Pagination note: most list_* tools take page_number (0-indexed) and n_per_page (1–100, default 20), and return has_more/next_page_number — keep n_per_page the same across pages.
Identity, organization & usage
#
| Tool |
Input |
Output |
What it does |
get_organization_by_external_id |
external_id (Clerk org id, org_...) |
Org id, name, slug, timestamps |
Looks up any organization by its Clerk id (not just your own) |
get_organization_settings |
(none) |
Email-domain whitelist setting, knowledge-sharing opt-in |
Your org’s settings — requires org admin/owner |
get_organization_roles |
page_number?, n_per_page? |
Every entity role in your org, with full per-resource permissions |
The role catalog add_entity_member/update_entity_member pick a role_id from |
get_organization_analytics |
start_date?, end_date? (epoch ms) |
Daily extraction counts by type/source, in-review counts, per-entity usage summary |
Usage dashboards / reporting |
get_billings |
(none) |
Current plan, AI-extraction usage/limits, entity-count usage/limits, trial status |
“Am I near my plan limit?” |
get_my_verification_count |
(none) |
Your own verified-invoice counts, last 90 days |
Personal activity stat |
get_my_prompt_usage |
(none) |
Your own self-prompt / tofie-prompt counts, all-time |
Personal activity stat |
Entities & members
#
| Tool |
Input |
Output |
What it does |
list_entities |
page_number?, n_per_page? |
Every entity you can access, with your role in each |
Find an entity’s id by name |
get_entity |
entity_id, force_reload? |
Full entity record: settings, accounting config, your role |
Read one entity’s full configuration |
create_entity (write) |
name, slug, country_id |
The created entity, with you added as Manager |
Creates a new entity — needs org-level Entity:Create |
update_entity_settings (write) |
entity_id + only the fields you want to change (name, slug, auto-publish/import flags, invoice-status settings, …) |
The updated entity |
Updates entity settings — needs entity- or org-level Entity:Update. Fields you don’t pass are left untouched; a no-op call returns no_op: true |
list_entity_settings |
page_number?, n_per_page? |
Every entity you can access, with its flags, entity_setting and per-type settings |
Read every entity’s settings before a bulk change |
create_entities (write) |
entities: 1–25 × name, slug, country_id (distinct slugs) |
summary + one SUCCESS (entity) or FAILURE (slug, error) per item |
Creates several entities, each on its own — needs org-level Entity:Create. A failed item never stops the rest |
update_entities_settings (write) |
entities: 1–100 × entity_id + only the fields to change, incl. entity_setting and ap_bill / ar_invoice / direct_expense / bank_statement |
summary + one SUCCESS or FAILURE (error) per entity_id |
Updates several entities in one transaction — needs entity- or org-level Entity:Update, checked per entity. A failed item is left out and the rest are written |
add_entity_member (write) |
entity_id, app_user_id (target’s Clerk id), role_id |
The new membership |
Adds an existing org member to an entity — needs Member:Write |
update_entity_member (write) |
entity_id, app_user_id (target’s BonsAI user id), role_id |
The updated membership, incl. previous_role |
Changes a member’s entity role — needs Member:Update |
remove_entity_member (write) |
entity_id, app_user_id (target’s BonsAI user id) |
Confirmation, incl. removed_role |
Removes a member from an entity — needs Member:Delete; refuses to remove the last member |
Documents
#
| Tool |
Input |
Output |
What it does |
upload_document (write) |
entity_id, files[] (file_name, mime_type, content_base64), extraction_type?, sync_with_integration? |
Created document(s), status PENDING |
Uploads up to 20 files (≤20MB each, ≤50MB combined). Passing extraction_type auto-triggers extraction on them |
list_documents |
entity_id, timestamp_from?, timestamp_to? (≤3-month range), updated_after?, paging |
Document summaries: file name, status, mime type, size |
Browse recently uploaded documents |
get_document |
document_id, entity_id |
Full document detail, incl. its pages |
One document’s status and page list |
get_document_page |
document_page_id, entity_id |
Page metadata: page number, rotation, bounding box |
One page’s metadata (no image bytes) |
get_document_page_image |
document_page_id, entity_id, size? (xs/sm/md/lg) |
Inline rendered image |
The page as an image the model can look at |
get_document_page_signed_urls |
document_page_id, entity_id |
Short-lived signed URLs, one per size up to xl |
For handing a page to a human to open in a browser — links expire in ~1 hour |
download_document_file |
document_id, entity_id |
The original uploaded file, inline bytes |
The raw source file (PDF/image) — refuses files over 750KB |
Invoices & AP bills / AR invoices
#
| Tool |
Input |
Output |
What it does |
get_invoice |
invoice_id (an invoice id, or an extraction id when is_extraction_id is true), entity_id, is_extraction_id? |
Status, publish/import state, current invoice_data (amounts, dates, contact, line items) |
One invoice’s current data |
get_invoice_data |
invoice_id, entity_id, action_types?, paging |
Version history of the invoice’s data (one row per edit/publish/verify/etc.) |
Audit trail for one invoice |
search_invoice_data |
entity_id, extraction_data_ids[] (1–50, from get_invoice_data/get_invoice) |
The matching invoices’ current data |
Batch-fetch by known invoice-data id (not a search — no filter by contact/amount/date exists yet) |
Credit notes
#
Credit notes (AP_CREDIT_NOTE / AR_CREDIT_NOTE) have separate storage and publishing endpoints.
The invoice tools above do not accept credit-note IDs. Dedicated external MCP credit-note tools
are outside this release; use the webapp credit-note review and publish flow described in
Credit Note Publishing.
Direct expenses
#
| Tool |
Input |
Output |
What it does |
get_direct_expense_by_extraction |
extraction_id, entity_id |
Status, publish/import state, current data |
One direct expense’s current data (keyed by extraction id, not a separate direct-expense id) |
get_direct_expense_data |
direct_expense_id, entity_id, action_types?, paging |
Version history of the expense’s data |
Audit trail for one direct expense |
Bank statements
#
| Tool |
Input |
Output |
What it does |
list_bank_statements |
entity_id, paging |
Bank statement summaries |
Browse bank statements |
get_bank_statement |
extraction_id, entity_id |
Every mapped account/data row for the statement (bank name, account number, opening/closing balance, period) |
One statement’s full detail |
| Tool |
Input |
Output |
What it does |
create_extraction (write) |
entity_id, type (AP_BILL/AR_INVOICE/BANK_STATEMENT/DIRECT_EXPENSE), pages[] (from an upload), title?, id? |
The new extraction, status PENDING, then processing starts |
Creates and triggers a new extraction from already-uploaded pages in one call |
trigger_extraction (write) |
entity_id, extraction_id, full_extraction? |
The extraction, intended status: PROCESSING — but the response can be a stale snapshot caught mid-transition (e.g. briefly showing an already-superseded status); poll get_extraction to confirm the real state |
Re-triggers an existing extraction (e.g. after CLASSIFY_AND_REVIEW held it, or to redo a failed run). full_extraction: true discards prior data and starts fresh |
get_extraction |
extraction_id, entity_id |
Status, error info, pages, flattened data summary |
Check on any extraction regardless of type — use get_invoice/get_direct_expense_by_extraction/get_bank_statement for the full typed detail |
list_extractions |
entity_id, types?, statuses?, timestamp_from?, timestamp_to? (≤3-month range), updated_after?, page_number?, n_per_page? |
Extraction summaries |
Browse/filter extractions by type and status |
Knowledge & learning
#
| Tool |
Input |
Output |
What it does |
create_entity_knowledge (write) |
entity_id, contents? (free text; omit to learn from history instead), extraction_types? (preferred over the deprecated extraction_type), preferred_language? |
{message: "Knowledge creation job has been queued"} |
Teaches tofie’s AI extraction a rule for future documents — async, needs entity-level EntityKnowledge:Update; poll list_knowledge for the result |
create_knowledge (write) |
entity_id, extraction_type, content, title?, knowledge_type? (defaults to EXTRACTION), target_fields?[] |
The created knowledge item |
Creates one knowledge card synchronously — needs EntityKnowledge:Create |
list_knowledge_conflicts |
entity_id, extraction_type |
Pending conflicts where a new learning contradicts an existing one |
Review learnings that need a human decision |
get_contact_learnings |
entity_id, extraction_type, paging |
Latest learning per contact (vendor name, contact name, learning text) |
What tofie has learned about each of your vendors/customers |
Integrations & reference data
#
| Tool |
Input |
Output |
What it does |
list_integrations |
entity_id, paging |
Every integration (accounting connections + trigger sources) on the entity |
See what’s connected |
get_integration |
integration_id, entity_id |
Full integration detail incl. accounting tax/rounding config |
One integration’s full config |
get_integration_details |
integration_id, entity_id |
Installation warnings only |
UI-style warnings for one integration |
accounting_tags |
entity_id, paging |
Tags/tracking categories configured on the entity |
e.g. Xero tracking categories |
accounting_tag_usage |
entity_id, tag_id |
Invoice/direct-expense usage counts for that tag |
How much a tag is actually used |
get_priority_fields |
entity_id, extraction_type, paging |
Priority field names for that entity + document type |
Fields Bonsai-Knowledge prioritizes when extracting |
get_countries |
page_number?, n_per_page? |
Every ISO 3166-1 alpha-2 country code bonsapi recognizes |
Valid values for country_id |
get_currencies |
page_number?, n_per_page? |
Every ISO 4217 currency code + tax decimal places |
Valid values for currency fields |
search_help_articles |
query, language? (en/ja), limit? |
Best-matching help center articles: title, url, description, section |
Answer “how do I…” questions from help.gotofu.com |
get_help_article |
url, offset? |
One help center article as markdown, in chunks (next_offset when truncated) |
Read the full article behind a search hit |
(write) tools change data and require the matching BonsAI permission on your account — you’ll get a clear error, not a silent failure, if you don’t have it.