@arbium/enterprise-agent-connect 0.0.0-stage → 0.1.1

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 (137) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +117 -2
  3. package/dist/connectors/dell-techdirect/connector.json +39 -0
  4. package/dist/connectors/dell-techdirect/index.js +7 -0
  5. package/dist/connectors/dell-techdirect/index.js.map +1 -0
  6. package/dist/connectors/dell-techdirect/tools.js +49 -0
  7. package/dist/connectors/dell-techdirect/tools.js.map +1 -0
  8. package/dist/connectors/dell-techdirect/vendor.js +57 -0
  9. package/dist/connectors/dell-techdirect/vendor.js.map +1 -0
  10. package/dist/connectors/entra/connector.json +85 -0
  11. package/dist/connectors/entra/index.js +4 -0
  12. package/dist/connectors/entra/index.js.map +1 -0
  13. package/dist/connectors/entra/tools.js +262 -0
  14. package/dist/connectors/entra/tools.js.map +1 -0
  15. package/dist/connectors/fedex/connector.json +118 -0
  16. package/dist/connectors/fedex/index.js +7 -0
  17. package/dist/connectors/fedex/index.js.map +1 -0
  18. package/dist/connectors/fedex/tools.js +152 -0
  19. package/dist/connectors/fedex/tools.js.map +1 -0
  20. package/dist/connectors/fedex/vendor.js +98 -0
  21. package/dist/connectors/fedex/vendor.js.map +1 -0
  22. package/dist/connectors/http/index.js +235 -0
  23. package/dist/connectors/http/index.js.map +1 -0
  24. package/dist/connectors/intune/connector.json +106 -0
  25. package/dist/connectors/intune/index.js +4 -0
  26. package/dist/connectors/intune/index.js.map +1 -0
  27. package/dist/connectors/intune/tools.js +416 -0
  28. package/dist/connectors/intune/tools.js.map +1 -0
  29. package/dist/connectors/jira/connector.json +129 -0
  30. package/dist/connectors/jira/index.js +7 -0
  31. package/dist/connectors/jira/index.js.map +1 -0
  32. package/dist/connectors/jira/jql.js +67 -0
  33. package/dist/connectors/jira/jql.js.map +1 -0
  34. package/dist/connectors/jira/tools.js +464 -0
  35. package/dist/connectors/jira/tools.js.map +1 -0
  36. package/dist/connectors/jira/vendor.js +94 -0
  37. package/dist/connectors/jira/vendor.js.map +1 -0
  38. package/dist/connectors/microsoft/client.js +434 -0
  39. package/dist/connectors/microsoft/client.js.map +1 -0
  40. package/dist/connectors/microsoft/provider.json +118 -0
  41. package/dist/connectors/outlook-calendar/connector.json +136 -0
  42. package/dist/connectors/outlook-calendar/index.js +4 -0
  43. package/dist/connectors/outlook-calendar/index.js.map +1 -0
  44. package/dist/connectors/outlook-calendar/tools.js +398 -0
  45. package/dist/connectors/outlook-calendar/tools.js.map +1 -0
  46. package/dist/connectors/outlook-mail/connector.json +154 -0
  47. package/dist/connectors/outlook-mail/index.js +4 -0
  48. package/dist/connectors/outlook-mail/index.js.map +1 -0
  49. package/dist/connectors/outlook-mail/tools.js +236 -0
  50. package/dist/connectors/outlook-mail/tools.js.map +1 -0
  51. package/dist/connectors/salesforce/connector.json +122 -0
  52. package/dist/connectors/salesforce/index.js +7 -0
  53. package/dist/connectors/salesforce/index.js.map +1 -0
  54. package/dist/connectors/salesforce/soql.js +60 -0
  55. package/dist/connectors/salesforce/soql.js.map +1 -0
  56. package/dist/connectors/salesforce/tools.js +234 -0
  57. package/dist/connectors/salesforce/tools.js.map +1 -0
  58. package/dist/connectors/salesforce/vendor.js +107 -0
  59. package/dist/connectors/salesforce/vendor.js.map +1 -0
  60. package/dist/connectors/sharepoint-files/connector.json +194 -0
  61. package/dist/connectors/sharepoint-files/excel.js +300 -0
  62. package/dist/connectors/sharepoint-files/excel.js.map +1 -0
  63. package/dist/connectors/sharepoint-files/index.js +12 -0
  64. package/dist/connectors/sharepoint-files/index.js.map +1 -0
  65. package/dist/connectors/sharepoint-files/tools.js +365 -0
  66. package/dist/connectors/sharepoint-files/tools.js.map +1 -0
  67. package/dist/connectors/sharepoint-files/vendor.js +167 -0
  68. package/dist/connectors/sharepoint-files/vendor.js.map +1 -0
  69. package/dist/connectors/teams/connector.json +298 -0
  70. package/dist/connectors/teams/index.js +5 -0
  71. package/dist/connectors/teams/index.js.map +1 -0
  72. package/dist/connectors/teams/tools.js +391 -0
  73. package/dist/connectors/teams/tools.js.map +1 -0
  74. package/dist/packages/connector-kit/src/branding.js +102 -0
  75. package/dist/packages/connector-kit/src/branding.js.map +1 -0
  76. package/dist/packages/connector-kit/src/certificate.js +84 -0
  77. package/dist/packages/connector-kit/src/certificate.js.map +1 -0
  78. package/dist/packages/connector-kit/src/common.js +107 -0
  79. package/dist/packages/connector-kit/src/common.js.map +1 -0
  80. package/dist/packages/connector-kit/src/connector.js +492 -0
  81. package/dist/packages/connector-kit/src/connector.js.map +1 -0
  82. package/dist/packages/connector-kit/src/oauth.js +79 -0
  83. package/dist/packages/connector-kit/src/oauth.js.map +1 -0
  84. package/dist/packages/connector-kit/src/types.js +20 -0
  85. package/dist/packages/connector-kit/src/types.js.map +1 -0
  86. package/dist/packages/server/migrations/0001_tables.sql +268 -0
  87. package/dist/packages/server/migrations/0002_organizations.sql +72 -0
  88. package/dist/packages/server/migrations/0003_drop_unused.sql +3 -0
  89. package/dist/packages/server/migrations/0004_trigger_runners.sql +15 -0
  90. package/dist/packages/server/migrations/0005_run_runner.sql +3 -0
  91. package/dist/packages/server/migrations/0006_approvals.sql +36 -0
  92. package/dist/packages/server/migrations/rollback/to-legacy.sql +87 -0
  93. package/dist/packages/server/src/api.js +684 -0
  94. package/dist/packages/server/src/api.js.map +1 -0
  95. package/dist/packages/server/src/app.js +444 -0
  96. package/dist/packages/server/src/app.js.map +1 -0
  97. package/dist/packages/server/src/builtin.js +24 -0
  98. package/dist/packages/server/src/builtin.js.map +1 -0
  99. package/dist/packages/server/src/consent.js +36 -0
  100. package/dist/packages/server/src/consent.js.map +1 -0
  101. package/dist/packages/server/src/index.js +129 -0
  102. package/dist/packages/server/src/index.js.map +1 -0
  103. package/dist/packages/server/src/migrate.js +134 -0
  104. package/dist/packages/server/src/migrate.js.map +1 -0
  105. package/dist/packages/server/src/openapi.js +101 -0
  106. package/dist/packages/server/src/openapi.js.map +1 -0
  107. package/dist/packages/server/src/secrets.js +76 -0
  108. package/dist/packages/server/src/secrets.js.map +1 -0
  109. package/dist/packages/server/src/server.js +69 -0
  110. package/dist/packages/server/src/server.js.map +1 -0
  111. package/dist/packages/server/src/service.js +908 -0
  112. package/dist/packages/server/src/service.js.map +1 -0
  113. package/dist/packages/server/src/store.js +411 -0
  114. package/dist/packages/server/src/store.js.map +1 -0
  115. package/dist/packages/server/src/teams/activity.js +187 -0
  116. package/dist/packages/server/src/teams/activity.js.map +1 -0
  117. package/dist/packages/server/src/teams/admin.js +699 -0
  118. package/dist/packages/server/src/teams/admin.js.map +1 -0
  119. package/dist/packages/server/src/teams/approval.js +118 -0
  120. package/dist/packages/server/src/teams/approval.js.map +1 -0
  121. package/dist/packages/server/src/teams/bot.js +124 -0
  122. package/dist/packages/server/src/teams/bot.js.map +1 -0
  123. package/dist/packages/server/src/teams/claude.js +165 -0
  124. package/dist/packages/server/src/teams/claude.js.map +1 -0
  125. package/dist/packages/server/src/teams/jwt.js +121 -0
  126. package/dist/packages/server/src/teams/jwt.js.map +1 -0
  127. package/dist/packages/server/src/teams/package.js +319 -0
  128. package/dist/packages/server/src/teams/package.js.map +1 -0
  129. package/dist/packages/server/src/teams/provision.js +505 -0
  130. package/dist/packages/server/src/teams/provision.js.map +1 -0
  131. package/dist/packages/server/src/teams/runner.js +143 -0
  132. package/dist/packages/server/src/teams/runner.js.map +1 -0
  133. package/dist/packages/server/src/teams/runtime.js +701 -0
  134. package/dist/packages/server/src/teams/runtime.js.map +1 -0
  135. package/dist/packages/server/src/teams/store.js +507 -0
  136. package/dist/packages/server/src/teams/store.js.map +1 -0
  137. package/package.json +42 -4
