Skip to content
Scalekit Docs

Bonsai MCP

Vendor MCP34 toolsOAuth 2.1/DCRProductivityProject ManagementCRM & Sales

Connect to Bonsai, the all-in-one business management platform for freelancers and agencies. Manage projects, tasks, CRM contacts, deals, invoices, and...

Bonsai MCP connector

  1. Terminal window
    npm install @scalekit-sdk/node

    Full SDK reference: Node.js | Python

  2. Add your Scalekit credentials to your .env file. 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>
  3. quickstart.ts
    import { ScalekitClient } from '@scalekit-sdk/node'
    import 'dotenv/config'
    const scalekit = new ScalekitClient(
    process.env.SCALEKIT_ENV_URL,
    process.env.SCALEKIT_CLIENT_ID,
    process.env.SCALEKIT_CLIENT_SECRET,
    )
    const actions = scalekit.actions
    const connector = 'bonsaimcp'
    const identifier = 'user_123'
    // Generate an authorization link for the user
    const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
    console.log('Authorize Bonsai MCP:', link)
    process.stdout.write('Press Enter after authorizing...')
    await new Promise(r => process.stdin.once('data', r))
    // Make your first call
    const result = await actions.executeTool({
    connector,
    identifier,
    toolName: 'bonsaimcp_list_board_groups',
    toolInput: {},
    })
    console.log(result)

Connect this agent connector to let your agent:

  • Update time entry, task, invoice item — Update an existing time entry in the user’s current company
  • List time entries, task statuses, subtasks — List time entries in the user’s current company, paginated, newest first
  • Get note, task — 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
  • Task destroy — Soft-delete a task in Bonsai by its UUID
  • Note destroy — Delete a note by its id
  • Item destroy invoice — Remove a single line item from an invoice; any linked time entries are unbilled and the invoice total is recomputed

Use the exact tool names from the Tool list below when you call execute_tool. If you’re not sure which name to use, list the tools available for the current user first.

bonsaimcp_create_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.3 params

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.

NameTypeRequiredDescription
bodystringrequiredThe 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_idintegeroptionalInteger id of the parent deal to comment on. Provide exactly one of `task_id` or `deal_id`. Resolve deal ids via `list_deals`.
task_idstringoptionalUUID 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_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.3 params

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.

NameTypeRequiredDescription
namestringrequiredThe name of the company to create.
default_contact_idintegeroptionalOptional ID of the default contact for this company.
domainsarrayoptionalOptional list of email domains associated with this company.
bonsaimcp_create_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.5 params

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.

NameTypeRequiredDescription
emailstringrequiredEmail address of the contact.
namestringrequiredFull name of the contact.
company_idintegeroptionalOptional ID of the company to link this contact to.
job_titlestringoptionalOptional job title of the contact.
phone_numberstringoptionalOptional phone number of the contact.
bonsaimcp_create_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).8 params

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).

NameTypeRequiredDescription
company_idintegerrequiredID of the client company to invoice.
contact_idintegerrequiredID of the billing contact for this invoice.
project_idintegerrequiredID of the project this invoice is for.
currencystringoptionalISO 4217 currency code for the invoice.
duestringoptionalDue terms for the invoice.
due_datestringoptionalPayment due date in YYYY-MM-DD format. Required when due is 'custom'.
invoice_itemsarrayoptionalOptional array of line items to add to the invoice.
titlestringoptionalOptional title for the invoice.
bonsaimcp_create_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.6 params

Add a line item to an existing Bonsai invoice. Requires invoice_id, name, amount, and rate (decimal strings). Optional description and unit_type.

NameTypeRequiredDescription
amountstringrequiredQuantity or amount for this line item as a decimal string.
invoice_idintegerrequiredID of the invoice to add the line item to.
namestringrequiredName or label for the invoice line item.
ratestringrequiredRate per unit for this line item as a decimal string.
descriptionstringoptionalOptional longer description for the line item.
unit_typestringoptionalOptional unit type for the line item.
bonsaimcp_create_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.5 params

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.

