@fourier-labs/harbour-contracts 0.98.0 → 0.100.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 (29) hide show
  1. package/contract-release.json +24 -24
  2. package/dist/gen-ts/app-integrations-declaration.d.ts +60 -2
  3. package/dist/gen-ts/contract-release.d.ts +6 -6
  4. package/dist/gen-ts/contract-release.js +6 -6
  5. package/dist/gen-ts/data-grant-v2.d.ts +66 -16
  6. package/dist/gen-ts/integration-error-details.d.ts +1 -1
  7. package/dist/gen-ts/integration-execute-input-rules.d.ts +27 -0
  8. package/dist/gen-ts/integration-execute-input-rules.js +13 -0
  9. package/dist/gen-ts/integration-execute-request.d.ts +13 -3
  10. package/dist/gen-ts/integration-execute-result.d.ts +27 -0
  11. package/dist/gen-ts/integration-operations.d.ts +15 -0
  12. package/dist/gen-ts/integration-operations.js +19 -0
  13. package/dist/gen-ts/saas-connection.d.ts +6 -6
  14. package/gen-ts/app-integrations-declaration.ts +60 -2
  15. package/gen-ts/contract-release.ts +6 -6
  16. package/gen-ts/data-grant-v2.ts +69 -15
  17. package/gen-ts/integration-error-details.ts +11 -1
  18. package/gen-ts/integration-execute-input-rules.ts +13 -0
  19. package/gen-ts/integration-execute-request.ts +15 -3
  20. package/gen-ts/integration-execute-result.ts +29 -0
  21. package/gen-ts/integration-operations.ts +19 -0
  22. package/gen-ts/saas-connection.ts +9 -3
  23. package/package.json +1 -1
  24. package/schema/app-integrations-declaration.schema.json +233 -3
  25. package/schema/data-grant-v2.schema.json +77 -2
  26. package/schema/integration-error-details.schema.json +11 -1
  27. package/schema/integration-execute-request.schema.json +109 -2
  28. package/schema/integration-execute-result.schema.json +97 -0
  29. package/schema/saas-connection.schema.json +18 -3
@@ -834,6 +834,15 @@ export const IntegrationOperations = {
834
834
  "declaredMode": false,
835
835
  "idempotencyKey": true
836
836
  },
