MCP tools reference
Joist MCP tools
13 tools for Joist on the Cotlet MCP server. Your agent picks them from tools/list.
- MCP server
- https://cotlet.dev/mcp/v1
- Connects with
- Your own Joist account (email and password at pro.joistapp.com; Joist accounts have a single user)
- Integration page
- Joist
| Endpoint | Access | Description |
|---|---|---|
| joist_list_estimates | read | Estimates with number, client, total, expiry date, status, and whether the client opened the email or signed. |
| joist_list_invoices | read | Invoices with number, client, total, amount paid, balance due and due date. Active or Paid. |
| joist_get_document | read | Full estimate or invoice: client, line items, tax, discount, deposit and the payments recorded. |
| joist_list_clients | read | Clients in your account with name, email, phone and address. |
| joist_list_items | read | Saved items from your Items list, with name, description and rate, to reuse as line items. |
| joist_get_report | read | A Joist report for a date range: revenue, invoices, estimates or sales tax. |
| joist_export_documents | read | Joist's monthly CSV of estimates or invoices, as a download link. |
| joist_add_client | write | New client in your Clients list, ready for estimates and invoices. |
| joist_add_item | write | Save a service or material to your Items list. |
| joist_create_estimate | write | New saved estimate with line items, optional deposit and expiry. Nothing is sent to the client. |
| joist_convert_estimate_to_invoice | write | Generate an invoice with everything from the estimate. Not sent until you call send_document. |
| joist_record_payment | write | Record a payment received outside Joist Payments; a fully paid invoice moves to Paid. |
| joist_send_document | write | Email an estimate or invoice to the client from Joist. |
List estimates
readMCP tool joist_list_estimates
Lists the estimates in your Joist account, newest first. Each item shows the status (pending until approved), the expiry date if one is set, and the two markers Joist shows in its list: client opened the email, and signed. Pass estimate_id to convert_estimate_to_invoice or get_document.
Parameters
| Name | Type | Description |
|---|---|---|
| search | string | Client name or estimate number. |
| limit | integer | 1 to 100. Default: 25. |
| cursor | string | Next page cursor from the previous call. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "joist_list_estimates",
"arguments": {}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"estimates": [
{
"estimate_id": "est_20418",
"number": "318",
"client": "Dana Lee",
"total": 700,
"status": "pending",
"expires_on": "2026-10-25",
"email_opened": true,
"signed": false
}
],
"next_cursor": null
},
"isError": false
} List invoices
readMCP tool joist_list_invoices
Lists invoices from the Active view (not paid in full) or the Paid view, newest first. Balance due is the total less recorded payments, so a partly paid invoice shows what is left. The due date is the creation date plus your Payment Terms, and overdue is true where Joist shows the Overdue badge. Each item shows whether the client opened the email and whether it is signed.
Parameters
| Name | Type | Description |
|---|---|---|
| view | enum | active (not paid in full) or paid. Default: active. |
| search | string | Client name or invoice number. |
| limit | integer | 1 to 100. Default: 25. |
| cursor | string | Next page cursor from the previous call. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "joist_list_invoices",
"arguments": {
"view": "active",
"limit": 100
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"invoices": [
{
"invoice_id": "inv_58213",
"number": "1042",
"client": "Mark Ruiz",
"total": 2400,
"amount_paid": 1200,
"balance_due": 1200,
"due_on": "2026-10-01",
"overdue": true,
"email_opened": true,
"signed": true
}
],
"next_cursor": null
},
"isError": false
} MCP tool joist_get_document
Returns one estimate or invoice with its client, every line item, tax, discount, requested deposit and, for an invoice, the payments recorded on it. Use it before changing or sending a document so your agent sees what the client will see.
Parameters
| Name | Type | Description |
|---|---|---|
| document_id required | string | Estimate or invoice ID from list_estimates or list_invoices. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "joist_get_document",
"arguments": {
"document_id": "document_8c41d2"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"document_id": "inv_58213",
"type": "invoice",
"number": "1042",
"client": {
"client_id": "cl_2210",
"name": "Mark Ruiz"
},
"line_items": [
{
"name": "Kitchen cabinet install",
"quantity": 1,
"rate": 2400
}
],
"tax": 0,
"discount": 0,
"total": 2400,
"payments": [
{
"amount": 1200,
"method": "bank_transfer",
"paid_on": "2026-09-25"
}
]
},
"isError": false
} List clients
readMCP tool joist_list_clients
Lists the clients in your Joist account. Use client_id from an item in create_estimate. Search matches part of a name, email or phone.
Parameters
| Name | Type | Description |
|---|---|---|
| search | string | Part of a name, email or phone. |
| limit | integer | 1 to 200. Default: 50. |
| cursor | string | Next page cursor from the previous call. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "joist_list_clients",
"arguments": {}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"clients": [
{
"client_id": "cl_3307",
"name": "Dana Lee",
"email": "dana@example.com",
"phone": "+1 555 0100",
"address": "14 Maple Street"
}
],
"next_cursor": null
},
"isError": false
} List items
readMCP tool joist_list_items
Lists the items you saved in Joist (Joist does not ship with prices built in). Your agent reuses their names and rates on new estimates instead of guessing prices.
Parameters
| Name | Type | Description |
|---|---|---|
| search | string | Part of the item name. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "joist_list_items",
"arguments": {}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"items": [
{
"item_id": "it_104",
"name": "Interior door, installed",
"description": "Supply and hang a pre-hung interior door",
"rate": 350
}
]
},
"isError": false
} Get report
readMCP tool joist_get_report
Returns one of Joist's Reports for a date range, optionally for one client: revenue received (partial payments included), invoice balances and statuses, estimate volume and statuses, or sales tax collected by jurisdiction. Joist reports only include data entered after 1 September 2022. If your account has no Reports, the call returns the error the app shows.
Parameters
| Name | Type | Description |
|---|---|---|
| report required | enum | revenue, invoices, estimates or sales_tax. |
| from required | date | Start of the range. |
| to required | date | End of the range. |
| client | string | Only this client, by name. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "joist_get_report",
"arguments": {
"report": "revenue",
"from": "2026-10-01",
"to": "2026-10-01"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"report": "revenue",
"from": "2026-09-01",
"to": "2026-09-30",
"total_received": 8450,
"invoices_with_payments": 6
},
"isError": false
} Export documents
readMCP tool joist_export_documents
Runs the same export as Joist's website, for one month: number, client name, subtotal, tax, total, date issued, date created and payment received less refunds. Line items are not in the export; use get_document for those. Returns a download link and the row count.
Parameters
| Name | Type | Description |
|---|---|---|
| type required | enum | estimates or invoices. |
| month required | string | Month as YYYY-MM. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "joist_export_documents",
"arguments": {
"type": "estimates",
"month": "month"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"type": "invoices",
"month": "2026-09",
"rows": 14,
"download_url": "https://files.cotlet.example/joist-invoices-2026-09.csv"
},
"isError": false
} Add client
writeMCP tool joist_add_client
Creates a client in your Joist account. It reaches no one and nothing is sent, so it runs without asking; you can delete the client in Joist. Check list_clients first to avoid a duplicate.
Parameters
| Name | Type | Description |
|---|---|---|
| name required | string | Client or company name. |
| string | Used when you send documents. | |
| phone | string | Phone number. |
| address | string | Job or billing address. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "joist_add_client",
"arguments": {
"name": "Jane Doe"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"client_id": "cl_3312",
"name": "Priya Nair",
"email": "priya@example.com"
},
"isError": false
} Add item
writeMCP tool joist_add_item
Saves an item with a name, rate and optional description to your Items list, so it can be reused on later estimates. It reaches no one, so it runs without asking.
Parameters
| Name | Type | Description |
|---|---|---|
| name required | string | Item name. |
| rate required | string | Price per unit, e.g. "350.00". |
| description | string | Shown on the line item. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "joist_add_item",
"arguments": {
"name": "Jane Doe",
"rate": "350.00"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"item_id": "it_105",
"name": "Baseboard, installed",
"rate": 4.5
},
"isError": false
} Create estimate
writeMCP tool joist_create_estimate
Creates and saves an estimate for a client. Nothing is sent: the client sees it only after send_document. A deposit is a percent or an amount and shows under the total as Deposit Due. The expiry date cannot be in the past. It reaches no one, so it runs without asking.
Parameters
| Name | Type | Description |
|---|---|---|
| client_id required | string | Client ID from list_clients or add_client. |
| line_items required | object[] | List of { name, description, quantity, rate }. |
| tax_rate | string | Tax percent applied to the estimate, e.g. "8.25". |
| discount | object | { type: percent or amount, value }. |
| deposit | object | Requested deposit: { type: percent or amount, value }. |
| expires_on | date | Expiry date. Must not be in the past. |
| notes | string | Note shown on the estimate. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "joist_create_estimate",
"arguments": {
"client_id": "cl_3307",
"line_items": [
{
"name": "Interior door, installed",
"description": "Supply and hang a pre-hung interior door",
"quantity": 2,
"rate": "350.00"
}
],
"tax_rate": "8.25",
"deposit": {
"type": "percent",
"value": 50
},
"expires_on": "2026-10-26"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"estimate_id": "est_20418",
"number": "318",
"client": "Dana Lee",
"line_items": [
{
"name": "Interior door, installed",
"quantity": 2,
"rate": 350,
"amount": 700
}
],
"total": 700,
"deposit_due": 350,
"expires_on": "2026-10-25",
"sent": false
},
"isError": false
} MCP tool joist_convert_estimate_to_invoice
Does what Generate Invoice does in Joist: the new invoice carries all the information from the estimate. The estimate stays in your Estimates list and its status changes from pending to approved. Nothing is sent to the client, so it runs without asking.
Parameters
| Name | Type | Description |
|---|---|---|
| estimate_id required | string | Estimate ID from list_estimates. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "joist_convert_estimate_to_invoice",
"arguments": {
"estimate_id": "est_20418"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"invoice_id": "inv_58300",
"number": "1051",
"from_estimate": "est_20418",
"total": 700,
"deposit_due": 350,
"sent": false,
"estimate_status": "approved"
},
"isError": false
} MCP tool joist_record_payment
Records a payment on an invoice, as Record Payment does in Joist. Partial payments are allowed, and an invoice can hold several. Once the invoice is paid in full it moves from Active to Paid. Payments made through Joist Payments are recorded by Joist itself. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| invoice_id required | string | Invoice ID from list_invoices. |
| amount required | string | Amount received, e.g. "1200.00". |
| method required | enum | cash, check, credit or bank_transfer. |
| paid_on | date | Payment date. Default: today. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "joist_record_payment",
"arguments": {
"invoice_id": "inv_58213",
"amount": "1200.00",
"method": "check",
"paid_on": "2026-10-09"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"invoice_id": "inv_58213",
"number": "1042",
"total": 2400,
"amount_paid": 2400,
"balance_due": 0,
"list": "paid",
"payments": [
{
"amount": 1200,
"method": "bank_transfer",
"paid_on": "2026-09-25"
},
{
"amount": 1200,
"method": "check",
"paid_on": "2026-10-09"
}
]
},
"isError": false
} MCP tool joist_send_document
Emails the document from Joist on your behalf, as the Email button does. The recipient is prefilled from the client on the document, and subject and body can be changed. The client sees it, and Joist marks it when they open the email or sign. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| document_id required | string | Estimate or invoice ID from list_estimates or list_invoices. |
| to | string | Recipient email. Default: the client email on the document. |
| subject | string | Email subject. Default: the Joist subject. |
| message | string | Email body. Default: the Joist message. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "joist_send_document",
"arguments": {
"document_id": "document_8c41d2"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"document_id": "inv_58300",
"to": [
"dana@example.com"
],
"status": "sent",
"sent_at": "2026-10-11T09:20:00+02:00"
},
"isError": false
}