@@ -0,0 +1,154 @@
1
+ {
2
+ "id": "outlook-mail",
3
+ "name": "Outlook mail",
4
+ "description": "Let each agent read and work on mail in its own mailbox.",
5
+ "logo": "/brand/outlook.svg",
6
+ "identity": "Your Microsoft app registration, through the Microsoft connection. Exchange lets it open only the mailboxes you choose for agents, and it uses no Microsoft 365 license.",
7
+ "provider": "microsoft",
8
+ "order": 1,
9
+ "accountKey": "tenantId",
10
+ "connectionKind": "guided",
11
+ "setup": [
12
+ {
13
+ "title": "Make sure the app cannot open every mailbox",
14
+ "body": "Outlook mail needs no Microsoft Graph permission on the app. Do not add Mail.Read, Mail.Send or Mail.ReadWrite under API permissions: they open every mailbox in your organization.",
15
+ "click": [
16
+ "In the Microsoft Entra admin center, go to Entra ID, then App registrations, open {brand.microsoft.appName} and select API permissions.",
17
+ "Check that no Mail permission is listed. Remove any that is."
18
+ ],
19
+ "copy": ["az ad app permission list --id {clientId} -o table"],
20
+ "shell": "bash"
21
+ },
22
+ {
23
+ "title": "Create the {brand.microsoft.mailboxGroup} group",
24
+ "body": "Agents can only reach mailboxes in this mail-enabled security group. Outlook calendar uses the same group, so you create it once. Each agent's mailbox is added to it when you make the agent's API key, on the Integrations tab.",
25
+ "link": {
26
+ "label": "Open the Exchange admin center",
27
+ "href": "https://admin.exchange.microsoft.com/#/groups"
28
+ },
29
+ "click": [
30
+ "In the Exchange admin center, go to Recipients, then Groups, then Mail-enabled security, and select Add a group.",
31
+ "Choose Mail-enabled security and select Next. Name it {brand.microsoft.mailboxGroup}, then Next.",
32
+ "Assign yourself as owner, skip members (you add each agent's mailbox later), then Next.",
33
+ "On Edit settings, enter a group email address such as {brand.microsoft.mailboxGroupAlias}@your-domain, then Next and Create group."
34
+ ],
35
+ "copy": [
36
+ "# Needs the ExchangeOnlineManagement module: Install-Module ExchangeOnlineManagement -Scope CurrentUser",
37
+ "Connect-ExchangeOnline",
38
+ "if (-not (Get-DistributionGroup -Identity '{brand.microsoft.mailboxGroup}' -ErrorAction SilentlyContinue)) { New-DistributionGroup -Name '{brand.microsoft.mailboxGroup}' -Type Security }"
39
+ ],
40
+ "shell": "powershell",
41
+ "confirm": "mailbox-group"
42
+ },
43
+ {
44
+ "title": "Limit the app to the mailboxes in that group",
45
+ "body": "This is the only mail access the app gets. Exchange enforces it, so the app cannot open any other mailbox. The role lines follow what you ticked in step 1; if you tick more later, run the matching New-ManagementRoleAssignment line again. Lines for what already exists (from Outlook calendar) are skipped. Exchange can take up to 2 hours to apply this before Check access passes.",
46
+ "link": {
47
+ "label": "Connect to Exchange Online PowerShell",
48
+ "href": "https://learn.microsoft.com/powershell/exchange/connect-to-exchange-online-powershell"
49
+ },
50
+ "clickUnavailable": true,
51
+ "copy": [
52
+ "# Needs the ExchangeOnlineManagement module: Install-Module ExchangeOnlineManagement -Scope CurrentUser",
53
+ "Connect-ExchangeOnline",
54
+ "if (-not (Get-ServicePrincipal -Identity {clientId} -ErrorAction SilentlyContinue)) { New-ServicePrincipal -AppId {clientId} -ObjectId {servicePrincipalId} -DisplayName \"{brand.microsoft.appName}\" }",
55
+ "if (-not (Get-ManagementScope -Identity \"{brand.microsoft.mailboxGroup}\" -ErrorAction SilentlyContinue)) { New-ManagementScope -Name \"{brand.microsoft.mailboxGroup}\" -RecipientRestrictionFilter \"MemberOfGroup -eq '$((Get-DistributionGroup '{brand.microsoft.mailboxGroup}').DistinguishedName)'\" }",
56
+ "New-ManagementRoleAssignment -Role \"{scope}\" -App {clientId} -CustomResourceScope \"{brand.microsoft.mailboxGroup}\""
57
+ ],
58
+ "shell": "powershell",
59
+ "confirm": "mail-roles"
60
+ }
61
+ ],
62
+ "afterConnect": [],
63
+ "fields": [],
64
+ "capabilities": [
65
+ {
66
+ "id": "read",
67
+ "label": "Read mail",
68
+ "description": "List and read messages in the agent's own mailbox.",
69
+ "required": true,
70
+ "scopes": ["Application Mail.Read"],
71
+ "roles": [],
72
+ "permissions": [],
73
+ "tools": ["mail_list_messages", "mail_get_message"],
74
+ "forbidden": "Microsoft refused this. The app needs the Exchange role {scopes} on the {brand.microsoft.mailboxGroup} scope, and this mailbox must be in that group. A role added in the last hour may not apply yet."
75
+ },
76
+ {
77
+ "id": "send",
78
+ "label": "Send mail",
79
+ "description": "Send new messages and reply from the agent's own mailbox.",
80
+ "scopes": ["Application Mail.Send"],
81
+ "roles": [],
82
+ "permissions": [],
83
+ "tools": ["mail_send", "mail_reply"],
84
+ "forbidden": "Microsoft refused this. The app needs the Exchange role {scopes} on the {brand.microsoft.mailboxGroup} scope, and this mailbox must be in that group. A role added in the last hour may not apply yet."
85
+ },
86
+ {
87
+ "id": "organize",
88
+ "label": "Organize mail",
89
+ "description": "Move messages between folders, flag them and mark them read or unread.",
90
+ "scopes": ["Application Mail.ReadWrite"],
91
+ "roles": [],
92
+ "permissions": [],
93
+ "tools": ["mail_move", "mail_flag", "mail_mark_read"],
94
+ "forbidden": "Microsoft refused this. The app needs the Exchange role {scopes} on the {brand.microsoft.mailboxGroup} scope, and this mailbox must be in that group. A role added in the last hour may not apply yet."
95
+ },
96
+ {
97
+ "id": "delete",
98
+ "label": "Delete mail",
99
+ "description": "Delete messages. They go to Deleted Items, where Microsoft 365 removes them after a while.",
100
+ "destructive": true,
101
+ "scopes": ["Application Mail.ReadWrite"],
102
+ "roles": [],
103
+ "permissions": [],
104
+ "tools": ["mail_delete"],
105
+ "forbidden": "Microsoft refused this. The app needs the Exchange role {scopes} on the {brand.microsoft.mailboxGroup} scope, and this mailbox must be in that group. A role added in the last hour may not apply yet."
106
+ }
107
+ ],
108
+ "limits": [
109
+ {
110
+ "id": "mailbox",
111
+ "label": "Mailbox",
112
+ "help": "The agent's own mailbox, a member of {brand.microsoft.mailboxGroup}. The agent can use no other.",
113
+ "kind": "text",
114
+ "required": true,
115
+ "pattern": "^[A-Za-z0-9._+-]+@[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)+$"
116
+ }
117
+ ],
118
+ "verify": {
119
+ "label": "Microsoft Graph permissions on the app (Outlook mail needs none: Exchange limits it to the {brand.microsoft.mailboxGroup} group)",
120
+ "check": "permissions"
121
+ },
122
+ "revoke": "In Exchange Online PowerShell, remove the app's mailbox access with Get-ManagementRoleAssignment -RoleAssignee {clientId} | Remove-ManagementRoleAssignment. To stop every Microsoft app at once, remove the app registration (see the Microsoft connection).",
123
+ "agentAccess": {
124
+ "limit": "mailbox",
125
+ "label": "Exchange lets the app open an agent's mailbox",
126
+ "path": "/v1.0/users/{value}/mailFolders/inbox?$select=id",
127
+ "granted": "The app can open this mailbox.",
128
+ "notGranted": "Exchange does not let the app open this mailbox yet. Check that it is in {brand.microsoft.mailboxGroup}. Also check that the app's mailbox access was given (step 3 on the Outlook mail page), and run Test-ServicePrincipalAuthorization to see which roles apply. Microsoft can take up to about 2 hours to apply a change.",
129
+ "notFound": "Exchange shows the app no mailbox at this address. Either there is none yet (check the address, or wait a few minutes if you just created it), or it is not in {brand.microsoft.mailboxGroup} yet: Exchange answers the same for a mailbox the app may not open. Microsoft can take up to about 2 hours to apply a change.",
130
+ "probes": {
131
+ "send": {
132
+ "method": "POST",
133
+ "path": "/v1.0/users/{value}/sendMail",
134
+ "body": {
135
+ "message": {}
136
+ },
137
+ "allowed": [400]
138
+ },
139
+ "organize": {
140
+ "method": "PATCH",
141
+ "path": "/v1.0/users/{value}/mailFolders/inbox",
142
+ "body": {},
143
+ "allowed": [200]
144
+ },
145
+ "delete": {
146
+ "method": "PATCH",
147
+ "path": "/v1.0/users/{value}/mailFolders/inbox",
148
+ "body": {},
149
+ "allowed": [200]
150
+ }
151
+ },
152
+ "missing": "The app can open this mailbox but Exchange does not let it do this yet: {missing}. Give that role (the step Limit the app to the mailboxes in that group, on the Outlook mail page) and check again. Microsoft can take up to about 2 hours to apply a change."
153
+ }
154
+ }
@@ -0,0 +1,4 @@
1
+ import { microsoftApp } from "../microsoft/client.js";
2
+ import { microsoftTools } from "./tools.js";
3
+ export default microsoftApp("outlook-mail", microsoftTools);
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../connectors/outlook-mail/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,eAAe,YAAY,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC"}
@@ -0,0 +1,236 @@
1
+ import { z } from "zod";
2
+ import { audited, Denied, json, textLimit, VendorFailed, } from "../../packages/connector-kit/src/common.js";
3
+ // Every call goes to the mailbox in the agent's grant. No tool takes a mailbox argument, so
4
+ // an agent cannot name another one.
5
+ const MOVE_TO = ["inbox", "archive"];
6
+ const MESSAGE_ID = /^[A-Za-z0-9_=-]{1,1024}$/;
7
+ const LIST_FIELDS = "id,subject,from,toRecipients,receivedDateTime,isRead,bodyPreview";
8
+ const MESSAGE_FIELDS = `${LIST_FIELDS},ccRecipients,body,conversationId,hasAttachments`;
9
+ // Where a listing continues: Graph pages a folder or calendar with $skip and a search with $skiptoken, so
10
+ // the cursor says which ("s" or "t") and carries only that value, never a path.
11
+ export function nextPage(data) {
12
+ const q = URL.parse(data["@odata.nextLink"] ?? "")?.searchParams;
13
+ const token = q?.get("$skiptoken");
14
+ const skip = q?.get("$skip");
15
+ return token ? `t${token}` : skip ? `s${skip}` : null;
16
+ }
17
+ export function pageParam(cursor) {
18
+ if (cursor === undefined)
19
+ return [];
20
+ if (/^s\d{1,6}$/.test(cursor))
21
+ return [`$skip=${cursor.slice(1)}`];
22
+ if (/^t.+$/.test(cursor))
23
+ return [`$skiptoken=${encodeURIComponent(cursor.slice(1))}`];
24
+ throw new Denied("Give cursor as the next value from the previous call");
25
+ }
26
+ export function mailboxPath(ctx) {
27
+ const mailbox = textLimit(ctx.limits, "mailbox");
28
+ if (!mailbox)
29
+ throw new Denied("No mailbox is set for this agent. Ask an administrator to set one.");
30
+ return `/v1.0/users/${encodeURIComponent(mailbox)}`;
31
+ }
32
+ function messagePath(ctx, id) {
33
+ if (!MESSAGE_ID.test(id))
34
+ throw new Denied("Give a message id from mail_list_messages");
35
+ return `${mailboxPath(ctx)}/messages/${encodeURIComponent(id)}`;
36
+ }
37
+ export async function ok(ctx, mark, req) {
38
+ const res = await ctx.call(req);
39
+ mark(res.status);
40
+ if (res.status < 200 || res.status >= 300) {
41
+ const message = res.data?.error?.message;
42
+ throw new VendorFailed(res.status, `Microsoft 365 answered ${res.status}${message ? `: ${message}` : ""}`);
43
+ }
44
+ return res.data;
45
+ }
46
+ const address = (a) => a?.emailAddress?.address ?? null;
47
+ const recipients = (list) => list.map((address) => ({ emailAddress: { address } }));
48
+ function summary(m) {
49
+ return {
50
+ id: m.id,
51
+ subject: m.subject ?? "",
52
+ from: address(m.from),
53
+ to: (m.toRecipients ?? []).map(address),
54
+ received: m.receivedDateTime ?? null,
55
+ read: m.isRead ?? null,
56
+ preview: m.bodyPreview ?? "",
57
+ };
58
+ }
59
+ export const microsoftTools = {
60
+ names: [
61
+ "mail_list_messages",
62
+ "mail_get_message",
63
+ "mail_send",
64
+ "mail_reply",
65
+ "mail_move",
66
+ "mail_flag",
67
+ "mail_mark_read",
68
+ "mail_delete",
69
+ ],
70
+ register(server, ctx, allowed) {
71
+ const readOnly = { readOnlyHint: true, openWorldHint: true };
72
+ const sends = { readOnlyHint: false, destructiveHint: false, openWorldHint: true };
73
+ const emails = z.array(z.email()).max(50);
74
+ if (allowed.has("mail_list_messages"))
75
+ server.registerTool("mail_list_messages", {
76
+ description: "List recent messages in this agent's mailbox, newest first. A page can hold few or none while more follow: when `more` is true, call again with `cursor` set to `next`.",
77
+ inputSchema: z.object({
78
+ folder: z.enum(["inbox", "sentitems", "drafts", "archive"]).default("inbox"),
79
+ search: z.string().max(200).optional().describe("Words to search for."),
80
+ unread_only: z.boolean().default(false),
81
+ max_results: z.number().int().min(1).max(50).default(20),
82
+ cursor: z
83
+ .string()
84
+ .max(4000)
85
+ .optional()
86
+ .describe("The `next` value from the previous call with the same folder, search and unread_only: the following page."),
87
+ }),
88
+ annotations: readOnly,
89
+ }, ({ folder, search, unread_only, max_results, cursor }) => audited(ctx, "mail_list_messages", folder, async (mark) => {
90
+ const query = [`$top=${max_results}`, `$select=${LIST_FIELDS}`, ...pageParam(cursor)];
91
+ // Microsoft does not combine $search with $filter on messages.
92
+ const words = search?.replaceAll('"', "").trim();
93
+ if (words)
94
+ query.push(`$search=${encodeURIComponent(`"${words}"`)}`);
95
+ else if (unread_only)
96
+ query.push(`$filter=${encodeURIComponent("isRead eq false")}`);
97
+ const data = await ok(ctx, mark, {
98
+ method: "GET",
99
+ path: `${mailboxPath(ctx)}/mailFolders/${folder}/messages?${query.join("&")}`,
100
+ });
101
+ const messages = data.value
102
+ .filter((m) => !unread_only || m.isRead === false)
103
+ .map(summary);
104
+ return json({ messages, more: Boolean(data["@odata.nextLink"]), next: nextPage(data) });
105
+ }));
106
+ if (allowed.has("mail_get_message"))
107
+ server.registerTool("mail_get_message", {
108
+ description: "Read one message in this agent's mailbox, with its body as plain text.",
109
+ inputSchema: z.object({ message_id: z.string().describe("Id from mail_list_messages.") }),
110
+ annotations: readOnly,
111
+ }, ({ message_id }) => audited(ctx, "mail_get_message", message_id, async (mark) => {
112
+ const m = await ok(ctx, mark, {
113
+ method: "GET",
114
+ path: `${messagePath(ctx, message_id)}?$select=${MESSAGE_FIELDS}`,
115
+ headers: { prefer: 'outlook.body-content-type="text"' },
116
+ });
117
+ return json({
118
+ ...summary(m),
119
+ cc: (m.ccRecipients ?? []).map(address),
120
+ conversation: m.conversationId ?? null,
121
+ attachments: m.hasAttachments ?? false,
122
+ body: m.body?.content ?? "",
123
+ });
124
+ }));
125
+ if (allowed.has("mail_send"))
126
+ server.registerTool("mail_send", {
127
+ description: "Send a plain-text email from this agent's mailbox.",
128
+ inputSchema: z.object({
129
+ to: emails.min(1),
130
+ cc: emails.default([]),
131
+ subject: z.string().min(1).max(255),
132
+ body: z.string().min(1).max(100000),
133
+ }),
134
+ annotations: sends,
135
+ }, ({ to, cc, subject, body }) => audited(ctx, "mail_send", [...to, ...cc].join(", "), async (mark) => {
136
+ await ok(ctx, mark, {
137
+ method: "POST",
138
+ path: `${mailboxPath(ctx)}/sendMail`,
139
+ body: {
140
+ message: {
141
+ subject,
142
+ body: { contentType: "Text", content: body },
143
+ toRecipients: recipients(to),
144
+ ccRecipients: recipients(cc),
145
+ },
146
+ saveToSentItems: true,
147
+ },
148
+ });
149
+ return json({ sent: true });
150
+ }));
151
+ if (allowed.has("mail_reply"))
152
+ server.registerTool("mail_reply", {
153
+ description: "Reply to the sender of a message in this agent's mailbox.",
154
+ inputSchema: z.object({
155
+ message_id: z.string().describe("Id from mail_list_messages."),
156
+ body: z.string().min(1).max(100000),
157
+ }),
158
+ annotations: sends,
159
+ }, ({ message_id, body }) => audited(ctx, "mail_reply", message_id, async (mark) => {
160
+ await ok(ctx, mark, {
161
+ method: "POST",
162
+ path: `${messagePath(ctx, message_id)}/reply`,
163
+ body: { comment: body },
164
+ });
165
+ return json({ sent: true });
166
+ }));
167
+ const organizes = { readOnlyHint: false, destructiveHint: false, openWorldHint: true };
168
+ const messageId = z.string().describe("Id from mail_list_messages.");
169
+ if (allowed.has("mail_move"))
170
+ server.registerTool("mail_move", {
171
+ // Deleted Items and Junk Email (purged automatically) would be deleting, which
172
+ // mail_delete covers. Checked inside audited() so a refusal is logged.
173
+ description: "Move a message in this agent's mailbox to another folder.",
174
+ inputSchema: z.object({
175
+ message_id: messageId,
176
+ folder: z.string().max(50).describe("inbox or archive"),
177
+ }),
178
+ annotations: organizes,
179
+ }, ({ message_id, folder }) => audited(ctx, "mail_move", `${message_id} → ${folder}`, async (mark) => {
180
+ if (!MOVE_TO.includes(folder))
181
+ throw new Denied("Messages can be moved to inbox or archive");
182
+ const moved = await ok(ctx, mark, {
183
+ method: "POST",
184
+ path: `${messagePath(ctx, message_id)}/move`,
185
+ body: { destinationId: folder },
186
+ });
187
+ // Moving gives the message a new id.
188
+ return json({ moved: true, message_id: moved?.id ?? null });
189
+ }));
190
+ if (allowed.has("mail_flag"))
191
+ server.registerTool("mail_flag", {
192
+ description: "Flag a message in this agent's mailbox, mark it complete, or clear the flag.",
193
+ inputSchema: z.object({
194
+ message_id: messageId,
195
+ flag: z.enum(["flagged", "complete", "notFlagged"]),
196
+ }),
197
+ annotations: organizes,
198
+ }, ({ message_id, flag }) => audited(ctx, "mail_flag", `${message_id}: ${flag}`, async (mark) => {
199
+ await ok(ctx, mark, {
200
+ method: "PATCH",
201
+ path: messagePath(ctx, message_id),
202
+ body: { flag: { flagStatus: flag } },
203
+ });
204
+ return json({ flag });
205
+ }));
206
+ if (allowed.has("mail_mark_read"))
207
+ server.registerTool("mail_mark_read", {
208
+ description: "Mark a message in this agent's mailbox read or unread.",
209
+ inputSchema: z.object({ message_id: messageId, read: z.boolean().default(true) }),
210
+ annotations: organizes,
211
+ }, ({ message_id, read }) => audited(ctx, "mail_mark_read", `${message_id}: ${read ? "read" : "unread"}`, async (mark) => {
212
+ await ok(ctx, mark, {
213
+ method: "PATCH",
214
+ path: messagePath(ctx, message_id),
215
+ body: { isRead: read },
216
+ });
217
+ return json({ read });
218
+ }));
219
+ if (allowed.has("mail_delete"))
220
+ server.registerTool("mail_delete", {
221
+ description: "Delete a message in this agent's mailbox: it moves to Deleted Items, where it can be restored until Microsoft 365 empties the folder.",
222
+ inputSchema: z.object({ message_id: messageId }),
223
+ annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: true },
224
+ }, ({ message_id }) => audited(ctx, "mail_delete", message_id, async (mark) => {
225
+ // A DELETE skips Deleted Items (it goes straight to Recoverable Items, which only
226
+ // an administrator can reach); a move keeps it where people look for it.
227
+ const moved = await ok(ctx, mark, {
228
+ method: "POST",
229
+ path: `${messagePath(ctx, message_id)}/move`,
230
+ body: { destinationId: "deleteditems" },
231
+ });
232
+ return json({ deleted: true, folder: "deleteditems", message_id: moved.id });
233
+ }));
234
+ },
235
+ };
236
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../connectors/outlook-mail/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,OAAO,EACP,MAAM,EACN,IAAI,EACJ,SAAS,EACT,YAAY,GAGb,MAAM,4CAA4C,CAAC;AAEpD,4FAA4F;AAC5F,oCAAoC;AAEpC,MAAM,OAAO,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;AACrC,MAAM,UAAU,GAAG,0BAA0B,CAAC;AAC9C,MAAM,WAAW,GAAG,kEAAkE,CAAC;AACvF,MAAM,cAAc,GAAG,GAAG,WAAW,kDAAkD,CAAC;AAExF,0GAA0G;AAC1G,gFAAgF;AAChF,MAAM,UAAU,QAAQ,CAAC,IAAoC;IAC3D,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC,EAAE,YAAY,CAAC;IACjE,MAAM,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7B,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACxD,CAAC;AACD,MAAM,UAAU,SAAS,CAAC,MAA0B;IAClD,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACpC,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,CAAC,SAAS,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACnE,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,CAAC,cAAc,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACvF,MAAM,IAAI,MAAM,CAAC,sDAAsD,CAAC,CAAC;AAC3E,CAAC;AAiBD,MAAM,UAAU,WAAW,CAAC,GAAgB;IAC1C,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACjD,IAAI,CAAC,OAAO;QACV,MAAM,IAAI,MAAM,CAAC,oEAAoE,CAAC,CAAC;IACzF,OAAO,eAAe,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;AACtD,CAAC;AAED,SAAS,WAAW,CAAC,GAAgB,EAAE,EAAU;IAC/C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,MAAM,IAAI,MAAM,CAAC,2CAA2C,CAAC,CAAC;IACxF,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,aAAa,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC;AAClE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,EAAE,CACtB,GAAgB,EAChB,IAAyB,EACzB,GAAuC;IAEvC,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjB,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;QAC1C,MAAM,OAAO,GAAI,GAAG,CAAC,IAAgD,EAAE,KAAK,EAAE,OAAO,CAAC;QACtF,MAAM,IAAI,YAAY,CACpB,GAAG,CAAC,MAAM,EACV,0BAA0B,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CACvE,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC,IAAW,CAAC;AACzB,CAAC;AAED,MAAM,OAAO,GAAG,CAAC,CAAW,EAAE,EAAE,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,IAAI,IAAI,CAAC;AAClE,MAAM,UAAU,GAAG,CAAC,IAAc,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAE9F,SAAS,OAAO,CAAC,CAAU;IACzB,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,EAAE;QACxB,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;QACrB,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;QACvC,QAAQ,EAAE,CAAC,CAAC,gBAAgB,IAAI,IAAI;QACpC,IAAI,EAAE,CAAC,CAAC,MAAM,IAAI,IAAI;QACtB,OAAO,EAAE,CAAC,CAAC,WAAW,IAAI,EAAE;KAC7B,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAY;IACrC,KAAK,EAAE;QACL,oBAAoB;QACpB,kBAAkB;QAClB,WAAW;QACX,YAAY;QACZ,WAAW;QACX,WAAW;QACX,gBAAgB;QAChB,aAAa;KACd;IAED,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO;QAC3B,MAAM,QAAQ,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAW,CAAC;QACtE,MAAM,KAAK,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAW,CAAC;QAC5F,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAE1C,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;YACnC,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;gBACE,WAAW,EACT,yKAAyK;gBAC3K,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;oBACpB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;oBAC5E,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;oBACvE,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;oBACvC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;oBACxD,MAAM,EAAE,CAAC;yBACN,MAAM,EAAE;yBACR,GAAG,CAAC,IAAI,CAAC;yBACT,QAAQ,EAAE;yBACV,QAAQ,CACP,2GAA2G,CAC5G;iBACJ,CAAC;gBACF,WAAW,EAAE,QAAQ;aACtB,EACD,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,CACvD,OAAO,CAAC,GAAG,EAAE,oBAAoB,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBACxD,MAAM,KAAK,GAAG,CAAC,QAAQ,WAAW,EAAE,EAAE,WAAW,WAAW,EAAE,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;gBACtF,+DAA+D;gBAC/D,MAAM,KAAK,GAAG,MAAM,EAAE,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBACjD,IAAI,KAAK;oBAAE,KAAK,CAAC,IAAI,CAAC,WAAW,kBAAkB,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC;qBAChE,IAAI,WAAW;oBAAE,KAAK,CAAC,IAAI,CAAC,WAAW,kBAAkB,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;gBACrF,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE;oBAC/B,MAAM,EAAE,KAAK;oBACb,IAAI,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,gBAAgB,MAAM,aAAa,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;iBAC9E,CAAC,CAAC;gBACH,MAAM,QAAQ,GAAI,IAAI,CAAC,KAAmB;qBACvC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC;qBACjD,GAAG,CAAC,OAAO,CAAC,CAAC;gBAChB,OAAO,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC1F,CAAC,CAAC,CACL,CAAC;QAEJ,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;YACjC,MAAM,CAAC,YAAY,CACjB,kBAAkB,EAClB;gBACE,WAAW,EAAE,wEAAwE;gBACrF,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC,EAAE,CAAC;gBACzF,WAAW,EAAE,QAAQ;aACtB,EACD,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CACjB,OAAO,CAAC,GAAG,EAAE,kBAAkB,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBAC1D,MAAM,CAAC,GAAY,MAAM,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE;oBACrC,MAAM,EAAE,KAAK;oBACb,IAAI,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,UAAU,CAAC,YAAY,cAAc,EAAE;oBACjE,OAAO,EAAE,EAAE,MAAM,EAAE,kCAAkC,EAAE;iBACxD,CAAC,CAAC;gBACH,OAAO,IAAI,CAAC;oBACV,GAAG,OAAO,CAAC,CAAC,CAAC;oBACb,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;oBACvC,YAAY,EAAE,CAAC,CAAC,cAAc,IAAI,IAAI;oBACtC,WAAW,EAAE,CAAC,CAAC,cAAc,IAAI,KAAK;oBACtC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE;iBAC5B,CAAC,CAAC;YACL,CAAC,CAAC,CACL,CAAC;QAEJ,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;YAC1B,MAAM,CAAC,YAAY,CACjB,WAAW,EACX;gBACE,WAAW,EAAE,oDAAoD;gBACjE,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;oBACpB,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;oBACjB,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;oBACtB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;oBACnC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;iBACpC,CAAC;gBACF,WAAW,EAAE,KAAK;aACnB,EACD,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAC5B,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBAClE,MAAM,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE;oBAClB,MAAM,EAAE,MAAM;oBACd,IAAI,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,WAAW;oBACpC,IAAI,EAAE;wBACJ,OAAO,EAAE;4BACP,OAAO;4BACP,IAAI,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;4BAC5C,YAAY,EAAE,UAAU,CAAC,EAAE,CAAC;4BAC5B,YAAY,EAAE,UAAU,CAAC,EAAE,CAAC;yBAC7B;wBACD,eAAe,EAAE,IAAI;qBACtB;iBACF,CAAC,CAAC;gBACH,OAAO,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9B,CAAC,CAAC,CACL,CAAC;QAEJ,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;YAC3B,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;gBACE,WAAW,EAAE,2DAA2D;gBACxE,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;oBACpB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;oBAC9D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;iBACpC,CAAC;gBACF,WAAW,EAAE,KAAK;aACnB,EACD,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,CACvB,OAAO,CAAC,GAAG,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBACpD,MAAM,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE;oBAClB,MAAM,EAAE,MAAM;oBACd,IAAI,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,UAAU,CAAC,QAAQ;oBAC7C,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;iBACxB,CAAC,CAAC;gBACH,OAAO,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9B,CAAC,CAAC,CACL,CAAC;QAEJ,MAAM,SAAS,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAW,CAAC;QAChG,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC,CAAC;QAErE,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;YAC1B,MAAM,CAAC,YAAY,CACjB,WAAW,EACX;gBACE,+EAA+E;gBAC/E,uEAAuE;gBACvE,WAAW,EAAE,2DAA2D;gBACxE,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;oBACpB,UAAU,EAAE,SAAS;oBACrB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC;iBACxD,CAAC;gBACF,WAAW,EAAE,SAAS;aACvB,EACD,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,CACzB,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,UAAU,MAAM,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBACpE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;oBAC3B,MAAM,IAAI,MAAM,CAAC,2CAA2C,CAAC,CAAC;gBAChE,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE;oBAChC,MAAM,EAAE,MAAM;oBACd,IAAI,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,UAAU,CAAC,OAAO;oBAC5C,IAAI,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE;iBAChC,CAAC,CAAC;gBACH,qCAAqC;gBACrC,OAAO,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;YAC9D,CAAC,CAAC,CACL,CAAC;QAEJ,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;YAC1B,MAAM,CAAC,YAAY,CACjB,WAAW,EACX;gBACE,WAAW,EACT,8EAA8E;gBAChF,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;oBACpB,UAAU,EAAE,SAAS;oBACrB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;iBACpD,CAAC;gBACF,WAAW,EAAE,SAAS;aACvB,EACD,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,CACvB,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,UAAU,KAAK,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBACjE,MAAM,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE;oBAClB,MAAM,EAAE,OAAO;oBACf,IAAI,EAAE,WAAW,CAAC,GAAG,EAAE,UAAU,CAAC;oBAClC,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE;iBACrC,CAAC,CAAC;gBACH,OAAO,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;YACxB,CAAC,CAAC,CACL,CAAC;QAEJ,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;YAC/B,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;gBACE,WAAW,EAAE,wDAAwD;gBACrE,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACjF,WAAW,EAAE,SAAS;aACvB,EACD,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,CACvB,OAAO,CACL,GAAG,EACH,gBAAgB,EAChB,GAAG,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,EAC5C,KAAK,EAAE,IAAI,EAAE,EAAE;gBACb,MAAM,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE;oBAClB,MAAM,EAAE,OAAO;oBACf,IAAI,EAAE,WAAW,CAAC,GAAG,EAAE,UAAU,CAAC;oBAClC,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;iBACvB,CAAC,CAAC;gBACH,OAAO,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;YACxB,CAAC,CACF,CACJ,CAAC;QAEJ,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;YAC5B,MAAM,CAAC,YAAY,CACjB,aAAa,EACb;gBACE,WAAW,EACT,uIAAuI;gBACzI,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;gBAChD,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;aACjF,EACD,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CACjB,OAAO,CAAC,GAAG,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBACrD,kFAAkF;gBAClF,yEAAyE;gBACzE,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE;oBAChC,MAAM,EAAE,MAAM;oBACd,IAAI,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,UAAU,CAAC,OAAO;oBAC5C,IAAI,EAAE,EAAE,aAAa,EAAE,cAAc,EAAE;iBACxC,CAAC,CAAC;gBACH,OAAO,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;YAC/E,CAAC,CAAC,CACL,CAAC;IACN,CAAC;CACF,CAAC"}
@@ -0,0 +1,122 @@
1
+ {
2
+ "id": "salesforce",
3
+ "name": "Salesforce",
4
+ "description": "Let agents look up and work on the Salesforce records you choose.",
5
+ "logo": "/brand/salesforce.svg",
6
+ "identity": "A Salesforce integration user named \"{brand.microsoft.appName}\". It uses a Salesforce Integration license, not a full user license.",
7
+ "accountKey": "myDomain",
8
+ "connectionKind": "guided",
9
+ "setup": [
10
+ {
11
+ "title": "Create an integration user",
12
+ "body": "In Setup, open Users and create a user named \"{brand.microsoft.appName}\" with the Salesforce Integration user license and the \"Minimum Access - API Only Integrations\" profile.",
13
+ "link": {
14
+ "label": "About integration users",
15
+ "href": "https://help.salesforce.com/s/articleView?id=sf.integration_user.htm"
16
+ }
17
+ },
18
+ {
19
+ "title": "Give it access to the records agents need",
20
+ "body": "Create a permission set for the Salesforce API Integration license with these object permissions on each object agents should use, plus access to their fields. Assign it to the integration user. Agents never see more than this user can. You can narrow each agent to specific objects here later.",
21
+ "permissions": true
22
+ },
23
+ {
24
+ "title": "Create an External Client App",
25
+ "body": "In Setup, open External Client App Manager and create an app named \"{brand.microsoft.appName}\". Enable OAuth, enter any callback URL (it is not used), select this OAuth scope, and enable the Client Credentials Flow.",
26
+ "copy": ["{scopes}"]
27
+ },
28
+ {
29
+ "title": "Run the app as the integration user",
30
+ "body": "In the app's Policies, under OAuth Policies, enable the Client Credentials Flow and set Run As to the \"{brand.microsoft.appName}\" user. Then open its Settings, select Consumer Key and Secret, and copy both."
31
+ },
32
+ {
33
+ "title": "Find your My Domain",
34
+ "body": "In Setup, open My Domain and copy the current My Domain URL, for example your-company.my.salesforce.com."
35
+ }
36
+ ],
37
+ "afterConnect": [],
38
+ "fields": [
39
+ {
40
+ "id": "my_domain",
41
+ "label": "My Domain",
42
+ "help": "Your Salesforce address, ending in .my.salesforce.com.",
43
+ "placeholder": "your-company.my.salesforce.com",
44
+ "secret": false
45
+ },
46
+ {
47
+ "id": "client_id",
48
+ "label": "Consumer key",
49
+ "secret": false
50
+ },
51
+ {
52
+ "id": "client_secret",
53
+ "label": "Consumer secret",
54
+ "secret": true
55
+ }
56
+ ],
57
+ "capabilities": [
58
+ {
59
+ "id": "read",
60
+ "label": "Read records",
61
+ "description": "Query and read records.",
62
+ "required": true,
63
+ "scopes": ["Manage user data via APIs (api)"],
64
+ "permissions": ["Read"],
65
+ "tools": ["salesforce_query", "salesforce_get_record"]
66
+ },
67
+ {
68
+ "id": "create",
69
+ "label": "Create records",
70
+ "description": "Create new records.",
71
+ "scopes": ["Manage user data via APIs (api)"],
72
+ "permissions": ["Create"],
73
+ "tools": ["salesforce_create_record"]
74
+ },
75
+ {
76
+ "id": "update",
77
+ "label": "Update records",
78
+ "description": "Change fields on existing records.",
79
+ "scopes": ["Manage user data via APIs (api)"],
80
+ "permissions": ["Edit"],
81
+ "tools": ["salesforce_update_record"]
82
+ },
83
+ {
84
+ "id": "delete",
85
+ "label": "Delete records",
86
+ "description": "Delete records. They go to the Recycle Bin, where Salesforce removes them after 15 days. Deleting a parent record also deletes its child records, so an agent limited to some objects cannot delete a record whose children are of other objects.",
87
+ "destructive": true,
88
+ "scopes": ["Manage user data via APIs (api)"],
89
+ "permissions": ["Edit", "Delete"],
90
+ "tools": ["salesforce_delete_record"]
91
+ }
92
+ ],
93
+ "limits": [
94
+ {
95
+ "id": "objects",
96
+ "label": "Objects",
97
+ "help": "Leave empty to allow every object the integration user can read.",
98
+ "kind": "list",
99
+ "required": false,
100
+ "pattern": "^[A-Za-z][A-Za-z0-9_]{0,79}$"
101
+ }
102
+ ],
103
+ "verify": {
104
+ "method": "GET",
105
+ "path": "/services/data/v63.0/sobjects/User/{userId}?fields=Username",
106
+ "label": "Signed in as",
107
+ "show": "Username"
108
+ },
109
+ "discover": {
110
+ "method": "GET",
111
+ "path": "/services/data/v63.0/sobjects",
112
+ "label": "Objects agents can see",
113
+ "show": "sobjects[].name",
114
+ "match": {
115
+ "queryable": true,
116
+ "layoutable": true,
117
+ "customSetting": false,
118
+ "deprecatedAndHidden": false
119
+ }
120
+ },
121
+ "revoke": "In Setup, open External Client App Manager, then {brand.microsoft.appName}, and disable the app or deactivate the {brand.microsoft.appName} user."
122
+ }
@@ -0,0 +1,7 @@
1
+ import { salesforceTools } from "./tools.js";
2
+ import { salesforceVendor } from "./vendor.js";
3
+ export default {
4
+ id: "salesforce",
5
+ create: () => ({ vendor: salesforceVendor(), toolset: salesforceTools }),
6
+ };
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../connectors/salesforce/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,eAAe;IACb,EAAE,EAAE,YAAY;IAChB,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC;CAC/C,CAAC"}
@@ -0,0 +1,60 @@
1
+ // Finds the one object a SOQL query reads, so an agent limited to some objects cannot read
2
+ // others. Anything that can reach a second object is refused rather than understood:
3
+ // subqueries (child relationships, semi-joins), relationship paths and aliases (a dot outside
4
+ // strings and numbers), TYPEOF, and more than one object after FROM.
5
+ export class SoqlRejected extends Error {
6
+ }
7
+ function tokenize(soql) {
8
+ const tokens = [];
9
+ let i = 0;
10
+ while (i < soql.length) {
11
+ const rest = soql.slice(i);
12
+ const space = /^\s+/.exec(rest);
13
+ if (space) {
14
+ i += space[0].length;
15
+ continue;
16
+ }
17
+ if (rest[0] === "'") {
18
+ let j = 1;
19
+ while (j < rest.length && rest[j] !== "'")
20
+ j += rest[j] === "\\" ? 2 : 1;
21
+ if (j >= rest.length)
22
+ throw new SoqlRejected("The query has an unterminated string");
23
+ tokens.push({ kind: "string", text: rest.slice(0, j + 1) });
24
+ i += j + 1;
25
+ continue;
26
+ }
27
+ // Numbers, dates and datetimes: 1.5, 2024-01-31, 2024-01-31T00:00:00Z, 2024-01-31T00:00:00+05:00
28
+ const number = /^\d[\d.:TZ+-]*/.exec(rest);
29
+ const word = /^[A-Za-z_][A-Za-z0-9_]*/.exec(rest);
30
+ const [kind, text] = number
31
+ ? ["number", number[0]]
32
+ : word
33
+ ? ["word", word[0]]
34
+ : ["punct", rest[0]];
35
+ tokens.push({ kind, text });
36
+ i += text.length;
37
+ }
38
+ return tokens;
39
+ }
40
+ const isWord = (t, w) => t?.kind === "word" && t.text.toUpperCase() === w;
41
+ export function soqlObject(soql) {
42
+ const tokens = tokenize(soql);
43
+ if (!isWord(tokens[0], "SELECT"))
44
+ throw new SoqlRejected("The query must start with SELECT");
45
+ const count = (w) => tokens.filter((t) => isWord(t, w)).length;
46
+ if (count("SELECT") !== 1 || count("FROM") !== 1)
47
+ throw new SoqlRejected("Subqueries are not allowed for this agent. Query one object at a time.");
48
+ if (count("TYPEOF") > 0)
49
+ throw new SoqlRejected("TYPEOF is not allowed for this agent");
50
+ if (tokens.some((t) => t.kind === "punct" && t.text === "."))
51
+ throw new SoqlRejected("Relationship fields and aliases (anything with a dot) are not allowed for this agent. Query the related object directly.");
52
+ const from = tokens.findIndex((t) => isWord(t, "FROM"));
53
+ const object = tokens[from + 1];
54
+ if (object?.kind !== "word")
55
+ throw new SoqlRejected("FROM must name an object");
56
+ if (tokens[from + 2]?.text === ",")
57
+ throw new SoqlRejected("Query one object at a time");
58
+ return object.text;
59
+ }
60
+ //# sourceMappingURL=soql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"soql.js","sourceRoot":"","sources":["../../../connectors/salesforce/soql.ts"],"names":[],"mappings":"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"}