837
+ "zohobooks.invoice.markSent": {
838
+ "kind": "saas",
839
+ "identities": [
840
+ "user"
841
+ ],
842
+ "readOnly": false,
843
+ "declaredMode": false,
844
+ "idempotencyKey": true
845
+ },
837
846
  "zohobooks.creditnote.create": {
838
847
  "kind": "saas",
839
848
  "identities": [
@@ -851,5 +860,15 @@ export const IntegrationOperations = {
851
860
  "readOnly": true,
852
861
  "declaredMode": false,
853
862
  "idempotencyKey": false
863
+ },
864
+ "mcp.tool.call": {
865
+ "kind": "mcp",
866
+ "identities": [
867
+ "user"
868
+ ],
869
+ "readOnly": false,
870
+ "declaredMode": false,
871
+ "idempotencyKey": false,
872
+ "runtimeIdempotency": true
854
873
  }
855
874
  };
@@ -55,15 +55,15 @@ export interface SaasConnection {
55
55
  * Operations IT allows apps to request on this connection: the provider's own SaaS operations (Slack: slack.channel.history, slack.message.post, slack.message.update, slack.message.delete, slack.dm.send, slack.user.lookup; Gmail: gmail.thread.list, gmail.thread.read, gmail.message.read, gmail.message.send, gmail.attachment.read; Basecamp (0.76.0): basecamp.project.list, basecamp.todolist.list, basecamp.todo.list, basecamp.todo.create, basecamp.todo.complete, basecamp.message.list, basecamp.message.post, basecamp.comment.list, basecamp.comment.post, basecamp.campfire.post, basecamp.people.list; SharePoint (0.78.0): sharepoint.list.list, sharepoint.item.list, sharepoint.item.create, sharepoint.item.update, sharepoint.drive.list, sharepoint.file.list, sharepoint.file.search, sharepoint.file.read, sharepoint.file.upload; Google Workspace and Microsoft 365 (0.86.0): the calendar.*, drive.*, docs.*, sheets.*, outlook.*, onedrive.*, excel.* and teams.* operations of the connection's provider). Never warehouse.view.read. Phone (0.82.0): phone.sms.list; 0.83.0 adds phone.number.get. Seventy-eight SaaS operations in all since 0.86.0.
56
56
  *
57
57
  * @minItems 1
58
- * @maxItems 91
58
+ * @maxItems 92
59
59
  */
60
- operations: ('slack.channel.history' | 'slack.message.post' | 'slack.message.update' | 'slack.message.delete' | 'slack.dm.send' | 'slack.user.lookup' | 'gmail.thread.list' | 'gmail.thread.read' | 'gmail.message.read' | 'gmail.message.send' | 'gmail.attachment.read' | 'basecamp.project.list' | 'basecamp.todolist.list' | 'basecamp.todo.list' | 'basecamp.todo.create' | 'basecamp.todo.complete' | 'basecamp.message.list' | 'basecamp.message.post' | 'basecamp.comment.list' | 'basecamp.comment.post' | 'basecamp.campfire.post' | 'basecamp.people.list' | 'sharepoint.list.list' | 'sharepoint.item.list' | 'sharepoint.item.create' | 'sharepoint.item.update' | 'sharepoint.drive.list' | 'sharepoint.file.list' | 'sharepoint.file.search' | 'sharepoint.file.read' | 'sharepoint.file.upload' | 'phone.sms.list' | 'phone.number.get' | 'calendar.calendar.list' | 'calendar.event.list' | 'calendar.event.read' | 'calendar.event.create' | 'calendar.event.update' | 'calendar.event.cancel' | 'drive.file.list' | 'drive.file.search' | 'drive.file.read' | 'drive.file.upload' | 'drive.folder.create' | 'docs.document.read' | 'docs.document.create' | 'docs.document.append' | 'docs.text.replace' | 'sheets.spreadsheet.read' | 'sheets.values.read' | 'sheets.values.append' | 'sheets.values.update' | 'sheets.values.clear' | 'sheets.spreadsheet.create' | 'outlook.message.list' | 'outlook.message.read' | 'outlook.attachment.read' | 'outlook.message.send' | 'outlook.message.reply' | 'outlook.event.list' | 'outlook.event.read' | 'outlook.event.create' | 'outlook.event.update' | 'outlook.event.cancel' | 'onedrive.file.list' | 'onedrive.file.search' | 'onedrive.file.read' | 'onedrive.file.upload' | 'onedrive.folder.create' | 'excel.worksheet.list' | 'excel.range.read' | 'excel.range.update' | 'excel.table.list' | 'excel.row.add' | 'excel.worksheet.add' | 'teams.message.list' | 'teams.message.post' | 'teams.reply.post' | 'warehouse.view.read' | 'warehouse.table.append' | 'service.request' | 'zohobooks.contact.list' | 'zohobooks.purchaseorder.list' | 'zohobooks.purchaseorder.read' | 'zohobooks.bill.create' | 'zohobooks.bill.read' | 'zohobooks.invoice.create' | 'zohobooks.invoice.read' | 'zohobooks.invoice.pdf' | 'zohobooks.salesorder.list' | 'zohobooks.salesorder.read' | 'zohobooks.invoice.reviseDraft' | 'zohobooks.creditnote.create' | 'zohobooks.creditnote.read')[];
60
+ operations: ('slack.channel.history' | 'slack.message.post' | 'slack.message.update' | 'slack.message.delete' | 'slack.dm.send' | 'slack.user.lookup' | 'gmail.thread.list' | 'gmail.thread.read' | 'gmail.message.read' | 'gmail.message.send' | 'gmail.attachment.read' | 'basecamp.project.list' | 'basecamp.todolist.list' | 'basecamp.todo.list' | 'basecamp.todo.create' | 'basecamp.todo.complete' | 'basecamp.message.list' | 'basecamp.message.post' | 'basecamp.comment.list' | 'basecamp.comment.post' | 'basecamp.campfire.post' | 'basecamp.people.list' | 'sharepoint.list.list' | 'sharepoint.item.list' | 'sharepoint.item.create' | 'sharepoint.item.update' | 'sharepoint.drive.list' | 'sharepoint.file.list' | 'sharepoint.file.search' | 'sharepoint.file.read' | 'sharepoint.file.upload' | 'phone.sms.list' | 'phone.number.get' | 'calendar.calendar.list' | 'calendar.event.list' | 'calendar.event.read' | 'calendar.event.create' | 'calendar.event.update' | 'calendar.event.cancel' | 'drive.file.list' | 'drive.file.search' | 'drive.file.read' | 'drive.file.upload' | 'drive.folder.create' | 'docs.document.read' | 'docs.document.create' | 'docs.document.append' | 'docs.text.replace' | 'sheets.spreadsheet.read' | 'sheets.values.read' | 'sheets.values.append' | 'sheets.values.update' | 'sheets.values.clear' | 'sheets.spreadsheet.create' | 'outlook.message.list' | 'outlook.message.read' | 'outlook.attachment.read' | 'outlook.message.send' | 'outlook.message.reply' | 'outlook.event.list' | 'outlook.event.read' | 'outlook.event.create' | 'outlook.event.update' | 'outlook.event.cancel' | 'onedrive.file.list' | 'onedrive.file.search' | 'onedrive.file.read' | 'onedrive.file.upload' | 'onedrive.folder.create' | 'excel.worksheet.list' | 'excel.range.read' | 'excel.range.update' | 'excel.table.list' | 'excel.row.add' | 'excel.worksheet.add' | 'teams.message.list' | 'teams.message.post' | 'teams.reply.post' | 'warehouse.view.read' | 'warehouse.table.append' | 'service.request' | 'zohobooks.contact.list' | 'zohobooks.purchaseorder.list' | 'zohobooks.purchaseorder.read' | 'zohobooks.bill.create' | 'zohobooks.bill.read' | 'zohobooks.invoice.create' | 'zohobooks.invoice.read' | 'zohobooks.invoice.pdf' | 'zohobooks.salesorder.list' | 'zohobooks.salesorder.read' | 'zohobooks.invoice.reviseDraft' | 'zohobooks.invoice.markSent' | 'zohobooks.creditnote.create' | 'zohobooks.creditnote.read' | 'mcp.tool.call')[];
61
61
  /**
62
62
  * Explicit user-mode operations eligible for automatic app access, subject to the connection operation ceiling and personal consent. Empty means review all; absent inherits company defaults or the existing userModeApproval migration rule. Governance validates provider and mode compatibility. Background execution still requires personal background consent, not a separate admin grant.
63
63
  *
64
- * @maxItems 91
64
+ * @maxItems 92
65
65
  */
66
- automaticUserOperations?: ('slack.channel.history' | 'slack.message.post' | 'slack.message.update' | 'slack.message.delete' | 'slack.dm.send' | 'slack.user.lookup' | 'gmail.thread.list' | 'gmail.thread.read' | 'gmail.message.read' | 'gmail.message.send' | 'gmail.attachment.read' | 'basecamp.project.list' | 'basecamp.todolist.list' | 'basecamp.todo.list' | 'basecamp.todo.create' | 'basecamp.todo.complete' | 'basecamp.message.list' | 'basecamp.message.post' | 'basecamp.comment.list' | 'basecamp.comment.post' | 'basecamp.campfire.post' | 'basecamp.people.list' | 'sharepoint.list.list' | 'sharepoint.item.list' | 'sharepoint.item.create' | 'sharepoint.item.update' | 'sharepoint.drive.list' | 'sharepoint.file.list' | 'sharepoint.file.search' | 'sharepoint.file.read' | 'sharepoint.file.upload' | 'phone.sms.list' | 'phone.number.get' | 'calendar.calendar.list' | 'calendar.event.list' | 'calendar.event.read' | 'calendar.event.create' | 'calendar.event.update' | 'calendar.event.cancel' | 'drive.file.list' | 'drive.file.search' | 'drive.file.read' | 'drive.file.upload' | 'drive.folder.create' | 'docs.document.read' | 'docs.document.create' | 'docs.document.append' | 'docs.text.replace' | 'sheets.spreadsheet.read' | 'sheets.values.read' | 'sheets.values.append' | 'sheets.values.update' | 'sheets.values.clear' | 'sheets.spreadsheet.create' | 'outlook.message.list' | 'outlook.message.read' | 'outlook.attachment.read' | 'outlook.message.send' | 'outlook.message.reply' | 'outlook.event.list' | 'outlook.event.read' | 'outlook.event.create' | 'outlook.event.update' | 'outlook.event.cancel' | 'onedrive.file.list' | 'onedrive.file.search' | 'onedrive.file.read' | 'onedrive.file.upload' | 'onedrive.folder.create' | 'excel.worksheet.list' | 'excel.range.read' | 'excel.range.update' | 'excel.table.list' | 'excel.row.add' | 'excel.worksheet.add' | 'teams.message.list' | 'teams.message.post' | 'teams.reply.post' | 'warehouse.view.read' | 'warehouse.table.append' | 'service.request' | 'zohobooks.contact.list' | 'zohobooks.purchaseorder.list' | 'zohobooks.purchaseorder.read' | 'zohobooks.bill.create' | 'zohobooks.bill.read' | 'zohobooks.invoice.create' | 'zohobooks.invoice.read' | 'zohobooks.invoice.pdf' | 'zohobooks.salesorder.list' | 'zohobooks.salesorder.read' | 'zohobooks.invoice.reviseDraft' | 'zohobooks.creditnote.create' | 'zohobooks.creditnote.read')[];
66
+ automaticUserOperations?: ('slack.channel.history' | 'slack.message.post' | 'slack.message.update' | 'slack.message.delete' | 'slack.dm.send' | 'slack.user.lookup' | 'gmail.thread.list' | 'gmail.thread.read' | 'gmail.message.read' | 'gmail.message.send' | 'gmail.attachment.read' | 'basecamp.project.list' | 'basecamp.todolist.list' | 'basecamp.todo.list' | 'basecamp.todo.create' | 'basecamp.todo.complete' | 'basecamp.message.list' | 'basecamp.message.post' | 'basecamp.comment.list' | 'basecamp.comment.post' | 'basecamp.campfire.post' | 'basecamp.people.list' | 'sharepoint.list.list' | 'sharepoint.item.list' | 'sharepoint.item.create' | 'sharepoint.item.update' | 'sharepoint.drive.list' | 'sharepoint.file.list' | 'sharepoint.file.search' | 'sharepoint.file.read' | 'sharepoint.file.upload' | 'phone.sms.list' | 'phone.number.get' | 'calendar.calendar.list' | 'calendar.event.list' | 'calendar.event.read' | 'calendar.event.create' | 'calendar.event.update' | 'calendar.event.cancel' | 'drive.file.list' | 'drive.file.search' | 'drive.file.read' | 'drive.file.upload' | 'drive.folder.create' | 'docs.document.read' | 'docs.document.create' | 'docs.document.append' | 'docs.text.replace' | 'sheets.spreadsheet.read' | 'sheets.values.read' | 'sheets.values.append' | 'sheets.values.update' | 'sheets.values.clear' | 'sheets.spreadsheet.create' | 'outlook.message.list' | 'outlook.message.read' | 'outlook.attachment.read' | 'outlook.message.send' | 'outlook.message.reply' | 'outlook.event.list' | 'outlook.event.read' | 'outlook.event.create' | 'outlook.event.update' | 'outlook.event.cancel' | 'onedrive.file.list' | 'onedrive.file.search' | 'onedrive.file.read' | 'onedrive.file.upload' | 'onedrive.folder.create' | 'excel.worksheet.list' | 'excel.range.read' | 'excel.range.update' | 'excel.table.list' | 'excel.row.add' | 'excel.worksheet.add' | 'teams.message.list' | 'teams.message.post' | 'teams.reply.post' | 'warehouse.view.read' | 'warehouse.table.append' | 'service.request' | 'zohobooks.contact.list' | 'zohobooks.purchaseorder.list' | 'zohobooks.purchaseorder.read' | 'zohobooks.bill.create' | 'zohobooks.bill.read' | 'zohobooks.invoice.create' | 'zohobooks.invoice.read' | 'zohobooks.invoice.pdf' | 'zohobooks.salesorder.list' | 'zohobooks.salesorder.read' | 'zohobooks.invoice.reviseDraft' | 'zohobooks.invoice.markSent' | 'zohobooks.creditnote.create' | 'zohobooks.creditnote.read' | 'mcp.tool.call')[];
67
67
  /**
68
68
  * Reusable permissions for admitted builders on explicit shared SaaS resources. Governance checks registered resources, provider/mode compatibility and the connection operation ceiling. Connection version and audit record changes; no per-entry approval metadata.
69
69
  *
@@ -168,9 +168,9 @@ export interface ReusableSaasAccess {
168
168
  mode: 'app' | 'user';
169
169
  /**
170
170
  * @minItems 1
171
- * @maxItems 91
171
+ * @maxItems 92
172
172
  */
173
- operations: ('slack.channel.history' | 'slack.message.post' | 'slack.message.update' | 'slack.message.delete' | 'slack.dm.send' | 'slack.user.lookup' | 'gmail.thread.list' | 'gmail.thread.read' | 'gmail.message.read' | 'gmail.message.send' | 'gmail.attachment.read' | 'basecamp.project.list' | 'basecamp.todolist.list' | 'basecamp.todo.list' | 'basecamp.todo.create' | 'basecamp.todo.complete' | 'basecamp.message.list' | 'basecamp.message.post' | 'basecamp.comment.list' | 'basecamp.comment.post' | 'basecamp.campfire.post' | 'basecamp.people.list' | 'sharepoint.list.list' | 'sharepoint.item.list' | 'sharepoint.item.create' | 'sharepoint.item.update' | 'sharepoint.drive.list' | 'sharepoint.file.list' | 'sharepoint.file.search' | 'sharepoint.file.read' | 'sharepoint.file.upload' | 'phone.sms.list' | 'phone.number.get' | 'calendar.calendar.list' | 'calendar.event.list' | 'calendar.event.read' | 'calendar.event.create' | 'calendar.event.update' | 'calendar.event.cancel' | 'drive.file.list' | 'drive.file.search' | 'drive.file.read' | 'drive.file.upload' | 'drive.folder.create' | 'docs.document.read' | 'docs.document.create' | 'docs.document.append' | 'docs.text.replace' | 'sheets.spreadsheet.read' | 'sheets.values.read' | 'sheets.values.append' | 'sheets.values.update' | 'sheets.values.clear' | 'sheets.spreadsheet.create' | 'outlook.message.list' | 'outlook.message.read' | 'outlook.attachment.read' | 'outlook.message.send' | 'outlook.message.reply' | 'outlook.event.list' | 'outlook.event.read' | 'outlook.event.create' | 'outlook.event.update' | 'outlook.event.cancel' | 'onedrive.file.list' | 'onedrive.file.search' | 'onedrive.file.read' | 'onedrive.file.upload' | 'onedrive.folder.create' | 'excel.worksheet.list' | 'excel.range.read' | 'excel.range.update' | 'excel.table.list' | 'excel.row.add' | 'excel.worksheet.add' | 'teams.message.list' | 'teams.message.post' | 'teams.reply.post' | 'warehouse.view.read' | 'warehouse.table.append' | 'service.request' | 'zohobooks.contact.list' | 'zohobooks.purchaseorder.list' | 'zohobooks.purchaseorder.read' | 'zohobooks.bill.create' | 'zohobooks.bill.read' | 'zohobooks.invoice.create' | 'zohobooks.invoice.read' | 'zohobooks.invoice.pdf' | 'zohobooks.salesorder.list' | 'zohobooks.salesorder.read' | 'zohobooks.invoice.reviseDraft' | 'zohobooks.creditnote.create' | 'zohobooks.creditnote.read')[];
173
+ operations: ('slack.channel.history' | 'slack.message.post' | 'slack.message.update' | 'slack.message.delete' | 'slack.dm.send' | 'slack.user.lookup' | 'gmail.thread.list' | 'gmail.thread.read' | 'gmail.message.read' | 'gmail.message.send' | 'gmail.attachment.read' | 'basecamp.project.list' | 'basecamp.todolist.list' | 'basecamp.todo.list' | 'basecamp.todo.create' | 'basecamp.todo.complete' | 'basecamp.message.list' | 'basecamp.message.post' | 'basecamp.comment.list' | 'basecamp.comment.post' | 'basecamp.campfire.post' | 'basecamp.people.list' | 'sharepoint.list.list' | 'sharepoint.item.list' | 'sharepoint.item.create' | 'sharepoint.item.update' | 'sharepoint.drive.list' | 'sharepoint.file.list' | 'sharepoint.file.search' | 'sharepoint.file.read' | 'sharepoint.file.upload' | 'phone.sms.list' | 'phone.number.get' | 'calendar.calendar.list' | 'calendar.event.list' | 'calendar.event.read' | 'calendar.event.create' | 'calendar.event.update' | 'calendar.event.cancel' | 'drive.file.list' | 'drive.file.search' | 'drive.file.read' | 'drive.file.upload' | 'drive.folder.create' | 'docs.document.read' | 'docs.document.create' | 'docs.document.append' | 'docs.text.replace' | 'sheets.spreadsheet.read' | 'sheets.values.read' | 'sheets.values.append' | 'sheets.values.update' | 'sheets.values.clear' | 'sheets.spreadsheet.create' | 'outlook.message.list' | 'outlook.message.read' | 'outlook.attachment.read' | 'outlook.message.send' | 'outlook.message.reply' | 'outlook.event.list' | 'outlook.event.read' | 'outlook.event.create' | 'outlook.event.update' | 'outlook.event.cancel' | 'onedrive.file.list' | 'onedrive.file.search' | 'onedrive.file.read' | 'onedrive.file.upload' | 'onedrive.folder.create' | 'excel.worksheet.list' | 'excel.range.read' | 'excel.range.update' | 'excel.table.list' | 'excel.row.add' | 'excel.worksheet.add' | 'teams.message.list' | 'teams.message.post' | 'teams.reply.post' | 'warehouse.view.read' | 'warehouse.table.append' | 'service.request' | 'zohobooks.contact.list' | 'zohobooks.purchaseorder.list' | 'zohobooks.purchaseorder.read' | 'zohobooks.bill.create' | 'zohobooks.bill.read' | 'zohobooks.invoice.create' | 'zohobooks.invoice.read' | 'zohobooks.invoice.pdf' | 'zohobooks.salesorder.list' | 'zohobooks.salesorder.read' | 'zohobooks.invoice.reviseDraft' | 'zohobooks.invoice.markSent' | 'zohobooks.creditnote.create' | 'zohobooks.creditnote.read' | 'mcp.tool.call')[];
174
174
  }
