The Bonsai MCP connector routes your AI agent's tool calls to Bonsai's own MCP server through Scalekit. Each user signs in to Bonsai once, and Scalekit stores and refreshes their tokens, so your agent never handles credentials. It comes with 49 tools.
- Tools
- 49
- What they doRead · write · destructive
- 23 · 20 · 623 read20 write6 destructive
- Users sign in with
- OAuth
- OAuth app
- Scalekit's or your own
Setup
Install the SDK
Terminal window npm install @scalekit-sdk/node dotenvTerminal window pip install scalekit-sdk-python python-dotenvSet your credentials
Add your Scalekit credentials to your
.envfile. Find values in app.scalekit.com > Developers > API Credentials..env SCALEKIT_ENVIRONMENT_URL=<your-environment-url>SCALEKIT_CLIENT_ID=<your-client-id>SCALEKIT_CLIENT_SECRET=<your-client-secret>Create the Bonsai MCP connection
In AgentKit > Connections, create a Bonsai MCP connection. The name you give it is the
connection_nameyour code passes. See Configure connections.Scalekit credentials are available for Bonsai MCP server, so you don't need to register an OAuth app.
Authorize a user and make your first call
quickstart.mts import { ScalekitClient } from '@scalekit-sdk/node'import 'dotenv/config'import { createInterface } from 'node:readline/promises'const scalekit = new ScalekitClient(process.env.SCALEKIT_ENVIRONMENT_URL,process.env.SCALEKIT_CLIENT_ID,process.env.SCALEKIT_CLIENT_SECRET,)const actions = scalekit.actionsconst connector = 'bonsaimcp'const identifier = 'user_123'// Generate an authorization link for the userconst { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })console.log('Authorize Bonsai MCP:', link)const rl = createInterface({ input: process.stdin, output: process.stdout })await rl.question('Press Enter after authorizing...')rl.close()// Make your first callconst result = await actions.executeTool({connector,identifier,toolName: 'bonsaimcp_list_board_groups',toolInput: {},})console.log(result)Terminal window npx tsx quickstart.mtsquickstart.py import osfrom scalekit import ScalekitClientfrom dotenv import load_dotenvload_dotenv()scalekit_client = ScalekitClient(env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"),client_id=os.getenv("SCALEKIT_CLIENT_ID"),client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),)actions = scalekit_client.actionsconnection_name = "bonsaimcp"identifier = "user_123"# Generate an authorization link for the userlink_response = actions.get_authorization_link(connection_name=connection_name,identifier=identifier,)print("Authorize Bonsai MCP:", link_response.link)input("Press Enter after authorizing...")# Make your first callresult = actions.execute_tool(tool_input={},tool_name="bonsaimcp_list_board_groups",connection_name=connection_name,identifier=identifier,)print(result)Terminal window python quickstart.pyEach user signs in once. See Authorize a user for the full flow and statuses.
Tools
Pass the exact name toexecute_toolbonsaimcp_get_companyFetch a single CRM company by its id, in the same shape `list_companies` returns per row.Read-onlyGet Company
Fetch a single CRM company by its id, in the same shape `list_companies` returns per row. Use it when you already hold a company id â from `list_companies`, a contact's `company_ids` or `default_company_id`, an invoice's `company_id`, or `create_company` â instead of paging through the list. Returns `id`, `name`, `default_contact_id`, `domains`, `created_at`, the profile fields `description`, `industry`, `company_size`, `source`, `linkedin`, `instagram`, `twitter` and `facebook`, `avatar_url` (the company logo, null when it has none), and `url`, a direct link to the company in the Bonsai app. Archived and deleted companies are reported as not found, just as `list_companies` leaves them out.
Inputs
idintegerrequired- Id of the company to fetch â from `list_companies`, a contact's `company_ids`, or an invoice's `company_id`.
bonsaimcp_get_docFetch a single document by its id â the `id` that `list_docs` or `create_doc` returned â in the same shape both of them use.Read-onlyGet Doc
Fetch a single document by its id â the `id` that `list_docs` or `create_doc` returned â in the same shape both of them use. Read it again after the user acts in Bonsai to see where the document stands: its `status` (`draft` until it is sent from the Bonsai app, then `sent`, and `completed` once everybody has signed, or `expired` if it lapsed first), how far each of the `recipients` has got (`pending`, `viewed` once they open it, `completed` once they are done), and which `unassigned_roles` still need somebody. Also returns `title`, `doc_number`, `deal_id`, `project_ids`, `created_at`, `updated_at`, and `url`, a direct link to the document in the Bonsai app. Signing links are never included. Templates are not documents: the id of a `list_templates` entry is not accepted here.
Inputs
idintegerrequired- Id of the document to fetch â the `id` from `list_docs` or `create_doc`.
bonsaimcp_get_noteFetch a single note by its id, including what it says as `content_plain_text` — the field a list response always leaves out, so read a note here whenever you need its body.Read-onlyGet Note
Fetch a single note by its id, including what it says as `content_plain_text` — the field a list response always leaves out, so read a note here whenever you need its body. Also returns `title`, `date` (the day the note is about, which is what the app sorts and groups by), `visibility` (`everyone` or `author_only`), `created_by_member_id`, `created_at`, `updated_at`, and `note_links` — the company, project or contact records the note is attached to, empty for a note that stands on its own in the workspace or whose records this user cannot reach. Resolve ids via `list_notes`. Anyone can read a note they wrote; reading someone else's needs permission to read notes.
Inputs
idstringrequired- Id of the note to fetch. Resolve via `list_notes`.
bonsaimcp_get_taskFetch a single task from Bonsai by its UUID.Read-onlyGet Task
Fetch a single task from Bonsai by its UUID.
Inputs
uuidstringrequired- UUID of the task to fetch.
bonsaimcp_list_board_groupsList board groups (pipeline stages for deals, project groups for projects) in the user's Bonsai company.Read-onlyList Board Groups
List board groups (pipeline stages for deals, project groups for projects) in the user's Bonsai company. Use to resolve group names to UUIDs for filtering deals and projects.
Inputs
namestring- Case-insensitive substring match on the board group name.
pageinteger- Page number (1-indexed). Default 1.default
1 page_sizeinteger- Items per page (max 100). Default 25.default
25 resource_typestring- Board type to narrow to. One of "Deal" or "Project". Omitted returns all boards.one of
DealProject
bonsaimcp_list_commentsList the comments on a task or a deal, paginated, newest first.Read-onlyList Comments
List the comments on a task or a deal, paginated, newest first. Provide exactly one parent — `task_id` (a task UUID) or `deal_id` (a deal id). By default only user-authored comments are returned; pass `kind` = `events` for system-generated activity (status changes, assignments) or `all` for both. Each comment carries `body_plain_text` (HTML stripped), its `kind`, `created_at`, the parent `commentable_id`, and `author_member_id` (null when the author is not a company member). Returns a `not_found` error when the parent does not exist or is not accessible.
Inputs
deal_idinteger- Integer id of the parent deal whose comments to list. Provide exactly one of `task_id` or `deal_id`. Resolve deal ids via `list_deals`.
kindstring- Which comment kinds to return: `user_created` (default) for user-authored comments, `events` for system-generated activity (status changes, assignments), or `all` for both. Omit to default to `user_created`.one of
user_createdeventsall pageinteger- Page number (1-indexed). Default 1.default
1 page_sizeinteger- Items per page (max 100). Default 25.default
25 task_idstring- UUID of the parent task whose comments to list. Provide exactly one of `task_id` or `deal_id`. Resolve task UUIDs via `list_tasks`, `get_task`, or `list_subtasks`.
bonsaimcp_list_companiesList CRM companies in the user's Bonsai account.Read-onlyList Companies
List CRM companies in the user's Bonsai account. Use to find existing companies before creating new ones or when resolving company_id for projects and invoices.
Inputs
namestring- Free-text search over company name (case-insensitive).
pageinteger- Page number (1-indexed). Default 1.default
1 page_sizeinteger- Items per page (max 100). Default 25.default
25
bonsaimcp_list_company_activitiesList what happened with a CRM company, newest first: its own events plus the events of every contact on it, merged into one stream â documents, invoices, emails, meetings, notes, deals, forms, client portal events, and changes to the company and its contacts.Read-onlyList Company Activities
List what happened with a CRM company, newest first: its own events plus the events of every contact on it, merged into one stream â documents, invoices, emails, meetings, notes, deals, forms, client portal events, and changes to the company and its contacts. Each occurrence appears once, even when it touched several contacts. A document is the exception: it is recorded per recipient, so one sent to two contacts is two activities (a legacy one, `details.legacy` true, appears once). Each activity carries `id`, `type` (`group.action`, e.g. `invoice.paid`), `occurred_at`, a one-line `summary`, the `actor` who did it (a team `member`, a `contact`, or `system`), the `subject` record it is about with a `url` to open it in Bonsai (an email, meeting or form has no page of its own, so its `url` opens the contact or company page), `contact_id`, `company_id`, and type-specific `details` (a changed field with its old and new values, an invoice amount, an email subject, â¦) or null. Only the activity types this user may read are returned. Email subjects and meeting titles are null when the mailbox they came from does not share them. Filter by `type` and by an `occurred_from` / `occurred_to` window of UTC days. Pages stop at 40: to read further back, call again with the same filters, `page` 1, and `occurred_to` set to the day of the last activity you read (the date in its `occurred_at`). The activity of that day you already read comes back again, and activity arriving while you page can repeat across pages, so dedupe by `id`. When all 40 pages fall on one day, paging cannot get past it: split that day into calls narrowed by `type`. Narrow to some of the contacts on the company with `contact_id`, which also leaves out the company's own activity and, like `type`, splits a day too busy to page through. Resolve `company_id` via `list_companies` or `get_company`, or from a contact's `company_ids` (`list_contacts`). Archived and deleted companies are reported as not found.
Inputs
company_idintegerrequired- Id of the company whose activity to list â from `list_companies`, `get_company`, or a contact's `company_ids`.
contact_idstring- Keep only the activity about these contacts, leaving out the company's own activity. Every id must be a contact on this company â resolve via `list_contacts` with `company_id`. Single value or array.
occurred_fromstring- Keep activity on or after this day (YYYY-MM-DD, UTC), inclusive.
occurred_tostring- Keep activity on or before this day (YYYY-MM-DD, UTC), inclusive. Past page 40, move it back to the date in the `occurred_at` of the last activity read.
pageinteger- Page number (1-indexed), at most 40. Default 1. To read further back, set `occurred_to` to the day of the last activity read (the date in its `occurred_at`) and start again from page 1.default
1 page_sizeinteger- Items per page (max 100). Default 25.default
25 typestring- Activity types (`invoice.paid`) or groups (`invoice`) to keep; a group stands for every type in it that this user may read. Single value or array; an array keeps activity matching any of them. A type this user may not read, or a group with no type they may, is refused, and the error names it.
bonsaimcp_list_contact_activitiesList what happened with one CRM contact, newest first: its own events â documents, invoices, emails, meetings, deals it was assigned to, form submissions, client portal events, and changes to the contact â the notes linked to it, and when it was added to or removed from a company.Read-onlyList Contact Activities
List what happened with one CRM contact, newest first: its own events â documents, invoices, emails, meetings, deals it was assigned to, form submissions, client portal events, and changes to the contact â the notes linked to it, and when it was added to or removed from a company. Activity recorded on the company is not here: changes to the company, and forms sent to this contact. Read it with `list_company_activities`, where `contact_id` keeps the forms sent to this contact. `contact_id` is always this contact, and `company_id` is null for activity tied to no company. Each activity carries `id`, `type` (`group.action`, e.g. `invoice.paid`), `occurred_at`, a one-line `summary`, the `actor` who did it (a team `member`, a `contact`, or `system`), the `subject` record it is about with a `url` to open it in Bonsai (an email, meeting or form has no page of its own, so its `url` opens the contact or company page), `contact_id`, `company_id`, and type-specific `details` (a changed field with its old and new values, an invoice amount, an email subject, â¦) or null. Only the activity types this user may read are returned. Email subjects and meeting titles are null when the mailbox they came from does not share them. Filter by `type` and by an `occurred_from` / `occurred_to` window of UTC days. Pages stop at 40: to read further back, call again with the same filters, `page` 1, and `occurred_to` set to the day of the last activity you read (the date in its `occurred_at`). The activity of that day you already read comes back again, and activity arriving while you page can repeat across pages, so dedupe by `id`. When all 40 pages fall on one day, paging cannot get past it: split that day into calls narrowed by `type`. Resolve `contact_id` via `list_contacts`, or from a company's `default_contact_id` (`list_companies`, `get_company`). Archived and deleted contacts are reported as not found.
Inputs
contact_idintegerrequired- Id of the contact whose activity to list â from `list_contacts`, or a company's `default_contact_id`.
occurred_fromstring- Keep activity on or after this day (YYYY-MM-DD, UTC), inclusive.
occurred_tostring- Keep activity on or before this day (YYYY-MM-DD, UTC), inclusive. Past page 40, move it back to the date in the `occurred_at` of the last activity read.
pageinteger- Page number (1-indexed), at most 40. Default 1. To read further back, set `occurred_to` to the day of the last activity read (the date in its `occurred_at`) and start again from page 1.default
1 page_sizeinteger- Items per page (max 100). Default 25.default
25 typestring- Activity types (`invoice.paid`) or groups (`invoice`) to keep; a group stands for every type in it that this user may read. Single value or array; an array keeps activity matching any of them. A type this user may not read, or a group with no type they may, is refused, and the error names it.
bonsaimcp_list_contactsList CRM contacts in the user's Bonsai account.Read-onlyList Contacts
List CRM contacts in the user's Bonsai account. Supports filtering by name, email, and company.
Inputs
company_idstring- Company id(s) to filter by â the company the contact belongs to, not your own account. Returns only contacts linked to the given company/companies. Single value or array.
emailstring- Free-text search over contact email (case-insensitive).
namestring- Free-text search over contact name (case-insensitive).
pageinteger- Page number (1-indexed). Default 1.default
1 page_sizeinteger- Items per page (max 100). Default 25.default
25
bonsaimcp_list_dealsList deals in the user's Bonsai company, paginated.Read-onlyList Deals
List deals in the user's Bonsai company, paginated. Each deal includes id, title, deal_value, currency, probability, close_date, status, pipeline stage, and assignee info.
Inputs
assignee_member_idstring- Filter by assignee. Pass a Company member id (e.g. 42), the literal "me" to resolve to the authenticated user's member, or an array for multi-assignee. Resolve member ids via `list_team_members` (the `company_member_id` field).
board_group_idstring- Filter by pipeline stage â matches deals filed under any of the given board groups. Pass a single BoardGroup UUID or an array for multiple stages. Resolve group names to UUIDs via `list_board_groups` with `resource_type=Deal`.
deal_numberstring- Free-text search over deal_number (word-start match, case-insensitive).
pageinteger- Page number (1-indexed). Default 1.default
1 page_sizeinteger- Items per page (max 100). Default 25.default
25 titlestring- Free-text search over deal title (word-start match, case-insensitive).
bonsaimcp_list_docsList the user's documents â proposals, contracts, quotes and the like â in the current company, paginated, newest first.Read-onlyList Docs
List the user's documents â proposals, contracts, quotes and the like â in the current company, paginated, newest first. Templates are not documents and never appear here; find them with `list_templates`. Each document comes back in the shape `create_doc` returns: `id`, `title`, `doc_number`, `status` (`draft` until it is sent from the Bonsai app, then `sent`, and `completed` once everybody has signed, or `expired` if it lapsed first), `recipients` (sender first, then receivers, then people copied in, each with how far they have got: `pending`, `viewed` or `completed`), `unassigned_roles` (the roles nobody fills yet), `deal_id`, `project_ids`, `created_at`, `updated_at`, and `url`, a direct link to the document in the Bonsai app. Signing links are never included. Filter by `status`, `company_id` (the client company a recipient represents â resolve via `list_companies`), `contact_id` (a contact who is a recipient â resolve via `list_contacts`), `project_id` (resolve via `list_projects`; a project this user cannot see matches nothing), `deal_id` (resolve via `list_deals`), and a `created_from`/`created_to` window over the day each document was created, in UTC (both bounds inclusive, either works alone). A document has to match every filter passed; a filter given several values matches any one of them.
Inputs
company_idstring- Filter by client company id(s) â the company a recipient represents on the document, not your own account. Resolve via `list_companies`. Single value or array.
contact_idstring- Filter by contact id(s) â documents the contact is a recipient on. Resolve via `list_contacts`. Single value or array.
created_fromstring- Documents created on or after this day (YYYY-MM-DD, UTC), inclusive.
created_tostring- Documents created on or before this day (YYYY-MM-DD, UTC), inclusive.
deal_idstring- Filter by deal id(s) the document is linked to â resolve via `list_deals`. Single value or array.
pageinteger- Page number (1-indexed). Default 1.default
1 page_sizeinteger- Items per page (max 100). Default 25.default
25 project_idstring- Filter by project id(s) the document is linked to â resolve via `list_projects`. A project this user cannot see matches nothing. Single value or array.
statusstring- One or more of `draft`, `sent`, `completed`, `expired`. Single value or array; an array matches documents in any of them.
bonsaimcp_list_invoicesList invoices in the user's Bonsai company, newest first.Read-onlyList Invoices
List invoices in the user's Bonsai company, newest first. Each invoice includes invoice_number, title, status, total_amount, due_date, client info, and line items.
Inputs
company_idstring- Filter by client company id(s) â the company being billed, not your own account. Resolve via `list_companies`. Single value or array.
invoice_numberstring- Exact lookup by invoice number (a sequential string, e.g. "1032"). The primary way to resolve an invoice number to its id. Single value or array for batch lookups.
pageinteger- Page number (1-indexed). Default 1.default
1 page_sizeinteger- Items per page (max 100). Default 25.default
25 project_idstring- Filter by project id(s) â resolve via `list_projects`. Single value or array.
bonsaimcp_list_notesList notes in the user's current company, paginated, ordered by when each note was written (newest first) — not by `date`, so a note backdated to last year still leads the page if it was written today.Read-onlyList Notes
List notes in the user's current company, paginated, ordered by when each note was written (newest first) — not by `date`, so a note backdated to last year still leads the page if it was written today. There is no way to sort by `date`; narrow with `date_from`/`date_to` instead. Each note exposes `id`, `title`, `date` (the day the note is about, which is what the app sorts and groups by), `visibility` (`everyone` or `author_only`), `created_by_member_id`, `created_at`, `updated_at`, and `note_links` — the company, project or contact records the note is attached to, empty for a note that stands on its own in the workspace or whose records this user cannot reach. The note body is never part of a list response; read a single note to get it. Filter by the attached record with `record_type` plus `record_id` (both together, or neither), by author with `created_by_member_id` (member id(s) or the literal "me"), and by a `date_from`/`date_to` window over the day each note is about (both bounds inclusive, either works alone).
Inputs
created_by_member_idstring- Filter by note author. Pass a Company member id (e.g. 42), the literal "me" to resolve to the authenticated user's member, or an array for several authors. Resolve member ids via `list_team_members` (the `company_member_id` field).
date_fromstring- Notes dated on or after this day (YYYY-MM-DD), inclusive.
date_tostring- Notes dated on or before this day (YYYY-MM-DD), inclusive.
pageinteger- Page number (1-indexed). Default 1.default
1 page_sizeinteger- Items per page (max 100). Default 25.default
25 record_idinteger- Return only notes attached to this record, in the resource named by `record_type` â resolve via `list_companies`, `list_projects`, or `list_contacts`. Requires `record_type`.
record_typestring- Return only notes attached to this kind of record: `company` (a CRM client), `project`, or `contact`. Requires `record_id` â neither narrows anything on its own.one of
companyprojectcontact
bonsaimcp_list_projectsList active projects in the user's Bonsai company, paginated.Read-onlyList Projects
List active projects in the user's Bonsai company, paginated. Supports filtering by title (free-text), public_url_token, and board_group_id (Project Group UUID).
Inputs
board_group_idstring- Exact lookup by Project Group â matches projects filed under any of the given groups. ("Project Group" is the UI name for a project's `board_group_id`, a board group UUID.) Pass a single UUID or an array for batch lookups. Resolve group names to UUIDs via `list_board_groups` with `resource_type=Project`.
budget_amount_maxstring- Upper bound on the project budget, inclusive, as a non-negative decimal string (e.g. "20000.00"). Works on its own or with `budget_amount_min`. Projects that track no budget are left out either way. Compares `budget.amount` as a bare number: the same "20000" means 20,000 hours on a `time` budget and 20,000 of the project currency on a `fee` one, and this filter tells neither apart â nor one currency from another. Whichever the question meant, hours or money, narrow the results on each project's `calculation_mode` and `currency` yourself. Needs permission to see project budgets.
budget_amount_minstring- Lower bound on the project budget, inclusive, as a non-negative decimal string (e.g. "5000.00"). Works on its own or with `budget_amount_max`. Projects that track no budget are left out either way, so pair it with `has_budget: true` only for emphasis. Compares `budget.amount` as a bare number: the same "5000" means 5,000 hours on a `time` budget and 5,000 of the project currency on a `fee` one, and this filter tells neither apart â nor one currency from another. Whichever the question meant, hours or money, narrow the results on each project's `calculation_mode` and `currency` yourself. Needs permission to see project budgets.
has_budgetboolean- Whether the project tracks a budget at all. `true` returns budgeted projects, `false` those with none. This is the only way to ask the presence question: a `budget_amount_min` of 0 drops every unbudgeted project rather than selecting them. Needs permission to see project budgets; without it the whole call fails with a permission error naming this filter.
pageinteger- Page number (1-indexed). Default 1.default
1 page_sizeinteger- Items per page (max 100). Default 25.default
25 public_url_tokenstring- Exact lookup by Bonsai's public_url_token. Pass a single token (e.g. "acme-website-x4n2") or an array for batch lookups.
statusstring- Project lifecycle status. Omit to default to `active`; `not_archived` returns active and completed, and `all` returns every status (`active`, `archived`, `not_archived`, `completed`, `all`).one of
activearchivednot_archivedcompletedall titlestring- Free-text search over project title (word-start match, case-insensitive).
bonsaimcp_list_subtasksList a parent task's subtasks (its child tasks), paginated, ordered by the manual subtask order.Read-onlyList Subtasks
List a parent task's subtasks (its child tasks), paginated, ordered by the manual subtask order. Each subtask carries the same summary fields as list_tasks (including assignee_member_name, due_date, task_status, and company_tags), plus parent_task_uuid pointing back at the parent. Archived and deleted subtasks are excluded; completed subtasks remain visible. Returns a not_found error when the parent task does not exist, belongs to another company, or is archived, deleted, or a template. Task descriptions are not included here — call get_task with a subtask's uuid to fetch its full description.
Inputs
task_idstringrequired- UUID of the parent task whose subtasks to list.
pageinteger- Page number (1-indexed). Default 1.default
1 page_sizeinteger- Items per page (max 100). Default 25.default
25
bonsaimcp_list_task_statusesList the caller's company task statuses, paginated.Read-onlyList Task Statuses
List the caller's company task statuses, paginated. A task status is a board column a task can occupy (e.g. "To Do" / "In Progress" / "Done", plus any custom columns), ordered by board position. Each entry exposes id (the task_status_id accepted by create_task and the list_tasks task_status_id filter), status (the column name), state ("active" or "complete", where "complete" marks a done column), color (nullable), and position. Use this to resolve a status name to the task_status_id those endpoints expect.
Inputs
pageinteger- Page number (1-indexed). Default 1.default
1 page_sizeinteger- Items per page (max 100). Default 25.default
25
bonsaimcp_list_tasksList tasks in the user's current Bonsai company, paginated and ordered by creation date (newest first).Read-onlyList Tasks
List tasks in the user's current Bonsai company, paginated and ordered by creation date (newest first). Supports filtering by assignee, scope, due-date window, priority, project, and tag.
Inputs
assignee_idstring- Filter by assignee. Pass an integer User id as a string (e.g. "42"), the literal "me" to resolve to the authenticated user, or an array for multi-assignee.
billableboolean- Whether time tracked on the task is billable. `true` returns billable tasks, `false` the rest â tasks created before billing was tracked count as not billable, so the two sides together are every task. Needs permission to see billing; without it the whole call fails with a permission error naming this filter, since it would otherwise answer for the `billable` key that same user is not shown.
deal_idstring- Integer Deal id(s) â the tasks sitting on those deals. Resolve ids via `list_deals`. Independent of `project_id`: a task can sit on a deal, a project, both or neither. Needs permission to see deals; without it the whole call fails with a permission error naming this filter, rather than quietly returning every task.
duestring- Named due-date window. Mutually exclusive with `due_from`/`due_to`.one of
todayoverduetoday_or_overduethis_weekthis_monthupcoming due_fromstring- Tasks due on or after this date (YYYY-MM-DD).
due_tostring- Tasks due on or before this date (YYYY-MM-DD).
pageinteger- Page number (1-indexed). Default 1.default
1 page_sizeinteger- Items per page (max 100). Default 25.default
25 prioritystring- One or more of `urgent`, `high`, `medium`, `low`.
project_idstring- Integer Project id(s).
scopestring- Task scope. Omit to default to `active` (only non-completed, non-archived tasks); filtering by `task_status_id` without a scope returns tasks in any state.one of
activecompletedarchivedallupcoming_and_overdueunplannedplannedmy_tasks tag_idstring- Integer CompanyTag id(s).
task_status_idstring- Filter by task status (board column). Pass a TaskStatus UUID (the `id` from `list_task_statuses`) or an array. Filtering by status returns tasks in any state (active, completed, or archived), overriding the default `active` scope.
titlestring- Free-text search over task title (case-insensitive).
bonsaimcp_list_team_membersList team members in the user's current Bonsai company.Read-onlyList Team Members
List team members in the user's current Bonsai company. Returns company_member_id (for task assignment), role, permission_profile, and lifecycle timestamps.
Inputs
idstring- Company member id(s) to filter by. Pass a single id or an array. Use the `company_member_id` field returned here when assigning tasks via `assignee_member_id`.
namestring- Free-text search over team-member name (word-start match, case-insensitive).
pageinteger- Page number (1-indexed). Default 1.default
1 page_sizeinteger- Items per page (max 100). Default 25.default
25 project_idstring- Project id(s). Returns only team members assigned to the given project(s). Single value or array.
user_idstring- User id(s) to filter by. Pass a single id or an array. For creating tasks, use `company_member_id` instead.
bonsaimcp_list_template_categoriesList the names `list_templates` accepts in its `category` and `industry` filters, paginated, categories first.Read-onlyList Template Categories
List the names `list_templates` accepts in its `category` and `industry` filters, paginated, categories first. Each entry is a `name` plus its `kind` â "category" or "industry" â which says which of the two filters the name feeds; pass the name verbatim. This is Bonsai's fixed vocabulary, the same for every account, so fetch it once and reuse it. A name here does not mean any template is filed under it: filtering by one that has none returns an empty page. The account's own saved templates are all filed under the "My Templates" category. `type` picks the kind of template the names belong to, and today only `Doc` exists. Filter by `kind` and by `name` (case-insensitive substring). When no category fits the kind of document the user wants â a contract, say â filter `list_templates` by `name` instead.
Inputs
kindstring- Limit to the names one `list_templates` filter accepts: `category` or `industry`. Worth sending â each kind fits in a single page, the two together may not.one of
categoryindustry namestring- Case-insensitive substring match on the name.
pageinteger- Page number (1-indexed). Default 1.default
1 page_sizeinteger- Items per page (max 100). Default 25.default
25 typestring- The kind of template the names belong to. Only `Doc` today â document templates for proposals, contracts, quotes and the like. Default `Doc`.one of
DocdefaultDoc
bonsaimcp_list_templatesList the templates the user can start a new document from, paginated: the account's own saved templates first (`source` "own"), then Bonsai's library (`source` "library").Read-onlyList Templates
List the templates the user can start a new document from, paginated: the account's own saved templates first (`source` "own"), then Bonsai's library (`source` "library"). Only templates the user could actually use come back â published, in a region that applies to the account, built in the current editor; drafts stay in the Bonsai app. `type` picks the kind of template, and today only `Doc` exists. Each entry exposes `id`, `name`, `source`, `region` (null when it applies everywhere), the `categories` and `industries` it is filed under, `roles` (the parts a document made from it expects somebody to fill: `sender`, `receiver` or `cc`), `updated_at`, and `url` (null when the user cannot edit it, as on a library template unless the account curates the library). Filter by `name` (case-insensitive substring), `source` (`own`, `library` or `all`), `category` and `industry` (names from `list_template_categories`), and `region` (defaults to the account's country). When no category fits the kind of document the user wants â a contract, say â filter by `name` instead of guessing one. Prefer the account's own template over a library one when both fit.
Inputs
categorystring- Category name(s), matched exactly but case-insensitively â take them from the `list_template_categories` rows with `kind: category`. The account's own templates are filed under "My Templates". Single value or array; an array matches templates filed under any of the names. When none fits the kind of document wanted â a contract, say â filter by `name` instead.
industrystring- Industry name(s), matched exactly but case-insensitively â take them from the `list_template_categories` rows with `kind: industry`. Single value or array; an array matches templates aimed at any of the names.
namestring- Case-insensitive substring match on the template name.
pageinteger- Page number (1-indexed). Default 1.default
1 page_sizeinteger- Items per page (max 100). Default 25.default
25 regionstring- Region the template is written for: `USA`, `CAN`, `GBR` or `AUS`. Defaults to the account's country. Templates that apply everywhere are always included.one of
USACANGBRAUS sourcestring- `own` for the account's saved templates, `library` for Bonsai's, `all` for both. Omit for both.one of
ownlibraryall typestring- The kind of template to list. Only `Doc` today â document templates for proposals, contracts, quotes and the like. Default `Doc`.one of
DocdefaultDoc
bonsaimcp_list_time_entriesList time entries in the user's current company, paginated, newest first.Read-onlyList Time Entries
List time entries in the user's current company, paginated, newest first. Each entry exposes key, seconds, formatted_time, date, notes, rate, non_billable, billable_amount, billing_status (billed, unbilled, or non_billable), status, currency, project_id, task_uuid, owner_member_id, and created_at. Supports filtering by date_from/date_to (inclusive YYYY-MM-DD window), owner_member_id (Company member id(s) or the literal "me"; listing other members needs the "all time entries" permission), project_id, company_id (client company billed — resolve via list_companies), billing_status, and currency. Multi-value filters accept a single value or an array. Without the billing permission rate, non_billable, billable_amount and billing_status are omitted from every entry, and billing_status is refused as a filter — retry without it rather than reading the refusal as "no access to time entries".
Inputs
billing_statusstring- One or more of `billed`, `unbilled`, `non_billable`. Single value or array. Needs the billing permission; without it the call is refused.
company_idstring- Filter by client company id(s), matched through the entry's project â the company being billed, not your own account. Resolve via `list_companies`. Single value or array.
currencystring- ISO 4217 currency code(s), e.g. "USD". Single value or array.
date_fromstring- Entries on or after this date (YYYY-MM-DD), inclusive.
date_tostring- Entries on or before this date (YYYY-MM-DD), inclusive.
owner_member_idstring- Filter by the entry owner. Pass a Company member id (e.g. 42), the literal "me" to resolve to the authenticated user's member, or an array for multiple owners. Resolve member ids via `list_team_members` (the `company_member_id` field). Listing other members' time requires the "all time entries" permission.
pageinteger- Page number (1-indexed). Default 1.default
1 page_sizeinteger- Items per page (max 100). Default 25.default
25 project_idstring- Filter by project id(s) â resolve via `list_projects`. Single value or array.
bonsaimcp_create_commentPost a user-authored comment on a task or a deal.WriteCreate Comment
Post a user-authored comment on a task or a deal. Provide exactly one parent — `task_id` (a task UUID) or `deal_id` (a deal id) — and a `body`. The comment is attributed to the authenticated member and stored with unsafe HTML stripped. Mentions and attachments are not supported: "@Name" in `body` is stored as literal text and notifies no one; notifications are automatic and determined by the parent record. Returns the created comment. Returns a `not_found` error when the parent does not exist or is not accessible.
Inputs
bodystringrequired- The comment body, as plain text. Required. Mentions are NOT supported: "@Name" is stored literally and does not link, mention, or notify anyone, and there is no way to notify a specific recipient. Notifications are automatic and determined by the parent record (a comment on a task notifies its subscribers/assignees; a comment on a deal notifies no one).
deal_idinteger- Integer id of the parent deal to comment on. Provide exactly one of `task_id` or `deal_id`. Resolve deal ids via `list_deals`.
task_idstring- UUID of the parent task to comment on. Provide exactly one of `task_id` or `deal_id`. Resolve task UUIDs via `list_tasks`, `get_task`, or `list_subtasks`.
bonsaimcp_create_companyCreate a CRM company in the user's Bonsai account.WriteCreate Company
Create a CRM company in the user's Bonsai account. Requires name. Optionally set a default contact and domains. Search with list_companies first to avoid duplicates.
Inputs
namestringrequired- Company name. Required.
company_sizestring- Headcount band for the company. One of `size_1_10`, `size_11_50`, `size_51_200`, `size_201_1000`, or `size_1000_plus`. Pass `null` or omit to leave unset.
default_contact_idstring- Contact id to mark as the company's primary contact. Must be accessible in the same account. Resolve via `list_contacts`. Pass `null` or omit to leave unset.
descriptionstring- Free text notes about the company. Pass `null` or omit to leave unset.
domainsstring- One or more domain strings (e.g. ["example.com"]). Each value is normalised server-side (protocol/www stripped, lowercased); a domain already claimed by another company in the account is rejected. Pass `null` or omit for none.
facebookstring- Link to the company's Facebook page. Pass `null` or omit to leave unset.
industrystring- The industry the company operates in. One of `arts_and_entertainment`, `business_and_consumer_services`, `community_and_society`, `computers_electronics_and_technology`, `e_commerce_and_shopping`, `finance`, `food_and_drink`, `gambling`, `games`, `health`, `heavy_industry_and_engineering`, `hobbies_and_leisure`, `home_and_garden`, `jobs_and_career`, `law_and_government`, `lifestyle`, `luxury`, `news_and_media`, `pets_and_animals`, `reference_materials`, `science_and_education`, `sports`, `travel_and_tourism`, or `vehicles`. Pass `null` or omit to leave unset.
instagramstring- Link to the company's Instagram profile. Pass `null` or omit to leave unset.
linkedinstring- Link to the company's LinkedIn profile. Pass `null` or omit to leave unset.
sourcestring- How the client was acquired. One of `organic_search`, `paid_search`, `email_marketing`, `organic_social`, `referrals`, `other_campaigns`, `direct_traffic`, `offline_sources`, `paid_social`, or `ai_referrals`. Pass `null` or omit to leave unset.
twitterstring- Link to the company's X profile. Pass `null` or omit to leave unset.
bonsaimcp_create_contactCreate a CRM contact in the user's Bonsai account.WriteCreate Contact
Create a CRM contact in the user's Bonsai account. Requires name and email. Optionally link to a company_id. Search with list_contacts first to avoid duplicates.
Inputs
emailstringrequired- Contact email. Required.
namestringrequired- Contact full name. Required.
company_idstring- Company id to link the contact to â the company the contact belongs to, not your own account. Resolve via `list_companies`. Pass `null` or omit for a standalone contact.
job_titlestring- Optional job title. Pass `null` or omit to leave it unset.
phone_numberstring- Optional phone number. Pass `null` or omit to leave it unset.
bonsaimcp_create_docCreate a draft document â a proposal, contract, quote and the like â from a template in the user's current company.WriteCreate Doc
Create a draft document â a proposal, contract, quote and the like â from a template in the user's current company. Nothing is sent: the draft waits in Bonsai for the user to review and send, which this tool cannot do. Requires `template_id` (the `id` of a `list_templates` entry; there is no blank document). The user is always the sender. `contact_id` fills the template's first receiver role; without it, a `project_id` or `deal_id` fills it from that record's client, and `company_id` alone fills it with the company's primary contact. `company_id`, `contact_id`, `project_id` and `deal_id` must all belong to the same client company â resolve them via `list_companies`, `list_contacts`, `list_projects` and `list_deals`. The client comes from `company_id`, else the project, else the deal, and every field that names a different company is refused with a message saying which field set the client. With only `contact_id`, the client is the contact's company when it has exactly one; a contact in several companies (`company_ids` in `list_contacts`) leaves the draft with no client, so pass `company_id` too. `title` defaults to the template name followed by the client's name. Only one receiver can be set here. Returns the draft with `recipients` (sender first, then receivers, then people copied in) and `unassigned_roles`, the roles nobody fills yet â tell the user to fill those in Bonsai before sending, since a receiver left unassigned cannot sign. Each call creates a new draft. Includes `url`, a direct link that opens the draft in the Bonsai editor â share it with the user so they can review and send it.
Inputs
template_idstringrequired- Id of the document template to start from â the `id` of a `list_templates` entry. Required: there is no blank document.
company_idstring- Client company the document is for â the company you are doing the work for, not your own account. Resolve via `list_companies`. With no `contact_id`, `project_id` or `deal_id`, its primary contact fills the receiver role. Pass `null` or omit to take the client from the project, else the deal, else the contact's company when the contact belongs to exactly one. For a contact in several companies, pass `company_id` â otherwise the document gets no client.
contact_idstring- Contact who fills the template's first receiver role â resolve via `list_contacts`. Must belong to the same client company as `company_id`, `project_id` and `deal_id`. Pass `null` or omit to let the project, deal or company pick the receiver.
deal_idstring- Deal to link the document to â resolve via `list_deals`. Must belong to the same client company. Without `contact_id`, the deal's client fills the receiver role. Pass `null` or omit for none.
project_idstring- Project to link the document to â resolve via `list_projects`. Must belong to the same client company. Without `contact_id`, the project's client fills the receiver role. Pass `null` or omit for none.
titlestring- Document title. Pass `null` or omit to default to the template name followed by the client company's name, or the template name alone when there is no client.
bonsaimcp_create_invoiceCreate a one-time invoice in Bonsai.WriteCreate Invoice
Create a one-time invoice in Bonsai. Requires company_id (client company), contact_id (billing contact), and project_id. Optional currency, title, due terms, and invoice_items array (each with name, amount, rate).
Inputs
company_idintegerrequired- Client company (Connection) id this invoice bills â the company you are doing the work for, not your own account. Required. Resolve via `list_companies`.
contact_idintegerrequired- Billing contact id at the client company â resolve via `list_contacts`. Required (upstream no longer falls back to a default contact). When the user does not name a contact, default to the company's primary contact â `default_contact_id` from `list_companies` â and confirm it with the user before creating, rather than asking for the contact outright.
project_idintegerrequired- Existing project id to invoice â resolve via `list_projects`. Required (upstream no longer supports project-less invoices). Must belong to the same client company as `company_id`. The public API never creates projects, so the project must already exist.
currencystring- ISO 4217 currency code (e.g. "USD"). Omit to default to the project currency.
duestring- Due-date term. `custom` requires `due_date`; `upon_receipt` rejects `due_date`. Omit to inherit the company-configured terms (may resolve to net-X days).one of
upon_receiptcustom due_datestring- Invoice due date (YYYY-MM-DD). Required when `due` is `custom`; rejected otherwise.
invoice_itemsarray- Optional inline line items. Omit for an invoice with no lines (total 0). Each line requires `name`, `amount`, and `rate`.
kindstring- What to create: `single` (a one-off â the default), `recurring` (reissued every `repeat_interval`), or `subscription` (recurring, and charged automatically to the card the client has on file). `bundled` invoices are assembled in the Bonsai app from invoices that already exist and cannot be created here. A recurring invoice starts reissuing itself shortly after creation, so confirm with the user before sending anything other than `single`.one of
singlerecurringsubscription repeat_finish_datestring- Date to stop reissuing the invoice (YYYY-MM-DD). Omit to keep the series running until it is stopped in the app. Only allowed when `kind` is `recurring` or `subscription`, and upstream rejects a date earlier than the first repeat â one `repeat_interval` after the issue date, which is today. Land it a whole number of intervals after today and the series ends with a final invoice on that date; off that grid it just stops after the last repeat that falls before it.
repeat_intervalstring- How often to reissue the invoice: `weekly`, `every two weeks`, `every four weeks`, `monthly`, `every two months`, `quarterly`, `every six months`, or `annually`. Required when `kind` is `recurring` or `subscription`; rejected otherwise.one of
weeklyevery two weeksevery four weeksmonthlyevery two monthsquarterlyevery six monthsannually titlestring- Invoice title. Omit to default to "<Client> Invoice".
bonsaimcp_create_invoice_itemAdd a line item to an existing Bonsai invoice.WriteCreate Invoice Item
Add a line item to an existing Bonsai invoice. Requires invoice_id, name, amount, and rate (decimal strings). Optional description and unit_type.
Inputs
amountstringrequired- Line quantity as a non-negative decimal string (e.g. "3"). Required.
invoice_idintegerrequired- Id of the invoice to add the line to. Required, in the path. Use the `id` returned by a prior `create_invoice` call, or resolve it via `list_invoices`.
namestringrequired- Line item name. Required.
ratestringrequired- Per-unit amount as a non-negative decimal string (e.g. "100"). Required.
descriptionstring- Optional line item description.
unit_typestring- Unit of the line: `flat`, `per_hour`, `per_day`, `per_item`, `per_word`, `per_week`, `per_month`, `per_year`, or `per_quarter`. Omit to default to `flat`.one of
flatper_hourper_dayper_itemper_wordper_weekper_monthper_yearper_quarter
bonsaimcp_create_noteWrite a note in the user's current company.WriteCreate Note
Write a note in the user's current company. Only `content` is required, and it is Markdown — Bonsai stores it as rich text, so headings, bold/italic, bullet, numbered and task lists, links, quotes, tables and code blocks all survive; leave a blank line between paragraphs, since a single newline is only a soft break. Attach the note to a client company, a project or a contact by passing `record_type` and `record_id` together (resolve ids via `list_companies`, `list_projects` or `list_contacts`); omit both for a note that stands on its own in the workspace. `title` defaults to empty and `date` — the day the note is about, which is what the app sorts and groups by — defaults to today in the account timezone. Notes written through the API are visible to everyone in the account. Returns the created note with its body as `content_plain_text`. Each call writes a new note.
Inputs
contentstringrequired- The note body, in Markdown. Required. Bonsai stores it as rich text, so headings, **bold**, *italic*, ~~strikethrough~~, bullet/numbered/`- [ ]` task lists, links, > quotes, --- dividers, tables, inline code and fenced code blocks all round-trip. A single newline is a soft break within one paragraph â leave a blank line between paragraphs. Raw HTML and images are reduced to their text. The response returns the stored body, never your Markdown: `content_plain_text` to read it, and `content_html` for the editor HTML â the field `update_note` takes to change it later.
datestring- The day the note is about (YYYY-MM-DD), which is what the app sorts and groups notes by. Pass `null` or omit to default to today in the account's timezone.
record_idstring- Id of the record to attach the note to, in the resource named by `record_type` â resolve via `list_companies`, `list_projects`, or `list_contacts`. Required when `record_type` is set.
record_typestring- What to attach the note to: `company` (a CRM client), `project`, or `contact`. Requires `record_id`. Omit both for a note that stands on its own in the workspace.
titlestring- Note title. Pass `null` or omit to leave it empty.
visibilitystring- Who can read the note: `everyone` in the account, or `author_only` for a private note nobody but its author â the user you are writing for â can see. Pass `null` or omit for the `everyone` default. Only the author can change this later, through `update_note`.
bonsaimcp_create_note_linkAttach a note that already exists to a client company, a project or a contact â use this to file a standalone note under a record after the fact, or to add a second record to a note that already has one.WriteCreate Note Link
Attach a note that already exists to a client company, a project or a contact â use this to file a standalone note under a record after the fact, or to add a second record to a note that already has one. Requires `note_id` (use the `id` from a prior `create_note` call or resolve via `list_notes`) plus `record_type` and `record_id` together (resolve ids via `list_companies`, `list_projects` or `list_contacts`). Attaching is idempotent: passing a record the note already carries hands back the attachment that was there and writes nothing, so a retry is safe. A note holds at most 10 records; an eleventh is rejected. Attaching takes the same permission as editing the note, so whoever wrote a note can always attach to it. Notes the caller cannot see return not-found; a visible note the caller may not edit returns a permission error, and a record the caller cannot reach is rejected. Returns the attachment, whose `id` is what `destroy_note_link` takes to undo it.
Inputs
note_idstringrequired- Id of the note to attach the record to. Required, in the path. Use the `id` returned by a prior `create_note` call, or resolve it via `list_notes`.
record_idintegerrequired- Id of the record to attach, in the resource named by `record_type` â resolve via `list_companies`, `list_projects`, or `list_contacts`. Required.
record_typestringrequired- What to attach the note to: `company` (a CRM client), `project`, or `contact`. Required.one of
companyprojectcontact
bonsaimcp_create_projectCreate a project for an existing client company in Bonsai.WriteCreate Project
Create a project for an existing client company in Bonsai. Requires title, company_id (resolve via list_companies), and billing_type (time/fixed_fee/retainer/not_billable). billing_fee required for fixed_fee/retainer; billing_cycle required for retainer.
Inputs
billing_typestringrequired- How the project bills. Required. One of `time`, `fixed_fee`, `retainer`, `not_billable`. Governs which of `billing_fee` / `billing_cycle` are required: `fixed_fee` needs `billing_fee` (no cycle); `retainer` needs both; `time` and `not_billable` accept neither.one of
timefixed_feeretainernot_billable company_idintegerrequired- Company id this project is for â the company you are doing the work for, not your own account. Required. Resolve via `list_companies`.
titlestringrequired- Project title. Required.
billing_cyclestring- Billing cadence: `weekly`, `monthly`, `quarterly`, `biannually`, or `yearly`. Required when `billing_type` is `retainer`; rejected for every other billing type.one of
weeklymonthlyquarterlybiannuallyyearly billing_feestring- Project fee as a non-negative decimal string (e.g. "5000.00"). Required when `billing_type` is `fixed_fee` or `retainer`; rejected for `time` / `not_billable`.
currencystring- ISO 4217 currency code (e.g. "USD"). Omit to default to the company currency. This is the only place it can be set â a project keeps it for life, so `update_project` cannot change it.
finish_datestring- Date work ends (ISO 8601 YYYY-MM-DD). Must be on or after `start_date`. Omit to leave the project open-ended.
start_datestring- ISO 8601 date (YYYY-MM-DD). Omit to default to today.
bonsaimcp_create_taskCreate a task in the user's Bonsai company.WriteCreate Task
Create a task in the user's Bonsai company. Supports title (required), optional project_id, assignee_member_id (company member id or 'me'), priority (urgent/high/medium/low), and due_date (YYYY-MM-DD).
Inputs
titlestringrequired- Task title.
assignee_member_idstring- Company member id of the assignee, or the literal "me" to assign to the caller. Resolve people via `list_team_members` and pass its `company_member_id` value. Pass `null` to leave unassigned.
billableboolean- Whether time tracked on the task is billable. Omit to take the default: a subtask inherits its parent, a task on a not-billable project is not billable, and everything else is billable. Honored only with permission to set task billing, on a plan that includes it; otherwise the value is silently ignored and the default applies â read `billable` back off the created task to see what stuck.
deal_idstring- Deal id to put the task on. Optional â resolve via `list_deals`. Independent of `project_id`: a task can sit on a deal, a project, both or neither, and unlike `project_id` this may be combined with `parent_task_uuid` (a subtask inherits its parent's project, never its deal). Needs permission to create deals on top of permission to create tasks; without it, or for a deal outside this account, the whole request fails. `null` or omitted leaves the task on no deal.
descriptionstring- Task description. Accepts an HTML fragment for rich-text formatting (e.g. `<p>`, `<strong>`, `<ul>`/`<li>`, `<a>`), stored verbatim. Plain text is fine too.
due_datestring- ISO 8601 date (YYYY-MM-DD). `null` or omitted leaves the task unscheduled. Must be on or after `start_date` when both are supplied.
parent_task_uuidstring- Parent task UUID â set this to create the task as a subtask of an existing task. The subtask inherits its parent's project, contractor company, and billable setting, so `project_id` must not be supplied alongside it (`billable` may be, and overrides what the parent would give). Resolve UUIDs via `list_tasks`, `get_task`, or `list_subtasks` (the task `uuid`). Tasks nest at most two levels below a top-level task; a parent already at the deepest level is rejected upstream.
prioritystring- Optional priority bucket: `urgent`, `high`, `medium`, or `low`.
project_idstring- Project id the task belongs to. Optional â tasks can exist outside a project. Resolve via `list_projects`. Must not be combined with `parent_task_uuid` â a subtask inherits its parent's project.
start_datestring- ISO 8601 date (YYYY-MM-DD) the task starts. Must be on or before `due_date` when both are supplied.
tag_idsarray- Company tag ids to set on the task â resolve via `list_company_tags` (task-type tags). Omit or pass `[]` to create the task with no tags.
task_status_idstring- TaskStatus UUID for the board column the task lands in. Resolve ids via `list_task_statuses`. `null` or omitted defaults to the company's "To Do" column.
time_estimate_in_minutesstring- Estimated effort in whole minutes (e.g. 90 for 1h30m). Positive integer.
bonsaimcp_create_time_entryLog a time entry in the user's Bonsai company.WriteCreate Time Entry
Log a time entry in the user's Bonsai company. Requires seconds (duration) and date (YYYY-MM-DD). Optionally attach to a project_id or task_uuid. Each call creates a new entry.
Inputs
datestringrequired- Date the work was done (YYYY-MM-DD). Required.
secondsintegerrequired- Duration of the entry, in whole seconds. Required. Users rarely state seconds, so convert their stated duration first â including decimal units: minutes à 60, hours à 3600 (e.g. "2h30m" â 9000, "45 min" â 2700, "1.5h" â 5400, "3.1h" â 11160), rounding to the nearest whole second. Do not assume a fixed workday length for "days"/"weeks" â a tracked day depends on the user's working hours, not 24h; resolve it to hours with the user before converting.
non_billablestring- Whether the entry is non-billable. Honored only with the billing permission; otherwise defaults from the task or project billing type.
notesstring- Free-text description of the work.
owner_member_idstring- Who logged the time: a Company member id or the literal "me" for the caller. Resolve people via `list_team_members` (its `company_member_id`). Logging time for another member requires the "all time entries" permission. Defaults to the caller when omitted.
project_idstring- Project to log against â resolve via `list_projects`. Ignored when `task_uuid` is set (the project is taken from the task). Sample/demo projects are not accepted.
ratestring- Hourly rate as a non-negative decimal string (e.g. "150.00"). Honored only with the billing permission; otherwise defaults from the project or member rate.
task_uuidstring- Task to link â resolve via `get_task` / `list_tasks`. When set, the project is taken from the task and `project_id` is ignored. Template tasks and tasks on sample/demo projects are not accepted.
bonsaimcp_stop_invoice_recurrenceEnd a recurring or subscription invoice series, so no further invoices are issued and a subscription stops charging the card the client has on file â the same thing ending a billing cycle does in the Bonsai app.WriteStop Invoice Recurrence
End a recurring or subscription invoice series, so no further invoices are issued and a subscription stops charging the card the client has on file â the same thing ending a billing cycle does in the Bonsai app. Nothing already issued changes: an outstanding invoice stays outstanding and still has to be paid, and nothing is deleted. Pass `invoice_id` â any invoice in the series will do, because the schedule lives on the most recent one, and that is the invoice acted on and returned, so the `id` that comes back is often not the one you sent. Confirm from `recurrence_active` on the result: false means the series is over. An invoice that had not repeated yet comes back as `single`, left behind as a one-off. Check `recurrence_active` before calling: when it is already false there is nothing left to stop and the call answers with a validation error, which is also what a second call gets â read that as the stop having already gone through, not as a failure. Stopping a subscription also turns off the auto-send that issued it. This cannot be undone, so confirm with the user before calling it. Returns the full invoice that carried the schedule, including `url`, a direct link to the record in Bonsai â share it with the user so they can open it.
Inputs
invoice_idintegerrequired- Id of any invoice in the series to stop. Required, in the path. Resolve via `list_invoices`, or use the `id` returned by a prior `create_invoice` call.
bonsaimcp_update_companyUpdate an existing CRM company in Bonsai.WriteUpdate Company
Update an existing CRM company in Bonsai. Requires id (resolve via list_companies). All other fields optional — only supplied fields are changed. Passing domains=[] removes all domains.
Inputs
idintegerrequired- Id of the company to update. Required. Resolve via `list_companies`.
company_sizestring- Headcount band for the company. One of `size_1_10`, `size_11_50`, `size_51_200`, `size_201_1000`, or `size_1000_plus`. Pass `null` to clear it, or omit to leave it unchanged.
default_contact_idinteger- Contact id to mark as the company's primary contact. Must be accessible in the same account. Resolve via `list_contacts`. Omit to leave it unchanged; unsetting the primary contact is not supported by this endpoint.
descriptionstring- Free text notes about the company. Pass `null` to clear it, or omit to leave it unchanged.
domainsarray- Domain strings for the company (e.g. ["example.com"]). A populated array ADDS each value â normalised server-side (protocol/www stripped, lowercased), re-asserting one the company already has is a no-op, and a domain claimed by another company in the account is rejected. Pass `[]` to remove every domain. Omit to leave domains unchanged.
facebookstring- Link to the company's Facebook page. Pass `null` to clear it, or omit to leave it unchanged.
industrystring- The industry the company operates in. One of `arts_and_entertainment`, `business_and_consumer_services`, `community_and_society`, `computers_electronics_and_technology`, `e_commerce_and_shopping`, `finance`, `food_and_drink`, `gambling`, `games`, `health`, `heavy_industry_and_engineering`, `hobbies_and_leisure`, `home_and_garden`, `jobs_and_career`, `law_and_government`, `lifestyle`, `luxury`, `news_and_media`, `pets_and_animals`, `reference_materials`, `science_and_education`, `sports`, `travel_and_tourism`, or `vehicles`. Pass `null` to clear it, or omit to leave it unchanged.
instagramstring- Link to the company's Instagram profile. Pass `null` to clear it, or omit to leave it unchanged.
linkedinstring- Link to the company's LinkedIn profile. Pass `null` to clear it, or omit to leave it unchanged.
namestring- New company name. Omit to leave it unchanged. Clearing the name is not supported by this endpoint; a blank string is rejected.
sourcestring- How the client was acquired. One of `organic_search`, `paid_search`, `email_marketing`, `organic_social`, `referrals`, `other_campaigns`, `direct_traffic`, `offline_sources`, `paid_social`, or `ai_referrals`. Pass `null` to clear it, or omit to leave it unchanged.
twitterstring- Link to the company's X profile. Pass `null` to clear it, or omit to leave it unchanged.
bonsaimcp_update_contactUpdate an existing CRM contact in Bonsai.WriteUpdate Contact
Update an existing CRM contact in Bonsai. Requires id (resolve via list_contacts). All other fields optional. Pass null for job_title or phone_number to clear them.
Inputs
idintegerrequired- Id of the contact to update. Required. Resolve via `list_contacts`.
emailstring- New contact email. Omit to leave it unchanged. Clearing the email is not supported by this endpoint; a blank value is rejected.
job_titlestring- Job title. Pass `null` to clear it, or omit to leave it unchanged.
namestring- New contact full name. Omit to leave it unchanged. Clearing the name is not supported by this endpoint; a blank value is rejected.
phone_numberstring- Phone number. Pass `null` to clear it, or omit to leave it unchanged.
bonsaimcp_update_invoicePartially update an existing invoice in the user's current company.WriteUpdate Invoice
Partially update an existing invoice in the user's current company. Requires `id` (the invoice — use the `id` from a prior `create_invoice` call or resolve via `list_invoices`); every other field is optional and only the ones supplied are changed. Supports `contact_id` (the billing contact — must belong to the invoice's existing client company; resolve via `list_contacts`), `currency` (ISO 4217), `title` (blank rejected), and `due`/`due_date` (`custom` requires `due_date`; `upon_receipt` rejects it; a standalone `due_date` sets a custom date). The client company, project, and line items cannot be changed here — the client and project are fixed at creation, and line items are managed with `create_invoice_item`, `update_invoice_item`, and `destroy_invoice_item`. A paid or pending invoice is not editable. Returns the full updated invoice. Includes `url`, a direct link to the record in Bonsai — share it with the user so they can open it.
- Idempotent
Inputs
idintegerrequired- Id of the invoice to update. Required, in the path. Use the `id` returned by a prior `create_invoice` call, or resolve it via `list_invoices`.
contact_idinteger- New billing contact id â must belong to the invoice's existing client company (resolve via `list_contacts`). Omit to leave it unchanged. The client company and project are fixed at creation and cannot be changed here.
currencystring- New ISO 4217 currency code (e.g. "USD"). Omit to leave it unchanged.
duestring- Due-date term. `custom` requires `due_date`; `upon_receipt` rejects `due_date`. Omit to leave it unchanged.one of
upon_receiptcustom due_datestring- Invoice due date (YYYY-MM-DD). Required when `due` is `custom`; rejected when `due` is `upon_receipt`. Supplying it alone (without `due`) sets a custom due date.
titlestring- New invoice title. Omit to leave it unchanged; a blank string is rejected.
bonsaimcp_update_invoice_itemUpdate the supplied fields of a single line item on an invoice; the invoice total is recomputed.WriteUpdate Invoice Item
Update the supplied fields of a single line item on an invoice; the invoice total is recomputed. Requires `invoice_id` (the invoice — use the `id` from a prior `create_invoice` call or resolve via `list_invoices`) and `id` (the line item — use the `id` from a prior `create_invoice_item` call); every other field is optional and only the ones supplied are changed. Supports `name` (blank rejected), `description`, `amount`, `rate` (non-negative decimal strings), and `unit_type` (`flat`/`per_hour`/`per_day`/`per_item`/`per_word`/`per_week`/`per_month`/`per_year`/`per_quarter`). The invoice must still be editable — a paid, pending, or partially paid invoice is rejected. Returns the updated line item including its server-computed `total`.
- Idempotent
Inputs
idintegerrequired- Id of the line item to update. Required, in the path. Use the `id` returned by a prior `create_invoice_item` call, or read it off the invoice `invoice_items`.
invoice_idintegerrequired- Id of the invoice the line item belongs to. Required, in the path. Use the `id` returned by a prior `create_invoice` call, or resolve it via `list_invoices`.
amountstring- New line quantity as a non-negative decimal string (e.g. "3"). Omit to leave it unchanged.
descriptionstring- New line item description. Omit to leave it unchanged.
namestring- New line item name. Omit to leave it unchanged; a blank string is rejected.
ratestring- New per-unit amount as a non-negative decimal string (e.g. "100"). Omit to leave it unchanged.
unit_typestring- New unit of the line: `flat`, `per_hour`, `per_day`, `per_item`, `per_word`, `per_week`, `per_month`, `per_year`, or `per_quarter`. Omit to leave it unchanged.one of
flatper_hourper_dayper_itemper_wordper_weekper_monthper_yearper_quarter
bonsaimcp_update_noteRewrite an existing note in the user's current company.WriteUpdate Note
Rewrite an existing note in the user's current company. Requires `id` (resolve via `list_notes`); `content_html`, `title`, `date` and `visibility` are all optional and only the ones supplied change. To change what a note says, read it with `get_note` first, take its `content_html`, edit the part the user asked about and send the whole thing back â `content_html` replaces the entire body, so anything you leave alone is preserved. Keep the editor's `data-*` attributes as they came: task-list items carry their tick state in `data-checked`, so rewriting them as plain list items loses the checkboxes. Markdown is not accepted here, unlike `create_note`, and `content_plain_text` cannot be sent back â this tool takes HTML. The body cannot be emptied. `title` clears on an empty string or `null`. `date` â the day the note is about, which the app sorts and groups by â can be moved but not cleared. `visibility` turns a note private (`author_only`) or opens it to `everyone` in the account, and is the author's alone to set: from anybody else a changed value fails the whole request and writes nothing at all, though sending back the value the note already has is always accepted. The records a note is attached to cannot be changed here â they are managed with `create_note_link` and `destroy_note_link`. Anyone can edit a note they wrote; editing someone else's needs permission to write notes. Returns the full updated note, body included.
Inputs
idstringrequired- Id of the note to update. Required. Resolve via `list_notes`, and read the note with `get_note` first whenever you are changing its body.
content_htmlstring- The new note body, as HTML. It replaces the whole body, so send the complete note and not just the part you changed: read `content_html` from `get_note`, edit what the user asked for and send the result back â everything you leave alone then survives untouched. Keep the editor's `data-*` attributes exactly as they came: a task list is `<ul data-type="taskList">` with `<li data-type="taskItem" data-checked="true">` items, and dropping those turns the user's checkboxes into plain bullets. Markdown is not accepted here, unlike `create_note`, and neither is `content_plain_text`. Bonsai strips script-execution vectors on the way in, and refuses a body that survives that as empty â the body cannot be emptied. Omit to leave it unchanged.
datestring- Move the day the note is about (YYYY-MM-DD) â the day the app sorts and groups notes by. Omit to leave it unchanged. A date cannot be cleared, so `null` is not accepted.
titlestring- New note title. Pass an empty string or `null` to clear it, or omit to leave it unchanged.
visibilitystring- Who can read the note: `everyone` in the account, or `author_only` for a private note nobody but its author can see. Only the member who wrote the note can change this â from anybody else a changed value fails the whole request and nothing at all is written, not even the other fields. So send a new value only when this user wrote the note (their own are the notes `list_notes` returns for `created_by_member_id: "me"`); repeating the value `get_note` already returned is always accepted, whoever you are. Omit to leave it unchanged; `null` is not accepted, since upstream would silently ignore it.one of
everyoneauthor_only
bonsaimcp_update_projectUpdate an existing project in the user's current company.WriteUpdate Project
Update an existing project in the user's current company. Requires `id` (resolve via `list_projects`); every other field is optional and only the ones supplied are changed. Supports `title`, `start_date` and `finish_date` (YYYY-MM-DD), `billing_type` (`time`/`fixed_fee`/`retainer`/`not_billable`), `billing_fee` (non-negative decimal string), `billing_cycle` (`weekly`/`monthly`/`quarterly`/`biannually`/`yearly`), and `board_group_id` (Project Group UUID â resolve via `list_board_groups`, and it must be a stage on the board the project already sits on). Only `finish_date`, `billing_fee`, and `billing_cycle` can be cleared with `null`. Changing `billing_type` re-checks the whole billing combination against the saved project, so clear or set the fee and cycle in the same call, and `finish_date` must land on or after `start_date` once applied, so send both when moving a project earlier. Changing `billing_type`, `billing_fee` or `billing_cycle` needs permission to see billing; without it the whole request is rejected and nothing is saved, so a refused billing change takes any title or date change sent with it down too. The project stays with the same company and the same currency â neither can be changed here, and the currency is fixed once the project exists because the amounts already recorded against it are never converted, so set it with `create_project`. Returns the updated project (`id`, `number`, `title`, `public_url_token`, `company_name`, `board_group_id`, `start_date`, `finish_date`, `currency`), along with its `budget` â the ceiling, what it is measured in (`fee` for money in `currency`, `time` for hours), and a `current_cycle` with the amount and percentage consumed. Moving the dates rebuilds the budget cycles, so the `current_cycle` returned here is the rebuilt one, not the one that was running before the call. Budgets themselves cannot be set or changed here; use `update_project_budget`, or `create_project_budget` on a project with none yet. `budget` is null on a project with no budget and absent entirely without permission to see project budgets, so treat a missing key as "not visible to this user" rather than as an unbudgeted project. Includes `url`, a direct link to the record in Bonsai â share it with the user so they can open it.
Inputs
idintegerrequired- Id of the project to update. Required. Resolve via `list_projects`.
billing_cyclestring- Billing cadence: `weekly`, `monthly`, `quarterly`, `biannually`, or `yearly`. Pass `null` to clear it, or omit to leave it unchanged.
billing_feestring- Project fee as a non-negative decimal string (e.g. "5000.00"). Pass `null` to clear it, or omit to leave it unchanged.
billing_typestring- How the project bills: `time`, `fixed_fee`, `retainer`, or `not_billable`. Changing it re-checks the whole billing combination, so send the matching `billing_fee` / `billing_cycle` (or `null` to clear them) in the same call: `fixed_fee` needs a fee and no cycle; `retainer` needs both; `time` and `not_billable` need neither. Omit to leave it unchanged.one of
timefixed_feeretainernot_billable board_group_idstring- BoardGroup UUID â the Project Group to move the project to. Must be a stage on the project board the project already sits on; a project on no board can be filed onto any of them. Resolve via `list_board_groups` (filter `resource_type=Project`). Cannot be cleared. Omit to leave the stage unchanged.
finish_datestring- Date work ends (ISO 8601 YYYY-MM-DD). Must be on or after `start_date`, whether you send both or only one â the other is taken from the project as it stands. Pass `null` to leave the project open-ended, or omit to leave it unchanged.
start_datestring- Date work starts (ISO 8601 YYYY-MM-DD). Must be on or before `finish_date`, whether you send both or only one â the other is taken from the project as it stands. Cannot be cleared. Omit to leave it unchanged.
titlestring- New project title. Cannot be blank. Omit to leave it unchanged.
bonsaimcp_update_taskUpdate an existing task in the user's current company.WriteUpdate Task
Update an existing task in the user's current company. Requires uuid (resolve via list_tasks, get_task, or list_subtasks); every other field is optional and only the ones supplied are changed. Supports title, project_id (null detaches), assignee_member_id (Company member id or the literal "me"; null unassigns), priority (urgent/high/medium/low), due_date and start_date (YYYY-MM-DD; null clears), description (HTML fragment or plain text; null clears), time_estimate_in_minutes (positive integer; null clears), task_status_id (TaskStatus UUID — resolve via list_task_statuses), and tag_ids (full-replace set of company tag ids; [] clears). Clearing title, priority, or the status is not supported. Returns the full updated task. Includes url, a direct link to the record in Bonsai — share it with the user so they can open it.
- Idempotent
Inputs
uuidstringrequired- UUID of the task to update. Required. Resolve via `list_tasks`, `get_task`, or `list_subtasks`.
assignee_member_idstring- Company member id of the assignee, or the literal "me" to assign to the caller. Resolve people via `list_team_members` (the `company_member_id` field). Pass `null` to unassign, or omit to leave the assignee unchanged.
billableboolean- Whether time tracked on the task is billable. Sent alongside `project_id` it wins over the new project's default; omitted, moving the task to another project re-derives the flag from that project and leaving the project alone leaves the flag alone. Changing it re-bills the task's existing time entries. Honored only with permission to set task billing, on a plan that includes it; otherwise the value is silently ignored â read `billable` back off the returned task to see what stuck.
deal_idstring- Move the task to another deal, or `null` to take it off the deal it is on. Resolve via `list_deals`. Independent of `project_id` â moving one leaves the other alone. Needs permission to create deals; without it, or for a deal outside this account, the whole request fails and no other field is written either. Omit to leave the deal unchanged.
descriptionstring- Task description. Accepts an HTML fragment for rich-text formatting, stored verbatim. Pass `null` to clear it, or omit to leave it unchanged.
due_datestring- ISO 8601 date (YYYY-MM-DD). Pass `null` to clear it, or omit to leave it unchanged.
prioritystring- Priority bucket: `urgent`, `high`, `medium`, or `low`. Omit to leave it unchanged; this endpoint cannot clear a priority once set.one of
urgenthighmediumlow project_idstring- Re-point the task to another project, or `null` to detach it from its project. Resolve via `list_projects`. Omit to leave the project unchanged.
start_datestring- ISO 8601 date (YYYY-MM-DD). Pass `null` to clear it, or omit to leave it unchanged.
tag_idsarray- Full-replace set of company tag ids on the task â resolve via `list_company_tags`. Pass `[]` to remove all tags. Omit to leave the tags unchanged.
task_status_idstring- TaskStatus UUID for the board column the task moves to. Resolve ids via `list_task_statuses`. Omit to leave the status unchanged.
time_estimate_in_minutesstring- Estimated effort in whole minutes (positive integer). Pass `null` to clear it, or omit to leave it unchanged.
titlestring- New task title. Omit to leave it unchanged. Clearing the title is not supported by this endpoint; a blank string is rejected.
bonsaimcp_update_time_entryUpdate an existing time entry in the user's current company.WriteUpdate Time Entry
Update an existing time entry in the user's current company. Requires key (resolve via list_time_entries); every other field is optional and only the ones supplied are changed. Supports seconds (duration), date (YYYY-MM-DD), project_id (null detaches; ignored when linked to a task), task_uuid (null unlinks and clears the derived project), notes (empty string or null clears), rate (a non-negative decimal string) and non_billable (both honored only with the billing permission), and owner_member_id (Company member id or the literal "me"; reassigning to another member needs the "all time entries" permission). Entries billed on a finalized invoice cannot be edited. Returns the full updated time entry including the server-computed status and, with the billing permission, billable_amount.
- Idempotent
Inputs
keystringrequired- Key of the time entry to update (the `key` field on a time entry). Required. Resolve via `list_time_entries`.
billing_statusstring- Move the entry's billing state: "billed" marks it billed by hand, "unbilled" moves it back. Requires the billing permission â unlike `rate` and `non_billable`, a value here without that permission fails the whole request instead of being ignored. Not for excluding an entry from billing: that is the `non_billable` flag, and "non_billable" is not accepted here. Marking billed needs the entry to be on a project and billable. An entry already attached to an invoice cannot be moved in either direction â bill or un-bill it through its invoice instead. Send it as the only field to bill an entry on a locked (submitted or approved) timesheet â combined with any other field the lock applies and the write is refused. Note the returned `status` tracks invoicing, not this field, so it stays "unbilled" on an entry you mark billed by hand; read `billing_status` back to confirm. Omit to leave it unchanged.one of
billedunbilled datestring- Date the work was done (YYYY-MM-DD). Omit to leave it unchanged.
non_billablestring- Whether the entry is non-billable. Honored only with the billing permission. Omit to leave it unchanged.
notesstring- Free-text description of the work. Pass an empty string or `null` to clear it, or omit to leave it unchanged.
owner_member_idstring- Reassign who logged the time: a Company member id or the literal "me" for the caller. Resolve people via `list_team_members` (its `company_member_id`). Reassigning to another member requires the "all time entries" permission. Omit to leave it unchanged.
project_idstring- Re-point the entry to another project â resolve via `list_projects`. Ignored when the entry is linked to a task. Pass `null` to detach the project, or omit to leave it unchanged.
ratestring- Hourly rate as a non-negative decimal string (e.g. "150.00"). Honored only with the billing permission. Omit to leave it unchanged.
secondsinteger- New duration of the entry, in whole seconds. Omit to leave it unchanged. Users rarely state seconds, so convert their stated duration first â minutes à 60, hours à 3600 (e.g. "2h30m" â 9000, "1.5h" â 5400), rounding to the nearest whole second.
task_uuidstring- Link the entry to a task â resolve via `list_tasks` / `get_task`. When set, the project is taken from the task. Pass `null` to unlink the task (and clear the derived project), or omit to leave it unchanged.
bonsaimcp_destroy_invoiceDelete a draft invoice, or cancel one that is scheduled or has been sent; either way it stops appearing in `list_invoices`.DestructiveDestroy Invoice
Delete a draft invoice, or cancel one that is scheduled or has been sent; either way it stops appearing in `list_invoices`. Its `status` decides which: a `drafted` invoice is deleted, while a `scheduled`, `outstanding` or `overdue` one is cancelled â it keeps its invoice number and history, a scheduled one is never sent, and a sent one's payment link stops accepting payment. Hours and expenses billed on it go back to unbilled; nothing logged is deleted. Refused with a validation error that says why and what to do instead (most have to be handled in the Bonsai app): a `paid` or `pending` invoice, a payment or refund in progress on any other, any payment recorded against it (even on a draft), the deposit a contract or proposal is waiting on, one that is part of an invoice bundle, and the most recent invoice of a series that is still running (`recurrence_active` true). For that last one, call `stop_invoice_recurrence` first, which ends the whole series, so confirm that with the user separately. An older invoice in a series can be deleted and leaves the series running. An invoice that has already been deleted comes back as not found. This cannot be undone, so confirm with the user before calling it; `sent_date` tells you whether the client has already received the invoice. Returns the invoice as it was removed, with `status: "deleted"`.
Inputs
idintegerrequired- Id of the invoice to delete or cancel: the numeric `id`, not `invoice_number`. Required, in the path. Use the `id` returned by a prior `create_invoice` call, or resolve it via `list_invoices` (filter by `invoice_number` when given a number).
bonsaimcp_destroy_invoice_itemRemove a single line item from an invoice; any linked time entries are unbilled and the invoice total is recomputed.DestructiveDestroy Invoice Item
Remove a single line item from an invoice; any linked time entries are unbilled and the invoice total is recomputed. Requires `invoice_id` (the invoice — use the `id` from a prior `create_invoice` call or resolve via `list_invoices`) and `id` (the line item to remove — use the `id` from a prior `create_invoice_item` call). The invoice must still be editable — a paid, pending, or partially paid invoice is rejected. Returns the deleted line item.
- Idempotent
Inputs
idintegerrequired- Id of the line item to remove. Required, in the path. Use the `id` returned by a prior `create_invoice_item` call, or read it off the invoice `invoice_items`.
invoice_idintegerrequired- Id of the invoice the line item belongs to. Required, in the path. Use the `id` returned by a prior `create_invoice` call, or resolve it via `list_invoices`.
bonsaimcp_destroy_noteDelete a note by its id.DestructiveDestroy Note
Delete a note by its id. The note stops appearing in every subsequent read, and there is no way to restore it, so confirm with the user before calling this. Returns the deleted note's final state — `title`, `date`, `visibility`, `created_by_member_id`, `created_at`, `updated_at`, its body as `content_plain_text`, and the `note_links` it was attached to — so you can tell the user what went. Resolve ids via `list_notes`, and read a note with `get_note` first if you need to check what it says before deleting. Anyone can delete a note they wrote; deleting someone else's needs permission to delete notes. Notes the caller cannot see return not-found, as does a note that is already deleted; a visible note the caller may not delete returns a permission error.
- Idempotent
Inputs
idstringrequired- Id of the note to delete. Resolve via `list_notes`.
bonsaimcp_destroy_note_linkDetach one record from a note, so the note stops appearing under that company, project or contact.DestructiveDestroy Note Link
Detach one record from a note, so the note stops appearing under that company, project or contact. The note itself is untouched â detaching its last record leaves it in the workspace as a note without records, it does not delete it. Pass `note_id` and `id`, where `id` is the attachment id from `note_links` on any note response, not the id of the attached record. There is no way to restore an attachment, so confirm with the user before calling this, and read the note with `get_note` first if you need to check which records it carries. Unlike attaching, this is not idempotent: a second call for the same attachment returns not-found. Detaching takes the same permission as editing the note, so whoever wrote a note can always detach from it; notes and attachments the caller cannot see return not-found, and a visible note the caller may not edit returns a permission error. Returns the attachment as it was, so you can tell the user what went.
Inputs
idintegerrequired- Id of the attachment to remove â not the id of the attached record. Read it off `note_links` on any note response, or use the `id` returned by a prior `create_note_link` call.
note_idstringrequired- Id of the note to detach the record from. Required, in the path. Resolve via `list_notes` or `get_note`.
bonsaimcp_destroy_project_budgetStop tracking a project's budget.DestructiveDestroy Project Budget
Stop tracking a project's budget. The budget and its cycles are removed, and the project reads back with `budget: null` on `list_projects`. The project itself, and the time and expenses logged on it, stay as they are. Requires `project_id` (resolve via `list_projects`). A removed budget cannot be restored, only started again from scratch with `create_project_budget`, so confirm with the user before calling this. Removing a budget needs permission to edit the project and see its budget, but not a plan that includes budgets, so a company that moved to a plan without them can still remove the ones it has; a project the user may not edit is refused with a permission error. The project needs a `start_date`, because budget cycles run from it â set one with `update_project` first. Returns the budget as it stood when removed, every setting included, with its final `current_cycle`, so you can tell the user what went. A project with no budget is reported as not found, which is also what a second call gets; after a lost response, read that as the first call having gone through.
Inputs
project_idintegerrequired- Id of the project whose budget to remove. Required, in the path. Resolve via `list_projects`.
bonsaimcp_destroy_taskSoft-delete a task in Bonsai by its UUID.DestructiveDelete Task
Soft-delete a task in Bonsai by its UUID. The task is removed from every subsequent read; archived tasks can be deleted directly. Returns the deleted task's final state. Tasks the caller cannot see return not-found; visible tasks the caller is not allowed to delete return a permission error.
- Idempotent
Inputs
uuidstringrequired- UUID of the task to delete.
No tools match.