mcp-zenskar 1.1.10 → 1.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,18 +1,17 @@
1
1
  # Zenskar MCP Server
2
2
 
3
- MCP server for the Zenskar API. 103 tools covering customers, contracts, invoices, payments, credit notes, accounting, products, plans, quotes, and more.
3
+ MCP server for the Zenskar API. 103 tools covering customers, contracts, invoices, payments, credit notes, accounting, products, plans, and more.
4
4
 
5
5
  ## What it does
6
6
 
7
- - Customers: list, search, create, update, addresses, contacts, payment methods
8
- - Contracts: create, read, update, delete, amend, add phases and pricing, expire
7
+ - Customers: list, search, create, update, delete, addresses, contacts, payment methods
8
+ - Contracts: create, read, update, delete, amend, add phases and pricing, pause/resume, expire
9
9
  - Invoices: list, get, approve, void, generate, credit notes, download
10
10
  - Payments: create, edit, refund, delete, auto-charge
11
11
  - Credit notes: list, create against invoice, get by ID
12
12
  - Accounting: chart of accounts, journal entries and lines, balance sheet, income statement, account balances
13
13
  - Products: CRUD, pricing configurations
14
14
  - Plans: list, create, add products, preview estimates
15
- - Quotes: create, preview, accept (converts to contract)
16
15
  - Business entities: list, get, create, update
17
16
  - Jobs: monitor async operations
18
17
  - Custom attributes and tax categories
@@ -91,6 +90,7 @@ Once configured, you can ask Claude to interact with your Zenskar data:
91
90
  | `getCustomerById` | Get a customer by ID |
92
91
  | `createCustomer` | Create a customer with address and tax info |
93
92
  | `updateCustomer` | Update customer details (partial update) |
93
+ | `deleteCustomer` | Permanently delete a customer by ID (only allowed when they have no active contracts or unpaid invoices) |
94
94
 
95
95
  ### Contacts
96
96
  | Tool | Description |
@@ -99,6 +99,7 @@ Once configured, you can ask Claude to interact with your Zenskar data:
99
99
  | `getContactById` | Get a contact by ID |
100
100
  | `createContact` | Create a contact for a customer |
101
101
  | `updateContact` | Update a contact's details |
102
+ | `deleteContact` | Delete a contact by ID |
102
103
 
103
104
  ### Contracts
104
105
  | Tool | Description |
@@ -112,6 +113,9 @@ Once configured, you can ask Claude to interact with your Zenskar data:
112
113
  | `createContractPhase` | Add a phase to a contract (add-ons, expansions) |
113
114
  | `createContractPhasePricing` | Add pricing to a contract phase |
114
115
  | `expireContract` | Expire an active contract |
116
+ | `pauseContract` | Pause an active contract from a given start date, with an unpause-extension policy (`extend` or `overlap`) and optional end date for auto-resume |
117
+ | `editPauseContract` | Edit an existing pause phase — set or change the resume date, shift the start, or change the unpause policy |
118
+ | `resumeContract` | Resume a paused contract |
115
119
  | `createContractPrompt` | Create a contract prompt |
116
120
  | `extractContractFromRaw` | Extract contract data from raw text using AI |
117
121
 
@@ -133,7 +137,8 @@ Once configured, you can ask Claude to interact with your Zenskar data:
133
137
  | `generateInvoicePaymentLink` | Generate a payment link for an invoice |
134
138
  | `payInvoice` | Initiate payment for an invoice |
135
139
  | `approveInvoice` | Approve an invoice for billing |
136
- | `voidInvoice` | Void an approved unpaid invoice |
140
+ | `voidInvoice` | Void an invoice |
141
+ | `deleteInvoice` | Delete a draft invoice |
137
142
  | `generateInvoice` | Generate an invoice for a contract and date range |
138
143
  | `createInvoiceCreditNote` | Create a credit note against an invoice |
139
144
  | `createInvoiceCharge` | Auto-charge an invoice via payment gateway |