NameTypeRequiredDescription
contentstringrequiredThe 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 body as `content_plain_text`, not Markdown.
datestringoptionalThe 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_idintegeroptionalId 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_typestringoptionalWhat 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.
titlestringoptionalNote title. Pass `null` or omit to leave it empty.
bonsaimcp_create_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.7 params

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.

NameTypeRequiredDescription
billing_typestringrequiredBilling type for the project.
company_idintegerrequiredThe ID of the client company this project belongs to.
titlestringrequiredThe title of the project to create.
billing_cyclestringoptionalBilling cycle for retainer projects. Required when billing_type is retainer.
billing_feestringoptionalBilling fee as a decimal string. Required for fixed_fee and retainer billing types.
currencystringoptionalISO 4217 currency code for the project, e.g. USD.
start_datestringoptionalProject start date in YYYY-MM-DD format.
bonsaimcp_create_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).11 params

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).

NameTypeRequiredDescription
titlestringrequiredThe title of the task to create.
assignee_member_idstringoptionalCompany member ID to assign the task to, or 'me' for the authenticated user.
descriptionstringoptionalTask description. Accepts an HTML fragment for rich-text formatting (e.g. <p>, <strong>, <ul>/<li>, <a>), stored verbatim. Plain text is fine too.
due_datestringoptionalDue date for the task in YYYY-MM-DD format. Must be on or after start_date when both are supplied.
parent_task_uuidstringoptionalParent 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. 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.
prioritystringoptionalPriority level for the task.
project_idintegeroptionalOptional ID of the project to associate this task with.
start_datestringoptionalDate the task starts, in YYYY-MM-DD format. Must be on or before due_date when both are supplied.
tag_idsarrayoptionalCompany 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_idstringoptionalTaskStatus 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_minutesintegeroptionalEstimated effort in whole minutes (e.g. 90 for 1h30m). Positive integer.
bonsaimcp_create_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.8 params

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.

NameTypeRequiredDescription
datestringrequiredDate of the time entry in YYYY-MM-DD format.
secondsintegerrequiredDuration of the time entry in seconds.
non_billablebooleanoptionalIf true, marks this time entry as non-billable.
notesstringoptionalOptional notes or description for the time entry.
owner_member_idstringoptionalCompany member ID who owns this time entry, or 'me' for the authenticated user.
project_idintegeroptionalOptional project ID to associate this time entry with.
ratestringoptionalOptional billing rate for this time entry as a decimal string.
task_uuidstringoptionalOptional UUID of the task to associate this time entry with.
bonsaimcp_destroy_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.2 params

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.

NameTypeRequiredDescription
idintegerrequiredId 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_idintegerrequiredId 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_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.1 param

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.

NameTypeRequiredDescription
idstringrequiredId of the note to delete. Resolve via `list_notes`.
bonsaimcp_destroy_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.1 param

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.

NameTypeRequiredDescription
uuidstringrequiredUUID of the task to delete.
bonsaimcp_get_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.1 param

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.

NameTypeRequiredDescription
idstringrequiredId of the note to fetch. Resolve via `list_notes`.
bonsaimcp_get_task#Fetch a single task from Bonsai by its UUID.1 param

Fetch a single task from Bonsai by its UUID.

NameTypeRequiredDescription
uuidstringrequiredUUID of the task to fetch.
bonsaimcp_list_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.4 params

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.

NameTypeRequiredDescription
namestringoptionalSubstring match on board group name.
pageintegeroptionalPage number to retrieve (1-based).
page_sizeintegeroptionalNumber of board groups per page. Maximum 100.
resource_typestringoptionalFilter by resource type: Deal (pipeline stages) or Project (project groups).
bonsaimcp_list_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.5 params

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.

