node-autotask 0.43.0 → 0.45.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/MCP_TOOL_CATALOG.json +156 -1253
  3. package/MCP_TOOL_MANIFEST.md +154 -220
  4. package/MCP_TOOL_OVERRIDES.json +8 -62
  5. package/N8N_MCP_MANIFEST.json +128 -705
  6. package/N8N_MCP_MANIFEST.md +43 -63
  7. package/README.md +10 -28
  8. package/capabilities.json +15315 -22219
  9. package/dist/{base-CVx2VMSj.d.cts → base-BVoYDlVA.d.cts} +2 -1
  10. package/dist/{base-CVx2VMSj.d.ts → base-BVoYDlVA.d.ts} +2 -1
  11. package/dist/capabilities.cjs +2 -2
  12. package/dist/capabilities.d.cts +2 -1
  13. package/dist/capabilities.d.ts +2 -1
  14. package/dist/capabilities.js +1 -1
  15. package/dist/{chunk-5VHSLJMR.js → chunk-A6LHCJQP.js} +30 -9
  16. package/dist/{chunk-JY2BWYXY.js → chunk-ASMCTZO2.js} +15314 -22218
  17. package/dist/{chunk-TH7B5H4P.cjs → chunk-DC3PY4EF.cjs} +1839 -1407
  18. package/dist/{chunk-4EFXIE53.js → chunk-DXKXQHCX.js} +5 -5
  19. package/dist/{chunk-SK3GYRNA.cjs → chunk-JO6WI763.cjs} +143 -143
  20. package/dist/{chunk-Q23JULNN.js → chunk-NSW7JPVS.js} +11529 -13319
  21. package/dist/{chunk-KTEDPS4X.js → chunk-O4PIPUS4.js} +1583 -1151
  22. package/dist/{chunk-MJTKK3QG.cjs → chunk-SN4BMQ2N.cjs} +31 -10
  23. package/dist/{chunk-5BDUMDAQ.cjs → chunk-VXVYFJH3.cjs} +15314 -22218
  24. package/dist/{chunk-VFLAMMIJ.cjs → chunk-YMBVKVK4.cjs} +10604 -12394
  25. package/dist/{index-C7rMJ4IV.d.ts → index-C5g1H_hF.d.ts} +1080 -1288
  26. package/dist/{index-Cm_Xpt7X.d.cts → index-Db0SNnQn.d.cts} +1080 -1288
  27. package/dist/{index-C3KFMnRT.d.cts → index-c549LvOb.d.cts} +332 -331
  28. package/dist/{index-C3KFMnRT.d.ts → index-c549LvOb.d.ts} +332 -331
  29. package/dist/index.cjs +23 -23
  30. package/dist/index.d.cts +15 -41
  31. package/dist/index.d.ts +15 -41
  32. package/dist/index.js +8 -8
  33. package/dist/operations/index.cjs +5 -2234
  34. package/dist/operations/index.d.cts +51 -323
  35. package/dist/operations/index.d.ts +51 -323
  36. package/dist/operations/index.js +30 -2259
  37. package/dist/pool.cjs +9 -9
  38. package/dist/pool.d.cts +4 -3
  39. package/dist/pool.d.ts +4 -3
  40. package/dist/pool.js +5 -5
  41. package/dist/resources/index.cjs +5 -5
  42. package/dist/resources/index.d.cts +2 -2
  43. package/dist/resources/index.d.ts +2 -2
  44. package/dist/resources/index.js +8 -8
  45. package/dist/types/index.d.cts +1 -1
  46. package/dist/types/index.d.ts +1 -1
  47. package/dist/untrusted.cjs +2 -2
  48. package/dist/untrusted.d.cts +14 -5
  49. package/dist/untrusted.d.ts +14 -5
  50. package/dist/untrusted.js +1 -1
  51. package/docs/API.md +321 -334
  52. package/docs/LIVE-TESTING.md +4 -6
  53. package/docs/N8N-ADAPTER.md +26 -26
  54. package/examples/mcp/schemas.ts +2 -0
  55. package/examples/mcp/tools-read.ts +3 -2
  56. package/n8n-mcp.curation.json +3 -3
  57. package/package.json +10 -9
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "generatedBy": "scripts/build-tool-catalog.mjs",
3
- "generatedAt": "2026-10-31T20:17:42.030Z",
4
- "planHash": "5c18b378722a038159564faccee795e7c278f048f30c77d77b5dc27e83ea2dee",
3
+ "generatedAt": "2026-11-01T10:43:53.138Z",
4
+ "planHash": "dc0c06eae0d75d77a9d41c50f8d9a4a7ce458f34e62aa1e7f9b5f35a487e4020",
5
5
  "metaTools": [
6
6
  {
7
7
  "name": "autotask_catalog",
@@ -51,7 +51,7 @@
51
51
  {
52
52
  "name": "autotask_read",
53
53
  "title": "Read One Registry Operation (read mode)",
54
- "description": "Route an effect=read registry operation by its exact name (never fuzzy, never a tool name): the 384 field/entity/UDF-info reads (getEntityInfo/getFieldInfo/getUdfInfo) have no dedicated tool and ride this one, and any read op is routable. For field discovery use operations.fieldCatalog (compact) instead of per-resource getFieldInfo (full dump). Read-only by construction — every op it can route is effect=read (zero mutating requests), and a write or delete op is refused BEFORE any request (cross-mode refusal; the message names the correct tool). Reads have no dry run (a read with dry_run: true is refused). Harness approval policy: approve every tool with readOnlyHint !== true (exactly 267 today); the 635 readOnlyHint: true tools — including this one — are safe ungated; the 57 destructiveHint: true tools (56 dedicated delete tools + autotask_delete) require confirm === the operation key. Migration: autotask_invoke is REPLACED by autotask_read/autotask_write/autotask_delete — update harness config. For query/count ops args[0] is a params object (filter/limit); call autotask_describe first for the exact arg shape and filter grammar. The argument set is CLOSED at the top level: an unknown argument is refused before any request, with a typed error naming the key and the valid keys.",
54
+ "description": "Route an effect=read registry operation by its exact name (never fuzzy, never a tool name): the 384 field/entity/UDF-info reads (getEntityInfo/getFieldInfo/getUdfInfo) have no dedicated tool and ride this one, and any read op is routable. For field discovery use operations.fieldCatalog (compact) instead of per-resource getFieldInfo (full dump). Read-only by construction — every op it can route is effect=read (zero mutating requests), and a write or delete op is refused BEFORE any request (cross-mode refusal; the message names the correct tool). Reads have no dry run (a read with dry_run: true is refused). Harness approval policy: approve every tool with readOnlyHint !== true (exactly 246 today); the 599 readOnlyHint: true tools — including this one — are safe ungated; the 57 destructiveHint: true tools (56 dedicated delete tools + autotask_delete) require confirm === the operation key. Migration: autotask_invoke is REPLACED by autotask_read/autotask_write/autotask_delete — update harness config. For query/count ops args[0] is a params object (filter/limit); call autotask_describe first for the exact arg shape and filter grammar. The argument set is CLOSED at the top level: an unknown argument is refused before any request, with a typed error naming the key and the valid keys.",
55
55
  "input": {
56
56
  "operation": {
57
57
  "type": "string",
@@ -71,7 +71,7 @@
71
71
  {
72
72
  "name": "autotask_write",
73
73
  "title": "Write One Registry Operation (write mode)",
74
- "description": "Route an effect=write registry operation by its exact name (never fuzzy, never a tool name), dry-run-first: the first call always travels dry_run: true (the pinned DryRunResult envelope, simulated: true — the mutating request is never issued); pass dry_run: false to apply. A read or delete op is refused BEFORE any request (cross-mode refusal; the message names the correct tool). The 3 approval-gated writes (configuration_items.moveConfigurationItem, contacts.moveToCompany, resources.transferOwnership) additionally require confirm === the operation key, in BOTH dry-run and apply mode. Harness approval policy: this tool is one of the 267 tools that require approval (readOnlyHint !== true); the 635 readOnlyHint: true tools are safe ungated, and the 57 destructiveHint: true tools (56 dedicated delete tools + autotask_delete) require confirm === the operation key. Migration: autotask_invoke is REPLACED by autotask_read/autotask_write/autotask_delete — update harness config. For query/count ops args[0] is a params object (filter/limit); call autotask_describe first for the exact arg shape and filter grammar. The argument set is CLOSED at the top level: an unknown argument is refused before any request, with a typed error naming the key and the valid keys.",
74
+ "description": "Route an effect=write registry operation by its exact name (never fuzzy, never a tool name), dry-run-first: the first call always travels dry_run: true (the pinned DryRunResult envelope, simulated: true — the mutating request is never issued); pass dry_run: false to apply. A read or delete op is refused BEFORE any request (cross-mode refusal; the message names the correct tool). The 2 approval-gated writes (configuration_items.moveConfigurationItem, contacts.moveToCompany) additionally require confirm === the operation key, in BOTH dry-run and apply mode. Harness approval policy: this tool is one of the 246 tools that require approval (readOnlyHint !== true); the 599 readOnlyHint: true tools are safe ungated, and the 57 destructiveHint: true tools (56 dedicated delete tools + autotask_delete) require confirm === the operation key. Migration: autotask_invoke is REPLACED by autotask_read/autotask_write/autotask_delete — update harness config. For query/count ops args[0] is a params object (filter/limit); call autotask_describe first for the exact arg shape and filter grammar. The argument set is CLOSED at the top level: an unknown argument is refused before any request, with a typed error naming the key and the valid keys.",
75
75
  "input": {
76
76
  "operation": {
77
77
  "type": "string",
@@ -101,7 +101,7 @@
101
101
  {
102
102
  "name": "autotask_delete",
103
103
  "title": "Delete One Registry Operation (delete mode)",
104
- "description": "Route an effect=destructive (delete) registry operation by its exact name (never fuzzy, never a tool name), dry-run-first: the first call always travels dry_run: true (the pinned DryRunResult envelope, simulated: true); pass dry_run: false to apply. confirm === the operation key is REQUIRED for every delete (all 56), in BOTH dry-run and apply mode — the deliberate act is the call, not the delete. A read or write op is refused BEFORE any request (cross-mode refusal; the message names the correct tool). Harness approval policy: this tool is one of the 57 destructiveHint: true tools that require approval + confirm; approve every tool with readOnlyHint !== true (exactly 267 today); the 635 readOnlyHint: true tools are safe ungated. Migration: autotask_invoke is REPLACED by autotask_read/autotask_write/autotask_delete — update harness config. The argument set is CLOSED at the top level: an unknown argument is refused before any request, with a typed error naming the key and the valid keys.",
104
+ "description": "Route an effect=destructive (delete) registry operation by its exact name (never fuzzy, never a tool name), dry-run-first: the first call always travels dry_run: true (the pinned DryRunResult envelope, simulated: true); pass dry_run: false to apply. confirm === the operation key is REQUIRED for every delete (all 56), in BOTH dry-run and apply mode — the deliberate act is the call, not the delete. A read or write op is refused BEFORE any request (cross-mode refusal; the message names the correct tool). Harness approval policy: this tool is one of the 57 destructiveHint: true tools that require approval + confirm; approve every tool with readOnlyHint !== true (exactly 246 today); the 599 readOnlyHint: true tools are safe ungated. Migration: autotask_invoke is REPLACED by autotask_read/autotask_write/autotask_delete — update harness config. The argument set is CLOSED at the top level: an unknown argument is refused before any request, with a typed error naming the key and the valid keys.",
105
105
  "input": {
106
106
  "operation": {
107
107
  "type": "string",
@@ -587,7 +587,7 @@
587
587
  "core": false,
588
588
  "tool": "autotask_billingItemApprovalLevel_create",
589
589
  "purpose": "Create a billing item approval level (the REST-only approval write for a time entry).",
590
- "preferredWhen": "Prefer time_entries.approve: it performs this create AND the documented follow-up update, then verifies the read-back. Use this raw create only when the follow-up update must be controlled separately.",
590
+ "preferredWhen": "Use this raw create (plus the documented follow-up update of the two approval fields) when the follow-up must be controlled separately — the approval composite (time_entries.approve) was cut in #292.",
591
591
  "backingOperation": "billing_item_approval_levels.create",
592
592
  "effect": "write",
593
593
  "dryRunFirst": true,
@@ -606,7 +606,7 @@
606
606
  "core": false,
607
607
  "tool": "autotask_billingItemApprovalLevel_get",
608
608
  "purpose": "Get one billing item approval level by id.",
609
- "preferredWhen": "Preferred when the numeric id is known (e.g. the id time_entries.approve returned); query by timeEntryID when it is not.",
609
+ "preferredWhen": "Preferred when the numeric id is known; query by timeEntryID when it is not.",
610
610
  "backingOperation": "billing_item_approval_levels.get",
611
611
  "effect": "read",
612
612
  "dryRunFirst": false,
@@ -654,28 +654,6 @@
654
654
  "reachReason": null,
655
655
  "boundedAlternative": null
656
656
  },
657
- {
658
- "operation": "billing_items.customRange",
659
- "core": false,
660
- "tool": "autotask_billingItems_customRange",
661
- "purpose": "Get billing items for an explicit itemDate range.",
662
- "preferredWhen": null,
663
- "backingOperation": "billing_items.customRange",
664
- "effect": "read",
665
- "dryRunFirst": false,
666
- "confirm": false,
667
- "requiredArgs": [
668
- "from",
669
- "to"
670
- ],
671
- "tier": "extended",
672
- "reachable": true,
673
- "reach": "dedicated tool",
674
- "reachReason": null,
675
- "boundedAlternative": null,
676
- "hidden": true,
677
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
678
- },
679
657
  {
680
658
  "operation": "billing_items.get",
681
659
  "core": false,
@@ -746,177 +724,6 @@
746
724
  "reachReason": "no dedicated tool — the op is still discoverable and invocable by exact name",
747
725
  "boundedAlternative": null
748
726
  },
749
- {
750
- "operation": "billing_items.last14",
751
- "core": false,
752
- "tool": "autotask_billingItems_last14",
753
- "purpose": "Get billing items for the last 14 days (rolling, itemDate).",
754
- "preferredWhen": null,
755
- "backingOperation": "billing_items.last14",
756
- "effect": "read",
757
- "dryRunFirst": false,
758
- "confirm": false,
759
- "requiredArgs": [],
760
- "tier": "extended",
761
- "reachable": true,
762
- "reach": "dedicated tool",
763
- "reachReason": null,
764
- "boundedAlternative": null,
765
- "hidden": true,
766
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
767
- },
768
- {
769
- "operation": "billing_items.last24h",
770
- "core": false,
771
- "tool": "autotask_billingItems_last24h",
772
- "purpose": "Get billing items for the last 24 hours (rolling, itemDate).",
773
- "preferredWhen": null,
774
- "backingOperation": "billing_items.last24h",
775
- "effect": "read",
776
- "dryRunFirst": false,
777
- "confirm": false,
778
- "requiredArgs": [],
779
- "tier": "extended",
780
- "reachable": true,
781
- "reach": "dedicated tool",
782
- "reachReason": null,
783
- "boundedAlternative": null,
784
- "hidden": true,
785
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
786
- },
787
- {
788
- "operation": "billing_items.last30",
789
- "core": false,
790
- "tool": "autotask_billingItems_last30",
791
- "purpose": "Get billing items for the last 30 days (rolling, itemDate).",
792
- "preferredWhen": null,
793
- "backingOperation": "billing_items.last30",
794
- "effect": "read",
795
- "dryRunFirst": false,
796
- "confirm": false,
797
- "requiredArgs": [],
798
- "tier": "extended",
799
- "reachable": true,
800
- "reach": "dedicated tool",
801
- "reachReason": null,
802
- "boundedAlternative": null,
803
- "hidden": true,
804
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
805
- },
806
- {
807
- "operation": "billing_items.last7",
808
- "core": false,
809
- "tool": "autotask_billingItems_last7",
810
- "purpose": "Get billing items for the last 7 days (rolling, itemDate).",
811
- "preferredWhen": null,
812
- "backingOperation": "billing_items.last7",
813
- "effect": "read",
814
- "dryRunFirst": false,
815
- "confirm": false,
816
- "requiredArgs": [],
817
- "tier": "extended",
818
- "reachable": true,
819
- "reach": "dedicated tool",
820
- "reachReason": null,
821
- "boundedAlternative": null,
822
- "hidden": true,
823
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
824
- },
825
- {
826
- "operation": "billing_items.last90",
827
- "core": false,
828
- "tool": "autotask_billingItems_last90",
829
- "purpose": "Get billing items for the last 90 days (rolling, itemDate).",
830
- "preferredWhen": null,
831
- "backingOperation": "billing_items.last90",
832
- "effect": "read",
833
- "dryRunFirst": false,
834
- "confirm": false,
835
- "requiredArgs": [],
836
- "tier": "extended",
837
- "reachable": true,
838
- "reach": "dedicated tool",
839
- "reachReason": null,
840
- "boundedAlternative": null,
841
- "hidden": true,
842
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
843
- },
844
- {
845
- "operation": "billing_items.lastFullFortnight",
846
- "core": false,
847
- "tool": "autotask_billingItems_lastFullFortnight",
848
- "purpose": "Get billing items for the last complete fortnight (itemDate).",
849
- "preferredWhen": null,
850
- "backingOperation": "billing_items.lastFullFortnight",
851
- "effect": "read",
852
- "dryRunFirst": false,
853
- "confirm": false,
854
- "requiredArgs": [],
855
- "tier": "extended",
856
- "reachable": true,
857
- "reach": "dedicated tool",
858
- "reachReason": null,
859
- "boundedAlternative": null,
860
- "hidden": true,
861
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
862
- },
863
- {
864
- "operation": "billing_items.lastFullMonth",
865
- "core": false,
866
- "tool": "autotask_billingItems_lastFullMonth",
867
- "purpose": "Get billing items for the last complete calendar month (itemDate).",
868
- "preferredWhen": null,
869
- "backingOperation": "billing_items.lastFullMonth",
870
- "effect": "read",
871
- "dryRunFirst": false,
872
- "confirm": false,
873
- "requiredArgs": [],
874
- "tier": "extended",
875
- "reachable": true,
876
- "reach": "dedicated tool",
877
- "reachReason": null,
878
- "boundedAlternative": null,
879
- "hidden": true,
880
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
881
- },
882
- {
883
- "operation": "billing_items.lastFullQuarter",
884
- "core": false,
885
- "tool": "autotask_billingItems_lastFullQuarter",
886
- "purpose": "Get billing items for the last complete calendar quarter (itemDate).",
887
- "preferredWhen": null,
888
- "backingOperation": "billing_items.lastFullQuarter",
889
- "effect": "read",
890
- "dryRunFirst": false,
891
- "confirm": false,
892
- "requiredArgs": [],
893
- "tier": "extended",
894
- "reachable": true,
895
- "reach": "dedicated tool",
896
- "reachReason": null,
897
- "boundedAlternative": null,
898
- "hidden": true,
899
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
900
- },
901
- {
902
- "operation": "billing_items.lastFullWeek",
903
- "core": false,
904
- "tool": "autotask_billingItems_lastFullWeek",
905
- "purpose": "Get billing items for the last complete ISO week (itemDate).",
906
- "preferredWhen": null,
907
- "backingOperation": "billing_items.lastFullWeek",
908
- "effect": "read",
909
- "dryRunFirst": false,
910
- "confirm": false,
911
- "requiredArgs": [],
912
- "tier": "extended",
913
- "reachable": true,
914
- "reach": "dedicated tool",
915
- "reachReason": null,
916
- "boundedAlternative": null,
917
- "hidden": true,
918
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
919
- },
920
727
  {
921
728
  "operation": "billing_items.query",
922
729
  "core": false,
@@ -953,25 +760,6 @@
953
760
  "reachReason": null,
954
761
  "boundedAlternative": null
955
762
  },
956
- {
957
- "operation": "billing_items.today",
958
- "core": false,
959
- "tool": "autotask_billingItems_today",
960
- "purpose": "Get billing items for today (itemDate = now, server date).",
961
- "preferredWhen": null,
962
- "backingOperation": "billing_items.today",
963
- "effect": "read",
964
- "dryRunFirst": false,
965
- "confirm": false,
966
- "requiredArgs": [],
967
- "tier": "extended",
968
- "reachable": true,
969
- "reach": "dedicated tool",
970
- "reachReason": null,
971
- "boundedAlternative": null,
972
- "hidden": true,
973
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
974
- },
975
763
  {
976
764
  "operation": "billing_items.update",
977
765
  "core": false,
@@ -992,25 +780,6 @@
992
780
  "reachReason": null,
993
781
  "boundedAlternative": null
994
782
  },
995
- {
996
- "operation": "billing_items.yesterday",
997
- "core": false,
998
- "tool": "autotask_billingItems_yesterday",
999
- "purpose": "Get billing items for yesterday (itemDate = previous server day).",
1000
- "preferredWhen": null,
1001
- "backingOperation": "billing_items.yesterday",
1002
- "effect": "read",
1003
- "dryRunFirst": false,
1004
- "confirm": false,
1005
- "requiredArgs": [],
1006
- "tier": "extended",
1007
- "reachable": true,
1008
- "reach": "dedicated tool",
1009
- "reachReason": null,
1010
- "boundedAlternative": null,
1011
- "hidden": true,
1012
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
1013
- },
1014
783
  {
1015
784
  "operation": "change_request_links.count",
1016
785
  "core": false,
@@ -1047,25 +816,6 @@
1047
816
  "reachReason": null,
1048
817
  "boundedAlternative": null
1049
818
  },
1050
- {
1051
- "operation": "change_request_links.createIfNotExists",
1052
- "core": false,
1053
- "tool": "autotask_changeRequestLinks_create_if_not_exists",
1054
- "purpose": "Create a ChangeRequestLink.",
1055
- "preferredWhen": null,
1056
- "backingOperation": "change_request_links.createIfNotExists",
1057
- "effect": "write",
1058
- "dryRunFirst": true,
1059
- "confirm": false,
1060
- "requiredArgs": [
1061
- "data"
1062
- ],
1063
- "tier": "extended",
1064
- "reachable": true,
1065
- "reach": "dedicated tool",
1066
- "reachReason": null,
1067
- "boundedAlternative": null
1068
- },
1069
819
  {
1070
820
  "operation": "change_request_links.delete",
1071
821
  "core": false,
@@ -4077,26 +3827,6 @@
4077
3827
  "reachReason": null,
4078
3828
  "boundedAlternative": null
4079
3829
  },
4080
- {
4081
- "operation": "expense_items.createIfNotExists",
4082
- "core": false,
4083
- "tool": "autotask_expenseItem_create_if_not_exists",
4084
- "purpose": "Create an ExpenseItem.",
4085
- "preferredWhen": null,
4086
- "backingOperation": "expense_items.createIfNotExists",
4087
- "effect": "write",
4088
- "dryRunFirst": true,
4089
- "confirm": false,
4090
- "requiredArgs": [
4091
- "parentId",
4092
- "data"
4093
- ],
4094
- "tier": "extended",
4095
- "reachable": true,
4096
- "reach": "dedicated tool",
4097
- "reachReason": null,
4098
- "boundedAlternative": null
4099
- },
4100
3830
  {
4101
3831
  "operation": "expense_items.get",
4102
3832
  "core": false,
@@ -4441,25 +4171,6 @@
4441
4171
  "reachReason": null,
4442
4172
  "boundedAlternative": null
4443
4173
  },
4444
- {
4445
- "operation": "holiday_sets.createIfNotExists",
4446
- "core": false,
4447
- "tool": "autotask_holidaySet_create_if_not_exists",
4448
- "purpose": "Create a HolidaySet.",
4449
- "preferredWhen": null,
4450
- "backingOperation": "holiday_sets.createIfNotExists",
4451
- "effect": "write",
4452
- "dryRunFirst": true,
4453
- "confirm": false,
4454
- "requiredArgs": [
4455
- "data"
4456
- ],
4457
- "tier": "advanced",
4458
- "reachable": true,
4459
- "reach": "dedicated tool",
4460
- "reachReason": null,
4461
- "boundedAlternative": null
4462
- },
4463
4174
  {
4464
4175
  "operation": "holiday_sets.delete",
4465
4176
  "core": false,
@@ -4642,26 +4353,6 @@
4642
4353
  "reachReason": null,
4643
4354
  "boundedAlternative": null
4644
4355
  },
4645
- {
4646
- "operation": "holidays.createIfNotExists",
4647
- "core": false,
4648
- "tool": "autotask_holiday_create_if_not_exists",
4649
- "purpose": "Create a Holiday.",
4650
- "preferredWhen": null,
4651
- "backingOperation": "holidays.createIfNotExists",
4652
- "effect": "write",
4653
- "dryRunFirst": true,
4654
- "confirm": false,
4655
- "requiredArgs": [
4656
- "parentId",
4657
- "data"
4658
- ],
4659
- "tier": "advanced",
4660
- "reachable": true,
4661
- "reach": "dedicated tool",
4662
- "reachReason": null,
4663
- "boundedAlternative": null
4664
- },
4665
4356
  {
4666
4357
  "operation": "holidays.delete",
4667
4358
  "core": false,
@@ -7928,38 +7619,18 @@
7928
7619
  "boundedAlternative": null
7929
7620
  },
7930
7621
  {
7931
- "operation": "resources.transferOwnership",
7622
+ "operation": "resources.update",
7932
7623
  "core": false,
7933
- "tool": "autotask_resource_transfer_ownership",
7934
- "purpose": "Transfer ownership of named resources to another resource.",
7935
- "preferredWhen": null,
7936
- "backingOperation": "resources.transferOwnership",
7624
+ "tool": "autotask_resource_update",
7625
+ "purpose": "Update a resource.",
7626
+ "preferredWhen": "Preferred over create or delete when the record exists and only some fields change.",
7627
+ "backingOperation": "resources.update",
7937
7628
  "effect": "write",
7938
7629
  "dryRunFirst": true,
7939
- "confirm": true,
7630
+ "confirm": false,
7940
7631
  "requiredArgs": [
7941
- "sourceResourceIds",
7942
- "destinationResourceId"
7943
- ],
7944
- "tier": "core",
7945
- "reachable": true,
7946
- "reach": "dedicated tool",
7947
- "reachReason": null,
7948
- "boundedAlternative": null
7949
- },
7950
- {
7951
- "operation": "resources.update",
7952
- "core": false,
7953
- "tool": "autotask_resource_update",
7954
- "purpose": "Update a resource.",
7955
- "preferredWhen": "Preferred over create or delete when the record exists and only some fields change.",
7956
- "backingOperation": "resources.update",
7957
- "effect": "write",
7958
- "dryRunFirst": true,
7959
- "confirm": false,
7960
- "requiredArgs": [
7961
- "id",
7962
- "data"
7632
+ "id",
7633
+ "data"
7963
7634
  ],
7964
7635
  "tier": "core",
7965
7636
  "reachable": true,
@@ -7984,6 +7655,25 @@
7984
7655
  "reachReason": null,
7985
7656
  "boundedAlternative": null
7986
7657
  },
7658
+ {
7659
+ "operation": "resources.workload",
7660
+ "core": false,
7661
+ "tool": "autotask_resource_workload",
7662
+ "purpose": "Get a resource's workload in a single call: its open tickets (rows + the exact open totals), its task assignments and the tasks behind them, its time-off balances and requests.",
7663
+ "preferredWhen": "The single read for \"what is this resource working on right now\" — replaces the get + the forResource rows + the forResource counts + the assignments + the task join + the balances + the time-off queries with one call.",
7664
+ "backingOperation": "resources.workload",
7665
+ "effect": "read",
7666
+ "dryRunFirst": false,
7667
+ "confirm": false,
7668
+ "requiredArgs": [
7669
+ "id"
7670
+ ],
7671
+ "tier": "extended",
7672
+ "reachable": true,
7673
+ "reach": "dedicated tool",
7674
+ "reachReason": null,
7675
+ "boundedAlternative": null
7676
+ },
7987
7677
  {
7988
7678
  "operation": "roles.count",
7989
7679
  "core": false,
@@ -9000,6 +8690,25 @@
9000
8690
  "reachReason": null,
9001
8691
  "boundedAlternative": null
9002
8692
  },
8693
+ {
8694
+ "operation": "service_calls.fullProfile",
8695
+ "core": false,
8696
+ "tool": "autotask_service_call_full_profile",
8697
+ "purpose": "Get a service call with its tickets, tasks and resource assignments in a single call — the assignment join runs through the call's task ids.",
8698
+ "preferredWhen": "The single read for \"tell me everything about this service call\" — replaces the get + the two FK queries + the task-id join with one call.",
8699
+ "backingOperation": "service_calls.fullProfile",
8700
+ "effect": "read",
8701
+ "dryRunFirst": false,
8702
+ "confirm": false,
8703
+ "requiredArgs": [
8704
+ "id"
8705
+ ],
8706
+ "tier": "extended",
8707
+ "reachable": true,
8708
+ "reach": "dedicated tool",
8709
+ "reachReason": null,
8710
+ "boundedAlternative": null
8711
+ },
9003
8712
  {
9004
8713
  "operation": "service_calls.get",
9005
8714
  "core": false,
@@ -11439,25 +11148,6 @@
11439
11148
  "reachReason": null,
11440
11149
  "boundedAlternative": null
11441
11150
  },
11442
- {
11443
- "operation": "time_entries.approve",
11444
- "core": false,
11445
- "tool": "autotask_timeEntry_approve",
11446
- "purpose": "Approve a time entry (the REST-only approval path): create the BillingItemApprovalLevels record, apply the vendor-documented follow-up update of BillingApprovalDateTime + BillingApprovalResourceID, then read the entry back and report whether the vendor accepted it.",
11447
- "preferredWhen": "Approving (or adding the next approval level to) a time entry. This is the only approval channel the REST API exposes — there is no TimeEntries/Approve path. When the follow-up update throws, the approval level record HAS been created on the vendor (there is no rollback and no delete): reconcile by re-reading the entry's billingApprovalLevelMostRecent or querying billing_item_approval_levels by timeEntryID.",
11448
- "backingOperation": "time_entries.approve",
11449
- "effect": "write",
11450
- "dryRunFirst": true,
11451
- "confirm": false,
11452
- "requiredArgs": [
11453
- "id"
11454
- ],
11455
- "tier": "extended",
11456
- "reachable": true,
11457
- "reach": "dedicated tool",
11458
- "reachReason": null,
11459
- "boundedAlternative": null
11460
- },
11461
11151
  {
11462
11152
  "operation": "time_entries.count",
11463
11153
  "core": false,
@@ -11494,72 +11184,11 @@
11494
11184
  "reachReason": null,
11495
11185
  "boundedAlternative": null
11496
11186
  },
11497
- {
11498
- "operation": "time_entries.createForResource",
11499
- "core": false,
11500
- "tool": "autotask_timeEntry_create_for_resource",
11501
- "purpose": "Create a time entry for a resource with the allocation-code dependency resolved by the node: it verifies the resource is active, honours the caller's linkage pin (else the default internal linkage), resolves an EXISTING active allocation code applicable to the resource (never creates one — the API user cannot), and posts the vendor-valid body.",
11502
- "preferredWhen": "Default for any agent-created time entry: it does the dependency heavy lifting the vendor enforces with 500s. time_entries.create is the low-level escape hatch (it posts exactly the given body and lets the vendor gates surface verbatim).",
11503
- "backingOperation": "time_entries.createForResource",
11504
- "effect": "write",
11505
- "dryRunFirst": true,
11506
- "confirm": false,
11507
- "requiredArgs": [
11508
- "resourceID",
11509
- "params"
11510
- ],
11511
- "tier": "extended",
11512
- "reachable": true,
11513
- "reach": "dedicated tool",
11514
- "reachReason": null,
11515
- "boundedAlternative": null
11516
- },
11517
- {
11518
- "operation": "time_entries.createIfNotExists",
11519
- "core": false,
11520
- "tool": "autotask_timeEntry_create_if_not_exists",
11521
- "purpose": "Create a TimeEntry.",
11522
- "preferredWhen": null,
11523
- "backingOperation": "time_entries.createIfNotExists",
11524
- "effect": "write",
11525
- "dryRunFirst": true,
11526
- "confirm": false,
11527
- "requiredArgs": [
11528
- "data"
11529
- ],
11530
- "tier": "extended",
11531
- "reachable": true,
11532
- "reach": "dedicated tool",
11533
- "reachReason": null,
11534
- "boundedAlternative": null
11535
- },
11536
- {
11537
- "operation": "time_entries.customRange",
11538
- "core": false,
11539
- "tool": "autotask_timeEntry_custom_range",
11540
- "purpose": "Get time entries for an explicit dateWorked range.",
11541
- "preferredWhen": null,
11542
- "backingOperation": "time_entries.customRange",
11543
- "effect": "read",
11544
- "dryRunFirst": false,
11545
- "confirm": false,
11546
- "requiredArgs": [
11547
- "from",
11548
- "to"
11549
- ],
11550
- "tier": "extended",
11551
- "reachable": true,
11552
- "reach": "dedicated tool",
11553
- "reachReason": null,
11554
- "boundedAlternative": null,
11555
- "hidden": true,
11556
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
11557
- },
11558
11187
  {
11559
11188
  "operation": "time_entries.dateWorkedWindow",
11560
11189
  "core": false,
11561
11190
  "tool": "autotask_timeEntry_date_worked_window",
11562
- "purpose": "The unambiguous-named alias for time_entries.postedWithin (issue #66): the dateWorked window read with the posted/unposted split derived from the billing_items.timeEntryID join — same wire, same result (incl. truncated). The window is ON dateWorked (entries worked within [from, to]); \"postedWithin\" keeps its historical name (its \"posted\" is the posted/unposted split, never a posted-date window or a postedDate read).",
11191
+ "purpose": "The ONE posted-state read (issue #290): a bounded read over the inclusive dateWorked window [from, to] (UTC 'YYYY-MM-DD' days) with the posted/unposted split derived from the billing_items.timeEntryID join — never a postedDate read (W-D3: this zone's TimeEntry entity has no postedDate; postedDate exist|notExist 500s, live ww29 2026-10-27). Approval is NOT consulted (ww29 never populates billingApprovalDateTime yet bills those entries). The no-window form is gone: read with no dateWorked filter goes through time_entries.query.",
11563
11192
  "preferredWhen": null,
11564
11193
  "backingOperation": "time_entries.dateWorkedWindow",
11565
11194
  "effect": "read",
@@ -11649,23 +11278,6 @@
11649
11278
  "reachReason": "no dedicated tool — the op is still discoverable and invocable by exact name",
11650
11279
  "boundedAlternative": null
11651
11280
  },
11652
- {
11653
- "operation": "time_entries.getPosted",
11654
- "core": false,
11655
- "tool": "autotask_timeEntry_get_posted",
11656
- "purpose": "Get posted time entries (an entry that a billing item references), optionally for one ticket and/or a dateWorked window — posted state derives from the billing_items.timeEntryID join, never a postedDate read or approval.",
11657
- "preferredWhen": null,
11658
- "backingOperation": "time_entries.getPosted",
11659
- "effect": "read",
11660
- "dryRunFirst": false,
11661
- "confirm": false,
11662
- "requiredArgs": [],
11663
- "tier": "extended",
11664
- "reachable": true,
11665
- "reach": "dedicated tool",
11666
- "reachReason": null,
11667
- "boundedAlternative": null
11668
- },
11669
11281
  {
11670
11282
  "operation": "time_entries.getUdfInfo",
11671
11283
  "core": false,
@@ -11683,194 +11295,6 @@
11683
11295
  "reachReason": "no dedicated tool — the op is still discoverable and invocable by exact name",
11684
11296
  "boundedAlternative": null
11685
11297
  },
11686
- {
11687
- "operation": "time_entries.getUnposted",
11688
- "core": false,
11689
- "tool": "autotask_timeEntry_get_unposted",
11690
- "purpose": "Get unposted time entries (entries no billing item references), optionally for one ticket and/or a dateWorked window — posted state derives from the billing_items.timeEntryID join, never a postedDate read or approval.",
11691
- "preferredWhen": null,
11692
- "backingOperation": "time_entries.getUnposted",
11693
- "effect": "read",
11694
- "dryRunFirst": false,
11695
- "confirm": false,
11696
- "requiredArgs": [],
11697
- "tier": "extended",
11698
- "reachable": true,
11699
- "reach": "dedicated tool",
11700
- "reachReason": null,
11701
- "boundedAlternative": null
11702
- },
11703
- {
11704
- "operation": "time_entries.last14",
11705
- "core": false,
11706
- "tool": "autotask_timeEntry_last14",
11707
- "purpose": "Get time entries for the last 14 days (rolling, dateWorked).",
11708
- "preferredWhen": null,
11709
- "backingOperation": "time_entries.last14",
11710
- "effect": "read",
11711
- "dryRunFirst": false,
11712
- "confirm": false,
11713
- "requiredArgs": [],
11714
- "tier": "extended",
11715
- "reachable": true,
11716
- "reach": "dedicated tool",
11717
- "reachReason": null,
11718
- "boundedAlternative": null,
11719
- "hidden": true,
11720
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
11721
- },
11722
- {
11723
- "operation": "time_entries.last24h",
11724
- "core": false,
11725
- "tool": "autotask_timeEntry_last24h",
11726
- "purpose": "Get time entries for the last 24 hours (rolling, dateWorked).",
11727
- "preferredWhen": null,
11728
- "backingOperation": "time_entries.last24h",
11729
- "effect": "read",
11730
- "dryRunFirst": false,
11731
- "confirm": false,
11732
- "requiredArgs": [],
11733
- "tier": "extended",
11734
- "reachable": true,
11735
- "reach": "dedicated tool",
11736
- "reachReason": null,
11737
- "boundedAlternative": null,
11738
- "hidden": true,
11739
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
11740
- },
11741
- {
11742
- "operation": "time_entries.last30",
11743
- "core": false,
11744
- "tool": "autotask_timeEntry_last30",
11745
- "purpose": "Get time entries for the last 30 days (rolling, dateWorked).",
11746
- "preferredWhen": null,
11747
- "backingOperation": "time_entries.last30",
11748
- "effect": "read",
11749
- "dryRunFirst": false,
11750
- "confirm": false,
11751
- "requiredArgs": [],
11752
- "tier": "extended",
11753
- "reachable": true,
11754
- "reach": "dedicated tool",
11755
- "reachReason": null,
11756
- "boundedAlternative": null,
11757
- "hidden": true,
11758
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
11759
- },
11760
- {
11761
- "operation": "time_entries.last7",
11762
- "core": false,
11763
- "tool": "autotask_timeEntry_last7",
11764
- "purpose": "Get time entries for the last 7 days (rolling, dateWorked).",
11765
- "preferredWhen": null,
11766
- "backingOperation": "time_entries.last7",
11767
- "effect": "read",
11768
- "dryRunFirst": false,
11769
- "confirm": false,
11770
- "requiredArgs": [],
11771
- "tier": "extended",
11772
- "reachable": true,
11773
- "reach": "dedicated tool",
11774
- "reachReason": null,
11775
- "boundedAlternative": null,
11776
- "hidden": true,
11777
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
11778
- },
11779
- {
11780
- "operation": "time_entries.last90",
11781
- "core": false,
11782
- "tool": "autotask_timeEntry_last90",
11783
- "purpose": "Get time entries for the last 90 days (rolling, dateWorked).",
11784
- "preferredWhen": null,
11785
- "backingOperation": "time_entries.last90",
11786
- "effect": "read",
11787
- "dryRunFirst": false,
11788
- "confirm": false,
11789
- "requiredArgs": [],
11790
- "tier": "extended",
11791
- "reachable": true,
11792
- "reach": "dedicated tool",
11793
- "reachReason": null,
11794
- "boundedAlternative": null,
11795
- "hidden": true,
11796
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
11797
- },
11798
- {
11799
- "operation": "time_entries.lastFullFortnight",
11800
- "core": false,
11801
- "tool": "autotask_timeEntry_lastFullFortnight",
11802
- "purpose": "Get time entries for the last complete fortnight.",
11803
- "preferredWhen": null,
11804
- "backingOperation": "time_entries.lastFullFortnight",
11805
- "effect": "read",
11806
- "dryRunFirst": false,
11807
- "confirm": false,
11808
- "requiredArgs": [],
11809
- "tier": "extended",
11810
- "reachable": true,
11811
- "reach": "dedicated tool",
11812
- "reachReason": null,
11813
- "boundedAlternative": null,
11814
- "hidden": true,
11815
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
11816
- },
11817
- {
11818
- "operation": "time_entries.lastFullMonth",
11819
- "core": false,
11820
- "tool": "autotask_timeEntry_lastFullMonth",
11821
- "purpose": "Get time entries for the last complete calendar month.",
11822
- "preferredWhen": null,
11823
- "backingOperation": "time_entries.lastFullMonth",
11824
- "effect": "read",
11825
- "dryRunFirst": false,
11826
- "confirm": false,
11827
- "requiredArgs": [],
11828
- "tier": "extended",
11829
- "reachable": true,
11830
- "reach": "dedicated tool",
11831
- "reachReason": null,
11832
- "boundedAlternative": null,
11833
- "hidden": true,
11834
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
11835
- },
11836
- {
11837
- "operation": "time_entries.lastFullQuarter",
11838
- "core": false,
11839
- "tool": "autotask_timeEntry_lastFullQuarter",
11840
- "purpose": "Get time entries for the last complete calendar quarter.",
11841
- "preferredWhen": null,
11842
- "backingOperation": "time_entries.lastFullQuarter",
11843
- "effect": "read",
11844
- "dryRunFirst": false,
11845
- "confirm": false,
11846
- "requiredArgs": [],
11847
- "tier": "extended",
11848
- "reachable": true,
11849
- "reach": "dedicated tool",
11850
- "reachReason": null,
11851
- "boundedAlternative": null,
11852
- "hidden": true,
11853
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
11854
- },
11855
- {
11856
- "operation": "time_entries.lastFullWeek",
11857
- "core": false,
11858
- "tool": "autotask_timeEntry_lastFullWeek",
11859
- "purpose": "Get time entries for the last complete calendar week.",
11860
- "preferredWhen": null,
11861
- "backingOperation": "time_entries.lastFullWeek",
11862
- "effect": "read",
11863
- "dryRunFirst": false,
11864
- "confirm": false,
11865
- "requiredArgs": [],
11866
- "tier": "extended",
11867
- "reachable": true,
11868
- "reach": "dedicated tool",
11869
- "reachReason": null,
11870
- "boundedAlternative": null,
11871
- "hidden": true,
11872
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
11873
- },
11874
11298
  {
11875
11299
  "operation": "time_entries.moveToTicket",
11876
11300
  "core": false,
@@ -11891,26 +11315,6 @@
11891
11315
  "reachReason": null,
11892
11316
  "boundedAlternative": null
11893
11317
  },
11894
- {
11895
- "operation": "time_entries.postedWithin",
11896
- "core": false,
11897
- "tool": "autotask_timeEntry_posted_within",
11898
- "purpose": "Get time entries WORKED within an inclusive dateWorked window with the posted/unposted split. The window is ON the dateWorked field — the name's \"posted\" is the posted/unposted SPLIT derived from the billing_items.timeEntryID join (an entry a billing item references is posted, approval is not consulted), never a posted-date window or a postedDate read. The counts cover the returned rows only; truncated flags a capped read. time_entries.dateWorkedWindow is the unambiguous name.",
11899
- "preferredWhen": null,
11900
- "backingOperation": "time_entries.postedWithin",
11901
- "effect": "read",
11902
- "dryRunFirst": false,
11903
- "confirm": false,
11904
- "requiredArgs": [
11905
- "from",
11906
- "to"
11907
- ],
11908
- "tier": "extended",
11909
- "reachable": true,
11910
- "reach": "dedicated tool",
11911
- "reachReason": null,
11912
- "boundedAlternative": null
11913
- },
11914
11318
  {
11915
11319
  "operation": "time_entries.query",
11916
11320
  "core": false,
@@ -11947,25 +11351,6 @@
11947
11351
  "reachReason": null,
11948
11352
  "boundedAlternative": null
11949
11353
  },
11950
- {
11951
- "operation": "time_entries.today",
11952
- "core": false,
11953
- "tool": "autotask_timeEntry_today",
11954
- "purpose": "Get time entries for today (dateWorked = now, server date).",
11955
- "preferredWhen": null,
11956
- "backingOperation": "time_entries.today",
11957
- "effect": "read",
11958
- "dryRunFirst": false,
11959
- "confirm": false,
11960
- "requiredArgs": [],
11961
- "tier": "extended",
11962
- "reachable": true,
11963
- "reach": "dedicated tool",
11964
- "reachReason": null,
11965
- "boundedAlternative": null,
11966
- "hidden": true,
11967
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
11968
- },
11969
11354
  {
11970
11355
  "operation": "time_entries.update",
11971
11356
  "core": false,
@@ -11984,26 +11369,7 @@
11984
11369
  "reachable": true,
11985
11370
  "reach": "dedicated tool",
11986
11371
  "reachReason": null,
11987
- "boundedAlternative": null
11988
- },
11989
- {
11990
- "operation": "time_entries.yesterday",
11991
- "core": false,
11992
- "tool": "autotask_timeEntry_yesterday",
11993
- "purpose": "Get time entries for yesterday (dateWorked = yesterday, server date).",
11994
- "preferredWhen": null,
11995
- "backingOperation": "time_entries.yesterday",
11996
- "effect": "read",
11997
- "dryRunFirst": false,
11998
- "confirm": false,
11999
- "requiredArgs": [],
12000
- "tier": "extended",
12001
- "reachable": true,
12002
- "reach": "dedicated tool",
12003
- "reachReason": null,
12004
- "boundedAlternative": null,
12005
- "hidden": true,
12006
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
11372
+ "boundedAlternative": null
12007
11373
  },
12008
11374
  {
12009
11375
  "operation": "time_entry_attachments.count",
@@ -12697,26 +12063,6 @@
12697
12063
  "reachReason": null,
12698
12064
  "boundedAlternative": null
12699
12065
  },
12700
- {
12701
- "operation": "companies.upsertByName",
12702
- "core": false,
12703
- "tool": "autotask_company_upsert_by_name",
12704
- "purpose": "Make sure a company with the given name exists — find-or-create that carries the blind-surface boundary IN THE RESULT instead of pretending total visibility.",
12705
- "preferredWhen": "The one-call 'make sure this company exists' for agents. companies.create stays the low-level escape hatch.",
12706
- "backingOperation": "companies.upsertByName",
12707
- "effect": "write",
12708
- "dryRunFirst": true,
12709
- "confirm": false,
12710
- "requiredArgs": [
12711
- "companyName",
12712
- "params"
12713
- ],
12714
- "tier": "extended",
12715
- "reachable": true,
12716
- "reach": "dedicated tool",
12717
- "reachReason": null,
12718
- "boundedAlternative": null
12719
- },
12720
12066
  {
12721
12067
  "operation": "company_alerts.count",
12722
12068
  "core": false,
@@ -14713,25 +14059,6 @@
14713
14059
  "reachReason": null,
14714
14060
  "boundedAlternative": null
14715
14061
  },
14716
- {
14717
- "operation": "configuration_items.createIfNotExists",
14718
- "core": false,
14719
- "tool": "autotask_configurationItems_create_if_not_exists",
14720
- "purpose": "Create a ConfigurationItem.",
14721
- "preferredWhen": null,
14722
- "backingOperation": "configuration_items.createIfNotExists",
14723
- "effect": "write",
14724
- "dryRunFirst": true,
14725
- "confirm": false,
14726
- "requiredArgs": [
14727
- "data"
14728
- ],
14729
- "tier": "core",
14730
- "reachable": true,
14731
- "reach": "dedicated tool",
14732
- "reachReason": null,
14733
- "boundedAlternative": null
14734
- },
14735
14062
  {
14736
14063
  "operation": "configuration_items.findBySerial",
14737
14064
  "core": false,
@@ -15230,6 +14557,25 @@
15230
14557
  "reachReason": null,
15231
14558
  "boundedAlternative": null
15232
14559
  },
14560
+ {
14561
+ "operation": "contacts.fullProfile",
14562
+ "core": false,
14563
+ "tool": "autotask_contact_full_profile",
14564
+ "purpose": "Get a contact with its company and its open tickets in a single call: the contact (the parent-scoped root read, or the stage-1 row when the contact has no company FK), its company, and its open tickets — every part separately reported.",
14565
+ "preferredWhen": "The single read for \"tell me everything about this contact\" — replaces the stage-1 query + the parent-scoped get + the company get + the status picklist + the open-tickets query with one call.",
14566
+ "backingOperation": "contacts.fullProfile",
14567
+ "effect": "read",
14568
+ "dryRunFirst": false,
14569
+ "confirm": false,
14570
+ "requiredArgs": [
14571
+ "id"
14572
+ ],
14573
+ "tier": "extended",
14574
+ "reachable": true,
14575
+ "reach": "dedicated tool",
14576
+ "reachReason": null,
14577
+ "boundedAlternative": null
14578
+ },
15233
14579
  {
15234
14580
  "operation": "contacts.get",
15235
14581
  "core": false,
@@ -15416,26 +14762,6 @@
15416
14762
  "reachReason": null,
15417
14763
  "boundedAlternative": null
15418
14764
  },
15419
- {
15420
- "operation": "contacts.upsertByEmail",
15421
- "core": false,
15422
- "tool": "autotask_contact_upsert_by_email",
15423
- "purpose": "Make sure a contact with the given email exists under the given company — find-or-create under the RIGHT parent, with the typed EXISTS/CREATED result (+ the record).",
15424
- "preferredWhen": "The one-call 'make sure this contact exists' for agents — the natural key is the email under a company. contacts.create stays the low-level escape hatch (it posts exactly the given body).",
15425
- "backingOperation": "contacts.upsertByEmail",
15426
- "effect": "write",
15427
- "dryRunFirst": true,
15428
- "confirm": false,
15429
- "requiredArgs": [
15430
- "companyID",
15431
- "email"
15432
- ],
15433
- "tier": "extended",
15434
- "reachable": true,
15435
- "reach": "dedicated tool",
15436
- "reachReason": null,
15437
- "boundedAlternative": null
15438
- },
15439
14765
  {
15440
14766
  "operation": "contract_billing_rules.count",
15441
14767
  "core": false,
@@ -15988,26 +15314,6 @@
15988
15314
  "reachReason": null,
15989
15315
  "boundedAlternative": null
15990
15316
  },
15991
- {
15992
- "operation": "contract_charges.createIfNotExists",
15993
- "core": false,
15994
- "tool": "autotask_contractCharge_create_if_not_exists",
15995
- "purpose": "Create a ContractCharge.",
15996
- "preferredWhen": null,
15997
- "backingOperation": "contract_charges.createIfNotExists",
15998
- "effect": "write",
15999
- "dryRunFirst": true,
16000
- "confirm": false,
16001
- "requiredArgs": [
16002
- "parentId",
16003
- "data"
16004
- ],
16005
- "tier": "extended",
16006
- "reachable": true,
16007
- "reach": "dedicated tool",
16008
- "reachReason": null,
16009
- "boundedAlternative": null
16010
- },
16011
15317
  {
16012
15318
  "operation": "contract_charges.delete",
16013
15319
  "core": false,
@@ -17958,26 +17264,6 @@
17958
17264
  "reachReason": null,
17959
17265
  "boundedAlternative": null
17960
17266
  },
17961
- {
17962
- "operation": "contract_services.createIfNotExists",
17963
- "core": false,
17964
- "tool": "autotask_contractService_create_if_not_exists",
17965
- "purpose": "Create a ContractService.",
17966
- "preferredWhen": null,
17967
- "backingOperation": "contract_services.createIfNotExists",
17968
- "effect": "write",
17969
- "dryRunFirst": true,
17970
- "confirm": false,
17971
- "requiredArgs": [
17972
- "parentId",
17973
- "data"
17974
- ],
17975
- "tier": "extended",
17976
- "reachable": true,
17977
- "reach": "dedicated tool",
17978
- "reachReason": null,
17979
- "boundedAlternative": null
17980
- },
17981
17267
  {
17982
17268
  "operation": "contract_services.get",
17983
17269
  "core": false,
@@ -18308,17 +17594,17 @@
18308
17594
  "boundedAlternative": null
18309
17595
  },
18310
17596
  {
18311
- "operation": "contracts.createIfNotExists",
17597
+ "operation": "contracts.fullProfile",
18312
17598
  "core": false,
18313
- "tool": "autotask_contract_create_if_not_exists",
18314
- "purpose": "Create a Contract.",
18315
- "preferredWhen": null,
18316
- "backingOperation": "contracts.createIfNotExists",
18317
- "effect": "write",
18318
- "dryRunFirst": true,
17599
+ "tool": "autotask_contract_full_profile",
17600
+ "purpose": "Get a contract with its services, billing rules, recent charges and service units in a single call — the charges part is the N newest (the count-anchored `latest` 50).",
17601
+ "preferredWhen": "The single read for \"tell me everything about this contract\" — replaces the get + the four FK queries with one call; the first read of a contract for the profitability workflow.",
17602
+ "backingOperation": "contracts.fullProfile",
17603
+ "effect": "read",
17604
+ "dryRunFirst": false,
18319
17605
  "confirm": false,
18320
17606
  "requiredArgs": [
18321
- "data"
17607
+ "id"
18322
17608
  ],
18323
17609
  "tier": "extended",
18324
17610
  "reachable": true,
@@ -18525,270 +17811,77 @@
18525
17811
  "reachable": true,
18526
17812
  "reach": "dedicated tool",
18527
17813
  "reachReason": null,
18528
- "boundedAlternative": null
18529
- },
18530
- {
18531
- "operation": "invoices.customRange",
18532
- "core": false,
18533
- "tool": "autotask_invoice_customRange",
18534
- "purpose": "Get invoices for an explicit invoiceDateTime range.",
18535
- "preferredWhen": null,
18536
- "backingOperation": "invoices.customRange",
18537
- "effect": "read",
18538
- "dryRunFirst": false,
18539
- "confirm": false,
18540
- "requiredArgs": [
18541
- "from",
18542
- "to"
18543
- ],
18544
- "tier": "extended",
18545
- "reachable": true,
18546
- "reach": "dedicated tool",
18547
- "reachReason": null,
18548
- "boundedAlternative": null,
18549
- "hidden": true,
18550
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
18551
- },
18552
- {
18553
- "operation": "invoices.get",
18554
- "core": false,
18555
- "tool": "autotask_invoice_get",
18556
- "purpose": "Get one Invoice by id.",
18557
- "preferredWhen": "Preferred when the numeric id is already known; invoices.resolve is for a field value.",
18558
- "backingOperation": "invoices.get",
18559
- "effect": "read",
18560
- "dryRunFirst": false,
18561
- "confirm": false,
18562
- "requiredArgs": [
18563
- "id"
18564
- ],
18565
- "tier": "extended",
18566
- "reachable": true,
18567
- "reach": "dedicated tool",
18568
- "reachReason": null,
18569
- "boundedAlternative": null
18570
- },
18571
- {
18572
- "operation": "invoices.getEntityInfo",
18573
- "core": false,
18574
- "tool": null,
18575
- "purpose": "Get the Invoice capability metadata (canCreate/canUpdate/hasUserDefinedFields/...).",
18576
- "preferredWhen": null,
18577
- "backingOperation": "invoices.getEntityInfo",
18578
- "effect": "read",
18579
- "dryRunFirst": false,
18580
- "confirm": false,
18581
- "requiredArgs": [],
18582
- "tier": "extended",
18583
- "reachable": true,
18584
- "reach": "autotask_read (exact operation name; effect=read — read-only; zero mutating requests)",
18585
- "reachReason": "no dedicated tool — the op is still discoverable and invocable by exact name",
18586
- "boundedAlternative": null
18587
- },
18588
- {
18589
- "operation": "invoices.getFieldInfo",
18590
- "core": false,
18591
- "tool": null,
18592
- "purpose": "Get the Invoice field catalog (types, picklists, required, maxLength) — the full raw field dump (the largest read of the info trio; compact discovery: operations.fieldCatalog).",
18593
- "preferredWhen": null,
18594
- "backingOperation": "invoices.getFieldInfo",
18595
- "effect": "read",
18596
- "dryRunFirst": false,
18597
- "confirm": false,
18598
- "requiredArgs": [],
18599
- "tier": "extended",
18600
- "reachable": true,
18601
- "reach": "autotask_read (exact operation name; effect=read — read-only; zero mutating requests)",
18602
- "reachReason": "no dedicated tool — the op is still discoverable and invocable by exact name",
18603
- "boundedAlternative": null
18604
- },
18605
- {
18606
- "operation": "invoices.getUdfInfo",
18607
- "core": false,
18608
- "tool": null,
18609
- "purpose": "Get the Invoice user-defined-field catalog.",
18610
- "preferredWhen": null,
18611
- "backingOperation": "invoices.getUdfInfo",
18612
- "effect": "read",
18613
- "dryRunFirst": false,
18614
- "confirm": false,
18615
- "requiredArgs": [],
18616
- "tier": "extended",
18617
- "reachable": true,
18618
- "reach": "autotask_read (exact operation name; effect=read — read-only; zero mutating requests)",
18619
- "reachReason": "no dedicated tool — the op is still discoverable and invocable by exact name",
18620
- "boundedAlternative": null
18621
- },
18622
- {
18623
- "operation": "invoices.last14",
18624
- "core": false,
18625
- "tool": "autotask_invoice_last14",
18626
- "purpose": "Get invoices for the last 14 days (rolling, invoiceDateTime).",
18627
- "preferredWhen": null,
18628
- "backingOperation": "invoices.last14",
18629
- "effect": "read",
18630
- "dryRunFirst": false,
18631
- "confirm": false,
18632
- "requiredArgs": [],
18633
- "tier": "extended",
18634
- "reachable": true,
18635
- "reach": "dedicated tool",
18636
- "reachReason": null,
18637
- "boundedAlternative": null,
18638
- "hidden": true,
18639
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
18640
- },
18641
- {
18642
- "operation": "invoices.last24h",
18643
- "core": false,
18644
- "tool": "autotask_invoice_last24h",
18645
- "purpose": "Get invoices for the last 24 hours (rolling, invoiceDateTime).",
18646
- "preferredWhen": null,
18647
- "backingOperation": "invoices.last24h",
18648
- "effect": "read",
18649
- "dryRunFirst": false,
18650
- "confirm": false,
18651
- "requiredArgs": [],
18652
- "tier": "extended",
18653
- "reachable": true,
18654
- "reach": "dedicated tool",
18655
- "reachReason": null,
18656
- "boundedAlternative": null,
18657
- "hidden": true,
18658
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
18659
- },
18660
- {
18661
- "operation": "invoices.last30",
18662
- "core": false,
18663
- "tool": "autotask_invoice_last30",
18664
- "purpose": "Get invoices for the last 30 days (rolling, invoiceDateTime).",
18665
- "preferredWhen": null,
18666
- "backingOperation": "invoices.last30",
18667
- "effect": "read",
18668
- "dryRunFirst": false,
18669
- "confirm": false,
18670
- "requiredArgs": [],
18671
- "tier": "extended",
18672
- "reachable": true,
18673
- "reach": "dedicated tool",
18674
- "reachReason": null,
18675
- "boundedAlternative": null,
18676
- "hidden": true,
18677
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
18678
- },
18679
- {
18680
- "operation": "invoices.last7",
18681
- "core": false,
18682
- "tool": "autotask_invoice_last7",
18683
- "purpose": "Get invoices for the last 7 days (rolling, invoiceDateTime).",
18684
- "preferredWhen": null,
18685
- "backingOperation": "invoices.last7",
18686
- "effect": "read",
18687
- "dryRunFirst": false,
18688
- "confirm": false,
18689
- "requiredArgs": [],
18690
- "tier": "extended",
18691
- "reachable": true,
18692
- "reach": "dedicated tool",
18693
- "reachReason": null,
18694
- "boundedAlternative": null,
18695
- "hidden": true,
18696
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
18697
- },
18698
- {
18699
- "operation": "invoices.last90",
18700
- "core": false,
18701
- "tool": "autotask_invoice_last90",
18702
- "purpose": "Get invoices for the last 90 days (rolling, invoiceDateTime).",
18703
- "preferredWhen": null,
18704
- "backingOperation": "invoices.last90",
18705
- "effect": "read",
18706
- "dryRunFirst": false,
18707
- "confirm": false,
18708
- "requiredArgs": [],
18709
- "tier": "extended",
18710
- "reachable": true,
18711
- "reach": "dedicated tool",
18712
- "reachReason": null,
18713
- "boundedAlternative": null,
18714
- "hidden": true,
18715
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
17814
+ "boundedAlternative": null
18716
17815
  },
18717
17816
  {
18718
- "operation": "invoices.lastFullFortnight",
17817
+ "operation": "invoices.get",
18719
17818
  "core": false,
18720
- "tool": "autotask_invoice_lastFullFortnight",
18721
- "purpose": "Get invoices for the last complete fortnight (invoiceDateTime).",
18722
- "preferredWhen": null,
18723
- "backingOperation": "invoices.lastFullFortnight",
17819
+ "tool": "autotask_invoice_get",
17820
+ "purpose": "Get one Invoice by id.",
17821
+ "preferredWhen": "Preferred when the numeric id is already known; invoices.resolve is for a field value.",
17822
+ "backingOperation": "invoices.get",
18724
17823
  "effect": "read",
18725
17824
  "dryRunFirst": false,
18726
17825
  "confirm": false,
18727
- "requiredArgs": [],
17826
+ "requiredArgs": [
17827
+ "id"
17828
+ ],
18728
17829
  "tier": "extended",
18729
17830
  "reachable": true,
18730
17831
  "reach": "dedicated tool",
18731
17832
  "reachReason": null,
18732
- "boundedAlternative": null,
18733
- "hidden": true,
18734
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
17833
+ "boundedAlternative": null
18735
17834
  },
18736
17835
  {
18737
- "operation": "invoices.lastFullMonth",
17836
+ "operation": "invoices.getEntityInfo",
18738
17837
  "core": false,
18739
- "tool": "autotask_invoice_lastFullMonth",
18740
- "purpose": "Get invoices for the last complete calendar month (invoiceDateTime).",
17838
+ "tool": null,
17839
+ "purpose": "Get the Invoice capability metadata (canCreate/canUpdate/hasUserDefinedFields/...).",
18741
17840
  "preferredWhen": null,
18742
- "backingOperation": "invoices.lastFullMonth",
17841
+ "backingOperation": "invoices.getEntityInfo",
18743
17842
  "effect": "read",
18744
17843
  "dryRunFirst": false,
18745
17844
  "confirm": false,
18746
17845
  "requiredArgs": [],
18747
17846
  "tier": "extended",
18748
17847
  "reachable": true,
18749
- "reach": "dedicated tool",
18750
- "reachReason": null,
18751
- "boundedAlternative": null,
18752
- "hidden": true,
18753
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
17848
+ "reach": "autotask_read (exact operation name; effect=read — read-only; zero mutating requests)",
17849
+ "reachReason": "no dedicated tool — the op is still discoverable and invocable by exact name",
17850
+ "boundedAlternative": null
18754
17851
  },
18755
17852
  {
18756
- "operation": "invoices.lastFullQuarter",
17853
+ "operation": "invoices.getFieldInfo",
18757
17854
  "core": false,
18758
- "tool": "autotask_invoice_lastFullQuarter",
18759
- "purpose": "Get invoices for the last complete calendar quarter (invoiceDateTime).",
17855
+ "tool": null,
17856
+ "purpose": "Get the Invoice field catalog (types, picklists, required, maxLength) — the full raw field dump (the largest read of the info trio; compact discovery: operations.fieldCatalog).",
18760
17857
  "preferredWhen": null,
18761
- "backingOperation": "invoices.lastFullQuarter",
17858
+ "backingOperation": "invoices.getFieldInfo",
18762
17859
  "effect": "read",
18763
17860
  "dryRunFirst": false,
18764
17861
  "confirm": false,
18765
17862
  "requiredArgs": [],
18766
17863
  "tier": "extended",
18767
17864
  "reachable": true,
18768
- "reach": "dedicated tool",
18769
- "reachReason": null,
18770
- "boundedAlternative": null,
18771
- "hidden": true,
18772
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
17865
+ "reach": "autotask_read (exact operation name; effect=read — read-only; zero mutating requests)",
17866
+ "reachReason": "no dedicated tool — the op is still discoverable and invocable by exact name",
17867
+ "boundedAlternative": null
18773
17868
  },
18774
17869
  {
18775
- "operation": "invoices.lastFullWeek",
17870
+ "operation": "invoices.getUdfInfo",
18776
17871
  "core": false,
18777
- "tool": "autotask_invoice_lastFullWeek",
18778
- "purpose": "Get invoices for the last complete ISO week (invoiceDateTime).",
17872
+ "tool": null,
17873
+ "purpose": "Get the Invoice user-defined-field catalog.",
18779
17874
  "preferredWhen": null,
18780
- "backingOperation": "invoices.lastFullWeek",
17875
+ "backingOperation": "invoices.getUdfInfo",
18781
17876
  "effect": "read",
18782
17877
  "dryRunFirst": false,
18783
17878
  "confirm": false,
18784
17879
  "requiredArgs": [],
18785
17880
  "tier": "extended",
18786
17881
  "reachable": true,
18787
- "reach": "dedicated tool",
18788
- "reachReason": null,
18789
- "boundedAlternative": null,
18790
- "hidden": true,
18791
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
17882
+ "reach": "autotask_read (exact operation name; effect=read — read-only; zero mutating requests)",
17883
+ "reachReason": "no dedicated tool — the op is still discoverable and invocable by exact name",
17884
+ "boundedAlternative": null
18792
17885
  },
18793
17886
  {
18794
17887
  "operation": "invoices.markupHtml",
@@ -18883,25 +17976,6 @@
18883
17976
  "reachReason": null,
18884
17977
  "boundedAlternative": null
18885
17978
  },
18886
- {
18887
- "operation": "invoices.today",
18888
- "core": false,
18889
- "tool": "autotask_invoice_today",
18890
- "purpose": "Get invoices for today (invoiceDateTime = now, server date).",
18891
- "preferredWhen": null,
18892
- "backingOperation": "invoices.today",
18893
- "effect": "read",
18894
- "dryRunFirst": false,
18895
- "confirm": false,
18896
- "requiredArgs": [],
18897
- "tier": "extended",
18898
- "reachable": true,
18899
- "reach": "dedicated tool",
18900
- "reachReason": null,
18901
- "boundedAlternative": null,
18902
- "hidden": true,
18903
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
18904
- },
18905
17979
  {
18906
17980
  "operation": "invoices.update",
18907
17981
  "core": false,
@@ -18922,25 +17996,6 @@
18922
17996
  "reachReason": null,
18923
17997
  "boundedAlternative": null
18924
17998
  },
18925
- {
18926
- "operation": "invoices.yesterday",
18927
- "core": false,
18928
- "tool": "autotask_invoice_yesterday",
18929
- "purpose": "Get invoices for yesterday (invoiceDateTime = previous server day).",
18930
- "preferredWhen": null,
18931
- "backingOperation": "invoices.yesterday",
18932
- "effect": "read",
18933
- "dryRunFirst": false,
18934
- "confirm": false,
18935
- "requiredArgs": [],
18936
- "tier": "extended",
18937
- "reachable": true,
18938
- "reach": "dedicated tool",
18939
- "reachReason": null,
18940
- "boundedAlternative": null,
18941
- "hidden": true,
18942
- "hiddenReason": "date-window helper (one date field, no company/contract scope): hidden from default results — prefer <resource>.query with a date filter or operations.aggregate; still callable by exact key"
18943
- },
18944
17999
  {
18945
18000
  "operation": "opportunities.count",
18946
18001
  "core": false,
@@ -18977,25 +18032,6 @@
18977
18032
  "reachReason": null,
18978
18033
  "boundedAlternative": null
18979
18034
  },
18980
- {
18981
- "operation": "opportunities.createIfNotExists",
18982
- "core": false,
18983
- "tool": "autotask_opportunity_create_if_not_exists",
18984
- "purpose": "Create an Opportunity.",
18985
- "preferredWhen": null,
18986
- "backingOperation": "opportunities.createIfNotExists",
18987
- "effect": "write",
18988
- "dryRunFirst": true,
18989
- "confirm": false,
18990
- "requiredArgs": [
18991
- "data"
18992
- ],
18993
- "tier": "extended",
18994
- "reachable": true,
18995
- "reach": "dedicated tool",
18996
- "reachReason": null,
18997
- "boundedAlternative": null
18998
- },
18999
18035
  {
19000
18036
  "operation": "opportunities.get",
19001
18037
  "core": false,
@@ -19508,26 +18544,6 @@
19508
18544
  "reachReason": null,
19509
18545
  "boundedAlternative": null
19510
18546
  },
19511
- {
19512
- "operation": "project_charges.createIfNotExists",
19513
- "core": false,
19514
- "tool": "autotask_projectCharge_create_if_not_exists",
19515
- "purpose": "Create a ProjectCharge.",
19516
- "preferredWhen": null,
19517
- "backingOperation": "project_charges.createIfNotExists",
19518
- "effect": "write",
19519
- "dryRunFirst": true,
19520
- "confirm": false,
19521
- "requiredArgs": [
19522
- "parentId",
19523
- "data"
19524
- ],
19525
- "tier": "extended",
19526
- "reachable": true,
19527
- "reach": "dedicated tool",
19528
- "reachReason": null,
19529
- "boundedAlternative": null
19530
- },
19531
18547
  {
19532
18548
  "operation": "project_charges.delete",
19533
18549
  "core": false,
@@ -20607,6 +19623,25 @@
20607
19623
  "reachReason": null,
20608
19624
  "boundedAlternative": null
20609
19625
  },
19626
+ {
19627
+ "operation": "quotes.withItems",
19628
+ "core": false,
19629
+ "tool": "autotask_quote_with_items",
19630
+ "purpose": "Get a quote with its line items in a single call — the items part is the bounded quoteID-filtered query.",
19631
+ "preferredWhen": "The single read for \"get me this quote with its items\" — replaces the get + the quoteID-filtered items query with one call (the invoice-export workflow's first read).",
19632
+ "backingOperation": "quotes.withItems",
19633
+ "effect": "read",
19634
+ "dryRunFirst": false,
19635
+ "confirm": false,
19636
+ "requiredArgs": [
19637
+ "id"
19638
+ ],
19639
+ "tier": "extended",
19640
+ "reachable": true,
19641
+ "reach": "dedicated tool",
19642
+ "reachReason": null,
19643
+ "boundedAlternative": null
19644
+ },
20610
19645
  {
20611
19646
  "operation": "subscriptions.count",
20612
19647
  "core": false,
@@ -21173,26 +20208,6 @@
21173
20208
  "reachReason": null,
21174
20209
  "boundedAlternative": null
21175
20210
  },
21176
- {
21177
- "operation": "ticket_additional_configuration_items.createIfNotExists",
21178
- "core": false,
21179
- "tool": "autotask_ticketAdditionalConfigurationItem_create_if_not_exists",
21180
- "purpose": "Create a TicketAdditionalConfigurationItem.",
21181
- "preferredWhen": null,
21182
- "backingOperation": "ticket_additional_configuration_items.createIfNotExists",
21183
- "effect": "write",
21184
- "dryRunFirst": true,
21185
- "confirm": false,
21186
- "requiredArgs": [
21187
- "parentId",
21188
- "data"
21189
- ],
21190
- "tier": "extended",
21191
- "reachable": true,
21192
- "reach": "dedicated tool",
21193
- "reachReason": null,
21194
- "boundedAlternative": null
21195
- },
21196
20211
  {
21197
20212
  "operation": "ticket_additional_configuration_items.delete",
21198
20213
  "core": false,
@@ -21357,26 +20372,6 @@
21357
20372
  "reachReason": null,
21358
20373
  "boundedAlternative": null
21359
20374
  },
21360
- {
21361
- "operation": "ticket_additional_contacts.createIfNotExists",
21362
- "core": false,
21363
- "tool": "autotask_ticketAdditionalContact_create_if_not_exists",
21364
- "purpose": "Create a TicketAdditionalContact.",
21365
- "preferredWhen": null,
21366
- "backingOperation": "ticket_additional_contacts.createIfNotExists",
21367
- "effect": "write",
21368
- "dryRunFirst": true,
21369
- "confirm": false,
21370
- "requiredArgs": [
21371
- "parentId",
21372
- "data"
21373
- ],
21374
- "tier": "extended",
21375
- "reachable": true,
21376
- "reach": "dedicated tool",
21377
- "reachReason": null,
21378
- "boundedAlternative": null
21379
- },
21380
20375
  {
21381
20376
  "operation": "ticket_additional_contacts.delete",
21382
20377
  "core": false,
@@ -21889,26 +20884,6 @@
21889
20884
  "reachReason": null,
21890
20885
  "boundedAlternative": null
21891
20886
  },
21892
- {
21893
- "operation": "ticket_charges.createIfNotExists",
21894
- "core": false,
21895
- "tool": "autotask_ticketCharge_create_if_not_exists",
21896
- "purpose": "Create a TicketCharge.",
21897
- "preferredWhen": null,
21898
- "backingOperation": "ticket_charges.createIfNotExists",
21899
- "effect": "write",
21900
- "dryRunFirst": true,
21901
- "confirm": false,
21902
- "requiredArgs": [
21903
- "parentId",
21904
- "data"
21905
- ],
21906
- "tier": "extended",
21907
- "reachable": true,
21908
- "reach": "dedicated tool",
21909
- "reachReason": null,
21910
- "boundedAlternative": null
21911
- },
21912
20887
  {
21913
20888
  "operation": "ticket_charges.delete",
21914
20889
  "core": false,
@@ -23141,25 +22116,6 @@
23141
22116
  "reachReason": null,
23142
22117
  "boundedAlternative": null
23143
22118
  },
23144
- {
23145
- "operation": "tickets.openWithNoteAndAssign",
23146
- "core": false,
23147
- "tool": "autotask_ticket_open_with_note_and_assign",
23148
- "purpose": "Open a ticket with an optional first scoped note and an optional assignment in ONE op — the node absorbs the ww29-proven create contract and the note/assignment wire choreography (6 calls today → 1).",
23149
- "preferredWhen": "The one-call 'open a ticket' for agents: the raw tickets.create + ticket_notes.create + tickets.update choreography (describe×3 + create + note + update = 6 calls today) collapses to this (1 call; ≤5 wire). tickets.create stays the low-level escape hatch (it posts exactly the given body and lets the vendor gates surface verbatim).",
23150
- "backingOperation": "tickets.openWithNoteAndAssign",
23151
- "effect": "write",
23152
- "dryRunFirst": true,
23153
- "confirm": false,
23154
- "requiredArgs": [
23155
- "params"
23156
- ],
23157
- "tier": "extended",
23158
- "reachable": true,
23159
- "reach": "dedicated tool",
23160
- "reachReason": null,
23161
- "boundedAlternative": null
23162
- },
23163
22119
  {
23164
22120
  "operation": "tickets.query",
23165
22121
  "core": false,
@@ -23329,23 +22285,6 @@
23329
22285
  "reachReason": null,
23330
22286
  "boundedAlternative": null
23331
22287
  },
23332
- {
23333
- "operation": "operations.blindSurfaces",
23334
- "core": false,
23335
- "tool": "autotask_blind_surfaces",
23336
- "purpose": "Answer 'can this tenant/see this table at all?' in one ZERO-wire call: the plan-pinned blind-surface inventory over the 116 query-able surfaces — which read ops are affected per resource, the blind class, the unfiltered row count the discovery sweep observed, the authority op, and the proof level — with the data-full set, the artifact counts, and the remedies.",
23337
- "preferredWhen": "Before planning any unfiltered read on a table that has returned 0 rows: check the inventory first (free) instead of re-discovering the blindness one empty result at a time. The 6 pinned surfaces keep their typed sentinel (byte-identical wording); this inventory is the WIDER discovery set. For a live re-check on this tenant use operations.probeReachability (caller-opted, capped).",
23338
- "backingOperation": "operations.blindSurfaces",
23339
- "effect": "read",
23340
- "dryRunFirst": false,
23341
- "confirm": false,
23342
- "requiredArgs": [],
23343
- "tier": "extended",
23344
- "reachable": true,
23345
- "reach": "dedicated tool",
23346
- "reachReason": null,
23347
- "boundedAlternative": null
23348
- },
23349
22288
  {
23350
22289
  "operation": "operations.createGuidance",
23351
22290
  "core": false,
@@ -23387,7 +22326,7 @@
23387
22326
  "core": false,
23388
22327
  "tool": "autotask_fetch_by_ids",
23389
22328
  "purpose": "Fetch up to 500 single records by id across mixed resources in one call (query-first chunked id-in reads with a per-id get fallback), with per-item typed results.",
23390
- "preferredWhen": "The default for 'fetch these N known ids in one shot' when N is 20..500 (mixed resources OK — fetchMany is the <=20 single-record GET batch). Wire cost: per resource ceil(uniqueIds/250) query calls + one get per query-missed id — a clean 500-id single-resource batch is 2 wire; a blind-surface worst case is 2 + up to 500 gets (fetchMany parity, never worse). For string identifiers (names, emails, serials) use operations.resolveAny; for a filtered set use the resource's bounded query op.",
22329
+ "preferredWhen": "The default for 'fetch these N known ids in one shot' when N is 20..500 (mixed resources OK). Wire cost: per resource ceil(uniqueIds/250) query calls + one get per query-missed id — a clean 500-id single-resource batch is 2 wire; a blind-surface worst case is 2 + up to 500 gets. For string identifiers (names, emails, serials) use operations.resolveAny; for a filtered set use the resource's bounded query op.",
23391
22330
  "backingOperation": "operations.fetchByIds",
23392
22331
  "effect": "read",
23393
22332
  "dryRunFirst": false,
@@ -23401,25 +22340,6 @@
23401
22340
  "reachReason": null,
23402
22341
  "boundedAlternative": null
23403
22342
  },
23404
- {
23405
- "operation": "operations.fetchMany",
23406
- "core": false,
23407
- "tool": "autotask_fetch_many",
23408
- "purpose": "Fetch up to 20 single records across mixed resources in one call (tickets + projects + companies in a single batch), with per-item typed results.",
23409
- "preferredWhen": "The default for 'fetch these N known ids in one shot' (mixed resources OK). For MORE than 20 records use operations.fetchByIds (up to 500 ids, mixed resources) or the resource's bounded query op (filtered sets). For string identifiers (names, emails, serials) use operations.resolveAny.",
23410
- "backingOperation": "operations.fetchMany",
23411
- "effect": "read",
23412
- "dryRunFirst": false,
23413
- "confirm": false,
23414
- "requiredArgs": [
23415
- "items"
23416
- ],
23417
- "tier": "extended",
23418
- "reachable": true,
23419
- "reach": "dedicated tool",
23420
- "reachReason": null,
23421
- "boundedAlternative": null
23422
- },
23423
22343
  {
23424
22344
  "operation": "operations.fieldCatalog",
23425
22345
  "core": false,
@@ -23437,42 +22357,6 @@
23437
22357
  "reachReason": null,
23438
22358
  "boundedAlternative": null
23439
22359
  },
23440
- {
23441
- "operation": "operations.probeReachability",
23442
- "core": false,
23443
- "tool": "autotask_probe_reachability",
23444
- "purpose": "Re-run the blind-surface discovery live, on this tenant, in one bounded caller-opted call: one read query per named surface, hard-capped, with per-surface failures recorded instead of aborting — the operator's once-per-tenant answer to 'which of these tables does this user actually see?'.",
23445
- "preferredWhen": "Once per tenant, after a batch of unfiltered reads returned surprising 0 rows: re-discover the visibility boundary live (the pinned inventory is the ww29 discovery artifact — a different tenant needs its own sweep). The op is deliberately expensive, so it is opt-in (confirmProbe) and hard-capped; never automatic, never on client construction.",
23446
- "backingOperation": "operations.probeReachability",
23447
- "effect": "read",
23448
- "dryRunFirst": false,
23449
- "confirm": false,
23450
- "requiredArgs": [],
23451
- "tier": "extended",
23452
- "reachable": true,
23453
- "reach": "dedicated tool",
23454
- "reachReason": null,
23455
- "boundedAlternative": null
23456
- },
23457
- {
23458
- "operation": "operations.recovery",
23459
- "core": false,
23460
- "tool": "autotask_recovery",
23461
- "purpose": "Find (and, where the vendor allows, delete) the record a write just created, in one typed call — the bounded, marker-filtered recovery path for tenants where created scratch records would otherwise become permanent residue.",
23462
- "preferredWhen": "After any create on a resource the plan stamps with the delete boundary (metadata.deleteBoundary — the create dry run warns with it): the write succeeded but the vendor cannot undo it, and the id was lost or needs cleanup. Prefer finding by the marker the write itself stamped (deterministic) — never by guessing ids.",
23463
- "backingOperation": "operations.recovery",
23464
- "effect": "write",
23465
- "dryRunFirst": true,
23466
- "confirm": false,
23467
- "requiredArgs": [
23468
- "input"
23469
- ],
23470
- "tier": "extended",
23471
- "reachable": true,
23472
- "reach": "dedicated tool",
23473
- "reachReason": null,
23474
- "boundedAlternative": null
23475
- },
23476
22360
  {
23477
22361
  "operation": "operations.relationshipMap",
23478
22362
  "core": false,
@@ -23511,11 +22395,30 @@
23511
22395
  "reachReason": null,
23512
22396
  "boundedAlternative": null
23513
22397
  },
22398
+ {
22399
+ "operation": "operations.resolveStaff",
22400
+ "core": false,
22401
+ "tool": "autotask_resolve_staff",
22402
+ "purpose": "Resolve staff with tenant-labelled API-user exclusions and honest metadata state.",
22403
+ "preferredWhen": "Resolve an owner or technician by email, username or name; use numeric id for an exact Resource fetch regardless of active/licence status.",
22404
+ "backingOperation": "operations.resolveStaff",
22405
+ "effect": "read",
22406
+ "dryRunFirst": false,
22407
+ "confirm": false,
22408
+ "requiredArgs": [
22409
+ "identifier"
22410
+ ],
22411
+ "tier": "extended",
22412
+ "reachable": true,
22413
+ "reach": "dedicated tool",
22414
+ "reachReason": null,
22415
+ "boundedAlternative": null
22416
+ },
23514
22417
  {
23515
22418
  "operation": "operations.revenueRollup",
23516
22419
  "core": false,
23517
22420
  "tool": "autotask_revenue_rollup",
23518
- "purpose": "Total revenue grouped by account vertical, contract type, category, company, contract, month, billing-item kind, line of business, technician or billing code over an invoice-date window, in one budgeted call with totals, excluded buckets, a reconciliation and optional non-chargeable work.",
22421
+ "purpose": "Total revenue grouped by account vertical, contract type, company, contract, month or line of business over an invoice-date window, in one budgeted call with totals, excluded buckets, a reconciliation and optional non-chargeable work.",
23519
22422
  "preferredWhen": "For any revenue-by-dimension question over a period (by vertical, contract type, customer, month); instead of walking invoices and billing_items by hand or via operations.aggregate (which caps at 2,500 rows, drops groups past top and has no join)",
23520
22423
  "backingOperation": "operations.revenueRollup",
23521
22424
  "effect": "read",
@@ -23588,10 +22491,10 @@
23588
22491
  }
23589
22492
  ],
23590
22493
  "counts": {
23591
- "registryOperations": 1281,
22494
+ "registryOperations": 1224,
23592
22495
  "coreOperations": 10,
23593
- "catalogRows": 1281,
23594
- "withTool": 897,
22496
+ "catalogRows": 1224,
22497
+ "withTool": 840,
23595
22498
  "readModeOnly": 384,
23596
22499
  "neverExposed": 0,
23597
22500
  "metaTools": 5