@@ -171,8 +176,6 @@ Once configured, you can ask Claude to interact with your Zenskar data:
171
176
  | `listPlans` | List plan templates |
172
177
  | `getPlanById` | Get a plan by ID with phases and pricing |
173
178
  | `createPlan` | Create a plan template |
174
- | `addProductsToPlan` | Add products to an existing plan |
175
- | `previewPlanEstimate` | Preview estimated billing for a plan |
176
179
 
177
180
  ### Accounting
178
181
  | Tool | Description |
@@ -189,14 +192,6 @@ Once configured, you can ask Claude to interact with your Zenskar data:
189
192
  | `getAccountBalance` | Get balance for a specific GL account |
190
193
  | `recogniseRevenue` | Trigger revenue recognition up to a date |
191
194
 
192
- ### Quotes
193
- | Tool | Description |
194
- |---|---|
195
- | `createQuote` | Create a quote/proposal |
196
- | `previewQuoteEstimate` | Preview estimated billing for a quote |
197
- | `getQuoteById` | Get a quote by ID |
198
- | `acceptQuote` | Accept a quote, converting to a contract |
199
-
200
195
  ### Custom Attributes and Tax
201
196
  | Tool | Description |
202
197
  |---|---|
@@ -227,6 +222,7 @@ Once configured, you can ask Claude to interact with your Zenskar data:
227
222
  | `updateCustomerAddress` | Update a customer address |
228
223
  | `listPaymentMethods` | List payment methods for a customer |
229
224
  | `attachPaymentMethod` | Attach a payment method to a customer |
225
+ | `deletePaymentMethod` | Delete a payment method from a customer |
230
226
 
231
227
  ### Metrics and Usage Events
232
228
  | Tool | Description |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-zenskar",
3
- "version": "1.1.10",
3
+ "version": "1.1.11",
4
4
  "description": "Model Context Protocol (MCP) server for Zenskar API - customer management, invoicing, and billing operations",
5
5
  "main": "src/server.js",
6
6
  "bin": {
@@ -586,7 +586,18 @@
586
586
  },