NameTypeRequiredDescription
deal_idintegeroptionalInteger id of the parent deal whose comments to list. Provide exactly one of `task_id` or `deal_id`. Resolve deal ids via `list_deals`.
kindstringoptionalWhich 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`.
pageintegeroptionalPage number (1-indexed). Default 1.
page_sizeintegeroptionalItems per page (max 100). Default 25.
task_idstringoptionalUUID 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_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.3 params

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.

NameTypeRequiredDescription
namestringoptionalFree-text search on company name.
pageintegeroptionalPage number to retrieve (1-based).
page_sizeintegeroptionalNumber of companies per page. Maximum 100.
bonsaimcp_list_company_tags#List the caller's company tags as a single flat collection across every tag type, paginated. A company tag is a reusable label attached to Bonsai records. Each entry exposes id (the integer CompanyTag id accepted by the list_tasks tag_id filter), name, tag_type (which record type the tag applies to), and color. Supports filtering by name (case-insensitive substring match) and tag_type (exact match — one of client, deal, project, vendor, task, time_entry, expense, supplier). An unknown tag_type returns a bad_request error. Only the tag types whose underlying records the caller may list come back, so a narrower role sees fewer types — an empty result for a given tag_type can mean "no permission" rather than "no tags".4 params

List the caller's company tags as a single flat collection across every tag type, paginated. A company tag is a reusable label attached to Bonsai records. Each entry exposes id (the integer CompanyTag id accepted by the list_tasks tag_id filter), name, tag_type (which record type the tag applies to), and color. Supports filtering by name (case-insensitive substring match) and tag_type (exact match — one of client, deal, project, vendor, task, time_entry, expense, supplier). An unknown tag_type returns a bad_request error. Only the tag types whose underlying records the caller may list come back, so a narrower role sees fewer types — an empty result for a given tag_type can mean "no permission" rather than "no tags".

NameTypeRequiredDescription
namestringoptionalCase-insensitive substring match on the tag name.
pageintegeroptionalPage number (1-indexed). Default 1.
page_sizeintegeroptionalItems per page (max 100). Default 25.
tag_typestringoptionalExact match on the tag type. One of client, deal, project, vendor, task, time_entry, expense, supplier. Omit to return every tag type.
bonsaimcp_list_contacts#List CRM contacts in the user's Bonsai account. Supports filtering by name, email, and company.5 params

List CRM contacts in the user's Bonsai account. Supports filtering by name, email, and company.

NameTypeRequiredDescription
company_idintegeroptionalFilter contacts by company ID.
emailstringoptionalFree-text search on contact email address.
namestringoptionalFree-text search on contact name.
pageintegeroptionalPage number to retrieve (1-based).
page_sizeintegeroptionalNumber of contacts per page. Maximum 100.
bonsaimcp_list_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.6 params

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.

NameTypeRequiredDescription
assignee_member_idstringoptionalFilter by assignee company member ID (as a string) or the literal value "me".
board_group_idstringoptionalUUID of the pipeline stage to filter deals by.
deal_numberstringoptionalFree-text search on deal number.
pageintegeroptionalPage number to retrieve (1-based).
page_sizeintegeroptionalNumber of deals per page. Maximum 100.
titlestringoptionalFree-text search on deal title.
bonsaimcp_list_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.5 params

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.

NameTypeRequiredDescription
company_idintegeroptionalFilter invoices by client company ID.
invoice_numberstringoptionalExact invoice number lookup.
pageintegeroptionalPage number to retrieve (1-based).
page_sizeintegeroptionalNumber of invoices per page. Maximum 100.
project_idintegeroptionalFilter invoices by project ID.
bonsaimcp_list_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).7 params

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).

NameTypeRequiredDescription
created_by_member_idintegeroptionalFilter 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_fromstringoptionalNotes dated on or after this day (YYYY-MM-DD), inclusive.
date_tostringoptionalNotes dated on or before this day (YYYY-MM-DD), inclusive.
pageintegeroptionalPage number (1-indexed). Default 1.
page_sizeintegeroptionalItems per page (max 100). Default 25.
record_idintegeroptionalReturn 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_typestringoptionalReturn only notes attached to this kind of record: `company` (a CRM client), `project`, or `contact`. Requires `record_id` — neither narrows anything on its own.
bonsaimcp_list_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).6 params

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).

NameTypeRequiredDescription
board_group_idstringoptionalUUID of the Project Group to filter by.
pageintegeroptionalPage number to retrieve (1-based).
page_sizeintegeroptionalNumber of projects per page. Maximum 100.
public_url_tokenstringoptionalExact public URL token lookup for a project.
statusstringoptionalProject lifecycle status. Omit to default to active; not_archived returns active and completed, and all returns every status (active, archived, not_archived, completed, all).
titlestringoptionalFree-text search on project title.
bonsaimcp_list_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.3 params

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.

NameTypeRequiredDescription
task_idstringrequiredUUID of the parent task whose subtasks to list.
pageintegeroptionalPage number (1-indexed). Default 1.
page_sizeintegeroptionalItems per page (max 100). Default 25.
bonsaimcp_list_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.2 params

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.

NameTypeRequiredDescription
pageintegeroptionalPage number (1-indexed). Default 1.
page_sizeintegeroptionalItems per page (max 100). Default 25.
bonsaimcp_list_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.12 params

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.

NameTypeRequiredDescription
assignee_idstringoptionalFilter by assignee. Pass an integer user ID as a string or the literal value "me" to filter by the current user.
duestringoptionalFilter by a named due-date window. Mutually exclusive with due_from/due_to.
due_fromstringoptionalFilter tasks due on or after this date (YYYY-MM-DD). Mutually exclusive with due.
due_tostringoptionalFilter tasks due on or before this date (YYYY-MM-DD). Mutually exclusive with due.
pageintegeroptionalPage number to retrieve (1-based).
page_sizeintegeroptionalNumber of tasks per page. Maximum 100.
prioritystringoptionalFilter by task priority.
project_idintegeroptionalFilter tasks by project ID.
scopestringoptionalScope of tasks to return.
tag_idintegeroptionalFilter tasks by tag ID.
task_status_idstringoptionalFilter by task status (board column). Pass a TaskStatus UUID (the id from list_task_statuses). Filtering by status returns tasks in any state (active, completed, or archived), overriding the default active scope.
titlestringoptionalFree-text search over task title (case-insensitive).
bonsaimcp_list_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.6 params

List team members in the user's current Bonsai company. Returns company_member_id (for task assignment), role, permission_profile, and lifecycle timestamps.

NameTypeRequiredDescription
idintegeroptionalCompany 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.
namestringoptionalFree-text search on team member name.
pageintegeroptionalPage number to retrieve (1-based).
page_sizeintegeroptionalNumber of team members per page. Maximum 100.
project_idintegeroptionalProject id(s). Returns only team members assigned to the given project(s). Single value or array.
user_idintegeroptionalUser id(s) to filter by. Pass a single id or an array. For creating tasks, use company_member_id instead.
bonsaimcp_list_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".9 params

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".

NameTypeRequiredDescription
billing_statusstringoptionalOne or more of billed, unbilled, non_billable. Single value or array. Needs the billing permission; without it the call is refused.
company_idintegeroptionalFilter 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.
currencystringoptionalISO 4217 currency code(s), e.g. "USD". Single value or array.
date_fromstringoptionalEntries on or after this date (YYYY-MM-DD), inclusive.
date_tostringoptionalEntries on or before this date (YYYY-MM-DD), inclusive.
owner_member_idstringoptionalFilter 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.
pageintegeroptionalPage number (1-indexed). Default 1.
page_sizeintegeroptionalItems per page (max 100). Default 25.
project_idintegeroptionalFilter by project id(s) — resolve via list_projects. Single value or array.
bonsaimcp_update_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.4 params

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.

NameTypeRequiredDescription
idintegerrequiredID of the company to update.
default_contact_idintegeroptionalUpdated default contact ID for the company.
domainsarrayoptionalUpdated list of domains for the company. Pass an empty array to remove all domains.
namestringoptionalUpdated name for the company.
bonsaimcp_update_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.5 params

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.

NameTypeRequiredDescription
idintegerrequiredID of the contact to update.
emailstringoptionalUpdated email address for the contact.
job_titlestringoptionalUpdated job title for the contact. Pass null to clear.
namestringoptionalUpdated full name for the contact.
phone_numberstringoptionalUpdated phone number for the contact. Pass null to clear.
bonsaimcp_update_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.6 params

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.

NameTypeRequiredDescription
idintegerrequiredId 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_idintegeroptionalNew 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.
currencystringoptionalNew ISO 4217 currency code (e.g. "USD"). Omit to leave it unchanged.
duestringoptionalDue-date term. `custom` requires `due_date`; `upon_receipt` rejects `due_date`. Omit to leave it unchanged.
due_datestringoptionalInvoice 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.
titlestringoptionalNew invoice title. Omit to leave it unchanged; a blank string is rejected.
bonsaimcp_update_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`.7 params

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`.

NameTypeRequiredDescription
idintegerrequiredId 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_idintegerrequiredId 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`.
amountstringoptionalNew line quantity as a non-negative decimal string (e.g. "3"). Omit to leave it unchanged.
descriptionstringoptionalNew line item description. Omit to leave it unchanged.
namestringoptionalNew line item name. Omit to leave it unchanged; a blank string is rejected.
ratestringoptionalNew per-unit amount as a non-negative decimal string (e.g. "100"). Omit to leave it unchanged.
unit_typestringoptionalNew 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.
bonsaimcp_update_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.11 params

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.