175
175
  export interface DevelopmentPreapproval {
176
176
  /**
@@ -97,11 +97,14 @@ export type DeclaredConnection = {
97
97
  'zohobooks.salesorder.list'?: UserModeChannelOperation;
98
98
  'zohobooks.salesorder.read'?: UserModeChannelOperation;
99
99
  'zohobooks.invoice.reviseDraft'?: UserModeChannelOperation;
100
+ 'zohobooks.invoice.markSent'?: UserModeChannelOperation;
100
101
  'zohobooks.creditnote.create'?: UserModeChannelOperation;
101
102
  'zohobooks.creditnote.read'?: UserModeChannelOperation;
103
+ 'mcp.tool.call'?: McpUserOperation;
102
104
  };
105
+ mcp?: McpToolSelection;
103
106
  };
104
- export type IntegrationConnectionKind = 'saas' | 'database' | 'service';
107
+ export type IntegrationConnectionKind = 'saas' | 'database' | 'service' | 'mcp';
105
108
  /**
106
109
  * Whose authority an operation runs under. Fixed per operation, except the declared-mode Slack operations (slack.message.post; since 0.71.0 also slack.channel.history, slack.message.update, slack.message.delete): declared per app for the access request, and named per call among the app's approved modes (execute request `mode`, 0.55.0).
107
110
  */
@@ -119,9 +122,13 @@ export type ResourceNames = IntegrationAlias[];
119
122
  * A plain warehouse column identifier, or `*` as the sole selection when IT exposed all current and future columns.
120
123
  */
121
124
  export type ColumnName = string;
125
+ /**
126
+ * Opaque, case-sensitive provider tool name. Never interpreted as a source alias or endpoint.
127
+ */
128
+ export type McpToolName = string;
122
129
 
123
130
  /**
124
- * Committed `.isomorph/integrations.json`: the app's declared use of tenant-wide integration connections. Keys are logical connection aliases (the governance sourceId); resources are logical names (Slack channel alias, warehouse view name), never IDs, tokens or URLs. The operation set is closed (eighty-one operations since 0.86.0, ADR 0018, ADR 0022, ADR 0024, ADR 0028, ADR 0029 and ADR 0032). Each operation carries a fixed identity mode — slack.dm.send=app, slack.user.lookup=app, every gmail.* operation=user, every basecamp.* operation=user, every sharepoint.* operation=user, every calendar.*, drive.*, docs.*, sheets.*, outlook.*, onedrive.*, excel.* and teams.* operation=user (0.86.0), warehouse.view.read=app, service.request=app — except the declared-mode Slack operations (slack.message.post, and since 0.71.0 slack.channel.history, slack.message.update and slack.message.delete), whose mode the app DECLARES: `app` acts as the company's Slack app (the one audited bot identity; a post goes out under the IT-approved per-app display name when the connection declares `presentation`), `user` acts as the signed-in person after their own consent (reads what they can read, edits what they wrote). The declared mode is the one the app requests access for; an app may hold approved grants for both modes after two requests, and each declared-mode call names which approved mode it runs under (`mode` on the execute request, 0.55.0) — a mode IT did not approve is refused, never swapped for the other. A `saas` connection may declare only the Slack, Gmail, Basecamp, SharePoint, phone, Google Workspace (calendar, drive, docs, sheets) and Microsoft 365 (outlook, onedrive, excel, teams) operations and a `database` connection only warehouse.view.read; `presentation` is a `saas` connection's optional per-app display name and icon for app-mode Slack posts, shown to IT at approval time and applied only from the approved grant. Gmail is user-mode only (reads, one send); its single resource is the fixed `inbox` alias. Basecamp (0.76.0, ADR 0022) is user-mode only too: basecamp.project.list runs on the fixed `account` alias (the company's pinned Basecamp account) and every other basecamp.* operation on a project alias IT mapped in the connection's `channels` map, so Basecamp itself refuses an id outside that project. SharePoint (0.78.0, ADR 0024) is user-mode only as well: every sharepoint.* operation runs on a site alias IT mapped in the connection's `channels` map (a Microsoft Graph site id), so Graph itself refuses a list, item or file outside that site. Google Workspace and Microsoft 365 (0.86.0, ADR 0032) are user-mode only too: every calendar.*, drive.*, docs.*, sheets.*, outlook.*, onedrive.* and excel.* operation runs on the provider's one fixed alias for the signed-in person's own data (governance resolves it, the way Gmail's is `inbox`; the contract does not pin the literal), and every teams.* operation on a channel alias IT mapped in the connection's `channels` map (a Teams team and channel id), so Graph itself refuses a message outside that channel. slack.dm.send and slack.user.lookup address people by email rather than a channel, so their single resource is the fixed `workspace` alias (the connection's installed workspace), the way Gmail's is `inbox`. This file also owns the shared IntegrationOperation / IntegrationIdentityMode / IntegrationEnvironment / IntegrationConnectionKind / IntegrationPresentation definitions referenced by the other integration schemas.
131
+ * Committed `.isomorph/integrations.json`: the app's declared use of tenant-wide integration connections. Keys are logical connection aliases (the governance sourceId); resources are logical names (Slack channel alias, warehouse view name), never IDs, tokens or URLs. The operation set is closed (eighty-one operations since 0.86.0, ADR 0018, ADR 0022, ADR 0024, ADR 0028, ADR 0029 and ADR 0032). Each operation carries a fixed identity mode — slack.dm.send=app, slack.user.lookup=app, every gmail.* operation=user, every basecamp.* operation=user, every sharepoint.* operation=user, every calendar.*, drive.*, docs.*, sheets.*, outlook.*, onedrive.*, excel.* and teams.* operation=user (0.86.0), warehouse.view.read=app, service.request=app — except the declared-mode Slack operations (slack.message.post, and since 0.71.0 slack.channel.history, slack.message.update and slack.message.delete), whose mode the app DECLARES: `app` acts as the company's Slack app (the one audited bot identity; a post goes out under the IT-approved per-app display name when the connection declares `presentation`), `user` acts as the signed-in person after their own consent (reads what they can read, edits what they wrote). The declared mode is the one the app requests access for; an app may hold approved grants for both modes after two requests, and each declared-mode call names which approved mode it runs under (`mode` on the execute request, 0.55.0) — a mode IT did not approve is refused, never swapped for the other. A `saas` connection may declare only the Slack, Gmail, Basecamp, SharePoint, phone, Google Workspace (calendar, drive, docs, sheets) and Microsoft 365 (outlook, onedrive, excel, teams) operations and a `database` connection only warehouse.view.read; `presentation` is a `saas` connection's optional per-app display name and icon for app-mode Slack posts, shown to IT at approval time and applied only from the approved grant. Gmail is user-mode only (reads, one send); its single resource is the fixed `inbox` alias. Basecamp (0.76.0, ADR 0022) is user-mode only too: basecamp.project.list runs on the fixed `account` alias (the company's pinned Basecamp account) and every other basecamp.* operation on a project alias IT mapped in the connection's `channels` map, so Basecamp itself refuses an id outside that project. SharePoint (0.78.0, ADR 0024) is user-mode only as well: every sharepoint.* operation runs on a site alias IT mapped in the connection's `channels` map (a Microsoft Graph site id), so Graph itself refuses a list, item or file outside that site. Google Workspace and Microsoft 365 (0.86.0, ADR 0032) are user-mode only too: every calendar.*, drive.*, docs.*, sheets.*, outlook.*, onedrive.* and excel.* operation runs on the provider's one fixed alias for the signed-in person's own data (governance resolves it, the way Gmail's is `inbox`; the contract does not pin the literal), and every teams.* operation on a channel alias IT mapped in the connection's `channels` map (a Teams team and channel id), so Graph itself refuses a message outside that channel. slack.dm.send and slack.user.lookup address people by email rather than a channel, so their single resource is the fixed `workspace` alias (the connection's installed workspace), the way Gmail's is `inbox`. This file also owns the shared IntegrationOperation / IntegrationIdentityMode / IntegrationEnvironment / IntegrationConnectionKind / IntegrationPresentation definitions referenced by the other integration schemas. Remote MCP connections add one generic user-only mcp.tool.call on server with exact accepted descriptors; an operation alone never authorizes every provider tool.
125
132
  */
126
133
  export interface AppIntegrationsDeclaration {
127
134
  schema: 'isomorph.app-integrations/2.0';
@@ -188,3 +195,54 @@ export interface ServiceOperation {
188
195
  */
189
196
  resources: 'api'[];
190
197
  }
198
+ export interface McpUserOperation {
199
+ identity: 'user';
200
+ /**
201
+ * @minItems 1
202
+ * @maxItems 1
203
+ */
204
+ resources: 'server'[];
205
+ }
206
+ /**
207
+ * Exact accepted tool selection. Runtime rejects duplicate names and bounds all selected descriptors across the app to 128 KiB serialized.
208
+ */
209
+ export interface McpToolSelection {
210
+ /**
211
+ * @minItems 1
212
+ * @maxItems 64
213
+ */
214
+ tools: McpSelectedTool[];
215
+ }
216
+ /**
217
+ * Runtime verifies name equals descriptor.name and hash is SHA256 of canonical {name,inputSchema,outputSchema?}; annotations and explanatory text are excluded.
218
+ */
219
+ export interface McpSelectedTool {
220
+ name: McpToolName;
221
+ contractHash: string;
222
+ descriptor: McpToolDescriptor;
223
+ }
224
+ /**
225
+ * Accepted provider descriptor. MCP schema dialect validation, in-document references and 64 KiB serialized descriptor bound are runtime checks; no remote references are fetched.
226
+ */
227
+ export interface McpToolDescriptor {
228
+ name: McpToolName;
229
+ title?: string;
230
+ description?: string;
231
+ inputSchema: {
232
+ [k: string]: unknown;
233
+ };
234
+ outputSchema?: {
235
+ [k: string]: unknown;
236
+ };
237
+ annotations?: McpToolAnnotations;
238
+ }
239
+ /**
240
+ * Provider hints pinned with the accepted descriptor; never proof of authorization or safety.
241
+ */
242
+ export interface McpToolAnnotations {
243
+ title?: string;
244
+ readOnlyHint?: boolean;
245
+ destructiveHint?: boolean;
246
+ idempotentHint?: boolean;
247
+ openWorldHint?: boolean;
248
+ }
@@ -1,10 +1,10 @@
1
1
  /* eslint-disable */
2
2
  // Code generated by tools/gen/gen.mjs from schema/*.json. DO NOT EDIT.
3
3
 
4
- export const ContractRepositoryVersion = "0.98.0.0" as const;
5
- export const ContractPublishVersion = "0.98.0" as const;
6
- export const ContractPublishTag = "v0.98.0" as const;
7
- export const ContractSchemasDigest = "sha256:c5ae6c789021697c7e00bf65bb1f072b4d8a61f151a9b31e1a74486992c6c196" as const;
4
+ export const ContractRepositoryVersion = "0.100.0.0" as const;
5
+ export const ContractPublishVersion = "0.100.0" as const;
6
+ export const ContractPublishTag = "v0.100.0" as const;
7
+ export const ContractSchemasDigest = "sha256:5a49b987a272e49117b6f47b8fb90854b8eb128516aa5409ac8f016c97fb3c1b" as const;
8
8
  export const ContractAiFixturesDigest = "sha256:edac31c92e146ca1c40130f2fb5649db82e24b8cd1ac758153b90612052fddb6" as const;
9
- export const ContractGeneratedGoDigest = "sha256:d8ea139537eae467b12402fac22e1a44f4e6dc50cad71e02a0083dfa6b63ee3d" as const;
10
- export const ContractGeneratedTypeScriptDigest = "sha256:95a22d7dd80f7a020e556f42a1b269a13bad0168f2872a96500deb4a184720d1" as const;
9
+ export const ContractGeneratedGoDigest = "sha256:7052659c5f2394396b097b4102a5d4b0369c11ddc7aa46a6e839825fee65ad8a" as const;
10
+ export const ContractGeneratedTypeScriptDigest = "sha256:5c9d13b601b1deb027b2518e4471316d72b079a647e99c3e26f0443f57861812" as const;
@@ -1,20 +1,10 @@
1
1
  /* eslint-disable */
2
2
  // Code generated by tools/gen/gen.mjs from schema/*.json. DO NOT EDIT.
3
3
 
4
- /**
5
- * Grant lifecycle state. Legal edges live in x-transitions; DENIED and REVOKED are terminal.
6
- */
7
- export type DataGrantV2Status = 'REQUESTED' | 'GRANTED' | 'DENIED' | 'REVOKED';
8
- /**
9
- * Provider-side work for the current approved scope (credential mint, cleanup, installation check).
10
- */
11
- export type DataGrantV2ProvisioningStatus = 'NONE' | 'PENDING' | 'FAILED' | 'DONE';
12
- export type DataGrantV2CleanupStatus = 'PENDING' | 'FAILED' | 'DONE';
13
-
14
4
  /**
15
5
  * An app's integration grant for one connection, environment and identity mode (control table sk APP#<appId>#IGRANT#<environment>#<sourceId>#<mode>; grantId = base64url(JSON ["v2",appId,environment,sourceId,mode])). Additive to the legacy DataGrant (data-grant.schema.json), which is never consulted by v2 paths. A fresh REQUESTED record carries empty `operations`/`resources` until the attached request is approved; approved resources are structured `{name, columns?}` entries (a Slack channel alias, the fixed Gmail `inbox` alias, a Basecamp project alias or the fixed Basecamp `account` alias, a SharePoint site alias, a Google Workspace or Microsoft 365 provider's fixed alias or a Teams channel alias (0.86.0), or a warehouse view alias with its approved columns). Expiry is enforced from UTC time on every call and SDK calls never extend it; `expiredAt` is stamped by the recovery sweep afterwards. Status edges live in x-transitions; DENIED and REVOKED are terminal (a regrant after revocation is a new REQUESTED record once cleanup is DONE). Database grants add credentialRef/mintedPrincipal; both hold references only. An app-mode Slack grant may carry `presentation` (0.53.0): the IT-approved display name and icon the app's posts go out under, copied from the approved request and read by every post — never from the call. `identityMode` and `installation` are the deprecated 0.45.0 spellings: the record carries `mode`, and a SaaS grant runs on the connection's single installation.
16
6
  */
17
- export interface DataGrantV2 {
7
+ export type DataGrantV2 = {
18
8
  schema: 'harbour.data-grant/2.0';
19
9
  tenantId: string;
20
10
  appId: string;
@@ -30,12 +20,12 @@ export interface DataGrantV2 {
30
20
  * Whose authority an operation runs under. Fixed per operation, except the declared-mode Slack operations (slack.message.post; since 0.71.0 also slack.channel.history, slack.message.update, slack.message.delete): declared per app for the access request, and named per call among the app's approved modes (execute request `mode`, 0.55.0).
31
21
  */
32
22
  mode: 'app' | 'user';
33
- kind: 'saas' | 'database' | 'service';
23
+ kind: 'saas' | 'database' | 'service' | 'mcp';
34
24
  status: DataGrantV2Status;
35
25
  /**
36
26
  * Approved operations; each must match this grant's mode. Empty until the first approval. At most the seventy-eight SaaS operations (0.86.0: eleven Slack and Gmail, eleven Basecamp, nine SharePoint, two phone, forty-five Google Workspace and Microsoft 365); a database grant holds up to two (warehouse.view.read, warehouse.table.append).
37
27
  *
38
- * @maxItems 91
28
+ * @maxItems 92
39
29
  */
40
30
  operations: (
41
31
  | 'slack.channel.history'
@@ -130,8 +120,10 @@ export interface DataGrantV2 {
130
120
  | 'zohobooks.salesorder.list'
131
121
  | 'zohobooks.salesorder.read'
132
122
  | 'zohobooks.invoice.reviseDraft'
123
+ | 'zohobooks.invoice.markSent'
133
124
  | 'zohobooks.creditnote.create'
134
125
  | 'zohobooks.creditnote.read'
126
+ | 'mcp.tool.call'
135
127
  )[];
136
128
  /**
137
129
  * Approved logical resources. Never inherited by wildcard. Empty until the first approval.
@@ -139,6 +131,7 @@ export interface DataGrantV2 {
139
131
  * @maxItems 64
140
132
  */
141
133
  resources: IntegrationResource[];
134
+ mcp?: McpToolSelection;
142
135
  reviewedScope?: ReviewedIntegrationScope;
143
136
  /**
144
137
  * Absent only for explicitly approved ongoing production access.
@@ -180,7 +173,17 @@ export interface DataGrantV2 {
180
173
  * Deprecated: a SaaS grant runs on the connection's single installation; the control plane never writes it.
181
174
  */
182
175
  installation?: string;
183
- }
176
+ };
177
+ /**
178
+ * Grant lifecycle state. Legal edges live in x-transitions; DENIED and REVOKED are terminal.
179
+ */
180
+ export type DataGrantV2Status = 'REQUESTED' | 'GRANTED' | 'DENIED' | 'REVOKED';
181
+ /**
182
+ * Provider-side work for the current approved scope (credential mint, cleanup, installation check).
183
+ */
184
+ export type DataGrantV2ProvisioningStatus = 'NONE' | 'PENDING' | 'FAILED' | 'DONE';
185
+ export type DataGrantV2CleanupStatus = 'PENDING' | 'FAILED' | 'DONE';
186
+
184
187
  /**
185
188
  * One approved logical resource: a Slack channel alias, the fixed Gmail `inbox` alias, a Basecamp project alias or the fixed Basecamp `account` alias (0.76.0), a SharePoint site alias (0.78.0), a phone number alias (0.82.0), or a warehouse view alias with the approved columns.
186
189
  */
@@ -197,12 +200,61 @@ export interface IntegrationResource {
197
200
  */
198
201
  columns?: string[];
199
202
  }
203
+ /**
204
+ * Exact accepted tool selection. Runtime rejects duplicate names and bounds all selected descriptors across the app to 128 KiB serialized.
205
+ */
206
+ interface McpToolSelection {
207
+ /**
208
+ * @minItems 1
209
+ * @maxItems 64
210
+ */
211
+ tools: McpSelectedTool[];
212
+ }
213
+ /**
214
+ * Runtime verifies name equals descriptor.name and hash is SHA256 of canonical {name,inputSchema,outputSchema?}; annotations and explanatory text are excluded.
215
+ */
216
+ interface McpSelectedTool {
217
+ /**
218
+ * Opaque, case-sensitive provider tool name. Never interpreted as a source alias or endpoint.
219
+ */
220
+ name: string;
221
+ contractHash: string;
222
+ descriptor: McpToolDescriptor;
223
+ }
224
+ /**
225
+ * Accepted provider descriptor. MCP schema dialect validation, in-document references and 64 KiB serialized descriptor bound are runtime checks; no remote references are fetched.
226
+ */
227
+ interface McpToolDescriptor {
228
+ /**
229
+ * Opaque, case-sensitive provider tool name. Never interpreted as a source alias or endpoint.
230
+ */
231
+ name: string;
232
+ title?: string;
233
+ description?: string;
234
+ inputSchema: {
235
+ [k: string]: unknown;
236
+ };
237
+ outputSchema?: {
238
+ [k: string]: unknown;
239
+ };
240
+ annotations?: McpToolAnnotations;
241
+ }
242
+ /**
243
+ * Provider hints pinned with the accepted descriptor; never proof of authorization or safety.
244
+ */
245
+ interface McpToolAnnotations {
246
+ title?: string;
247
+ readOnlyHint?: boolean;
248
+ destructiveHint?: boolean;
249
+ idempotentHint?: boolean;
250
+ openWorldHint?: boolean;
251
+ }
200
252
  /**
201
253
  * Only for SaaS grants mixing reviewed and automatic access: the previously human-reviewed scope. The remaining scope must satisfy current automatic rules. Homogeneous grants continue using approvedBy alone. Governance validates this is a subset of the grant; database behaviour is unchanged.
202
254
  */
203
255
  export interface ReviewedIntegrationScope {
204
256
  /**
205
- * @maxItems 91
257
+ * @maxItems 92
206
258
  */
207
259
  operations: (
208
260
  | 'slack.channel.history'
@@ -297,8 +349,10 @@ export interface ReviewedIntegrationScope {
297
349
  | 'zohobooks.salesorder.list'
298
350
  | 'zohobooks.salesorder.read'
299
351
  | 'zohobooks.invoice.reviseDraft'
352
+ | 'zohobooks.invoice.markSent'
300
353
  | 'zohobooks.creditnote.create'
301
354
  | 'zohobooks.creditnote.read'
355
+ | 'mcp.tool.call'
302
356
  )[];
303
357
  /**
304
358
  * @maxItems 64
@@ -40,7 +40,17 @@ export type IntegrationErrorCode =
40
40
  | 'UNAVAILABLE'
41
41
  | 'MODE_NOT_GRANTED'
42
42
  | 'MODE_REQUIRED'
43
- | 'SAMPLE_ROWS_NOT_ALLOWED';
43
+ | 'SAMPLE_ROWS_NOT_ALLOWED'
44
+ | 'CALL_IN_PROGRESS'
45
+ | 'CALL_OUTCOME_UNKNOWN'
46
+ | 'KEY_REUSED'
47
+ | 'MCP_TOOL_NOT_GRANTED'
48
+ | 'MCP_ARGUMENTS_INVALID'
49
+ | 'MCP_OUTPUT_INVALID'
50
+ | 'MCP_CONNECTION_FAILED'
51
+ | 'MCP_TOOL_ERROR'
52
+ | 'MCP_BUSY'
53
+ | 'MCP_OAUTH_SETUP_REQUIRED';
44
54
 
45
55
  /**
46
56
  * The `error` member of an integration failure response `{error, requestId}` on the execute/connect routes; the SDK maps it onto IsomorphError(category, message, details). `category` is the app-SDK IsomorphErrorCategory (not the deployment pipeline's dot-path error-category registry), with the HTTP status fixed per category: 401 AUTH_REQUIRED, 403 FORBIDDEN (denied/revoked/expired), 404 NOT_FOUND (unknown app/connection/resource), 409 CONFLICT (pending provisioning/consent/concurrent request), 400 or 413 VALIDATION_FAILED (invalid input / size overflow), 429 RATE_LIMITED (+ Retry-After header), 503 UNAVAILABLE. `details.code` is the closed stable reason set; `message` is human-facing and never carries provider error bodies, tokens or SQL.
@@ -797,6 +797,12 @@ export const IntegrationExecuteInputRules = {
797
797
  } },
798
798
  },
799
799
  },
800
+ "zohobooks.invoice.markSent": {
801
+ idempotencyKey: true,
802
+ fields: {
803
+ documentId: { kind: "string", required: true, minLength: 0, maxLength: 32, pattern: "^[0-9]{1,32}$" },
804
+ },
805
+ },
800
806
  "zohobooks.creditnote.create": {
801
807
  idempotencyKey: true,
802
808
  fields: {
@@ -815,6 +821,13 @@ export const IntegrationExecuteInputRules = {
815
821
  documentId: { kind: "string", required: true, minLength: 0, maxLength: 32, pattern: "^[0-9]{1,32}$" },
816
822
  },
817
823
  },
824
+ "mcp.tool.call": {
825
+ idempotencyKey: false,
826
+ fields: {
827
+ tool: { kind: "string", required: true, minLength: 1, maxLength: 128 },
828
+ arguments: { kind: "object", required: true },
829
+ },
830
+ },
818
831
  } as const satisfies Record<string, IntegrationExecuteOperationRule>;
819
832
 
820
833
  export type IntegrationExecuteOperation = keyof typeof IntegrationExecuteInputRules;
@@ -105,8 +105,10 @@ export type IntegrationExecuteRequest = {
105
105
  | 'zohobooks.salesorder.list'
106
106
  | 'zohobooks.salesorder.read'
107
107
  | 'zohobooks.invoice.reviseDraft'
108
+ | 'zohobooks.invoice.markSent'
108
109
  | 'zohobooks.creditnote.create'
109
- | 'zohobooks.creditnote.read';
110
+ | 'zohobooks.creditnote.read'
111
+ | 'mcp.tool.call';
110
112
  /**
111
113
  * Tenant-wide logical alias of a connection (governance sourceId) or of a resource under it.
112
114
  */
@@ -476,13 +478,23 @@ export type IntegrationExecuteRequest = {
476
478
  lineItemId?: string;
477
479
  salesOrderItemId?: string;
478
480
  }[];
481
+ /**
482
+ * Opaque, case-sensitive provider tool name. Never interpreted as a source alias or endpoint.
483
+ */
484
+ tool?: string;
485
+ /**
486
+ * Validated against the accepted tool inputSchema at runtime; arbitrary nested provider arguments are permitted only here.
487
+ */
488
+ arguments?: {
489
+ [k: string]: unknown;
490
+ };
479
491
  };
480
492
  /**
481
- * UUID of one explicit Send action; required for the sends (slack.message.post, slack.dm.send, gmail.message.send), the receipted Basecamp writes (basecamp.todo.create, basecamp.message.post, basecamp.comment.post, basecamp.campfire.post; 0.76.0) the receipted SharePoint writes (sharepoint.item.create, sharepoint.file.upload; 0.78.0) the receipted warehouse append (warehouse.table.append; 0.82.0, where it is also the BigQuery load job id) and the receipted Google Workspace and Microsoft 365 writes (0.86.0: calendar.event.create, drive.file.upload, drive.folder.create, docs.document.create, sheets.values.append, sheets.spreadsheet.create, outlook.message.send, outlook.message.reply, outlook.event.create, onedrive.file.upload, onedrive.folder.create, excel.row.add, excel.worksheet.add, teams.message.post, teams.reply.post), refused everywhere else. The same key with the same payload and subject returns the recorded outcome for seven days.
493
+ * UUID of one explicit Send action; required for the sends (slack.message.post, slack.dm.send, gmail.message.send), the receipted Basecamp writes (basecamp.todo.create, basecamp.message.post, basecamp.comment.post, basecamp.campfire.post; 0.76.0) the receipted SharePoint writes (sharepoint.item.create, sharepoint.file.upload; 0.78.0) the receipted warehouse append (warehouse.table.append; 0.82.0, where it is also the BigQuery load job id) and the receipted Google Workspace and Microsoft 365 writes (0.86.0: calendar.event.create, drive.file.upload, drive.folder.create, docs.document.create, sheets.values.append, sheets.spreadsheet.create, outlook.message.send, outlook.message.reply, outlook.event.create, onedrive.file.upload, onedrive.folder.create, excel.row.add, excel.worksheet.add, teams.message.post, teams.reply.post), refused everywhere else. The same key with the same payload and subject returns the recorded outcome for seven days. MCP permits omission only for an accepted readOnlyHint=true descriptor; runtime requires the UUID for unknown/write tools.
482
494
  */
483
495
  idempotencyKey?: string;
484
496
  /**
485
- * The declared-mode Slack operations only (slack.message.post since 0.55.0; slack.channel.history, slack.message.update and slack.message.delete since 0.71.0): which of the app's IT-approved modes this call runs under — app (the company's Slack app; a post goes out under the grant's per-app name and the footer) or user (the signed-in person, after their consent; no name, no footer). Required when the app holds approved grants for both modes (else MODE_REQUIRED); may be omitted when it holds one, which is then used. A named mode without an approved grant is refused with MODE_NOT_GRANTED; governance never falls back to the other mode. Every other operation's mode is fixed, so the field is refused there.
497
+ * The declared-mode Slack operations only (slack.message.post since 0.55.0; slack.channel.history, slack.message.update and slack.message.delete since 0.71.0): which of the app's IT-approved modes this call runs under — app (the company's Slack app; a post goes out under the grant's per-app name and the footer) or user (the signed-in person, after their consent; no name, no footer). Required when the app holds approved grants for both modes (else MODE_REQUIRED); may be omitted when it holds one, which is then used. A named mode without an approved grant is refused with MODE_NOT_GRANTED; governance never falls back to the other mode. Every other operation's mode is fixed, so the field is refused there. MCP accepts explicit user only; shared app mode is deferred.
486
498
  */
487
499
  mode?: 'app' | 'user';
488
500
  /**
@@ -384,11 +384,40 @@ export type IntegrationExecuteResult = {
384
384
  }[];
385
385
  referenceNumber?: string;
386
386
  }[];
387
+ mcp?: McpToolResult;
387
388
  };
388
389
  /**
389
390
  * An event's state (0.86.0): confirmed (Google `confirmed`, Graph not cancelled and not tentative), tentative, or cancelled.
390
391
  */
391
392
  export type CalendarEventStatus = 'confirmed' | 'tentative' | 'cancelled';
393
+ /**
394
+ * Bounded MCP CallToolResult. Content blocks are SDK-validated and redacted before delivery. Small results may be replayed in full; incomplete replay returns an explicit completion summary rather than executing again.
395
+ */
396
+ export type McpToolResult = McpToolResult1 & {
397
+ /**
398
+ * @maxItems 256
399
+ */
400
+ content?: {
401
+ [k: string]: unknown;
402
+ }[];
403
+ structuredContent?: {
404
+ [k: string]: unknown;
405
+ };
406
+ isError?: boolean;
407
+ replay?: {
408
+ complete: boolean;
409
+ summary?: string;
410
+ };
411
+ };
412
+ export type McpToolResult1 =
413
+ | {
414
+ [k: string]: unknown;
415
+ }
416
+ | {
417
+ replay: {
418
+ complete?: false;
419
+ };
420
+ };
392
421
 
393
422
  export interface ChannelMessage {
394
423
  id: string;
@@ -835,6 +835,15 @@ export const IntegrationOperations = {
835
835
  "declaredMode": false,
836
836
  "idempotencyKey": true
837
837
  },
838
+ "zohobooks.invoice.markSent": {
839
+ "kind": "saas",
840
+ "identities": [
841
+ "user"
842
+ ],
843
+ "readOnly": false,
844
+ "declaredMode": false,
845
+ "idempotencyKey": true
846
+ },
838
847
  "zohobooks.creditnote.create": {
839
848
  "kind": "saas",
840
849
  "identities": [
@@ -852,5 +861,15 @@ export const IntegrationOperations = {
852
861
  "readOnly": true,
853
862
  "declaredMode": false,
854
863
  "idempotencyKey": false
864
+ },
865
+ "mcp.tool.call": {
866
+ "kind": "mcp",
867
+ "identities": [
868
+ "user"
869
+ ],
870
+ "readOnly": false,
871
+ "declaredMode": false,
872
+ "idempotencyKey": false,
873
+ "runtimeIdempotency": true
855
874
  }
856
875
  } as const;
@@ -73,7 +73,7 @@ export interface SaasConnection {
73
73
  * Operations IT allows apps to request on this connection: the provider's own SaaS operations (Slack: slack.channel.history, slack.message.post, slack.message.update, slack.message.delete, slack.dm.send, slack.user.lookup; Gmail: gmail.thread.list, gmail.thread.read, gmail.message.read, gmail.message.send, gmail.attachment.read; Basecamp (0.76.0): basecamp.project.list, basecamp.todolist.list, basecamp.todo.list, basecamp.todo.create, basecamp.todo.complete, basecamp.message.list, basecamp.message.post, basecamp.comment.list, basecamp.comment.post, basecamp.campfire.post, basecamp.people.list; SharePoint (0.78.0): sharepoint.list.list, sharepoint.item.list, sharepoint.item.create, sharepoint.item.update, sharepoint.drive.list, sharepoint.file.list, sharepoint.file.search, sharepoint.file.read, sharepoint.file.upload; Google Workspace and Microsoft 365 (0.86.0): the calendar.*, drive.*, docs.*, sheets.*, outlook.*, onedrive.*, excel.* and teams.* operations of the connection's provider). Never warehouse.view.read. Phone (0.82.0): phone.sms.list; 0.83.0 adds phone.number.get. Seventy-eight SaaS operations in all since 0.86.0.
74
74
  *
75
75
  * @minItems 1
76
- * @maxItems 91
76
+ * @maxItems 92
77
77
  */
78
78
  operations: (
79
79
  | 'slack.channel.history'
@@ -168,13 +168,15 @@ export interface SaasConnection {
168
168
  | 'zohobooks.salesorder.list'
169
169
  | 'zohobooks.salesorder.read'
170
170
  | 'zohobooks.invoice.reviseDraft'
171
+ | 'zohobooks.invoice.markSent'
171
172
  | 'zohobooks.creditnote.create'
172
173
  | 'zohobooks.creditnote.read'
174
+ | 'mcp.tool.call'
173
175
  )[];
174
176
  /**
175
177
  * Explicit user-mode operations eligible for automatic app access, subject to the connection operation ceiling and personal consent. Empty means review all; absent inherits company defaults or the existing userModeApproval migration rule. Governance validates provider and mode compatibility. Background execution still requires personal background consent, not a separate admin grant.
176
178
  *
177
- * @maxItems 91
179
+ * @maxItems 92
178
180
  */
179
181
  automaticUserOperations?: (
180
182
  | 'slack.channel.history'
@@ -269,8 +271,10 @@ export interface SaasConnection {
269
271
  | 'zohobooks.salesorder.list'
270
272
  | 'zohobooks.salesorder.read'
271
273
  | 'zohobooks.invoice.reviseDraft'
274
+ | 'zohobooks.invoice.markSent'
272
275
  | 'zohobooks.creditnote.create'
273
276
  | 'zohobooks.creditnote.read'
277
+ | 'mcp.tool.call'
274
278
  )[];
275
279
  /**
276
280
  * Reusable permissions for admitted builders on explicit shared SaaS resources. Governance checks registered resources, provider/mode compatibility and the connection operation ceiling. Connection version and audit record changes; no per-entry approval metadata.
@@ -376,7 +380,7 @@ export interface ReusableSaasAccess {
376
380
  mode: 'app' | 'user';
377
381
  /**
378
382
  * @minItems 1
379
- * @maxItems 91
383
+ * @maxItems 92
380
384
  */
381
385
  operations: (
382
386
  | 'slack.channel.history'
@@ -471,8 +475,10 @@ export interface ReusableSaasAccess {
471
475
  | 'zohobooks.salesorder.list'
472
476
  | 'zohobooks.salesorder.read'
473
477
  | 'zohobooks.invoice.reviseDraft'
478
+ | 'zohobooks.invoice.markSent'
474
479
  | 'zohobooks.creditnote.create'
475
480
  | 'zohobooks.creditnote.read'
481
+ | 'mcp.tool.call'
476
482
  )[];
477
483
  }
478
484
  export interface DevelopmentPreapproval {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fourier-labs/harbour-contracts",
3
- "version": "0.98.0",
3
+ "version": "0.100.0",
4
4
  "description": "Single source of truth for every data shape that crosses a boundary between Isomorph components.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,