MCP tools
Team, settings and profile
MCP tools for team members and invitations, organization settings and your profile.
This page gathers the tools that run the organization: team members and their invitations, the company details printed on quotations, and your own profile. Most are for the owner and admin roles, some for the owner alone, and each tool says who may use it.
Six roles can be assigned: admin, sales, purchasing, technical, viewer and viewer_no_pricing. The admin manages the team and integrations, while billing, the organization's own record and the team activity log stay with the owner. Sales and purchasing work on bids, quotations and the catalog, and both see sale prices. Sales does not see cost prices or supplier quotes, while purchasing sees both sides. Technical reads the catalog, manufacturers and tenders with no prices at all. Viewer is read-only with all prices, and viewer (no pricing) is read-only without prices. The owner is whoever created the organization: that role cannot be assigned, changed or removed with these tools.
| Tool | What it does |
|---|---|
| team_list | List the team |
| team_update_role | Change a member's role |
| team_remove | Remove a team member |
| team_invite_create | Invite a team member |
| team_invite_resend | Resend an invitation |
| team_invite_cancel | Cancel an invitation |
| settings_get | Get organization settings |
| settings_update | Update organization settings |
| profile_get | Get your profile |
| profile_update | Update your profile |
| zoho_books_get | Get the Zoho Books connection |
| zoho_books_organizations_list | List Zoho Books organizations |
| zoho_books_settings_update | Update Zoho Books sync settings |
| zoho_books_sync | Sync Zoho Books now |
| zoho_books_disconnect | Disconnect Zoho Books |
Team members and invitations
An invitation lasts 7 days. Seats are counted from current members and pending invitations together.
team_list
Lists the organization's members, each with their email and mobile number, and the pending invitations that can still be accepted. It is where the membership and invitation IDs for the other team tools come from.
Read-only · scope team.read · roles: owner, admin · Pro and Enterprise plans
No parameters.
Returns: members (each with id, the membership ID, user_id, role, created_at and a profiles object holding email, first_name, last_name, full_name, phone_number and company_name) and invitations (each with id, email, phone_number, role, status and expires_at).
- Expired, accepted and cancelled invitations are not listed: only those that can still be accepted appear.
team_update_role
Changes a team member's role. The owner's role can never be changed, and owner can never be assigned with this tool.
Changes data · scope team.write · roles: owner, admin · Pro and Enterprise plans
| Parameter | Type | Required | Description |
|---|---|---|---|
member_id | integer | Yes | The membership ID: the member's id in the reply to team_list, not the user ID. |
role | string | Yes | The new role: admin, sales, purchasing, technical, viewer or viewer_no_pricing, explained at the top of this page. owner is never accepted. |
{
"member_id": 27,
"role": "purchasing"
}Returns: A confirmation, success: true.
- Only the owner is protected: changing the owner's role answers 403, while any other member's role, an admin's included, can be changed. An unknown member answers 404.
- The new role applies to the member's next requests at once.
team_remove
Removes a member from the organization and ends their access to the platform. This cannot be undone: to bring them back you invite them again. The owner cannot be removed.
Deletes or overwrites data · scope team.write · roles: owner, admin · Pro and Enterprise plans
| Parameter | Type | Required | Description |
|---|---|---|---|
member_id | integer | Yes | The membership ID: the member's id in the reply to team_list. |
Returns: A confirmation, success: true.
- Trying to remove the owner answers 403, and an unknown member answers 404.
- API keys the member created stop working once they leave the organization.
team_invite_create
Emails an invitation to join the organization with a chosen role. The invitee's mobile (WhatsApp) number is required beside their email; it is copied to their profile when they accept, and the platform recognizes them by it, for example when approving WhatsApp group join requests. Members and pending invitations count together against your plan's seat limit, or against the paid seats when your subscription is billed per user. At the limit the owner adds a seat from the billing or team page in the app, because that charges the card.
Changes data · scope team.write · roles: owner, admin · Pro and Enterprise plans
| Parameter | Type | Required | Description |
|---|---|---|---|
email | string | Yes | The invitee's email address, up to 320 characters. It is stored in lowercase. |
phone_number | string | Yes | The invitee's mobile (WhatsApp) number with country code, such as +9665XXXXXXXX. A Saudi local number 05XXXXXXXX is accepted and completed with the country code, and the number is stored as digits only. An invalid number answers 400. |
role | string | Yes | The role the member will get: admin, sales, purchasing, technical, viewer or viewer_no_pricing, explained at the top of this page. owner is never accepted. |
{
"email": "layla.hassan@acme-medical.example",
"phone_number": "+966501234567",
"role": "sales"
}Returns: success, invitation_id and email_sent, which says whether the invitation email actually went out.
- When members plus pending invitations reach your plan's limit the call answers 402
plan_limit_reachedwithlimitandcurrent. A plan without role differentiation (Starter) accepts only theadminrole, and any other role answers 402plan_feature_required. - The call answers 409 when the person already belongs to an organization, this one or another, or has a pending invitation to any organization: one person has one organization and one open invitation.
- The invitation expires after 7 days. Its link takes the invitee to sign-up, where they join this organization.
team_invite_resend
Sends the email of a pending, unexpired invitation again, with the same link. It does not extend the invitation's 7 days.
Changes data · scope team.write · roles: owner, admin · Pro and Enterprise plans
| Parameter | Type | Required | Description |
|---|---|---|---|
invitation_id | integer | Yes | The invitation's ID, from team_list. |
Returns: success and email_sent, which says whether the email actually went out.
- An unknown invitation answers 404, one that is no longer pending (accepted or cancelled) answers 400, and an expired one answers 410: cancel it and send a new one.
team_invite_cancel
Cancels a pending invitation so its link can no longer be accepted. This cannot be undone: to invite the person again, send a new invitation.
Deletes or overwrites data · scope team.write · roles: owner, admin · Pro and Enterprise plans
| Parameter | Type | Required | Description |
|---|---|---|---|
invitation_id | integer | Yes | The invitation's ID, from team_list. |
Returns: A confirmation, success: true.
- Only a pending invitation can be cancelled; any other (an accepted one, say) answers 400. Cancelling gives the seat back to your plan's limit.
Organization settings
These details are printed on quotations and their documents, and only the owner may read or change them. The logo and stamp images have their own upload tools, such as `settings_logo_upload_url_create` and `settings_stamp_upload_url_create`.
settings_get
Returns the organization's details as printed on quotations: names, registration numbers, address and contact details, and the defaults for new quotations. Owner only.
Read-only · scope settings.read · roles: owner · Pro and Enterprise plans
No parameters.
Returns: The organization record: name, legal_name_ar, legal_name_en, cr_number, cc_number, sfda_license, vat_number, address_ar, address_en, phone, fax, po_box, city, postal_code, the default fields and quote_number_prefix, plus logo_path and stamp_path, which show whether the two images exist.
- Even reading is limited to the owner: any other role answers 403.
logo_pathandstamp_pathare read-only here. The images are uploaded or removed with the logo and stamp tools.
settings_update
Changes the organization's text details and the defaults for new quotations. Only what you send changes, and an empty string clears a field. Owner only.
Changes data · scope settings.write · roles: owner · Pro and Enterprise plans
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No | The organization's display name, 1 to 200 characters. It cannot be cleared. |
legal_name_ar | string | No | The legal name in Arabic, up to 200 characters. Send null to clear it. |
legal_name_en | string | No | The legal name in English, up to 200 characters. Send null to clear it. |
cr_number | string | No | The commercial registration number, up to 50 characters. Send null to clear it. |
cc_number | string | No | The chamber of commerce number, up to 50 characters. Send null to clear it. |
sfda_license | string | No | The SFDA license number, up to 100 characters. Send null to clear it. |
vat_number | string | No | The VAT number, up to 50 characters. Send null to clear it. |
address_ar | string | No | The address in Arabic, up to 500 characters. Send null to clear it. |
address_en | string | No | The address in English, up to 500 characters. Send null to clear it. |
phone | string | No | The organization's phone number, up to 50 characters. Send null to clear it. |
fax | string | No | The fax number, up to 50 characters. Send null to clear it. |
po_box | string | No | The PO box, up to 50 characters. Send null to clear it. |
city | string | No | The city, up to 100 characters. Send null to clear it. |
postal_code | string | No | The postal code, up to 20 characters. Send null to clear it. |
default_quote_validity_days | integer | No | The default quotation validity in days, from 1 to 3650. New quotations start with it. |
default_delivery_period_days | integer | No | The default delivery period in days, from 1 to 3650. New quotations start with it. |
default_payment_terms | string | No | The default payment terms for new quotations. Either a preset key: advance_100 (full advance payment), advance_50_balance_on_delivery (half in advance, the rest on delivery), on_delivery (due on delivery), or net_30, net_60, net_90 (30, 60 or 90 days from the invoice date); or custom text printed as you write it, up to 500 characters. Send null so new quotations print no payment terms. |
default_first_delivery_days | integer | No | The organization's default first-delivery lead time in days, from 0 to 3650. Bid documents use it when a product sets no lead time of its own. |
default_order_delivery_days | integer | No | The organization's default order-delivery lead time in days, from 0 to 3650. Bid documents use it when a product sets no lead time of its own. |
quote_number_prefix | string | No | The prefix quotation numbers start with, 1 to 10 characters. |
catalog_pricing_lowest_price | boolean | No | When several catalog products share an item's NUPCO code and the code has no default, tenders_catalog_pricing prices the item at the lowest sale price among them. On by default; false leaves such items for a person to decide. |
{
"cr_number": "1010123456",
"vat_number": "300012345600003",
"default_quote_validity_days": 30,
"default_payment_terms": "net_30",
"quote_number_prefix": "ACM-"
}Returns: A confirmation, success: true.
- A text field is cleared with an empty string or
null.name,quote_number_prefixand the day counts cannot be cleared. - Existing quotations keep the details they were printed with when they were made, and a change reaches new quotations only.
Your profile
Both tools work on the member who connected, the person every write is attributed to.
profile_get
Returns the profile of the member who connected: name, email and mobile number, along with their organization, the connection's scopes, their role, the organization's plan and what the role may do.
Read-only · scope settings.read · all roles · Pro and Enterprise plans
No parameters.
Returns: user_id, org_id, scopes, role, plan (with tier and features), capabilities (what the role may see and manage, such as can_view_bid_pricing), first_name, last_name, full_name, phone_number and email.
plan.featuresshows what the organization's plan includes. A tool that belongs to a feature the plan lacks answers 403plan_upgrade_required.capabilitiessums up what the role can do: see prices, supplier quotes, deliveries and orders, and edit bids and products.- A key whose owner has left the organization answers 403 on every call, not on this tool alone, and an admin has to issue a new one.
profile_update
Updates your own profile: first name, last name and mobile number. The number doubles as your salesperson contact on quotations, and the platform recognizes you by it, for example when approving WhatsApp group join requests.
Changes data · scope settings.write · roles: owner, admin, sales, purchasing · Pro and Enterprise plans
| Parameter | Type | Required | Description |
|---|---|---|---|
first_name | string | No | The first name, up to 100 characters. Send null to clear it. |
last_name | string | No | The family name, up to 100 characters. Send null to clear it. |
full_name | string | No | The full name as an alternative to the two names above, up to 200 characters. It is split at the first space into a first and a family name, and ignored when the same call changes the first or family name. Send null to clear it. |
phone_number | string | No | Your mobile (WhatsApp) number with country code, up to 30 characters. It is stored as digits only, and a Saudi local number 05XXXXXXXX is completed with the country code. Send null or an empty string to clear it. |
{
"first_name": "Layla",
"last_name": "Hassan",
"phone_number": "+966501234567"
}Returns: A confirmation, success: true.
- The full name is derived from the first and family names. An invalid number answers 400, and so does a call that carries no field.
- Sales roster entries linked to you update with your profile, while quotations already made keep the contact details printed on them.
Zoho Books connection
Each organization uses its own Zoho API client. An owner or admin enters that client and connects under Settings → Integrations in the app, because the client secret never passes through these tools and access is granted on Zoho's own page. Once connected, the sync is managed with these tools. It runs every hour and never deletes a record on either side.
zoho_books_get
Shows whether Zoho Books is connected, the Zoho Books organization in use, which directions are on, the start date, and the last run's outcome and counts.
Read-only · scope settings.read · roles: owner, admin · Pro and Enterprise plans
No parameters.
Returns: An object with connected, zoho_organization_name, import_sales_orders, import_mode, export_sales_orders, export_quotations, sync_since, last_sync_at, last_sync_ok and last_sync_summary. No access token is ever returned.
zoho_books_organizations_list
Lists the Zoho Books organizations the connected login reaches, so you can choose the one to sync with.
Read-only · scope settings.read · roles: owner, admin · Pro and Enterprise plans
No parameters.
Returns: An organizations list, each with organization_id and name.
zoho_books_settings_update
Chooses the Zoho Books organization and turns sync directions on or off. Only what you send changes.
Changes data · scope settings.write · roles: owner, admin · Pro and Enterprise plans
| Parameter | Type | Required | Description |
|---|---|---|---|
zoho_organization_id | string | No | The organization id from zoho_books_organizations_list. |
import_sales_orders | boolean | No | Import sales orders from Zoho Books. |
import_mode | string | No | How sales orders come in: records copies the order and its files every hour, and files creates nothing by itself; a member reads the attached purchase order on the sales order import page. |
import_sales_order_documents | boolean | No | In records mode, also copy the files attached to each order. On by default. |
export_sales_orders | boolean | No | Send sales orders to Zoho Books. Orders imported from it are never sent back. |
export_quotations | boolean | No | Send approved quotations as estimates, once they have stayed approved for 24 hours. |
sync_since | string | No | A YYYY-MM-DD day; only records dated on or after it move. |
{
"import_sales_orders": true,
"import_mode": "files",
"export_quotations": true
}Returns: The connection after the change, as zoho_books_get returns it.
- No direction can be turned on before an organization is chosen; the call answers 409.
zoho_books_sync
Runs the sync now instead of waiting for the next hourly run, and returns what it did.
Changes data · scope settings.write · roles: owner, admin · Pro and Enterprise plans
No parameters.
Returns: A summary with the counts of orders and files imported and sales orders and quotations sent, and one line per record Zoho refused.
- Answers 409 while another run is going or when no direction is on.
zoho_books_disconnect
Revokes ProcDuck's access to Zoho Books, stops the sync and deletes the organization's stored client secret. Nothing already copied is deleted on either side.
Deletes or overwrites data · scope settings.write · roles: owner, admin · Pro and Enterprise plans
No parameters.
Returns: A confirmation, disconnected: true.
- Reconnecting is done in the app only, and never copies a record twice.