node-autotask 0.44.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.
- package/CHANGELOG.md +28 -0
- package/MCP_TOOL_CATALOG.json +153 -1269
- package/MCP_TOOL_MANIFEST.md +28 -95
- package/MCP_TOOL_OVERRIDES.json +8 -62
- package/N8N_MCP_MANIFEST.json +118 -695
- package/N8N_MCP_MANIFEST.md +32 -52
- package/README.md +5 -10
- package/capabilities.json +23788 -31075
- package/dist/{base-CftidiyZ.d.cts → base-BVoYDlVA.d.cts} +2 -2
- package/dist/{base-CftidiyZ.d.ts → base-BVoYDlVA.d.ts} +2 -2
- package/dist/capabilities.cjs +2 -2
- package/dist/capabilities.js +1 -1
- package/dist/{chunk-N6IWPGHB.js → chunk-ASMCTZO2.js} +23787 -31074
- package/dist/{chunk-6WLGHKIU.cjs → chunk-DC3PY4EF.cjs} +1839 -1407
- package/dist/{chunk-BKTOMNT2.js → chunk-DXKXQHCX.js} +5 -5
- package/dist/{chunk-KWQSGWY5.cjs → chunk-JO6WI763.cjs} +143 -143
- package/dist/{chunk-LYI5FRPX.js → chunk-NSW7JPVS.js} +11544 -13365
- package/dist/{chunk-7MCKJTSA.js → chunk-O4PIPUS4.js} +1583 -1151
- package/dist/{chunk-PH3ESYAF.cjs → chunk-VXVYFJH3.cjs} +23787 -31074
- package/dist/{chunk-EMYDC5SG.cjs → chunk-YMBVKVK4.cjs} +6123 -7944
- package/dist/{index-YbEk0awP.d.cts → index-C5g1H_hF.d.ts} +1194 -1415
- package/dist/{index-D8FtzUGP.d.ts → index-Db0SNnQn.d.cts} +1194 -1415
- package/dist/{index-DgBA1JMH.d.cts → index-c549LvOb.d.cts} +188 -188
- package/dist/{index-DgBA1JMH.d.ts → index-c549LvOb.d.ts} +188 -188
- package/dist/index.cjs +22 -22
- package/dist/index.d.cts +15 -42
- package/dist/index.d.ts +15 -42
- package/dist/index.js +7 -7
- package/dist/operations/index.cjs +5 -2327
- package/dist/operations/index.d.cts +7 -287
- package/dist/operations/index.d.ts +7 -287
- package/dist/operations/index.js +29 -2351
- package/dist/pool.cjs +8 -8
- package/dist/pool.d.cts +1 -1
- package/dist/pool.d.ts +1 -1
- package/dist/pool.js +4 -4
- package/dist/resources/index.cjs +4 -4
- package/dist/resources/index.d.cts +2 -2
- package/dist/resources/index.d.ts +2 -2
- package/dist/resources/index.js +7 -7
- package/dist/types/index.d.cts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/docs/API.md +201 -303
- package/docs/LIVE-TESTING.md +4 -6
- package/docs/N8N-ADAPTER.md +26 -26
- package/n8n-mcp.curation.json +3 -3
- package/package.json +1 -1
package/N8N_MCP_MANIFEST.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# N8N MCP Manifest — node-autotask (consumer projection)
|
|
2
2
|
|
|
3
|
-
<!-- GENERATED by scripts/project-n8n-mcp.mjs at 2026-11-
|
|
3
|
+
<!-- GENERATED by scripts/project-n8n-mcp.mjs at 2026-11-01T10:43:53.479Z — do not hand-edit. -->
|
|
4
4
|
|
|
5
5
|
The n8n CONSUMER projection of the capability registry: the canonical source for what the
|
|
6
6
|
n8n-side MCP tools must expose. The SDK is canonical — this is a projection of it, never a
|
|
@@ -24,19 +24,19 @@ user's n8n instances; PROD is read-only for any verification).
|
|
|
24
24
|
| tool | mode | entity | readOnlyHint | destructiveHint | idempotentHint | openWorldHint | operations |
|
|
25
25
|
|------|------|--------|--------------|-----------------|----------------|---------------|------------|
|
|
26
26
|
| `autotask_ticket` | read | ticket | true | false | true | true | 17 |
|
|
27
|
-
| `autotask_ticket_write` | write | ticket | false | false | false | true |
|
|
28
|
-
| `autotask_contact` | read | contact | true | false | true | true |
|
|
29
|
-
| `autotask_contact_write` | write | contact | false | false | false | true |
|
|
27
|
+
| `autotask_ticket_write` | write | ticket | false | false | false | true | 3 |
|
|
28
|
+
| `autotask_contact` | read | contact | true | false | true | true | 11 |
|
|
29
|
+
| `autotask_contact_write` | write | contact | false | false | false | true | 3 |
|
|
30
30
|
| `autotask_company` | read | company | true | false | true | true | 14 |
|
|
31
|
-
| `autotask_company_write` | write | company | false | false | false | true |
|
|
31
|
+
| `autotask_company_write` | write | company | false | false | false | true | 2 |
|
|
32
32
|
| `autotask_companyLocation` | read | companyLocation | true | false | true | true | 8 |
|
|
33
33
|
| `autotask_companyLocation_write` | write | companyLocation | false | false | false | true | 2 |
|
|
34
34
|
| `autotask_ticketNote` | read | ticketNote | true | false | true | true | 7 |
|
|
35
35
|
| `autotask_ticketNote_write` | write | ticketNote | false | false | false | true | 2 |
|
|
36
|
-
| `autotask_resource` | read | resource | true | false | true | true |
|
|
37
|
-
| `autotask_resource_write` | write | resource | false | false |
|
|
38
|
-
| `autotask_timeEntry` | read | timeEntry | true | false | true | true |
|
|
39
|
-
| `autotask_timeEntry_write` | write | timeEntry | false | false | false | true |
|
|
36
|
+
| `autotask_resource` | read | resource | true | false | true | true | 10 |
|
|
37
|
+
| `autotask_resource_write` | write | resource | false | false | true | true | 1 |
|
|
38
|
+
| `autotask_timeEntry` | read | timeEntry | true | false | true | true | 8 |
|
|
39
|
+
| `autotask_timeEntry_write` | write | timeEntry | false | false | false | true | 2 |
|
|
40
40
|
|
|
41
41
|
### `autotask_ticket` (read — ticket)
|
|
42
42
|
|
|
@@ -64,25 +64,25 @@ user's n8n instances; PROD is read-only for any verification).
|
|
|
64
64
|
|
|
65
65
|
### `autotask_ticket_write` (write — ticket)
|
|
66
66
|
|
|
67
|
-
> Write ticket records (mode: write — the registry operations with effect=write for tickets: changeStatus, create,
|
|
67
|
+
> Write ticket records (mode: write — the registry operations with effect=write for tickets: changeStatus, create, update). Writes are dry-run first: dry_run defaults to true — the request is validated against the registry inputSchema and a DryRunResult envelope is returned; the mutating request is never issued unless the caller passes confirm (the n8n-side handler must force dry-run unless confirm is present, mirroring the SDK governor). Destructive operations are refused without the confirm flag — confirm must equal the operation key exactly (the deliberate act is the call). The n8n consumer surface excludes destructive operations by curation default (excludeDestructive); they remain available on the canonical SDK server (autotask_delete / per-op tools). By curation default (excludeDestructive) no destructive operation is included; destructive capability remains on the canonical SDK server surface. Per-operation required arguments: changeStatus [id, targetStatus]; create [data]; update [id, data]. Errors carry the SDK error contract: code, category, retryable, operation, httpStatus, suggestedAction (the nextAction directive — follow the directive), correlationId, vendorError (when the vendor returned a response body — the deep-redacted body, host-sourced text wrapped as untrusted content when untrusted-wrapping is on); credentials never appear in an error message.
|
|
68
68
|
|
|
69
|
-
Tool input: {"operation":{"type":"string","enum":["changeStatus","create","
|
|
69
|
+
Tool input: {"operation":{"type":"string","enum":["changeStatus","create","update"]},"id":{"type":"number | string (the ticket id — a safe integer, or a canonical integer string for ids above 2^53)"},"targetStatus":{"type":"number (validated pre-request against the tenant's LIVE status picklist from the entity metadata when it is resolvable — a value the live picklist lacks → typed STATUS_UNKNOWN; when the metadata is unavailable the vendor's own validation decides)"},"fields":{"type":"object (optional) — extra ticket fields merged into the same PUT (the caller value wins over the node map defaults; the merge keeps every other current field)"},"data":{"type":"object","ref":"tickets body (see types)"},"dry_run":{"type":"boolean","default":true,"note":"true (the default) = the pinned DryRunResult envelope; the mutating request is never issued. The handler must force dry-run unless confirm is present."},"confirm":{"type":"string","note":"The operation key (e.g. \"tickets.create\") — its presence lifts the dry run. For destructive/approval-gated operations confirm must equal the operation key exactly; the call is refused pre-request without it."}} (required: operation)
|
|
70
70
|
|
|
71
71
|
| backingOperation | verb | effect | flags | requiredArgs | purpose |
|
|
72
72
|
|------------------|------|--------|-------|--------------|---------|
|
|
73
73
|
| `tickets.changeStatus` | changeStatus | write | — | id, targetStatus | Move a ticket to a target status in ONE op — the node validates targetStatus against the tenant's LIVE status picklist (entity metadata; vendor rejection is the fallback when the metadata is unavailable) + the live-discovered per-status required-field map and fills the proven-safe defaults itself (the vendor 500s when a target status has unsatisfied field requirements; the MCP LLM has no way to know the map). Dry-run first (dry_run). |
|
|
74
74
|
| `tickets.create` | create | write | — | data | Create a ticket. Dry-run first (dry_run). |
|
|
75
|
-
| `tickets.openWithNoteAndAssign` | openWithNoteAndAssign | write | — | params | 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). Dry-run first (dry_run). |
|
|
76
75
|
| `tickets.update` | update | write | idempotent | id, data | Update a ticket. Dry-run first (dry_run). Idempotent. |
|
|
77
76
|
|
|
78
77
|
### `autotask_contact` (read — contact)
|
|
79
78
|
|
|
80
|
-
> Read contact records (mode: read — effect=read operations only; zero mutating requests, ungated by design). Registry operations for contacts: count: Count contact records matching a JSON filter. (under a company) | findByEmail: Find a contact by email address. | get: Get one Contact by id. | getContext: Get a contact with its primary context records in one call. (under a company) | getEntityInfo: Get the Contact capability metadata (canCreate/canUpdate/hasUserDefinedFields/...). | getFieldInfo: Get the Contact field catalog (types, picklists, required, maxLength) — the full raw field dump (the largest read of the info trio; compact discovery: operations.fieldCatalog). | getUdfInfo: Get the Contact user-defined-field catalog. | query: Query Contact records with a JSON filter. | resolve: Resolve a Contact from a numeric id (the direct fetch, tried first) or an exact value of its primary text field(s) (firstName + lastName — exact match only). Returns the Contact record with the numeric id for get/update/delete. Other identifier forms (e.g. an email address) are NOT tried by resolve — use the resource's dedicated lookup op where one exists (see autotask_catalog). | search: Search contact records by text (contains on the searchable fields). (under a company). Bounds: Sensitive. Bounded: server-side pagination — ordinary limit default 500, max 2500; walk.maxRows independently sets the total cap, with pages at most min(500, limit); 1000-page guard; hasMore/truncated flag remaining rows. Sensitive. Bounded: limit default 25, max 500. Sensitive. Errors carry the SDK error contract: code, category, retryable, operation, httpStatus, suggestedAction (the nextAction directive — follow the directive), correlationId, vendorError (when the vendor returned a response body — the deep-redacted body, host-sourced text wrapped as untrusted content when untrusted-wrapping is on); credentials never appear in an error message.
|
|
79
|
+
> Read contact records (mode: read — effect=read operations only; zero mutating requests, ungated by design). Registry operations for contacts: count: Count contact records matching a JSON filter. (under a company) | findByEmail: Find a contact by email address. | fullProfile: 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. | get: Get one Contact by id. | getContext: Get a contact with its primary context records in one call. (under a company) | getEntityInfo: Get the Contact capability metadata (canCreate/canUpdate/hasUserDefinedFields/...). | getFieldInfo: Get the Contact field catalog (types, picklists, required, maxLength) — the full raw field dump (the largest read of the info trio; compact discovery: operations.fieldCatalog). | getUdfInfo: Get the Contact user-defined-field catalog. | query: Query Contact records with a JSON filter. | resolve: Resolve a Contact from a numeric id (the direct fetch, tried first) or an exact value of its primary text field(s) (firstName + lastName — exact match only). Returns the Contact record with the numeric id for get/update/delete. Other identifier forms (e.g. an email address) are NOT tried by resolve — use the resource's dedicated lookup op where one exists (see autotask_catalog). | search: Search contact records by text (contains on the searchable fields). (under a company). Bounds: Sensitive. Bounded: server-side pagination — ordinary limit default 500, max 2500; walk.maxRows independently sets the total cap, with pages at most min(500, limit); 1000-page guard; hasMore/truncated flag remaining rows. Sensitive. Bounded: limit default 25, max 500. Sensitive. Errors carry the SDK error contract: code, category, retryable, operation, httpStatus, suggestedAction (the nextAction directive — follow the directive), correlationId, vendorError (when the vendor returned a response body — the deep-redacted body, host-sourced text wrapped as untrusted content when untrusted-wrapping is on); credentials never appear in an error message.
|
|
81
80
|
|
|
82
81
|
| backingOperation | verb | effect | flags | requiredArgs | purpose |
|
|
83
82
|
|------------------|------|--------|-------|--------------|---------|
|
|
84
83
|
| `contacts.count` | count | read | sensitive | none | Count contact records matching a JSON filter. (under a company) Sensitive. |
|
|
85
84
|
| `contacts.findByEmail` | findByEmail | read | sensitive | value | Find a contact by email address. Sensitive. |
|
|
85
|
+
| `contacts.fullProfile` | fullProfile | read | — | id | 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. |
|
|
86
86
|
| `contacts.get` | get | read | sensitive | parentId, id | Get one Contact by id. Sensitive. |
|
|
87
87
|
| `contacts.getContext` | getContext | read | sensitive | id | Get a contact with its primary context records in one call. (under a company) Sensitive. |
|
|
88
88
|
| `contacts.getEntityInfo` | getEntityInfo | read | sensitive | none | Get the Contact capability metadata (canCreate/canUpdate/hasUserDefinedFields/...). Sensitive. |
|
|
@@ -94,16 +94,15 @@ Tool input: {"operation":{"type":"string","enum":["changeStatus","create","openW
|
|
|
94
94
|
|
|
95
95
|
### `autotask_contact_write` (write — contact)
|
|
96
96
|
|
|
97
|
-
> Write contact records (mode: write — the registry operations with effect=write for contacts: create, moveToCompany, update
|
|
97
|
+
> Write contact records (mode: write — the registry operations with effect=write for contacts: create, moveToCompany, update). Writes are dry-run first: dry_run defaults to true — the request is validated against the registry inputSchema and a DryRunResult envelope is returned; the mutating request is never issued unless the caller passes confirm (the n8n-side handler must force dry-run unless confirm is present, mirroring the SDK governor). Destructive operations are refused without the confirm flag — confirm must equal the operation key exactly (the deliberate act is the call). The n8n consumer surface excludes destructive operations by curation default (excludeDestructive); they remain available on the canonical SDK server (autotask_delete / per-op tools). By curation default (excludeDestructive) no destructive operation is included; destructive capability remains on the canonical SDK server surface. Approval-gated operations (contacts.moveToCompany) additionally require confirm equal to the operation key. Per-operation required arguments: create [parentId, data]; moveToCompany [sourceContactId, destinationCompanyId]; update [parentId, id, data]. Errors carry the SDK error contract: code, category, retryable, operation, httpStatus, suggestedAction (the nextAction directive — follow the directive), correlationId, vendorError (when the vendor returned a response body — the deep-redacted body, host-sourced text wrapped as untrusted content when untrusted-wrapping is on); credentials never appear in an error message.
|
|
98
98
|
|
|
99
|
-
Tool input: {"operation":{"type":"string","enum":["create","moveToCompany","update"
|
|
99
|
+
Tool input: {"operation":{"type":"string","enum":["create","moveToCompany","update"]},"parentId":{"type":"number | string"},"data":{"type":"object","ref":"contacts body (see types)"},"sourceContactId":{"type":"number | string"},"destinationCompanyId":{"type":"number | string"},"id":{"type":"number | string"},"dry_run":{"type":"boolean","default":true,"note":"true (the default) = the pinned DryRunResult envelope; the mutating request is never issued. The handler must force dry-run unless confirm is present."},"confirm":{"type":"string","note":"The operation key (e.g. \"tickets.create\") — its presence lifts the dry run. For destructive/approval-gated operations confirm must equal the operation key exactly; the call is refused pre-request without it."}} (required: operation)
|
|
100
100
|
|
|
101
101
|
| backingOperation | verb | effect | flags | requiredArgs | purpose |
|
|
102
102
|
|------------------|------|--------|-------|--------------|---------|
|
|
103
103
|
| `contacts.create` | create | write | — | parentId, data | Create a contact. (under a company) Dry-run first (dry_run). |
|
|
104
104
|
| `contacts.moveToCompany` | moveToCompany | write | requiresApproval+sensitive | sourceContactId, destinationCompanyId | Move a contact to a different company. Dry-run first (dry_run). Requires confirmation (confirm: contacts.moveToCompany). Sensitive. |
|
|
105
105
|
| `contacts.update` | update | write | idempotent | parentId, id, data | Update a contact. (under a company) Dry-run first (dry_run). Idempotent. |
|
|
106
|
-
| `contacts.upsertByEmail` | upsertByEmail | write | — | companyID, email | 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). Dry-run first (dry_run). |
|
|
107
106
|
|
|
108
107
|
### `autotask_company` (read — company)
|
|
109
108
|
|
|
@@ -128,15 +127,14 @@ Tool input: {"operation":{"type":"string","enum":["create","moveToCompany","upda
|
|
|
128
127
|
|
|
129
128
|
### `autotask_company_write` (write — company)
|
|
130
129
|
|
|
131
|
-
> Write company records (mode: write — the registry operations with effect=write for companies: create, update
|
|
130
|
+
> Write company records (mode: write — the registry operations with effect=write for companies: create, update). Writes are dry-run first: dry_run defaults to true — the request is validated against the registry inputSchema and a DryRunResult envelope is returned; the mutating request is never issued unless the caller passes confirm (the n8n-side handler must force dry-run unless confirm is present, mirroring the SDK governor). Destructive operations are refused without the confirm flag — confirm must equal the operation key exactly (the deliberate act is the call). The n8n consumer surface excludes destructive operations by curation default (excludeDestructive); they remain available on the canonical SDK server (autotask_delete / per-op tools). By curation default (excludeDestructive) no destructive operation is included; destructive capability remains on the canonical SDK server surface. Per-operation required arguments: create [data]; update [id, data]. Errors carry the SDK error contract: code, category, retryable, operation, httpStatus, suggestedAction (the nextAction directive — follow the directive), correlationId, vendorError (when the vendor returned a response body — the deep-redacted body, host-sourced text wrapped as untrusted content when untrusted-wrapping is on); credentials never appear in an error message.
|
|
132
131
|
|
|
133
|
-
Tool input: {"operation":{"type":"string","enum":["create","update"
|
|
132
|
+
Tool input: {"operation":{"type":"string","enum":["create","update"]},"data":{"type":"object","ref":"companies body (see types)"},"id":{"type":"number | string"},"dry_run":{"type":"boolean","default":true,"note":"true (the default) = the pinned DryRunResult envelope; the mutating request is never issued. The handler must force dry-run unless confirm is present."},"confirm":{"type":"string","note":"The operation key (e.g. \"tickets.create\") — its presence lifts the dry run. For destructive/approval-gated operations confirm must equal the operation key exactly; the call is refused pre-request without it."}} (required: operation)
|
|
134
133
|
|
|
135
134
|
| backingOperation | verb | effect | flags | requiredArgs | purpose |
|
|
136
135
|
|------------------|------|--------|-------|--------------|---------|
|
|
137
136
|
| `companies.create` | create | write | — | data | Create a company. Dry-run first (dry_run). |
|
|
138
137
|
| `companies.update` | update | write | idempotent | id, data | Update a company. Dry-run first (dry_run). Idempotent. |
|
|
139
|
-
| `companies.upsertByName` | upsertByName | write | — | companyName, params | 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. Dry-run first (dry_run). |
|
|
140
138
|
|
|
141
139
|
### `autotask_companyLocation` (read — companyLocation)
|
|
142
140
|
|
|
@@ -191,7 +189,7 @@ Tool input: {"operation":{"type":"string","enum":["create","update"]},"parentId"
|
|
|
191
189
|
|
|
192
190
|
### `autotask_resource` (read — resource)
|
|
193
191
|
|
|
194
|
-
> Read resource records (mode: read — effect=read operations only; zero mutating requests, ungated by design). Registry operations for resources: count: Count resource records matching a JSON filter. | get: Get one Resource by id. | getEntityInfo: Get the Resource capability metadata (canCreate/canUpdate/hasUserDefinedFields/...). | getFieldInfo: Get the Resource field catalog (types, picklists, required, maxLength) — the full raw field dump (the largest read of the info trio; compact discovery: operations.fieldCatalog). | getUdfInfo: Get the Resource user-defined-field catalog. | query: Query Resource records with a JSON filter. | resolve: Resolve a resource from a numeric id (the direct fetch, tried first) or an exact value of its primary text field(s) (firstName + lastName — exact match only). Returns the Resource record with the numeric id for get/update/delete. Other identifier forms (e.g. an email address) are NOT tried by resolve — use the resource's dedicated lookup op where one exists (see autotask_catalog). | search: Search resource records by text (contains on the searchable fields). | whoAmI: Identify the resource the current credentials act as.. Bounds: Sensitive. Bounded: server-side pagination — ordinary limit default 500, max 2500; walk.maxRows independently sets the total cap, with pages at most min(500, limit); 1000-page guard; hasMore/truncated flag remaining rows. Sensitive. Bounded: limit default 25, max 500. Sensitive. Errors carry the SDK error contract: code, category, retryable, operation, httpStatus, suggestedAction (the nextAction directive — follow the directive), correlationId, vendorError (when the vendor returned a response body — the deep-redacted body, host-sourced text wrapped as untrusted content when untrusted-wrapping is on); credentials never appear in an error message.
|
|
192
|
+
> Read resource records (mode: read — effect=read operations only; zero mutating requests, ungated by design). Registry operations for resources: count: Count resource records matching a JSON filter. | get: Get one Resource by id. | getEntityInfo: Get the Resource capability metadata (canCreate/canUpdate/hasUserDefinedFields/...). | getFieldInfo: Get the Resource field catalog (types, picklists, required, maxLength) — the full raw field dump (the largest read of the info trio; compact discovery: operations.fieldCatalog). | getUdfInfo: Get the Resource user-defined-field catalog. | query: Query Resource records with a JSON filter. | resolve: Resolve a resource from a numeric id (the direct fetch, tried first) or an exact value of its primary text field(s) (firstName + lastName — exact match only). Returns the Resource record with the numeric id for get/update/delete. Other identifier forms (e.g. an email address) are NOT tried by resolve — use the resource's dedicated lookup op where one exists (see autotask_catalog). | search: Search resource records by text (contains on the searchable fields). | whoAmI: Identify the resource the current credentials act as. | workload: 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.. Bounds: Sensitive. Bounded: server-side pagination — ordinary limit default 500, max 2500; walk.maxRows independently sets the total cap, with pages at most min(500, limit); 1000-page guard; hasMore/truncated flag remaining rows. Sensitive. Bounded: limit default 25, max 500. Sensitive. Errors carry the SDK error contract: code, category, retryable, operation, httpStatus, suggestedAction (the nextAction directive — follow the directive), correlationId, vendorError (when the vendor returned a response body — the deep-redacted body, host-sourced text wrapped as untrusted content when untrusted-wrapping is on); credentials never appear in an error message.
|
|
195
193
|
|
|
196
194
|
| backingOperation | verb | effect | flags | requiredArgs | purpose |
|
|
197
195
|
|------------------|------|--------|-------|--------------|---------|
|
|
@@ -204,60 +202,42 @@ Tool input: {"operation":{"type":"string","enum":["create","update"]},"parentId"
|
|
|
204
202
|
| `resources.resolve` | resolve | read | sensitive | identifier | Resolve a resource from a numeric id (the direct fetch, tried first) or an exact value of its primary text field(s) (firstName + lastName — exact match only). Returns the Resource record with the numeric id for get/update/delete. Other identifier forms (e.g. an email address) are NOT tried by resolve — use the resource's dedicated lookup op where one exists (see autotask_catalog). Sensitive. |
|
|
205
203
|
| `resources.search` | search | read | sensitive | query | Search resource records by text (contains on the searchable fields). Bounded: limit default 25, max 500. Sensitive. |
|
|
206
204
|
| `resources.whoAmI` | whoAmI | read | sensitive | none | Identify the resource the current credentials act as. Sensitive. |
|
|
205
|
+
| `resources.workload` | workload | read | — | id | 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. |
|
|
207
206
|
|
|
208
207
|
### `autotask_resource_write` (write — resource)
|
|
209
208
|
|
|
210
|
-
> Write resource records (mode: write — the registry operations with effect=write for resources:
|
|
209
|
+
> Write resource records (mode: write — the registry operations with effect=write for resources: update). Writes are dry-run first: dry_run defaults to true — the request is validated against the registry inputSchema and a DryRunResult envelope is returned; the mutating request is never issued unless the caller passes confirm (the n8n-side handler must force dry-run unless confirm is present, mirroring the SDK governor). Destructive operations are refused without the confirm flag — confirm must equal the operation key exactly (the deliberate act is the call). The n8n consumer surface excludes destructive operations by curation default (excludeDestructive); they remain available on the canonical SDK server (autotask_delete / per-op tools). By curation default (excludeDestructive) no destructive operation is included; destructive capability remains on the canonical SDK server surface. Per-operation required arguments: update [id, data]. Errors carry the SDK error contract: code, category, retryable, operation, httpStatus, suggestedAction (the nextAction directive — follow the directive), correlationId, vendorError (when the vendor returned a response body — the deep-redacted body, host-sourced text wrapped as untrusted content when untrusted-wrapping is on); credentials never appear in an error message.
|
|
211
210
|
|
|
212
|
-
Tool input: {"operation":{"type":"string","enum":["
|
|
211
|
+
Tool input: {"operation":{"type":"string","enum":["update"]},"id":{"type":"number | string"},"data":{"type":"object","ref":"resources body (see types)"},"dry_run":{"type":"boolean","default":true,"note":"true (the default) = the pinned DryRunResult envelope; the mutating request is never issued. The handler must force dry-run unless confirm is present."},"confirm":{"type":"string","note":"The operation key (e.g. \"tickets.create\") — its presence lifts the dry run. For destructive/approval-gated operations confirm must equal the operation key exactly; the call is refused pre-request without it."}} (required: operation)
|
|
213
212
|
|
|
214
213
|
| backingOperation | verb | effect | flags | requiredArgs | purpose |
|
|
215
214
|
|------------------|------|--------|-------|--------------|---------|
|
|
216
|
-
| `resources.transferOwnership` | transferOwnership | write | requiresApproval+sensitive | sourceResourceIds, destinationResourceId | Transfer ownership of named resources to another resource. Dry-run first (dry_run). Requires confirmation (confirm: resources.transferOwnership). Sensitive. |
|
|
217
215
|
| `resources.update` | update | write | idempotent+sensitive | id, data | Update a resource. Dry-run first (dry_run). Idempotent. Sensitive. |
|
|
218
216
|
|
|
219
217
|
### `autotask_timeEntry` (read — timeEntry)
|
|
220
218
|
|
|
221
|
-
> Read timeEntry records (mode: read — effect=read operations only; zero mutating requests, ungated by design). Registry operations for time_entries: count: Count time entry records matching a JSON filter. |
|
|
219
|
+
> Read timeEntry records (mode: read — effect=read operations only; zero mutating requests, ungated by design). Registry operations for time_entries: count: Count time entry records matching a JSON filter. | dateWorkedWindow: 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. | get: Get one TimeEntry by id. | getEntityInfo: Get the TimeEntry capability metadata (canCreate/canUpdate/hasUserDefinedFields/...). | getFieldInfo: Get the TimeEntry field catalog (types, picklists, required, maxLength) — the full raw field dump (the largest read of the info trio; compact discovery: operations.fieldCatalog). | getUdfInfo: Get the TimeEntry user-defined-field catalog. | query: Query TimeEntry records with a JSON filter. | resolve: Resolve a time entry from a numeric id (the direct fetch) only — this resource has no searchable text field, so a non-numeric identifier throws a config error.. Bounds: Bounded: server-side pagination — ordinary limit default 500, max 2500; walk.maxRows independently sets the total cap, with pages at most min(500, limit); 1000-page guard; hasMore/truncated flag remaining rows. Errors carry the SDK error contract: code, category, retryable, operation, httpStatus, suggestedAction (the nextAction directive — follow the directive), correlationId, vendorError (when the vendor returned a response body — the deep-redacted body, host-sourced text wrapped as untrusted content when untrusted-wrapping is on); credentials never appear in an error message.
|
|
222
220
|
|
|
223
221
|
| backingOperation | verb | effect | flags | requiredArgs | purpose |
|
|
224
222
|
|------------------|------|--------|-------|--------------|---------|
|
|
225
223
|
| `time_entries.count` | count | read | — | none | Count time entry records matching a JSON filter. |
|
|
226
|
-
| `time_entries.
|
|
227
|
-
| `time_entries.dateWorkedWindow` | dateWorkedWindow | read | — | from, to | 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). |
|
|
224
|
+
| `time_entries.dateWorkedWindow` | dateWorkedWindow | read | — | from, to | 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. |
|
|
228
225
|
| `time_entries.get` | get | read | — | id | Get one TimeEntry by id. |
|
|
229
226
|
| `time_entries.getEntityInfo` | getEntityInfo | read | — | none | Get the TimeEntry capability metadata (canCreate/canUpdate/hasUserDefinedFields/...). |
|
|
230
227
|
| `time_entries.getFieldInfo` | getFieldInfo | read | — | none | Get the TimeEntry field catalog (types, picklists, required, maxLength) — the full raw field dump (the largest read of the info trio; compact discovery: operations.fieldCatalog). |
|
|
231
|
-
| `time_entries.getPosted` | getPosted | read | — | none | 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. |
|
|
232
228
|
| `time_entries.getUdfInfo` | getUdfInfo | read | — | none | Get the TimeEntry user-defined-field catalog. |
|
|
233
|
-
| `time_entries.getUnposted` | getUnposted | read | — | none | 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. |
|
|
234
|
-
| `time_entries.last14` | last14 | read | — | none | Get time entries for the last 14 days (rolling, dateWorked). |
|
|
235
|
-
| `time_entries.last24h` | last24h | read | — | none | Get time entries for the last 24 hours (rolling, dateWorked). |
|
|
236
|
-
| `time_entries.last30` | last30 | read | — | none | Get time entries for the last 30 days (rolling, dateWorked). |
|
|
237
|
-
| `time_entries.last7` | last7 | read | — | none | Get time entries for the last 7 days (rolling, dateWorked). |
|
|
238
|
-
| `time_entries.last90` | last90 | read | — | none | Get time entries for the last 90 days (rolling, dateWorked). |
|
|
239
|
-
| `time_entries.lastFullFortnight` | lastFullFortnight | read | — | none | Get time entries for the last complete fortnight. |
|
|
240
|
-
| `time_entries.lastFullMonth` | lastFullMonth | read | — | none | Get time entries for the last complete calendar month. |
|
|
241
|
-
| `time_entries.lastFullQuarter` | lastFullQuarter | read | — | none | Get time entries for the last complete calendar quarter. |
|
|
242
|
-
| `time_entries.lastFullWeek` | lastFullWeek | read | — | none | Get time entries for the last complete calendar week. |
|
|
243
|
-
| `time_entries.postedWithin` | postedWithin | read | — | from, to | 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. |
|
|
244
229
|
| `time_entries.query` | query | read | — | none | Query TimeEntry records with a JSON filter. Bounded: server-side pagination — ordinary limit default 500, max 2500; walk.maxRows independently sets the total cap, with pages at most min(500, limit); 1000-page guard; hasMore/truncated flag remaining rows. |
|
|
245
230
|
| `time_entries.resolve` | resolve | read | — | identifier | Resolve a time entry from a numeric id (the direct fetch) only — this resource has no searchable text field, so a non-numeric identifier throws a config error. |
|
|
246
|
-
| `time_entries.today` | today | read | — | none | Get time entries for today (dateWorked = now, server date). |
|
|
247
|
-
| `time_entries.yesterday` | yesterday | read | — | none | Get time entries for yesterday (dateWorked = yesterday, server date). |
|
|
248
231
|
|
|
249
232
|
### `autotask_timeEntry_write` (write — timeEntry)
|
|
250
233
|
|
|
251
|
-
> Write timeEntry records (mode: write — the registry operations with effect=write for time_entries:
|
|
234
|
+
> Write timeEntry records (mode: write — the registry operations with effect=write for time_entries: create, update). Writes are dry-run first: dry_run defaults to true — the request is validated against the registry inputSchema and a DryRunResult envelope is returned; the mutating request is never issued unless the caller passes confirm (the n8n-side handler must force dry-run unless confirm is present, mirroring the SDK governor). Destructive operations are refused without the confirm flag — confirm must equal the operation key exactly (the deliberate act is the call). The n8n consumer surface excludes destructive operations by curation default (excludeDestructive); they remain available on the canonical SDK server (autotask_delete / per-op tools). By curation default (excludeDestructive) no destructive operation is included; destructive capability remains on the canonical SDK server surface. Per-operation required arguments: create [data]; update [id, data]. Errors carry the SDK error contract: code, category, retryable, operation, httpStatus, suggestedAction (the nextAction directive — follow the directive), correlationId, vendorError (when the vendor returned a response body — the deep-redacted body, host-sourced text wrapped as untrusted content when untrusted-wrapping is on); credentials never appear in an error message.
|
|
252
235
|
|
|
253
|
-
Tool input: {"operation":{"type":"string","enum":["
|
|
236
|
+
Tool input: {"operation":{"type":"string","enum":["create","update"]},"data":{"type":"object","ref":"time_entries body (see types)"},"id":{"type":"number | string"},"dry_run":{"type":"boolean","default":true,"note":"true (the default) = the pinned DryRunResult envelope; the mutating request is never issued. The handler must force dry-run unless confirm is present."},"confirm":{"type":"string","note":"The operation key (e.g. \"tickets.create\") — its presence lifts the dry run. For destructive/approval-gated operations confirm must equal the operation key exactly; the call is refused pre-request without it."}} (required: operation)
|
|
254
237
|
|
|
255
238
|
| backingOperation | verb | effect | flags | requiredArgs | purpose |
|
|
256
239
|
|------------------|------|--------|-------|--------------|---------|
|
|
257
|
-
| `time_entries.approve` | approve | write | — | id | 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. Dry-run first (dry_run). |
|
|
258
240
|
| `time_entries.create` | create | write | — | data | Create a time entry. Dry-run first (dry_run). |
|
|
259
|
-
| `time_entries.createForResource` | createForResource | write | — | resourceID, params | 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. Dry-run first (dry_run). |
|
|
260
|
-
| `time_entries.createIfNotExists` | createIfNotExists | write | — | data | Create a TimeEntry. Dry-run first (dry_run). |
|
|
261
241
|
| `time_entries.update` | update | write | idempotent | id, data | Update a time entry. Dry-run first (dry_run). Idempotent. |
|
|
262
242
|
|
|
263
243
|
## Destructive operations — excluded by default, available via the SDK server (P2 honesty)
|
|
@@ -275,19 +255,19 @@ only via a recorded change to `n8n-mcp.curation.json`.
|
|
|
275
255
|
|
|
276
256
|
## Stats
|
|
277
257
|
|
|
278
|
-
- registryRecords:
|
|
258
|
+
- registryRecords: 1224
|
|
279
259
|
- curatedEntities: 7
|
|
280
260
|
- includedEntities: 7
|
|
281
261
|
- readTools: 7
|
|
282
262
|
- writeTools: 7
|
|
283
263
|
- totalTools: 14
|
|
284
|
-
- readOperations:
|
|
285
|
-
- writeOperations:
|
|
286
|
-
- approvalGatedWrites:
|
|
264
|
+
- readOperations: 75
|
|
265
|
+
- writeOperations: 15
|
|
266
|
+
- approvalGatedWrites: 1
|
|
287
267
|
- destructiveExcluded: 4
|
|
288
268
|
|
|
289
269
|
## Meta
|
|
290
270
|
|
|
291
|
-
- generatedAt: 2026-11-
|
|
292
|
-
- capabilitiesHash:
|
|
293
|
-
- curationHash:
|
|
271
|
+
- generatedAt: 2026-11-01T10:43:53.479Z
|
|
272
|
+
- capabilitiesHash: 729ea0d47099fd45e1dde837510a92bd566a793368d0a4882e2613cbe05f7594
|
|
273
|
+
- curationHash: 623fbca25fa416f983dde22c8b736ce813a2db1bd8c188f7124abba710f52452
|
package/README.md
CHANGED
|
@@ -343,9 +343,8 @@ The SDK ships the mechanical substrate, not a server (no MCP imports, no zod):
|
|
|
343
343
|
governor place: `src/operations/invoke.ts`).
|
|
344
344
|
|
|
345
345
|
<!-- BEGIN GENERATED:approval-policy -->
|
|
346
|
-
**Harness approval policy (recommended).** Require approval on every tool whose MCP annotation is `readOnlyHint !== true` — today exactly **
|
|
346
|
+
**Harness approval policy (recommended).** Require approval on every tool whose MCP annotation is `readOnlyHint !== true` — today exactly **246 tools**: the 244 dedicated write/delete tools (188 `effect=write` + 56 `effect=destructive`, every one of them has a dedicated tool) + `autotask_write` + `autotask_delete`. The remaining **599 tools** (the 586 dedicated read tools + the 10 core read tools + `autotask_read` + `autotask_catalog` + `autotask_describe`) all carry `readOnlyHint: true` and are safe ungated: every op they can route is `effect=read` (zero mutating requests). Refined class for the highest-risk ops: the **57 tools with `destructiveHint: true`** (56 dedicated delete tools + `autotask_delete`) additionally require `confirm === <operation key>` even inside `autotask_delete`. The approval-gated writes (`configuration_items.moveConfigurationItem`, `contacts.moveToCompany`) require the same confirm inside `autotask_write`. Migration: `autotask_invoke` is REPLACED by `autotask_read`/`autotask_write`/`autotask_delete` — update harness config and remove any `autotask_invoke` entry. The rule is derivable from the registry `effect` column and the mode tools’ fixed annotations; it never needs a hand-maintained name list.
|
|
347
347
|
<!-- END GENERATED:approval-policy -->
|
|
348
|
-
|
|
349
348
|
**Provider tool-search interop.** Hosts with provider-native tool search
|
|
350
349
|
(OpenAI `type: "tool_search"` / `defer_loading`; Anthropic's tool search
|
|
351
350
|
tool) defer-load tool arrays host-side. Two coexistences, both already
|
|
@@ -404,12 +403,8 @@ The SDK ships the mechanical substrate, not a server (no MCP imports, no zod):
|
|
|
404
403
|
source.
|
|
405
404
|
|
|
406
405
|
7. **Agent QoL surface (the stage-12 issue wave, live-verified on ww29)** —
|
|
407
|
-
the zero-wire planning
|
|
408
|
-
|
|
409
|
-
facts with verbatim vendor evidence), the bounded live
|
|
410
|
-
`operations.probeReachability` sweep (confirm-gated, over-cap refuses),
|
|
411
|
-
`operations.recovery` (find the records a marker-tagged write created;
|
|
412
|
-
delete is dry-run-first under `confirm`), `time_entries.postedWithin`
|
|
406
|
+
the zero-wire planning read `operations.createGuidance` (per-child zone
|
|
407
|
+
facts with verbatim vendor evidence), `time_entries.postedWithin`
|
|
413
408
|
(the inclusive UTC window read over `dateWorked` — posted/ticket/resource
|
|
414
409
|
narrowing), the issue #13 create-path recovery (a drifted 2xx answers
|
|
415
410
|
`idFrom: 'marker-recovery'` from ONE bounded marker read, or the typed
|
|
@@ -570,8 +565,8 @@ suites are the release gate, the live scripts are the ground-truth check.
|
|
|
570
565
|
the 14-issue wave (agent profile + ClientPool/gateway mode, untrusted-content
|
|
571
566
|
markers, the doctor preflight CLI, closed MCP input, wire-level surface probes
|
|
572
567
|
+ `npm run verify`, the Node-24 floor, the per-tenant 429 cooldown, delete
|
|
573
|
-
boundaries
|
|
574
|
-
|
|
568
|
+
boundaries, the blind-surface inventory (the plan data the served artifacts
|
|
569
|
+
stamp from), the zone-fact create-guidance catalog, the posted/unposted rework
|
|
575
570
|
(first the spec `postedDate` wire, replaced in 0.32.0 by the
|
|
576
571
|
billing-item join because ww29 has no `postedDate`; W-D3 +
|
|
577
572
|
`postedWithin`), the create-path marker recovery, the typed `emptyReason`,
|