NameTypeRequiredDescription
uuidstringrequiredUUID of the task to update. Required. Resolve via list_tasks, get_task, or list_subtasks.
assignee_member_idstringoptionalCompany 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.
descriptionstringoptionalTask description. Accepts an HTML fragment for rich-text formatting, stored verbatim. Pass null to clear it, or omit to leave it unchanged.
due_datestringoptionalISO 8601 date (YYYY-MM-DD). Pass null to clear it, or omit to leave it unchanged.
prioritystringoptionalPriority bucket: urgent, high, medium, or low. Omit to leave it unchanged; this endpoint cannot clear a priority once set.
project_idintegeroptionalRe-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_datestringoptionalISO 8601 date (YYYY-MM-DD). Pass null to clear it, or omit to leave it unchanged.
tag_idsarrayoptionalFull-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_idstringoptionalTaskStatus UUID for the board column the task moves to. Resolve ids via list_task_statuses. Omit to leave the status unchanged.
time_estimate_in_minutesintegeroptionalEstimated effort in whole minutes (positive integer). Pass null to clear it, or omit to leave it unchanged.
titlestringoptionalNew task title. Omit to leave it unchanged. Clearing the title is not supported by this endpoint; a blank string is rejected.
bonsaimcp_update_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.9 params

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.

NameTypeRequiredDescription
keystringrequiredKey of the time entry to update (the key field on a time entry). Required. Resolve via list_time_entries.
datestringoptionalDate the work was done (YYYY-MM-DD). Omit to leave it unchanged.
non_billablebooleanoptionalWhether the entry is non-billable. Honored only with the billing permission. Omit to leave it unchanged.
notesstringoptionalFree-text description of the work. Pass an empty string or null to clear it, or omit to leave it unchanged.
owner_member_idstringoptionalReassign 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_idintegeroptionalRe-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.
ratestringoptionalHourly rate as a non-negative decimal string (e.g. "150.00"). Honored only with the billing permission. Omit to leave it unchanged.
secondsintegeroptionalNew 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_uuidstringoptionalLink 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.