MCP tools reference
Kickserv MCP tools
15 tools for Kickserv on the Cotlet MCP server. Your agent picks them from tools/list.
- MCP server
- https://cotlet.dev/mcp/v1
- Connects with
- Your own Kickserv account (admin role for invoices and payments)
- Integration page
- Kickserv
| Endpoint | Access | Description |
|---|---|---|
| kickserv_list_customers | read | Customers and contacts, searchable by name, email, phone or address. |
| kickserv_get_customer | read | One customer with addresses, contacts, notes and jobs. |
| kickserv_list_jobs | read | Jobs with status, service type, customer, assigned techs and scheduled date. |
| kickserv_get_job | read | Full job: description, scope of work, charges, schedule events, time entries, notes and invoice status. |
| kickserv_list_opportunities | read | Opportunities with customer, service type and whether an estimate was sent. |
| kickserv_list_invoices | read | Invoices with customer, total, balance and whether they were sent and viewed. |
| kickserv_create_customer | write | New person or company contact with service and billing address. |
| kickserv_create_job | write | New job, or a new opportunity to estimate first, for a customer. |
| kickserv_add_charge | write | Add one charge item to the estimate or invoice of a job or opportunity. |
| kickserv_schedule_event | write | Add a work event to a job, optionally assigned to a technician. |
| kickserv_log_time_entry | write | Record hours worked on a job by an employee. |
| kickserv_send_estimate | write | Email the estimate of an opportunity to the customer. |
| kickserv_generate_invoice | write | Create the invoice for a job from its charges. Nothing is sent. |
| kickserv_send_invoice | write | Email the invoice of a job to the customer. |
| kickserv_record_payment | write | Log a manual payment (check, cash, other) on a job and mark the invoice paid. No card is charged. |
List customers
readMCP tool kickserv_list_customers
Returns customers with their number, contact details and service address. Search matches name, email, phone and street address. Pass the customer_number to get_customer, create_job and the other tools.
Parameters
| Name | Type | Description |
|---|---|---|
| query | string | Name, email, phone or street address. |
| page | integer | Page number. Default: 1. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "kickserv_list_customers",
"arguments": {}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"customers": [
{
"customer_number": "2218",
"name": "Lee Residence",
"email": "lee@example.com",
"phone": "555-0142",
"service_address": "41 Maple St, Austin, TX 78701"
}
],
"page": 1
},
"isError": false
} Get customer
readMCP tool kickserv_get_customer
Returns one customer with service and billing addresses, saved contacts, special instructions, notes and the list of their jobs with status. Use it before creating a job so your agent reuses the right contact.
Parameters
| Name | Type | Description |
|---|---|---|
| customer_number required | string | Customer number from list_customers. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "kickserv_get_customer",
"arguments": {
"customer_number": "customer number"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"customer_number": "2218",
"name": "Lee Residence",
"billing_address": "41 Maple St, Austin, TX 78701",
"contacts": [
{
"name": "Mrs. Lee",
"email": "lee@example.com",
"primary": true
}
],
"jobs": [
{
"job_number": "1037",
"service_type": "Water heater replacement",
"status": "complete"
}
]
},
"isError": false
} List jobs
readMCP tool kickserv_list_jobs
Returns jobs 30 per page, filtered by status, scheduled date or technician. Use job_number in get_job and the write tools.
Parameters
| Name | Type | Description |
|---|---|---|
| status | enum | unscheduled, scheduled, in_progress, on_hold, canceled or complete. |
| scheduled | enum | today, tomorrow, yesterday, this_week, next_week, last_week, this_month, next_month, last_month, this_year or last_year. |
| employee | string | Only jobs assigned to this employee. |
| page | integer | Page number. Default: 1. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "kickserv_list_jobs",
"arguments": {
"status": "complete",
"scheduled": "yesterday",
"page": 1
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"jobs": [
{
"job_number": "1037",
"service_type": "Water heater replacement",
"customer": "Lee Residence",
"status": "complete",
"scheduled_on": "2026-10-09",
"employees": [
"Dana Ruiz"
]
}
],
"page": 1
},
"isError": false
} Get job
readMCP tool kickserv_get_job
Returns one job or opportunity with its internal description, the customer-facing scope of work, charges with the running total, schedule events, time entries, notes and whether an invoice exists and is paid.
Parameters
| Name | Type | Description |
|---|---|---|
| job_number required | string | Job number from list_jobs, list_opportunities or get_job. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "kickserv_get_job",
"arguments": {
"job_number": "job number"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"job_number": "1042",
"service_type": "Water heater replacement",
"customer": "Lee Residence",
"status": "new",
"description": "Website lead: 40 gal tank leaking",
"scope_of_work": "Replace the 40 gallon gas water heater.",
"charges": [],
"total": "0.00",
"events": [],
"time_entries": [],
"invoice": null
},
"isError": false
} List opportunities
readMCP tool kickserv_list_opportunities
Returns opportunities from the Opportunities page. A new opportunity appears under the New tab; in the app an opportunity can be marked won or lost.
Parameters
| Name | Type | Description |
|---|---|---|
| stage | enum | new, won or lost. Default: new. |
| page | integer | Page number. Default: 1. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "kickserv_list_opportunities",
"arguments": {}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"opportunities": [
{
"job_number": "1042",
"service_type": "Water heater replacement",
"customer": "Lee Residence",
"stage": "new",
"estimate_sent": false,
"created_on": "2026-10-10"
}
],
"page": 1
},
"isError": false
} List invoices
readMCP tool kickserv_list_invoices
Returns the invoices shown on the Invoices page, from its unpaid or paid tab. Each has a sent flag and a viewed flag, the same as the blue letter and purple eye icons in the app.
Parameters
| Name | Type | Description |
|---|---|---|
| tab | enum | unpaid or paid. Default: unpaid. |
| page | integer | Page number. Default: 1. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "kickserv_list_invoices",
"arguments": {}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"invoices": [
{
"job_number": "1037",
"customer": "Lee Residence",
"total": "480.00",
"balance_remaining": "480.00",
"sent": true,
"viewed": true
}
],
"page": 1
},
"isError": false
} Create customer
writeMCP tool kickserv_create_customer
Creates a customer and returns its customer_number. It sends nothing to the customer and one edit in Kickserv undoes it, so it runs without asking first. Search with list_customers before creating one, to avoid duplicates.
Parameters
| Name | Type | Description |
|---|---|---|
| name required | string | Person or company name. |
| is_company | boolean | Company instead of a person. Default: false. |
| string | Customer email. | |
| phone | string | Phone number. |
| service_address | object | street, city, state, zip_code, country. |
| billing_address | object | Same fields. Default: the service address. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "kickserv_create_customer",
"arguments": {
"name": "Jane Doe"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"customer_number": "2219",
"name": "Rivera Dental",
"status": "created"
},
"isError": false
} Create job
writeMCP tool kickserv_create_job
Creates a job for a customer and returns its job_number. With as_opportunity set to true it creates an opportunity under the New tab instead. The description is internal and the scope of work is shown to the customer. It sends nothing to the customer, so it runs without asking first.
Parameters
| Name | Type | Description |
|---|---|---|
| customer_number required | string | Customer number from list_customers. |
| service_type required | string | Service type as named in your account. |
| description | string | Internal description, not shown to the customer. |
| scope_of_work | string | Customer-facing scope of work. |
| as_opportunity | boolean | Create an opportunity for an estimate instead of a job. Default: false. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "kickserv_create_job",
"arguments": {
"customer_number": "2231",
"service_type": "Water heater replacement",
"description": "Lead from website form, 11:40 p.m.: 40 gal tank leaking in garage",
"scope_of_work": "Inspect and replace the 40 gallon gas water heater.",
"as_opportunity": true
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"job_number": "1051",
"type": "opportunity",
"stage": "new",
"customer_number": "2218",
"service_type": "Water heater replacement"
},
"isError": false
} Add charge
writeMCP tool kickserv_add_charge
Adds one charge line and returns the running total of the job. Call it once per line. Nothing reaches the customer until you send the estimate or invoice, so it runs without asking first.
Parameters
| Name | Type | Description |
|---|---|---|
| job_number required | string | Job number from list_jobs, list_opportunities or get_job. |
| item required | string | Charge item from your account, or a new item name. |
| description | string | Line description. |
| quantity | string | Decimal, e.g. 1 or 2.5. Default: 1. |
| price_per_unit | string | Price as a decimal, e.g. 129.00. |
| taxable | boolean | Apply sales tax. Default: the item setting. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "kickserv_add_charge",
"arguments": {
"job_number": "1042",
"item": "Labor",
"description": "Remove old tank, install and test new heater",
"quantity": "3",
"price_per_unit": "95.00",
"taxable": false
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"job_number": "1042",
"charge": {
"item": "Labor",
"quantity": "2.5",
"price_per_unit": "95.00",
"line_total": "237.50"
},
"total": "886.50"
},
"isError": false
} MCP tool kickserv_schedule_event
Adds an event with a start time, an optional end, a task type and an optional technician. Without a technician the event stays unassigned. Depending on your reminder settings, Kickserv can send reminders for the event. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| job_number required | string | Job number from list_jobs, list_opportunities or get_job. |
| starts_at required | datetime | ISO 8601 with time zone. |
| ends_at | datetime | End of the event. |
| task_type | string | Task type as named in your account, e.g. Work. Default: Work. |
| employee | string | Technician to assign. Default: unassigned. |
| description | string | Notes for the technician. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "kickserv_schedule_event",
"arguments": {
"job_number": "job number",
"starts_at": "2026-10-01T09:00:00Z"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"job_number": "1050",
"event_id": "ev_3381",
"task_type": "Work",
"starts_at": "2026-10-15T09:00:00-05:00",
"employee": "Dana Ruiz",
"job_status": "scheduled"
},
"isError": false
} Log time entry
writeMCP tool kickserv_log_time_entry
Adds a time entry to the job and returns it. Hours are a decimal. It reaches no one and an admin can delete the entry in Kickserv, so it runs without asking first.
Parameters
| Name | Type | Description |
|---|---|---|
| job_number required | string | Job number from list_jobs, list_opportunities or get_job. |
| hours required | string | Number of hours as a decimal, e.g. 2.5. |
| date required | date | Day the work was done. |
| employee required | string | Employee name. |
| billable | boolean | Billable time. Default: true. |
| note | string | What was done. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "kickserv_log_time_entry",
"arguments": {
"job_number": "job number",
"hours": "hours",
"date": "2026-10-01",
"employee": "employee"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"job_number": "1049",
"time_entry_id": "te_7702",
"employee": "Dana Ruiz",
"date": "2026-10-09",
"hours": "2.5",
"billable": true,
"note": "Installed water heater"
},
"isError": false
} MCP tool kickserv_send_estimate
Emails the estimate to the main customer of the job and copies the addresses you add. Subject and message come from your Messaging Templates unless you set them. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| job_number required | string | Job number from list_jobs, list_opportunities or get_job. |
| to | string[] | Recipient emails. Default: the main customer of the job. |
| cc | string[] | Extra emails to copy. |
| subject | string | Email subject. Default: your Messaging Templates subject. |
| message | string | Custom message. Default: your Messaging Templates message. |
| attach_pdf | boolean | Also attach a PDF copy. Default: your Messaging Templates setting. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "kickserv_send_estimate",
"arguments": {
"job_number": "job number"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"job_number": "1042",
"status": "sent",
"sent_to": [
"lee@example.com"
],
"cc": [
"office@example.com"
],
"total": "886.50"
},
"isError": false
} Generate invoice
writeMCP tool kickserv_generate_invoice
Creates the invoice from the charges on the job, the same as Generate Invoice in the job header, and returns its total. It sends nothing to the customer and the invoice can be edited afterwards, so it runs without asking first.
Parameters
| Name | Type | Description |
|---|---|---|
| job_number required | string | Job number from list_jobs, list_opportunities or get_job. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "kickserv_generate_invoice",
"arguments": {
"job_number": "job number"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"job_number": "1037",
"invoice_status": "not_sent",
"total": "480.00",
"balance_remaining": "480.00"
},
"isError": false
} MCP tool kickserv_send_invoice
Emails the invoice to the main customer of the job and copies the addresses you add. The invoice then shows as sent on the Invoices page. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| job_number required | string | Job number from list_jobs, list_opportunities or get_job. |
| to | string[] | Recipient emails. Default: the main customer of the job. |
| cc | string[] | Extra emails to copy. |
| subject | string | Email subject. Default: your Messaging Templates subject. |
| message | string | Custom message. Default: your Messaging Templates message. |
| attach_pdf | boolean | Also attach a PDF copy. Default: your Messaging Templates setting. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "kickserv_send_invoice",
"arguments": {
"job_number": "1037"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"job_number": "1037",
"invoice_status": "sent",
"sent_to": [
"lee@example.com"
],
"total": "480.00",
"balance_remaining": "480.00"
},
"isError": false
} MCP tool kickserv_record_payment
Logs the payment type on the job, then marks the invoice paid when mark_paid is true. Kickserv does not bring the balance to zero for manual payments on its own, so the type is recorded first. No card is charged. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| job_number required | string | Job number from list_jobs, list_opportunities or get_job. |
| amount required | string | Amount as a decimal, e.g. 480.00. |
| method required | string | Payment type as named in your account, e.g. Check. |
| paid_on | date | Default: today. |
| mark_paid | boolean | Mark the invoice paid afterwards. Default: true. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "kickserv_record_payment",
"arguments": {
"job_number": "1051",
"amount": "150.00",
"method": "Cash",
"paid_on": "2026-10-12",
"mark_paid": false
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"job_number": "1037",
"amount": "480.00",
"method": "Check",
"paid_on": "2026-10-10",
"invoice_status": "paid",
"balance_remaining": "0.00"
},
"isError": false
}