@desktopaccountingapi/quickbooks-desktop-mcp 0.2.0 → 0.3.0

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/CHANGELOG.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## 0.1.0
4
4
 
5
- First release of `@desktopaccountingapi/quickbooks-desktop-mcp`, generated from API contract sha256 `6f5ac28d7c33` (API version 1.0.0, 275 operations).
5
+ First release of `@desktopaccountingapi/quickbooks-desktop-mcp`, generated from API contract sha256 `79b06eb20083` (API version 1.0.0, 275 operations).
6
6
 
7
7
  - Local MCP server over stdio: `npx -y @desktopaccountingapi/quickbooks-desktop-mcp`. Node.js 20 or later on Windows, macOS and Linux; no other runtime and no runtime dependencies.
8
8
  - Tools: `list_end_users`, `list_api_endpoints`, `get_api_endpoint_schema`, `invoke_api_endpoint`, `search_docs`; optional one tool per operation with `--resources`.
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  - Writes carry an idempotency key and are never retried blindly. Read-only keys are enforced by the API itself.
7
7
  - Runs over stdio with Node.js 20 or later on Windows, macOS and Linux, with no runtime dependencies.
8
8
 
9
- The current version is **0.2.0**. [MCP guide](https://www.desktopaccountingapi.com/docs/guides/mcp/) · [Documentation](https://www.desktopaccountingapi.com/docs/) · [Changelog](CHANGELOG.md) · [Status](https://status.desktopaccountingapi.com)
9
+ The current version is **0.3.0**. [MCP guide](https://www.desktopaccountingapi.com/docs/guides/mcp/) · [Documentation](https://www.desktopaccountingapi.com/docs/) · [Changelog](CHANGELOG.md) · [Status](https://status.desktopaccountingapi.com)
10
10
 
11
11
  ## Hosted server or local package
12
12
 
@@ -37,14 +37,14 @@ Open **Settings > Developer > Edit Config** (`claude_desktop_config.json`) and a
37
37
  "mcpServers": {
38
38
  "quickbooks-desktop": {
39
39
  "command": "npx",
40
- "args": ["-y", "@desktopaccountingapi/quickbooks-desktop-mcp@0.2.0"],
40
+ "args": ["-y", "@desktopaccountingapi/quickbooks-desktop-mcp@0.3.0"],
41
41
  "env": { "DAAPI_SECRET_KEY": "sk_live_..." }
42
42
  }
43
43
  }
44
44
  }
45
45
  ```
46
46
 
47
- If the file already has an `mcpServers` section, add the `quickbooks-desktop` entry inside it, then restart Claude Desktop. Drop `@0.2.0` from the package name to always run the latest version.
47
+ If the file already has an `mcpServers` section, add the `quickbooks-desktop` entry inside it, then restart Claude Desktop. Drop `@0.3.0` from the package name to always run the latest version.
48
48
 
49
49
  ### Claude Code
50
50
 
@@ -173,7 +173,7 @@ Clients send their own secret key as `Authorization: Bearer sk_...`; the server
173
173
  ## Versioning and changelog
174
174
 
175
175
  - The package follows [semantic versioning](https://semver.org/) and is released together with the [Node.js](https://github.com/DesktopAccountingAPI/quickbooks-desktop-node), [Python](https://github.com/DesktopAccountingAPI/quickbooks-desktop-python), [.NET](https://github.com/DesktopAccountingAPI/quickbooks-desktop-dotnet) and [Java](https://github.com/DesktopAccountingAPI/quickbooks-desktop-java) SDKs, with the same version number.
176
- - It is generated from the Desktop Accounting API contract (sha256 `6f5ac28d7c33...` for this release) by the same pipeline as the SDKs.
176
+ - It is generated from the Desktop Accounting API contract (sha256 `79b06eb20083...` for this release) by the same pipeline as the SDKs.
177
177
  - Every release is listed in [CHANGELOG.md](CHANGELOG.md) and tagged `v<version>` on GitHub.
178
178
 
179
179
  ## Support
package/dist/catalog.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // Code generated by packages/sdk-generator from packages/mcp/src. DO NOT EDIT.
2
- // Contract: packages/api-contract/generated/openapi.json (OpenAPI 3.1.0) sha256:6f5ac28d7c33ac90aa7e2c15d88efd50e8e41c808bcc5489f0c8b1cb7833326a
2
+ // Contract: packages/api-contract/generated/openapi.json (OpenAPI 3.1.0) sha256:79b06eb2008381661d24d3bd5e23643483ec1bf9b70d5f4cdff2a2a71e22fe94
3
3
  // MCP endpoint catalog: a compact, input-only view of the public OpenAPI contract that the MCP
4
4
  // tools search, describe and invoke. Built from packages/api-contract/generated/openapi.json by
5
5
  // scripts/api-contract.mjs (committed as packages/mcp/generated/catalog.json, drift-checked) and
package/dist/catalog.json CHANGED
@@ -11490,13 +11490,10 @@
11490
11490
  },
11491
11491
  {
11492
11492
  "name": "fiscalYear",
11493
- "required": false,
11493
+ "required": true,
11494
11494
  "description": "Filter by fiscal year.",
11495
11495
  "schema": {
11496
- "type": [
11497
- "integer",
11498
- "null"
11499
- ]
11496
+ "type": "integer"
11500
11497
  }
11501
11498
  },
11502
11499
  {
@@ -17785,7 +17782,7 @@
17785
17782
  "revisionNumber": {
17786
17783
  "type": "string",
17787
17784
  "maxLength": 16,
17788
- "description": "Current revision of this account. Send it unchanged when updating; a stale value is rejected."
17785
+ "description": "Current revision of this account. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
17789
17786
  },
17790
17787
  "name": {
17791
17788
  "type": "string",
@@ -18439,7 +18436,7 @@
18439
18436
  "revisionNumber": {
18440
18437
  "type": "string",
18441
18438
  "maxLength": 16,
18442
- "description": "Current revision of this bill check payment. Send it unchanged when updating; a stale value is rejected."
18439
+ "description": "Current revision of this bill check payment. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
18443
18440
  },
18444
18441
  "transactionDate": {
18445
18442
  "type": "string",
@@ -18668,7 +18665,7 @@
18668
18665
  "revisionNumber": {
18669
18666
  "type": "string",
18670
18667
  "maxLength": 16,
18671
- "description": "Current revision of this bill. Send it unchanged when updating; a stale value is rejected."
18668
+ "description": "Current revision of this bill. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
18672
18669
  },
18673
18670
  "vendorId": {
18674
18671
  "type": "string",
@@ -18867,7 +18864,7 @@
18867
18864
  "revisionNumber": {
18868
18865
  "type": "string",
18869
18866
  "maxLength": 16,
18870
- "description": "Current revision of this build assembly. Send it unchanged when updating; a stale value is rejected."
18867
+ "description": "Current revision of this build assembly. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
18871
18868
  },
18872
18869
  "inventorySiteId": {
18873
18870
  "type": "string",
@@ -19051,7 +19048,7 @@
19051
19048
  "revisionNumber": {
19052
19049
  "type": "string",
19053
19050
  "maxLength": 16,
19054
- "description": "Current revision of this check. Send it unchanged when updating; a stale value is rejected."
19051
+ "description": "Current revision of this check. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
19055
19052
  },
19056
19053
  "bankAccountId": {
19057
19054
  "type": "string",
@@ -19184,7 +19181,7 @@
19184
19181
  "revisionNumber": {
19185
19182
  "type": "string",
19186
19183
  "maxLength": 16,
19187
- "description": "Current revision of this class. Send it unchanged when updating; a stale value is rejected."
19184
+ "description": "Current revision of this class. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
19188
19185
  },
19189
19186
  "name": {
19190
19187
  "type": "string",
@@ -19276,7 +19273,7 @@
19276
19273
  "null"
19277
19274
  ],
19278
19275
  "maxLength": 16,
19279
- "description": "Current revision of this contacts. Send it unchanged when updating; a stale value is rejected.",
19276
+ "description": "Current revision of this contacts. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected.",
19280
19277
  "x-daapi-clearable": true
19281
19278
  },
19282
19279
  "salutation": {
@@ -19410,7 +19407,7 @@
19410
19407
  "revisionNumber": {
19411
19408
  "type": "string",
19412
19409
  "maxLength": 16,
19413
- "description": "Current revision of this credit card charge. Send it unchanged when updating; a stale value is rejected."
19410
+ "description": "Current revision of this credit card charge. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
19414
19411
  },
19415
19412
  "accountId": {
19416
19413
  "type": "string",
@@ -19603,7 +19600,7 @@
19603
19600
  "revisionNumber": {
19604
19601
  "type": "string",
19605
19602
  "maxLength": 16,
19606
- "description": "Current revision of this credit card credit. Send it unchanged when updating; a stale value is rejected."
19603
+ "description": "Current revision of this credit card credit. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
19607
19604
  },
19608
19605
  "accountId": {
19609
19606
  "type": "string",
@@ -20418,7 +20415,7 @@
20418
20415
  "revisionNumber": {
20419
20416
  "type": "string",
20420
20417
  "maxLength": 16,
20421
- "description": "Current revision of this credit memo. Send it unchanged when updating; a stale value is rejected."
20418
+ "description": "Current revision of this credit memo. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
20422
20419
  },
20423
20420
  "customerId": {
20424
20421
  "type": "string",
@@ -20685,7 +20682,7 @@
20685
20682
  "revisionNumber": {
20686
20683
  "type": "string",
20687
20684
  "maxLength": 16,
20688
- "description": "Current revision of this currency. Send it unchanged when updating; a stale value is rejected."
20685
+ "description": "Current revision of this currency. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
20689
20686
  },
20690
20687
  "name": {
20691
20688
  "type": "string",
@@ -21103,7 +21100,7 @@
21103
21100
  "revisionNumber": {
21104
21101
  "type": "string",
21105
21102
  "maxLength": 16,
21106
- "description": "Current revision of this customer. Send it unchanged when updating; a stale value is rejected."
21103
+ "description": "Current revision of this customer. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
21107
21104
  },
21108
21105
  "name": {
21109
21106
  "type": "string",
@@ -21894,7 +21891,7 @@
21894
21891
  "revisionNumber": {
21895
21892
  "type": "string",
21896
21893
  "maxLength": 16,
21897
- "description": "Current revision of this deposit. Send it unchanged when updating; a stale value is rejected."
21894
+ "description": "Current revision of this deposit. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
21898
21895
  },
21899
21896
  "transactionDate": {
21900
21897
  "type": "string",
@@ -22034,7 +22031,7 @@
22034
22031
  "revisionNumber": {
22035
22032
  "type": "string",
22036
22033
  "maxLength": 16,
22037
- "description": "Current revision of this discount item. Send it unchanged when updating; a stale value is rejected."
22034
+ "description": "Current revision of this discount item. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
22038
22035
  },
22039
22036
  "name": {
22040
22037
  "type": "string",
@@ -22578,7 +22575,7 @@
22578
22575
  "revisionNumber": {
22579
22576
  "type": "string",
22580
22577
  "maxLength": 16,
22581
- "description": "Current revision of this employee. Send it unchanged when updating; a stale value is rejected."
22578
+ "description": "Current revision of this employee. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
22582
22579
  },
22583
22580
  "isActive": {
22584
22581
  "type": "boolean",
@@ -23456,7 +23453,7 @@
23456
23453
  "revisionNumber": {
23457
23454
  "type": "string",
23458
23455
  "maxLength": 16,
23459
- "description": "Current revision of this estimate. Send it unchanged when updating; a stale value is rejected."
23456
+ "description": "Current revision of this estimate. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
23460
23457
  },
23461
23458
  "customerId": {
23462
23459
  "type": "string",
@@ -24088,7 +24085,7 @@
24088
24085
  "revisionNumber": {
24089
24086
  "type": "string",
24090
24087
  "maxLength": 16,
24091
- "description": "Current revision of this inventory adjustment. Send it unchanged when updating; a stale value is rejected."
24088
+ "description": "Current revision of this inventory adjustment. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
24092
24089
  },
24093
24090
  "accountId": {
24094
24091
  "type": "string",
@@ -24310,7 +24307,7 @@
24310
24307
  "revisionNumber": {
24311
24308
  "type": "string",
24312
24309
  "maxLength": 16,
24313
- "description": "Current revision of this inventory assembly item. Send it unchanged when updating; a stale value is rejected."
24310
+ "description": "Current revision of this inventory assembly item. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
24314
24311
  },
24315
24312
  "name": {
24316
24313
  "type": "string",
@@ -24607,7 +24604,7 @@
24607
24604
  "revisionNumber": {
24608
24605
  "type": "string",
24609
24606
  "maxLength": 16,
24610
- "description": "Current revision of this inventory item. Send it unchanged when updating; a stale value is rejected."
24607
+ "description": "Current revision of this inventory item. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
24611
24608
  },
24612
24609
  "name": {
24613
24610
  "type": "string",
@@ -24810,7 +24807,7 @@
24810
24807
  "revisionNumber": {
24811
24808
  "type": "string",
24812
24809
  "maxLength": 16,
24813
- "description": "Current revision of this inventory site. Send it unchanged when updating; a stale value is rejected."
24810
+ "description": "Current revision of this inventory site. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
24814
24811
  },
24815
24812
  "name": {
24816
24813
  "type": "string",
@@ -25482,7 +25479,7 @@
25482
25479
  "revisionNumber": {
25483
25480
  "type": "string",
25484
25481
  "maxLength": 16,
25485
- "description": "Current revision of this invoice. Send it unchanged when updating; a stale value is rejected."
25482
+ "description": "Current revision of this invoice. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
25486
25483
  },
25487
25484
  "customerId": {
25488
25485
  "type": "string",
@@ -25892,7 +25889,7 @@
25892
25889
  "revisionNumber": {
25893
25890
  "type": "string",
25894
25891
  "maxLength": 16,
25895
- "description": "Current revision of this item group. Send it unchanged when updating; a stale value is rejected."
25892
+ "description": "Current revision of this item group. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
25896
25893
  },
25897
25894
  "name": {
25898
25895
  "type": "string",
@@ -26300,7 +26297,7 @@
26300
26297
  "revisionNumber": {
26301
26298
  "type": "string",
26302
26299
  "maxLength": 16,
26303
- "description": "Current revision of this item receipt. Send it unchanged when updating; a stale value is rejected."
26300
+ "description": "Current revision of this item receipt. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
26304
26301
  },
26305
26302
  "vendorId": {
26306
26303
  "type": "string",
@@ -26586,7 +26583,7 @@
26586
26583
  "revisionNumber": {
26587
26584
  "type": "string",
26588
26585
  "maxLength": 16,
26589
- "description": "Current revision of this journal entry. Send it unchanged when updating; a stale value is rejected."
26586
+ "description": "Current revision of this journal entry. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
26590
26587
  },
26591
26588
  "transactionDate": {
26592
26589
  "type": "string",
@@ -26831,7 +26828,7 @@
26831
26828
  "revisionNumber": {
26832
26829
  "type": "string",
26833
26830
  "maxLength": 16,
26834
- "description": "Current revision of this non-inventory item. Send it unchanged when updating; a stale value is rejected."
26831
+ "description": "Current revision of this non-inventory item. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
26835
26832
  },
26836
26833
  "name": {
26837
26834
  "type": "string",
@@ -27074,7 +27071,7 @@
27074
27071
  "revisionNumber": {
27075
27072
  "type": "string",
27076
27073
  "maxLength": 16,
27077
- "description": "Current revision of this other charge item. Send it unchanged when updating; a stale value is rejected."
27074
+ "description": "Current revision of this other charge item. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
27078
27075
  },
27079
27076
  "name": {
27080
27077
  "type": "string",
@@ -27248,7 +27245,7 @@
27248
27245
  "revisionNumber": {
27249
27246
  "type": "string",
27250
27247
  "maxLength": 16,
27251
- "description": "Current revision of this other name. Send it unchanged when updating; a stale value is rejected."
27248
+ "description": "Current revision of this other name. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
27252
27249
  },
27253
27250
  "name": {
27254
27251
  "type": "string",
@@ -27627,7 +27624,7 @@
27627
27624
  "revisionNumber": {
27628
27625
  "type": "string",
27629
27626
  "maxLength": 16,
27630
- "description": "Current revision of this price level. Send it unchanged when updating; a stale value is rejected."
27627
+ "description": "Current revision of this price level. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
27631
27628
  },
27632
27629
  "name": {
27633
27630
  "type": "string",
@@ -28180,7 +28177,7 @@
28180
28177
  "revisionNumber": {
28181
28178
  "type": "string",
28182
28179
  "maxLength": 16,
28183
- "description": "Current revision of this purchase order. Send it unchanged when updating; a stale value is rejected."
28180
+ "description": "Current revision of this purchase order. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
28184
28181
  },
28185
28182
  "vendorId": {
28186
28183
  "type": "string",
@@ -28456,7 +28453,7 @@
28456
28453
  "revisionNumber": {
28457
28454
  "type": "string",
28458
28455
  "maxLength": 16,
28459
- "description": "Current revision of this received payment. Send it unchanged when updating; a stale value is rejected."
28456
+ "description": "Current revision of this received payment. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
28460
28457
  },
28461
28458
  "customerId": {
28462
28459
  "type": "string",
@@ -29758,7 +29755,7 @@
29758
29755
  "revisionNumber": {
29759
29756
  "type": "string",
29760
29757
  "maxLength": 16,
29761
- "description": "Current revision of this sales order. Send it unchanged when updating; a stale value is rejected."
29758
+ "description": "Current revision of this sales order. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
29762
29759
  },
29763
29760
  "customerId": {
29764
29761
  "type": "string",
@@ -30561,7 +30558,7 @@
30561
30558
  "revisionNumber": {
30562
30559
  "type": "string",
30563
30560
  "maxLength": 16,
30564
- "description": "Current revision of this sales receipt. Send it unchanged when updating; a stale value is rejected."
30561
+ "description": "Current revision of this sales receipt. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
30565
30562
  },
30566
30563
  "customerId": {
30567
30564
  "type": "string",
@@ -30786,7 +30783,7 @@
30786
30783
  "revisionNumber": {
30787
30784
  "type": "string",
30788
30785
  "maxLength": 16,
30789
- "description": "Current revision of this sales representative. Send it unchanged when updating; a stale value is rejected."
30786
+ "description": "Current revision of this sales representative. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
30790
30787
  },
30791
30788
  "initial": {
30792
30789
  "type": [
@@ -30850,7 +30847,7 @@
30850
30847
  "revisionNumber": {
30851
30848
  "type": "string",
30852
30849
  "maxLength": 16,
30853
- "description": "Current revision of this sales tax code. Send it unchanged when updating; a stale value is rejected."
30850
+ "description": "Current revision of this sales tax code. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
30854
30851
  },
30855
30852
  "name": {
30856
30853
  "type": "string",
@@ -30938,7 +30935,7 @@
30938
30935
  "revisionNumber": {
30939
30936
  "type": "string",
30940
30937
  "maxLength": 16,
30941
- "description": "Current revision of this sales tax group item. Send it unchanged when updating; a stale value is rejected."
30938
+ "description": "Current revision of this sales tax group item. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
30942
30939
  },
30943
30940
  "name": {
30944
30941
  "type": "string",
@@ -31051,7 +31048,7 @@
31051
31048
  "revisionNumber": {
31052
31049
  "type": "string",
31053
31050
  "maxLength": 16,
31054
- "description": "Current revision of this sales tax item. Send it unchanged when updating; a stale value is rejected."
31051
+ "description": "Current revision of this sales tax item. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
31055
31052
  },
31056
31053
  "name": {
31057
31054
  "type": "string",
@@ -31205,7 +31202,7 @@
31205
31202
  "revisionNumber": {
31206
31203
  "type": "string",
31207
31204
  "maxLength": 16,
31208
- "description": "Current revision of this sales tax payment check. Send it unchanged when updating; a stale value is rejected."
31205
+ "description": "Current revision of this sales tax payment check. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
31209
31206
  },
31210
31207
  "transactionDate": {
31211
31208
  "type": "string",
@@ -31383,7 +31380,7 @@
31383
31380
  "revisionNumber": {
31384
31381
  "type": "string",
31385
31382
  "maxLength": 16,
31386
- "description": "Current revision of this service item. Send it unchanged when updating; a stale value is rejected."
31383
+ "description": "Current revision of this service item. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
31387
31384
  },
31388
31385
  "name": {
31389
31386
  "type": "string",
@@ -31928,7 +31925,7 @@
31928
31925
  "revisionNumber": {
31929
31926
  "type": "string",
31930
31927
  "maxLength": 16,
31931
- "description": "Current revision of this subtotal item. Send it unchanged when updating; a stale value is rejected."
31928
+ "description": "Current revision of this subtotal item. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
31932
31929
  },
31933
31930
  "name": {
31934
31931
  "type": "string",
@@ -32127,7 +32124,7 @@
32127
32124
  "revisionNumber": {
32128
32125
  "type": "string",
32129
32126
  "maxLength": 16,
32130
- "description": "Current revision of this time tracking activity. Send it unchanged when updating; a stale value is rejected."
32127
+ "description": "Current revision of this time tracking activity. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
32131
32128
  },
32132
32129
  "transactionDate": {
32133
32130
  "type": "string",
@@ -32307,7 +32304,7 @@
32307
32304
  "revisionNumber": {
32308
32305
  "type": "string",
32309
32306
  "maxLength": 16,
32310
- "description": "Current revision of this transfer. Send it unchanged when updating; a stale value is rejected."
32307
+ "description": "Current revision of this transfer. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
32311
32308
  },
32312
32309
  "transactionDate": {
32313
32310
  "type": "string",
@@ -32753,7 +32750,7 @@
32753
32750
  "revisionNumber": {
32754
32751
  "type": "string",
32755
32752
  "maxLength": 16,
32756
- "description": "Current revision of this vendor credit. Send it unchanged when updating; a stale value is rejected."
32753
+ "description": "Current revision of this vendor credit. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
32757
32754
  },
32758
32755
  "vendorId": {
32759
32756
  "type": "string",
@@ -32839,7 +32836,7 @@
32839
32836
  "revisionNumber": {
32840
32837
  "type": "string",
32841
32838
  "maxLength": 16,
32842
- "description": "Current revision of this vendor. Send it unchanged when updating; a stale value is rejected."
32839
+ "description": "Current revision of this vendor. Send it unchanged when updating; a stale value is rejected. QuickBooks changes it at most once per second, so a second edit within the same second keeps the same value. This API spaces its own consecutive writes to one object by over a second; edits made elsewhere in the same second are not detected."
32843
32840
  },
32844
32841
  "name": {
32845
32842
  "type": "string",
@@ -33128,14 +33125,15 @@
33128
33125
  "request.outcome_unknown",
33129
33126
  "request.outcome_resolved",
33130
33127
  "connection.setup_completed",
33131
- "connection.status_changed"
33128
+ "connection.status_changed",
33129
+ "connection.company_file_remarked"
33132
33130
  ],
33133
- "description": "`request.succeeded`, `request.failed`, `request.canceled`: a request reached that status. `request.outcome_unknown`: a write was sent without a confirmed result. `request.outcome_resolved`: such a write was resolved. `connection.setup_completed`: an end user finished setup and the first check passed. `connection.status_changed`: the derived connection status changed (offline is announced after it holds for 30 seconds).",
33131
+ "description": "`request.succeeded`, `request.failed`, `request.canceled`: a request reached that status. `request.outcome_unknown`: a write was sent without a confirmed result. `request.outcome_resolved`: such a write was resolved. `connection.setup_completed`: an end user finished setup and the first check passed. `connection.status_changed`: the derived connection status changed (offline is announced after it holds for 30 seconds). `connection.company_file_remarked`: the private marker that identifies the connected company file was created, written back after the file lost it (for example a restored backup) or adopted from the file; `data.reason` is `marker_created`, `marker_restored` or `marker_adopted`.",
33134
33132
  "x-daapi-open-enum": true,
33135
33133
  "example": "request.succeeded"
33136
33134
  },
33137
33135
  "minItems": 1,
33138
- "maxItems": 7,
33136
+ "maxItems": 8,
33139
33137
  "description": "Event types to deliver. At least one."
33140
33138
  },
33141
33139
  "description": {
@@ -33182,14 +33180,15 @@
33182
33180
  "request.outcome_unknown",
33183
33181
  "request.outcome_resolved",
33184
33182
  "connection.setup_completed",
33185
- "connection.status_changed"
33183
+ "connection.status_changed",
33184
+ "connection.company_file_remarked"
33186
33185
  ],
33187
- "description": "`request.succeeded`, `request.failed`, `request.canceled`: a request reached that status. `request.outcome_unknown`: a write was sent without a confirmed result. `request.outcome_resolved`: such a write was resolved. `connection.setup_completed`: an end user finished setup and the first check passed. `connection.status_changed`: the derived connection status changed (offline is announced after it holds for 30 seconds).",
33186
+ "description": "`request.succeeded`, `request.failed`, `request.canceled`: a request reached that status. `request.outcome_unknown`: a write was sent without a confirmed result. `request.outcome_resolved`: such a write was resolved. `connection.setup_completed`: an end user finished setup and the first check passed. `connection.status_changed`: the derived connection status changed (offline is announced after it holds for 30 seconds). `connection.company_file_remarked`: the private marker that identifies the connected company file was created, written back after the file lost it (for example a restored backup) or adopted from the file; `data.reason` is `marker_created`, `marker_restored` or `marker_adopted`.",
33188
33187
  "x-daapi-open-enum": true,
33189
33188
  "example": "request.succeeded"
33190
33189
  },
33191
33190
  "minItems": 1,
33192
- "maxItems": 7,
33191
+ "maxItems": 8,
33193
33192
  "description": "Event types to deliver. At least one."
33194
33193
  },
33195
33194
  "description": {
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  // Code generated by packages/sdk-generator from packages/mcp/src. DO NOT EDIT.
3
- // Contract: packages/api-contract/generated/openapi.json (OpenAPI 3.1.0) sha256:6f5ac28d7c33ac90aa7e2c15d88efd50e8e41c808bcc5489f0c8b1cb7833326a
3
+ // Contract: packages/api-contract/generated/openapi.json (OpenAPI 3.1.0) sha256:79b06eb2008381661d24d3bd5e23643483ec1bf9b70d5f4cdff2a2a71e22fe94
4
4
  // Local (stdio) MCP server for the Desktop Accounting API.
5
5
  //
6
6
  // npx -y @desktopaccountingapi/quickbooks-desktop-mcp [--read-only] [--resources invoices,customers] [--end-user-id eu_...]
package/dist/http.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // Code generated by packages/sdk-generator from packages/mcp/src. DO NOT EDIT.
2
- // Contract: packages/api-contract/generated/openapi.json (OpenAPI 3.1.0) sha256:6f5ac28d7c33ac90aa7e2c15d88efd50e8e41c808bcc5489f0c8b1cb7833326a
2
+ // Contract: packages/api-contract/generated/openapi.json (OpenAPI 3.1.0) sha256:79b06eb2008381661d24d3bd5e23643483ec1bf9b70d5f4cdff2a2a71e22fe94
3
3
  // Streamable HTTP transport (MCP 2025-03-26 and later), stateless: each POST carries one JSON-RPC
4
4
  // message (or a batch, for 2025-03-26 clients) and is answered with application/json. No server
5
5
  // sessions and no server-initiated stream, so GET and DELETE return 405. Web-standard Request and
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // Code generated by packages/sdk-generator from packages/mcp/src. DO NOT EDIT.
2
- // Contract: packages/api-contract/generated/openapi.json (OpenAPI 3.1.0) sha256:6f5ac28d7c33ac90aa7e2c15d88efd50e8e41c808bcc5489f0c8b1cb7833326a
2
+ // Contract: packages/api-contract/generated/openapi.json (OpenAPI 3.1.0) sha256:79b06eb2008381661d24d3bd5e23643483ec1bf9b70d5f4cdff2a2a71e22fe94
3
3
  // Runtime-agnostic MCP server core (no Node-only imports); the tool design is in tools.ts.
4
4
  export { buildCatalog, defsFor } from './catalog.js';
5
5
  export { handleMcpRequest } from './http.js';
package/dist/key.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // Code generated by packages/sdk-generator from packages/mcp/src. DO NOT EDIT.
2
- // Contract: packages/api-contract/generated/openapi.json (OpenAPI 3.1.0) sha256:6f5ac28d7c33ac90aa7e2c15d88efd50e8e41c808bcc5489f0c8b1cb7833326a
2
+ // Contract: packages/api-contract/generated/openapi.json (OpenAPI 3.1.0) sha256:79b06eb2008381661d24d3bd5e23643483ec1bf9b70d5f4cdff2a2a71e22fe94
3
3
  // Local secret-key check (same rule as the API and SDKs, docs/api-conventions.md section 2):
4
4
  // `sk_live_`/`sk_test_` + 40 base62 chars, the last 6 being the base62 CRC32 of the first 34.
5
5
  // Rejecting a mistyped key locally keeps it from counting against the API's per-IP
package/dist/server.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // Code generated by packages/sdk-generator from packages/mcp/src. DO NOT EDIT.
2
- // Contract: packages/api-contract/generated/openapi.json (OpenAPI 3.1.0) sha256:6f5ac28d7c33ac90aa7e2c15d88efd50e8e41c808bcc5489f0c8b1cb7833326a
2
+ // Contract: packages/api-contract/generated/openapi.json (OpenAPI 3.1.0) sha256:79b06eb2008381661d24d3bd5e23643483ec1bf9b70d5f4cdff2a2a71e22fe94
3
3
  // Model Context Protocol server core: JSON-RPC 2.0 message handling for the `tools` capability.
4
4
  // Transport-independent; stdio.ts and http.ts carry the messages. Implements the lifecycle
5
5
  // (initialize with version negotiation, notifications/initialized, ping) plus tools/list and
package/dist/stdio.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // Code generated by packages/sdk-generator from packages/mcp/src. DO NOT EDIT.
2
- // Contract: packages/api-contract/generated/openapi.json (OpenAPI 3.1.0) sha256:6f5ac28d7c33ac90aa7e2c15d88efd50e8e41c808bcc5489f0c8b1cb7833326a
2
+ // Contract: packages/api-contract/generated/openapi.json (OpenAPI 3.1.0) sha256:79b06eb2008381661d24d3bd5e23643483ec1bf9b70d5f4cdff2a2a71e22fe94
3
3
  // stdio transport: newline-delimited JSON-RPC on stdin/stdout (MCP specification, "stdio").
4
4
  // Only protocol messages go to stdout; diagnostics go to stderr. Pure Node.js (no Deno, no
5
5
  // POSIX-only features), so it runs the same on Windows, macOS and Linux.
package/dist/tools.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // Code generated by packages/sdk-generator from packages/mcp/src. DO NOT EDIT.
2
- // Contract: packages/api-contract/generated/openapi.json (OpenAPI 3.1.0) sha256:6f5ac28d7c33ac90aa7e2c15d88efd50e8e41c808bcc5489f0c8b1cb7833326a
2
+ // Contract: packages/api-contract/generated/openapi.json (OpenAPI 3.1.0) sha256:79b06eb2008381661d24d3bd5e23643483ec1bf9b70d5f4cdff2a2a71e22fe94
3
3
  // MCP tools over the Desktop Accounting API. Runtime-agnostic (fetch and Web Crypto only), so the
4
4
  // same code runs in the hosted Cloudflare Worker (apps/mcp) and the stdio npm package.
5
5
  //
@@ -449,26 +449,54 @@ export class Tools {
449
449
  }
450
450
  errorResult(r, e, idempotencyKey) {
451
451
  const err = r.json?.error;
452
- if (!err)
453
- return text(`HTTP ${r.status} from the API: ${r.raw.slice(0, 2000)}`, true);
452
+ if (!err) {
453
+ // A non-JSON error (edge or proxy page) says nothing about whether a write happened.
454
+ const write = e?.write && idempotencyKey ? ` It is unknown whether this write happened: do not send it with a new idempotency key; repeat this exact call with idempotency_key "${idempotencyKey}", which returns the original result instead of writing twice.` : '';
455
+ return text(`HTTP ${r.status} from the API: ${r.raw.slice(0, 2000)}${write}`, true);
456
+ }
454
457
  const guidance = [];
455
458
  const outcome = err.outcome;
459
+ // The request that keeps running is details.requestId (504 QBD_REQUEST_TIMEOUT, 502 outcome unknown); the
460
+ // error's own requestId is this HTTP call, which for a lost submit identifies nothing (Fable F-19).
461
+ const details = (err.details ?? {});
462
+ const pendingId = typeof details.requestId === 'string' ? details.requestId : null;
463
+ const retrieve = (id, wait) => `invoke_api_endpoint endpoint "requests.retrieve" with args {"id": "${id}"${wait ? ', "waitSeconds": 60' : ''}}`;
464
+ const sameKey = idempotencyKey ? ` Only ever repeat this call with idempotency_key "${idempotencyKey}"; that returns the original request instead of a second write.` : '';
456
465
  if (err.code === 'API_KEY_READ_ONLY')
457
466
  guidance.push('This secret key is read-only. Do not try other ways to make the change; tell the user it needs a full-access key.');
458
- else if (outcome === 'unknown' || outcome === 'pending') {
459
- guidance.push(`It is not known yet whether this write took effect. Do not send it again with a new idempotency key. Check the request with invoke_api_endpoint endpoint "requests.retrieve" and args {"id": "${String(err.requestId)}"}${idempotencyKey ? `, or repeat this exact call with idempotency_key "${idempotencyKey}" to attach to the original` : ''}.`);
467
+ else if (outcome === 'pending') {
468
+ guidance.push(`QuickBooks is still processing this write${pendingId ? ` (request ${pendingId})` : ''}. Do not send it again.${pendingId ? ` Wait for its result with ${retrieve(pendingId, true)}.` : ''}${sameKey}`);
469
+ }
470
+ else if (outcome === 'unknown') {
471
+ guidance.push(`It is unknown whether this write took effect, and the API will not find out on its own${pendingId ? ` (request ${pendingId})` : ''}. Do not send it again with a new idempotency key.${pendingId ? ` Check ${retrieve(pendingId, false)}, and check the record in QuickBooks${typeof details.externalId === 'string' ? ` (externalId ${details.externalId})` : ''} before doing anything else.` : ''}${sameKey}`);
472
+ }
473
+ else if (err.code === 'QBD_REQUEST_TIMEOUT' && pendingId) {
474
+ guidance.push(`QuickBooks is still working on this read. Get its result with ${retrieve(pendingId, true)} instead of repeating the call.`);
475
+ }
476
+ else if (err.retryable === true) {
477
+ const after = r.headers.get('Retry-After');
478
+ const wait = after ? ` Wait ${after} seconds first (Retry-After).` : '';
479
+ guidance.push(e?.write && idempotencyKey ? `Retryable: repeat with idempotency_key "${idempotencyKey}".${wait}` : `Retryable: try again shortly.${wait}`);
460
480
  }
461
- else if (err.retryable === true)
462
- guidance.push(e?.write && idempotencyKey ? `Retryable: repeat with idempotency_key "${idempotencyKey}".` : 'Retryable: try again shortly.');
463
481
  if (err.code === 'END_USER_ID_MISSING' || err.code === 'RESOURCE_MISSING')
464
482
  guidance.push('Check end_user_id and IDs with list_end_users or a list operation.');
465
483
  const keep = ['type', 'code', 'message', 'userFacingMessage', 'cause', 'fixes', 'outcome', 'retryable', 'param', 'details', 'requestId', 'docsUrl', 'integrationCode'];
466
484
  const slim = { httpStatus: r.status };
485
+ // `cause` and `fixes` are fixed catalog text (never caller or QuickBooks data), so they go outside
486
+ // the envelope whose preamble says not to follow instructions in it (Fable re-review F-19).
467
487
  for (const k of keep)
468
- if (err[k] !== undefined && err[k] !== null && !(k === 'details' && Object.keys(err[k]).length === 0))
488
+ if (k !== 'cause' && k !== 'fixes' && err[k] !== undefined && err[k] !== null && !(k === 'details' && Object.keys(err[k]).length === 0))
469
489
  slim[k] = err[k];
470
- // Error messages can quote QuickBooks data (names, memos), so they get the same envelope.
471
- return text(`${untrusted(JSON.stringify(slim))}${guidance.length ? `\n${guidance.join(' ')}` : ''}`, true);
490
+ const catalog = [];
491
+ if (typeof err.code === 'string')
492
+ catalog.push(`Error ${err.code}${typeof err.type === 'string' ? ` (${err.type})` : ''}.`);
493
+ if (typeof err.cause === 'string')
494
+ catalog.push(`Cause: ${err.cause}`);
495
+ const fixes = Array.isArray(err.fixes) ? err.fixes.filter((f) => typeof f?.action === 'string') : [];
496
+ if (fixes.length)
497
+ catalog.push(`How to fix: ${fixes.map((f) => `${f.actor === 'end_user' ? 'the end user' : f.actor === 'support' ? 'support' : 'you'}: ${String(f.action)}`).join(' ')}`);
498
+ // Error messages and details can quote QuickBooks data (names, memos), so they get the envelope.
499
+ return text(`${catalog.length ? `${catalog.join('\n')}\n` : ''}${untrusted(JSON.stringify(slim))}${guidance.length ? `\n${guidance.join(' ')}` : ''}`, true);
472
500
  }
473
501
  async searchDocs(args) {
474
502
  const query = String(args.query ?? '').trim();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@desktopaccountingapi/quickbooks-desktop-mcp",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Model Context Protocol (MCP) server for Desktop Accounting API: QuickBooks Desktop for Claude, Cursor, VS Code, Codex and other AI tools.",
5
5
  "license": "MIT",
6
6
  "author": "Desktop Accounting API",