587
587
  {
588
588
  "name": "payInvoice",
589
- "description": "Initiate payment for an invoice using a payload.",
589
+ "description": "Initiate payment for an invoice using a payload. MONEY-MOVING ACTION — only call when the user explicitly authorizes payment for this specific invoice.",
590
+ "needsApproval": true,
591
+ "approvalConfig": {
592
+ "title": "Pay Invoice",
593
+ "description": "This will initiate a payment against the invoice using the provided payload.",
594
+ "warningText": "Money-moving action — funds will be charged. Verify the invoice and amount before confirming.",
595
+ "confirmText": "Pay Invoice",
596
+ "cancelText": "Cancel",
597
+ "sensitiveFields": [
598
+ "payload"
599
+ ]
600
+ },
590
601
  "args": [
591
602
  {
592
603
  "name": "payload",
@@ -2719,7 +2730,18 @@
2719
2730
  },
2720
2731
  {
2721
2732
  "name": "deleteContract",
2722
- "description": "Delete a contract by its ID. Only works on draft contracts. Returns the deleted contract object with a deleted_at timestamp.",
2733
+ "description": "Permanently delete a DRAFT contract. ONLY works on contracts with status='draft'. Do NOT call on ACTIVE, EXPIRED, or PAUSED contracts. DESTRUCTIVE: removes all phases, products, and pricing associations. NEVER call as automatic recovery from another failed operation (e.g., do not retry as a fallback after expireContract or voidInvoice fails). ONLY call when the user explicitly says 'delete' or 'remove' for THIS draft contract. If a non-destructive action fails, surface the error verbatim and stop.",
2734
+ "needsApproval": true,
2735
+ "approvalConfig": {
2736
+ "title": "Delete Draft Contract",
2737
+ "description": "This will permanently delete the draft contract along with all its phases, products, and pricing associations.",
2738
+ "warningText": "DESTRUCTIVE — this cannot be undone. Only draft contracts may be deleted; verify status before confirming.",
2739
+ "confirmText": "Delete Contract",
2740
+ "cancelText": "Cancel",
2741
+ "sensitiveFields": [
2742
+ "contractId"
2743
+ ]
2744
+ },
2723
2745
  "args": [
2724
2746
  {
2725
2747
  "name": "contractId",
@@ -2956,7 +2978,19 @@
2956
2978
  },
2957
2979
  {
2958
2980
  "name": "expireContract",
2959
- "description": "Expire an active contract. Only works on contracts with status 'active'. Optionally specify an expiry_date (defaults to today). The contract expires at end of day 23:59:59.999999.",
2981
+ "description": "Expire an ACTIVE or PAUSED contract by adjusting its end_date. Allowed status transitions: ACTIVE→EXPIRED, PAUSED→EXPIRED. EXPIRED is terminal — calling on an already-expired contract returns 400; do NOT retry, do NOT escalate to deleteContract or any other destructive tool as a fallback. Verify contract.status via getContractById before calling. Idempotency: NO. The contract expires at end of day 23:59:59.999999.",
2982
+ "needsApproval": true,
2983
+ "approvalConfig": {
2984
+ "title": "Expire Contract",
2985
+ "description": "This will set the contract's end_date and transition status to EXPIRED. EXPIRED is terminal.",
2986
+ "warningText": "Once expired, the contract cannot be re-activated through this endpoint. Future-dated phases beyond the expiry will be removed.",
2987
+ "confirmText": "Expire Contract",
2988
+ "cancelText": "Cancel",
2989
+ "sensitiveFields": [
2990
+ "contractId",
2991
+ "expiry_date"
2992
+ ]
2993
+ },
2960
2994
  "args": [
2961
2995
  {
2962
2996
  "name": "contractId",
@@ -2967,7 +3001,7 @@
2967
3001
  },
2968
3002
  {
2969
3003
  "name": "expiry_date",
2970
- "description": "Date to expire the contract (e.g. 2026-12-31). Defaults to today if not provided.",
3004
+ "description": "Date to expire the contract (e.g. 2026-12-31). Defaults to today if not provided. Must not be earlier than contract.start_date.",
2971
3005
  "type": "string",
2972
3006
  "required": false,
2973
3007
  "position": "body"
@@ -2986,7 +3020,18 @@
2986
3020
  },
2987
3021
  {
2988
3022
  "name": "voidInvoice",
2989
- "description": "Void an invoice by its ID. Only works on approved invoices that have not been fully paid. Voiding reverses the invoice and creates appropriate accounting entries.",
3023
+ "description": "Void an invoice. ONLY works on approved or paid invoices with invoice_total == 0 (zero-balance, typically after a full credit-note offset). For non-zero approved invoices, issue a credit note via createInvoiceCreditNote first to bring the balance to zero, then void. If the call returns INVOICE_CANNOT_BE_VOIDED, surface that error verbatim — do NOT retry, do NOT escalate to deleteInvoice.",
3024
+ "needsApproval": true,
3025
+ "approvalConfig": {
3026
+ "title": "Void Invoice",
3027
+ "description": "This will set the invoice status to 'void' and post the corresponding accounting entries. Only zero-balance approved/paid invoices are eligible.",
3028
+ "warningText": "Voiding affects accounting records and cannot be easily undone.",
3029
+ "confirmText": "Void Invoice",
3030
+ "cancelText": "Cancel",
3031
+ "sensitiveFields": [
3032
+ "invoiceId"
3033
+ ]
3034
+ },
2990
3035
  "args": [
2991
3036
  {
2992
3037
  "name": "invoiceId",
@@ -3007,6 +3052,40 @@
3007
3052
  "prependBody": "## Invoice Voided\n\n"
3008
3053
  }
3009
3054
  },
3055
+ {
3056
+ "name": "deleteInvoice",
3057
+ "description": "Permanently delete a draft invoice. ONLY works on status='draft'. For approved invoices, use voidInvoice (with caveats) or createInvoiceCreditNote — do NOT call deleteInvoice on approved invoices. DESTRUCTIVE: record removed permanently. ONLY call when the user explicitly says 'delete' for THIS invoice; never call as automatic recovery from another failed operation.",
3058
+ "needsApproval": true,
3059
+ "approvalConfig": {
3060
+ "title": "Delete Invoice",
3061
+ "description": "This will permanently delete the draft invoice.",
3062
+ "warningText": "DESTRUCTIVE — invoice record will be removed and cannot be recovered.",
3063
+ "confirmText": "Delete Invoice",
3064
+ "cancelText": "Cancel",
3065
+ "sensitiveFields": [
3066
+ "invoiceId"
3067
+ ]
3068
+ },
3069
+ "args": [
3070
+ {
3071
+ "name": "invoiceId",
3072
+ "description": "The unique identifier (UUID) of the draft or upcoming invoice to delete.",
3073
+ "type": "string",
3074
+ "required": true,
3075
+ "position": "path"
3076
+ }
3077
+ ],
3078
+ "requestTemplate": {
3079
+ "url": "/invoices/{invoiceId}",
3080
+ "method": "DELETE",
3081
+ "headers": {
3082
+ "Content-Type": "application/json"
3083
+ }
3084
+ },
3085
+ "responseTemplate": {
3086
+ "prependBody": "## Invoice Deleted\n\n"
3087
+ }
3088
+ },
3010
3089
  {
3011
3090
  "name": "createInvoiceCreditNote",
3012
3091
  "description": "Create a credit note against a specific invoice. The credit_note_amount is in the invoice's currency (e.g. 25 for $25). The API stores amounts in cents internally. Returns the created credit note.",
@@ -3046,7 +3125,7 @@
3046
3125
  },
3047
3126
  {
3048
3127
  "name": "generateInvoice",
3049
- "description": "Generate an invoice for a customer given a contract and date range. Use this for billing replay or on-demand invoice generation.",
3128
+ "description": "Generate ONE invoice covering ALL products active in the (contract, customer, from_date, to_date) tuple. The invoice contains every applicable product as separate line items — do NOT call once per product. Granularity is per-phase, NOT per-product. To bill a multi-phase contract, call ONCE per phase using that phase's start/end as from_date/to_date — e.g., a 2-phase contract with 2 products = 2 calls (yielding 2 invoices, each with 2 line items), NOT 4 calls. Iterating per product produces fragmented duplicate invoices and is incorrect. Use for billing replay or on-demand invoice generation.",
3050
3129
  "args": [
3051
3130
  {
3052
3131
  "name": "contract_id",
@@ -3302,7 +3381,18 @@
3302
3381
  },
3303
3382
  {
3304
3383
  "name": "deleteManualPayment",
3305
- "description": "Delete a manual payment. Only works on payments that are in an eligible status for deletion.",
3384
+ "description": "Permanently delete a manual payment record. Only works on payments in an eligible status for deletion. DESTRUCTIVE — only call when the user explicitly says 'delete' for THIS payment; never as automatic recovery from another failed operation.",
3385
+ "needsApproval": true,
3386
+ "approvalConfig": {
3387
+ "title": "Delete Manual Payment",
3388
+ "description": "This will permanently remove the manual payment record.",
3389
+ "warningText": "DESTRUCTIVE — payment record will be removed and cannot be recovered. Linked invoice balance may shift as a result.",
3390
+ "confirmText": "Delete Payment",
3391
+ "cancelText": "Cancel",
3392
+ "sensitiveFields": [
3393
+ "paymentId"
3394
+ ]
3395
+ },
3306
3396
  "args": [
3307
3397
  {
3308
3398
  "name": "paymentId",
@@ -4126,7 +4216,7 @@
4126
4216
  },
4127
4217
  {
4128
4218
  "name": "createProductPricing",
4129
- "description": "Create a new pricing configuration for a product. The pricing_data object is a discriminated union — the 'pricing_type' field determines which pricing model schema to use.",
4219
+ "description": "Create a new pricing configuration for a product. The pricing_data object is a discriminated union — the 'pricing_type' field determines which pricing model schema. IMPORTANT: ask the user explicitly for currency, quantity_type (fixed|metered), and unit amount BEFORE calling. Do not silently default any of these. unit_amount is in MAJOR currency units (float), e.g. 3 means $3, not 300 cents.",
4130
4220
  "args": [
4131
4221
  {
4132
4222
  "name": "productId",
@@ -4151,11 +4241,18 @@
4151
4241
  },
4152
4242
  {
4153
4243
  "name": "pricing_data",
4154
- "description": "Pricing data object (required). Must include 'pricing_type' discriminator. Supported types: flat_fee: {pricing_type:'flat_fee', unit_amount:10000}. per_unit: {pricing_type:'per_unit', unit_amount:500}. tiered: {pricing_type:'tiered', unit_amount:[1000,500], up_to:[100,null]}. volume: {pricing_type:'volume', unit_amount:[1000,500], up_to:[100,null]}. percent: {pricing_type:'percent', percentage:5.0}. package: {pricing_type:'package', package_size:10, unit_amount:5000}. step: {pricing_type:'step', unit_amount:[...], up_to:[...]}. matrix: {pricing_type:'matrix', dimensions:[...], values:[...]}.",
4244
+ "description": "Pricing data object (required). MUST include 'pricing_type' discriminator AND 'currency' (ISO 4217, e.g. 'USD'). 'unit_amount' is in MAJOR currency units (float) — 3 means $3, NOT 300 cents. Do NOT convert to cents. Supported pricing_type values with examples: flat_fee: {pricing_type:'flat_fee', unit_amount:100, currency:'USD'}. per_unit: {pricing_type:'per_unit', unit_amount:3, currency:'USD'}. tiered: {pricing_type:'tiered', unit_amount:[10,5], up_to:[100,null], currency:'USD'}. volume: {pricing_type:'volume', unit_amount:[10,5], up_to:[100,null], currency:'USD'}. percent: {pricing_type:'percent', percentage:5.0, currency:'USD'}. package: {pricing_type:'package', package_size:10, unit_amount:50, currency:'USD'}. step: {pricing_type:'step', unit_amount:[...], up_to:[...], currency:'USD'}. matrix: {pricing_type:'matrix', dimensions:[...], values:[...], currency:'USD'}. Optional inside pricing_data for per_unit: 'proration_type' ('day_based'|'cadence_based'), 'charge_full_amount' (bool).",
4155
4245
  "type": "object",
4156
4246
  "required": true,
4157
4247
  "position": "body"
4158
4248
  },
4249
+ {
4250
+ "name": "quantity",
4251
+ "description": "Quantity configuration (REQUIRED for usage-based pricing — ask the user). Top-level object, NOT inside pricing_data. Shape: {type: 'fixed'|'metered', quantity?: number, unit?: string, aggregate_id?: UUID}. 'fixed' means a static quantity (e.g. seats). 'metered' means consumption tracked via a billable metric — set aggregate_id to the billable-metric UUID. Without a quantity object the resulting pricing has no billing_metric and renders as 0 in the UI.",
4252
+ "type": "object",
4253
+ "required": false,
4254
+ "position": "body"
4255
+ },
4159
4256
  {
4160
4257
  "name": "billing_period",
4161
4258
  "description": "Billing cadence for this pricing. Object with 'cadence' (ISO 8601 duration, e.g. 'P1M' for monthly, 'P3M' for quarterly, 'P1Y' for annually) and optional 'offset'. Example: {cadence: 'P1M'}.",
@@ -4191,7 +4288,7 @@
4191
4288
  },
4192
4289
  {
4193
4290
  "name": "listPlans",
4194
- "description": "Retrieve a paginated list of plans (templates v3) that define reusable contract structures.",
4291
+ "description": "Retrieve a paginated list of plans that define reusable contract structures. Hits /plans — the same data the Zenskar app's Plans page reads.",
4195
4292
  "args": [
4196
4293
  {
4197
4294
  "name": "cursor",
@@ -4223,7 +4320,7 @@
4223
4320
  }
4224
4321
  ],
4225
4322
  "requestTemplate": {
4226
- "url": "/templates/plan",
4323
+ "url": "/plans",
4227
4324
  "method": "GET",
4228
4325
  "headers": {
4229
4326
  "Content-Type": "application/json"
@@ -4246,7 +4343,7 @@
4246
4343
  }
4247
4344
  ],
4248
4345
  "requestTemplate": {
4249
- "url": "/templates/plan/{planId}",
4346
+ "url": "/plans/{planId}",
4250
4347
  "method": "GET",
4251
4348
  "headers": {
4252
4349
  "Content-Type": "application/json"
@@ -4258,7 +4355,7 @@
4258
4355
  },
4259
4356
  {
4260
4357
  "name": "createPlan",
4261
- "description": "Create a new plan (template) that defines a reusable contract structure with products and pricing.",
4358
+ "description": "Create a new plan — a reusable contract template with products and pricing. Hits POST /plans (same store the Zenskar app's Plans page reads).",
4262
4359
  "args": [
4263
4360
  {
4264
4361
  "name": "name",
@@ -4318,7 +4415,7 @@
4318
4415
  }
4319
4416
  ],
4320
4417
  "requestTemplate": {
4321
- "url": "/templates/plan",
4418
+ "url": "/plans",
4322
4419
  "method": "POST",
4323
4420
  "headers": {
4324
4421
  "Content-Type": "application/json"
@@ -4328,73 +4425,6 @@
4328
4425
  "prependBody": "## Created Plan\n\n"
4329
4426
  }
4330
4427
  },
4331
- {
4332
- "name": "addProductsToPlan",
4333
- "description": "Add products with pricing to an existing plan.",
4334
- "args": [
4335
- {
4336
- "name": "planId",
4337
- "description": "The unique identifier of the plan.",
4338
- "type": "string",
4339
- "required": true,
4340
- "position": "path"
4341
- },
4342
- {
4343
- "name": "products",
4344
- "description": "Array of product objects to add, each with product_id and pricing configuration.",
4345
- "type": "array",
4346
- "required": true,
4347
- "position": "body"
4348
- }
4349
- ],
4350
- "requestTemplate": {
4351
- "url": "/templates/plan/{planId}/products",
4352
- "method": "POST",
4353
- "headers": {
4354
- "Content-Type": "application/json"
4355
- }
4356
- },
4357
- "responseTemplate": {
4358
- "prependBody": "## Updated Plan Products\n\n"
4359
- }
4360
- },
4361
- {
4362
- "name": "previewPlanEstimate",
4363
- "description": "Preview the estimated billing for a plan, showing projected charges per phase.",
4364
- "args": [
4365
- {
4366
- "name": "planId",
4367
- "description": "The unique identifier of the plan.",
4368
- "type": "string",
4369
- "required": true,
4370
- "position": "path"
4371
- },
4372
- {
4373
- "name": "start_date",
4374
- "description": "Start date for the estimate (YYYY-MM-DD).",
4375
- "type": "string",
4376
- "required": true,
4377
- "position": "body"
4378
- },
4379
- {
4380
- "name": "end_date",
4381
- "description": "End date for the estimate (YYYY-MM-DD). Optional — calculated from plan duration if omitted.",
4382
- "type": "string",
4383
- "required": false,
4384
- "position": "body"
4385
- }
4386
- ],
4387
- "requestTemplate": {
4388
- "url": "/templates/plan/{planId}/preview",
4389
- "method": "POST",
4390
- "headers": {
4391
- "Content-Type": "application/json"
4392
- }
4393
- },
4394
- "responseTemplate": {
4395
- "prependBody": "## Plan Estimate Preview\n\n"
4396
- }
4397
- },
4398
4428
  {
4399
4429
  "name": "listCustomAttributes",
4400
4430
  "description": "Retrieve a list of custom attribute definitions configured for the organization.",
@@ -5107,7 +5137,18 @@
5107
5137
  },
5108
5138
  {
5109
5139
  "name": "deleteCustomer",
5110
- "description": "Delete a customer by ID. This is permanent and cannot be undone. The customer must not have active contracts or unpaid invoices.",
5140
+ "description": "Permanently delete a customer by ID. DESTRUCTIVE and cannot be undone. The customer must not have active contracts or unpaid invoices. ONLY call when the user explicitly says 'delete' for THIS customer; never as automatic recovery from another failed operation.",
5141
+ "needsApproval": true,
5142
+ "approvalConfig": {
5143
+ "title": "Delete Customer",
5144
+ "description": "This will permanently delete the customer and all associated records.",
5145
+ "warningText": "DESTRUCTIVE — customer record cannot be recovered. Verify there are no active contracts or unpaid invoices first.",
5146
+ "confirmText": "Delete Customer",
5147
+ "cancelText": "Cancel",
5148
+ "sensitiveFields": [
5149
+ "customerId"
5150
+ ]
5151
+ },
5111
5152
  "args": [
5112
5153
  {
5113
5154
  "name": "customerId",
@@ -5130,7 +5171,18 @@
5130
5171
  },
5131
5172
  {
5132
5173
  "name": "deleteContact",
5133
- "description": "Delete a contact by ID.",
5174
+ "description": "Permanently delete a contact by ID. DESTRUCTIVE — only call when the user explicitly says 'delete' for THIS contact; never as automatic recovery from another failed operation.",
5175
+ "needsApproval": true,
5176
+ "approvalConfig": {
5177
+ "title": "Delete Contact",
5178
+ "description": "This will permanently delete the contact record.",
5179
+ "warningText": "DESTRUCTIVE — contact record will be removed and cannot be recovered.",
5180
+ "confirmText": "Delete Contact",
5181
+ "cancelText": "Cancel",
5182
+ "sensitiveFields": [
5183
+ "contactId"
5184
+ ]
5185
+ },
5134
5186
  "args": [
5135
5187
  {
5136
5188
  "name": "contactId",
@@ -5153,7 +5205,19 @@
5153
5205
  },
5154
5206
  {
5155
5207
  "name": "deletePaymentMethod",
5156
- "description": "Delete a payment method from a customer.",
5208
+ "description": "Permanently delete a payment method from a customer. DESTRUCTIVE — saved card/bank details will be removed; recurring auto-charges using this method will fail. Only call when the user explicitly says 'delete' for THIS payment method.",
5209
+ "needsApproval": true,
5210
+ "approvalConfig": {
5211
+ "title": "Delete Payment Method",
5212
+ "description": "This will permanently delete the payment method from the customer's profile.",
5213
+ "warningText": "DESTRUCTIVE — saved payment details will be removed. Any auto-charge or scheduled charge using this method will fail.",
5214
+ "confirmText": "Delete Payment Method",
5215
+ "cancelText": "Cancel",
5216
+ "sensitiveFields": [
5217
+ "customerId",
5218
+ "paymentMethodId"
5219
+ ]
5220
+ },
5157
5221
  "args": [
5158
5222
  {
5159
5223
  "name": "customerId",
@@ -5183,7 +5247,7 @@
5183
5247
  },
5184
5248
  {
5185
5249
  "name": "pauseContract",
5186
- "description": "Pause an active contract. Requires a start_date for the pause and an unpause_extension_policy.",
5250
+ "description": "Pause an active contract. ALWAYS ask the user explicitly for both 'start_date' and 'unpause_extension_policy' before calling — do NOT silently default. A future-dated start_date will create a scheduled pause that has not yet begun; the contract's top-level status stays 'active' until start_date passes. Use 'editPauseContract' to adjust the pause window or set a resume date afterward.",
5187
5251
  "args": [
5188
5252
  {
5189
5253
  "name": "contractId",
@@ -5194,14 +5258,14 @@
5194
5258
  },
5195
5259
  {
5196
5260
  "name": "start_date",
5197
- "description": "Date when the pause begins (ISO 8601 format, e.g. 2026-04-01T00:00:00).",
5261
+ "description": "Date when the pause begins (ISO 8601 format, e.g. 2026-04-01T00:00:00). REQUIRED — ask the user; never default to today or a future date silently.",
5198
5262
  "type": "string",
5199
5263
  "required": true,
5200
5264
  "position": "body"
5201
5265
  },
5202
5266
  {
5203
5267
  "name": "unpause_extension_policy",
5204
- "description": "How to handle the contract end date when unpaused.",
5268
+ "description": "How to handle the contract end date when unpaused. 'extend' pushes the end_date out by the pause duration; 'overlap' keeps end_date fixed. ASK the user.",
5205
5269
  "type": "string",
5206
5270
  "required": true,
5207
5271
  "position": "body",
@@ -5229,9 +5293,57 @@
5229
5293
  "prependBody": "## Contract Paused\n\n"
5230
5294
  }
5231
5295
  },
5296
+ {
5297
+ "name": "editPauseContract",
5298
+ "description": "Edit an existing pause phase on a contract. Use this when 'resumeContract' returns 'pause phase not found' for a future-dated pause, or when the user wants to set a resume date (pause end_date), shift the pause start, or change the unpause_extension_policy. Hits PATCH /contract_v2/{contractId}/pause.",
5299
+ "args": [
5300
+ {
5301
+ "name": "contractId",
5302
+ "description": "The unique identifier (UUID) of the contract whose pause phase to edit.",
5303
+ "type": "string",
5304
+ "required": true,
5305
+ "position": "path"
5306
+ },
5307
+ {
5308
+ "name": "start_date",
5309
+ "description": "New pause start date (ISO 8601). Optional.",
5310
+ "type": "string",
5311
+ "required": false,
5312
+ "position": "body"
5313
+ },
5314
+ {
5315
+ "name": "end_date",
5316
+ "description": "Resume date — when the pause ends (ISO 8601). Set this to schedule a future resume.",
5317
+ "type": "string",
5318
+ "required": false,
5319
+ "position": "body"
5320
+ },
5321
+ {
5322
+ "name": "unpause_extension_policy",
5323
+ "description": "How to handle the contract end date when unpaused. 'extend' or 'overlap'.",
5324
+ "type": "string",
5325
+ "required": false,
5326
+ "position": "body",
5327
+ "enum": [
5328
+ "extend",
5329
+ "overlap"
5330
+ ]
5331
+ }
5332
+ ],
5333
+ "requestTemplate": {
5334
+ "url": "/contract_v2/{contractId}/pause",
5335
+ "method": "PATCH",
5336
+ "headers": {
5337
+ "Content-Type": "application/json"
5338
+ }
5339
+ },
5340
+ "responseTemplate": {
5341
+ "prependBody": "## Pause Phase Updated\n\n"
5342
+ }
5343
+ },
5232
5344
  {
5233
5345
  "name": "resumeContract",
5234
- "description": "Resume a paused contract. No request body needed.",
5346
+ "description": "Resume an actively-running pause on a contract. PRECONDITIONS: the pause's start_date must be strictly in the past (not today, not future). For pauses scheduled for a future start, or to set a future resume date, use 'editPauseContract' instead (sets the pause's end_date). The error 'pause phase not found' means no pause phase has yet started — NOT that no pause exists. If this call fails, surface the error verbatim and consider 'editPauseContract'; do NOT escalate to deleteContract or any destructive fallback.",
5235
5347
  "args": [
5236
5348
  {
5237
5349
  "name": "contractId",