@assemblyline-agents/core 1.0.0 → 3.0.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 (118) hide show
  1. package/LICENSE +1 -1
  2. package/dist/adapter-metadata.d.ts.map +1 -1
  3. package/dist/adapter-metadata.js +94 -36
  4. package/dist/adapter-metadata.js.map +1 -1
  5. package/dist/agent-capabilities.d.ts +34 -0
  6. package/dist/agent-capabilities.d.ts.map +1 -0
  7. package/dist/agent-capabilities.js +50 -0
  8. package/dist/agent-capabilities.js.map +1 -0
  9. package/dist/agent-definition.d.ts +43 -0
  10. package/dist/agent-definition.d.ts.map +1 -0
  11. package/dist/agent-definition.js +4 -0
  12. package/dist/agent-definition.js.map +1 -0
  13. package/dist/agent-hooks.d.ts +60 -0
  14. package/dist/agent-hooks.d.ts.map +1 -0
  15. package/dist/agent-hooks.js +198 -0
  16. package/dist/agent-hooks.js.map +1 -0
  17. package/dist/agent-state.d.ts +18 -0
  18. package/dist/agent-state.d.ts.map +1 -0
  19. package/dist/agent-state.js +2 -0
  20. package/dist/agent-state.js.map +1 -0
  21. package/dist/artifact-dir.d.ts +1 -7
  22. package/dist/artifact-dir.d.ts.map +1 -1
  23. package/dist/artifact-dir.js +3 -12
  24. package/dist/artifact-dir.js.map +1 -1
  25. package/dist/audience.d.ts +16 -0
  26. package/dist/audience.d.ts.map +1 -0
  27. package/dist/audience.js +2 -0
  28. package/dist/audience.js.map +1 -0
  29. package/dist/brand.d.ts +2 -17
  30. package/dist/brand.d.ts.map +1 -1
  31. package/dist/brand.js +2 -17
  32. package/dist/brand.js.map +1 -1
  33. package/dist/connection-auth.d.ts.map +1 -1
  34. package/dist/connection-auth.js +17 -2
  35. package/dist/connection-auth.js.map +1 -1
  36. package/dist/connection-events.d.ts +35 -0
  37. package/dist/connection-events.d.ts.map +1 -0
  38. package/dist/connection-events.js +131 -0
  39. package/dist/connection-events.js.map +1 -0
  40. package/dist/connection-types.d.ts +240 -6
  41. package/dist/connection-types.d.ts.map +1 -1
  42. package/dist/connection-types.js +8 -1
  43. package/dist/connection-types.js.map +1 -1
  44. package/dist/definitions.d.ts +11 -43
  45. package/dist/definitions.d.ts.map +1 -1
  46. package/dist/definitions.js +60 -14
  47. package/dist/definitions.js.map +1 -1
  48. package/dist/deploy-secrets.d.ts +16 -0
  49. package/dist/deploy-secrets.d.ts.map +1 -0
  50. package/dist/deploy-secrets.js +43 -0
  51. package/dist/deploy-secrets.js.map +1 -0
  52. package/dist/deploy.d.ts +17 -5
  53. package/dist/deploy.d.ts.map +1 -1
  54. package/dist/deploy.js.map +1 -1
  55. package/dist/harness.d.ts +40 -2
  56. package/dist/harness.d.ts.map +1 -1
  57. package/dist/harness.js.map +1 -1
  58. package/dist/index.d.ts +84 -41
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +32 -2
  61. package/dist/index.js.map +1 -1
  62. package/dist/manifest-types.d.ts +138 -22
  63. package/dist/manifest-types.d.ts.map +1 -1
  64. package/dist/model-metadata.d.ts +33 -0
  65. package/dist/model-metadata.d.ts.map +1 -0
  66. package/dist/model-metadata.js +13 -0
  67. package/dist/model-metadata.js.map +1 -0
  68. package/dist/plugin-connection-factories.d.ts +31 -0
  69. package/dist/plugin-connection-factories.d.ts.map +1 -0
  70. package/dist/plugin-connection-factories.js +416 -0
  71. package/dist/plugin-connection-factories.js.map +1 -0
  72. package/dist/plugin-contract.d.ts +161 -0
  73. package/dist/plugin-contract.d.ts.map +1 -0
  74. package/dist/plugin-contract.js +52 -0
  75. package/dist/plugin-contract.js.map +1 -0
  76. package/dist/plugin.d.ts +5 -126
  77. package/dist/plugin.d.ts.map +1 -1
  78. package/dist/plugin.js +863 -369
  79. package/dist/plugin.js.map +1 -1
  80. package/dist/resource-types.d.ts +1 -1
  81. package/dist/resource-types.d.ts.map +1 -1
  82. package/dist/sandbox-file-metadata.d.ts +9 -0
  83. package/dist/sandbox-file-metadata.d.ts.map +1 -0
  84. package/dist/sandbox-file-metadata.js +33 -0
  85. package/dist/sandbox-file-metadata.js.map +1 -0
  86. package/dist/sandbox-filesystem-contract.d.ts +9 -9
  87. package/dist/sandbox-filesystem-contract.d.ts.map +1 -1
  88. package/dist/sandbox-filesystem-contract.js +31 -29
  89. package/dist/sandbox-filesystem-contract.js.map +1 -1
  90. package/dist/sandbox-paths.d.ts +1 -1
  91. package/dist/sandbox-paths.d.ts.map +1 -1
  92. package/dist/sandbox-paths.js +1 -1
  93. package/dist/sandbox-paths.js.map +1 -1
  94. package/dist/sandbox-security.d.ts +0 -3
  95. package/dist/sandbox-security.d.ts.map +1 -1
  96. package/dist/sandbox-security.js +7 -12
  97. package/dist/sandbox-security.js.map +1 -1
  98. package/dist/sandbox-types.d.ts +74 -3
  99. package/dist/sandbox-types.d.ts.map +1 -1
  100. package/dist/sandbox-types.js +13 -1
  101. package/dist/sandbox-types.js.map +1 -1
  102. package/dist/secrets-types.d.ts +25 -0
  103. package/dist/secrets-types.d.ts.map +1 -0
  104. package/dist/secrets-types.js +22 -0
  105. package/dist/secrets-types.js.map +1 -0
  106. package/dist/skill-bundles.d.ts +14 -0
  107. package/dist/skill-bundles.d.ts.map +1 -0
  108. package/dist/skill-bundles.js +85 -0
  109. package/dist/skill-bundles.js.map +1 -0
  110. package/dist/tool-wire-name.d.ts +8 -0
  111. package/dist/tool-wire-name.d.ts.map +1 -0
  112. package/dist/tool-wire-name.js +26 -0
  113. package/dist/tool-wire-name.js.map +1 -0
  114. package/package.json +1 -1
  115. package/dist/env-alias.d.ts +0 -38
  116. package/dist/env-alias.d.ts.map +0 -1
  117. package/dist/env-alias.js +0 -82
  118. package/dist/env-alias.js.map +0 -1
package/dist/plugin.js CHANGED
@@ -1,186 +1,5 @@
1
- import { PLUGIN_EXPORT_NAME } from "./brand.js";
2
- import { defineMcpClientConnection, defineMcpRelayConnection, defineMcpStdioConnection, defineOpenAPIConnection, defineSandboxCliConnection } from "./definitions.js";
3
- export function definePlugin(module) {
4
- return module;
5
- }
6
- /** Reads the `assemblyLinePlugin` export from a dynamically imported module namespace. */
7
- export function pluginModuleFromImport(imported) {
8
- const candidates = [imported, imported?.default];
9
- for (const candidate of candidates) {
10
- if (!candidate || typeof candidate !== "object")
11
- continue;
12
- const value = candidate[PLUGIN_EXPORT_NAME];
13
- if (isPluginModule(value))
14
- return value;
15
- }
16
- return undefined;
17
- }
18
- /**
19
- * Provider packages use this factory instead of implementing transport or
20
- * credential plumbing. The developer still owns the provider application,
21
- * token/OAuth grant, and any required MCP bridge.
22
- */
23
- export function defineMcpPluginConnection(plugin, options) {
24
- if (plugin.protocol !== "mcp") {
25
- throw new Error(`${plugin.helper}: ${plugin.provider} uses OpenAPI; call defineOpenAPIPluginConnection instead.`);
26
- }
27
- if ((plugin.transport ?? "http") !== "http") {
28
- throw new Error(`${plugin.helper}: ${plugin.provider} uses stdio; call defineStdioMcpPluginConnection instead.`);
29
- }
30
- validatePluginAccess(plugin, options.access);
31
- const url = options.url ?? environmentValue(plugin.urlEnv) ?? plugin.defaultUrl;
32
- if (!url)
33
- throw new Error(`${plugin.helper}: set ${plugin.urlEnv ?? "a connection URL"} or pass url.`);
34
- const definition = {
35
- transport: "http",
36
- url,
37
- description: options.description ?? plugin.description,
38
- access: pluginAccessDefinition(plugin, options.access),
39
- required: options.required ?? true,
40
- subject: options.subject ?? plugin.subject ?? "user",
41
- metadata: {
42
- provider: plugin.provider,
43
- plugin: plugin.packageName ?? plugin.provider,
44
- ...(options.metadata ?? {})
45
- }
46
- };
47
- const auth = options.auth === false || plugin.tokenHeader
48
- ? (options.auth === false ? undefined : options.auth)
49
- : options.auth ?? (plugin.tokenRequired === false ? undefined : tokenAuth(plugin.tokenEnv));
50
- if (auth)
51
- definition.auth = auth;
52
- const tokenHeaders = options.auth === undefined && plugin.tokenHeader
53
- ? tokenHeader(plugin.tokenHeader, plugin.tokenEnv)
54
- : undefined;
55
- const headers = mergeHeaders(tokenHeaders, options.headers);
56
- if (headers)
57
- definition.headers = headers;
58
- const tools = options.tools ?? cloneToolFilter(plugin.tools);
59
- if (tools)
60
- definition.tools = tools;
61
- return defineMcpClientConnection(definition);
62
- }
63
- export function defineStdioMcpPluginConnection(plugin, options) {
64
- if (plugin.protocol !== "mcp" || plugin.transport !== "stdio") {
65
- throw new Error(`${plugin.helper}: ${plugin.provider} uses HTTP; call defineMcpPluginConnection instead.`);
66
- }
67
- validatePluginAccess(plugin, options.access);
68
- const definition = {
69
- transport: "stdio",
70
- command: options.command,
71
- ...(options.args ? { args: [...options.args] } : {}),
72
- ...(options.cwd ? { cwd: options.cwd } : {}),
73
- ...(options.env ? { env: { ...options.env } } : {}),
74
- description: options.description ?? plugin.description,
75
- access: pluginAccessDefinition(plugin, options.access),
76
- required: options.required ?? true,
77
- subject: options.subject ?? plugin.subject ?? "environment",
78
- metadata: {
79
- provider: plugin.provider,
80
- plugin: plugin.packageName ?? plugin.provider,
81
- ...(options.metadata ?? {})
82
- }
83
- };
84
- const tools = options.tools ?? cloneToolFilter(plugin.tools);
85
- if (tools)
86
- definition.tools = tools;
87
- return defineMcpStdioConnection(definition);
88
- }
89
- export function defineRelayMcpPluginConnection(plugin, options) {
90
- if (plugin.protocol !== "mcp" || plugin.transport !== "relay") {
91
- throw new Error(`${plugin.helper}: ${plugin.provider} does not use the OpenEve relay transport.`);
92
- }
93
- validatePluginAccess(plugin, options.access);
94
- const url = options.url ?? environmentValue(plugin.urlEnv) ?? plugin.defaultUrl;
95
- if (!url)
96
- throw new Error(`${plugin.helper}: set ${plugin.urlEnv ?? "a relay URL"} or pass url.`);
97
- const credentialEnv = options.credentialEnv ?? plugin.credentialEnv;
98
- if (!credentialEnv)
99
- throw new Error(`${plugin.helper}: relay metadata must declare credentialEnv.`);
100
- const definition = {
101
- transport: "relay",
102
- url,
103
- credentialEnv,
104
- ...(options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),
105
- description: options.description ?? plugin.description,
106
- access: pluginAccessDefinition(plugin, options.access),
107
- required: options.required ?? true,
108
- subject: options.subject ?? plugin.subject ?? "environment",
109
- metadata: {
110
- provider: plugin.provider,
111
- plugin: plugin.packageName ?? plugin.provider,
112
- ...(options.metadata ?? {})
113
- }
114
- };
115
- const tools = options.tools ?? cloneToolFilter(plugin.tools);
116
- if (tools)
117
- definition.tools = tools;
118
- return defineMcpRelayConnection(definition);
119
- }
120
- /** Build a direct HTTP API connection from a provider's reviewed OpenAPI metadata. */
121
- export function defineOpenAPIPluginConnection(plugin, options) {
122
- if (plugin.protocol !== "openapi") {
123
- throw new Error(`${plugin.helper}: ${plugin.provider} uses MCP; call defineMcpPluginConnection instead.`);
124
- }
125
- validatePluginAccess(plugin, options.access);
126
- const spec = options.spec ?? environmentValue(plugin.specEnv) ?? plugin.defaultSpec;
127
- if (!spec)
128
- throw new Error(`${plugin.helper}: set ${plugin.specEnv ?? "an OpenAPI specification"} or pass spec.`);
129
- const baseUrl = options.baseUrl ?? environmentValue(plugin.baseUrlEnv) ?? plugin.defaultBaseUrl;
130
- const definition = {
131
- spec,
132
- ...(baseUrl ? { baseUrl } : {}),
133
- description: options.description ?? plugin.description,
134
- access: pluginAccessDefinition(plugin, options.access),
135
- required: options.required ?? true,
136
- subject: options.subject ?? plugin.subject ?? "user",
137
- metadata: {
138
- provider: plugin.provider,
139
- plugin: plugin.packageName ?? plugin.provider,
140
- ...(options.metadata ?? {})
141
- }
142
- };
143
- const auth = options.auth === false
144
- ? undefined
145
- : options.auth ?? (plugin.tokenRequired === false ? undefined : tokenAuth(plugin.tokenEnv));
146
- if (auth)
147
- definition.auth = auth;
148
- if (options.headers)
149
- definition.headers = options.headers;
150
- const operations = options.operations ?? cloneToolFilter(plugin.tools);
151
- if (operations)
152
- definition.operations = operations;
153
- return defineOpenAPIConnection(definition);
154
- }
155
- /**
156
- * Build a connection whose reviewed operations run through a provider CLI in
157
- * the agent sandbox rather than on the OpenEve gateway host.
158
- */
159
- export function defineSandboxCliPluginConnection(plugin, options) {
160
- if (plugin.protocol !== "cli" || plugin.transport !== "sandbox") {
161
- throw new Error(`${plugin.helper}: ${plugin.provider} does not use the sandbox CLI transport.`);
162
- }
163
- validatePluginAccess(plugin, options.access);
164
- const command = options.command ?? plugin.command;
165
- if (!command)
166
- throw new Error(`${plugin.helper}: sandbox CLI metadata must declare command.`);
167
- return defineSandboxCliConnection({
168
- transport: "sandbox",
169
- command,
170
- description: options.description ?? plugin.description,
171
- tools: options.tools,
172
- access: pluginAccessDefinition(plugin, options.access),
173
- ...(options.auth ? { auth: options.auth } : {}),
174
- ...(options.maxOutputChars !== undefined ? { maxOutputChars: options.maxOutputChars } : {}),
175
- required: options.required ?? true,
176
- subject: options.subject ?? plugin.subject ?? "environment",
177
- metadata: {
178
- provider: plugin.provider,
179
- plugin: plugin.packageName ?? plugin.provider,
180
- ...(options.metadata ?? {})
181
- }
182
- });
183
- }
1
+ export * from "./plugin-contract.js";
2
+ export * from "./plugin-connection-factories.js";
184
3
  export function connectionPluginMetadata(kind) {
185
4
  return CONNECTION_PLUGIN_CATALOG.find((entry) => entry.kind === kind);
186
5
  }
@@ -190,6 +9,55 @@ export function connectionPluginMetadataForHelper(helper) {
190
9
  export function allConnectionPluginMetadata() {
191
10
  return CONNECTION_PLUGIN_CATALOG.map(cloneMetadata);
192
11
  }
12
+ export function toolPackPluginMetadata(kind) {
13
+ const metadata = TOOL_PACK_PLUGIN_CATALOG.find((entry) => entry.kind === kind);
14
+ return metadata ? cloneToolPackMetadata(metadata) : undefined;
15
+ }
16
+ export function allToolPackPluginMetadata() {
17
+ return TOOL_PACK_PLUGIN_CATALOG.map(cloneToolPackMetadata);
18
+ }
19
+ const TOOL_PACK_PLUGIN_CATALOG = [
20
+ {
21
+ kind: "openui",
22
+ role: "tools",
23
+ packageName: "@assemblyline-agents/openui",
24
+ description: "Full OpenUI component packs with developer policy, immutable revisions, and storage-issued publication links.",
25
+ tools: [
26
+ {
27
+ name: "openui_create",
28
+ helper: "defineOpenUiCreateTool",
29
+ description: "Create an immutable artifact revision from developer-approved OpenUI components. Raw HTML is not accepted.",
30
+ needsApproval: false
31
+ },
32
+ {
33
+ name: "openui_update",
34
+ helper: "defineOpenUiUpdateTool",
35
+ description: "Create a new immutable revision of an existing OpenUI artifact. Raw HTML is not accepted.",
36
+ needsApproval: false
37
+ },
38
+ {
39
+ name: "openui_publish",
40
+ helper: "defineOpenUiPublishTool",
41
+ description: "Publish one OpenUI artifact revision to an unlisted, storage-issued HTTPS link.",
42
+ needsApproval: false
43
+ }
44
+ ],
45
+ config: {
46
+ path: "tool-config/openui.ts",
47
+ helper: "defineOpenUiConfig",
48
+ options: {}
49
+ },
50
+ skills: ["openui-artifacts"],
51
+ requiredEnv: [],
52
+ optionalEnv: ["R2_PUBLIC_BASE_URL", "S3_PUBLIC_BASE_URL"],
53
+ setup: [{
54
+ kind: "tools",
55
+ name: "openui-public-blob-origin",
56
+ required: true,
57
+ message: "Configure an HTTPS public base URL on the blob adapter, then review the generated OpenUI component and brand policy before publishing."
58
+ }]
59
+ }
60
+ ];
193
61
  const READ_PATTERNS = [
194
62
  "regex:(^|[-_])(search|read|list|fetch|get|retrieve|query|lookup|find|describe|details?|discover)([-_]|$)"
195
63
  ];
@@ -226,12 +94,18 @@ function catalogEntry(input) {
226
94
  optionalEnv,
227
95
  capabilities: ["mcp", "live-tools", input.transport === "stdio" ? "stdio" : input.transport === "relay" ? "e2ee-device-relay" : "streamable-http"],
228
96
  scopes: [...(input.scopes ?? [])],
229
- subject: input.subject ?? "user",
97
+ // Plugins with user-scoped grants declare subject: "user" explicitly; an
98
+ // unannotated plugin gets a deployment credential usable on every surface.
99
+ subject: input.subject ?? "workspace",
230
100
  ...(input.tools ? { tools: cloneToolFilter(input.tools) } : {}),
231
101
  ...(input.hostRequirements ? { hostRequirements: cloneHostRequirements(input.hostRequirements) } : {}),
232
102
  readToolPatterns: input.readToolPatterns ?? READ_PATTERNS,
233
103
  writeToolPatterns: input.writeToolPatterns ?? (input.write ? WRITE_PATTERNS : []),
234
- skill: input.kind,
104
+ ...(input.eventCatalog ? { eventCatalog: [...input.eventCatalog] } : {}),
105
+ ...(input.defaultEvents ? { defaultEvents: [...input.defaultEvents] } : {}),
106
+ ...(input.eventMode ? { eventMode: input.eventMode } : {}),
107
+ ...(input.eventScope ? { eventScope: input.eventScope } : {}),
108
+ ...(input.eventRequiredEnv ? { eventRequiredEnv: [...input.eventRequiredEnv] } : {}),
235
109
  setup: [{
236
110
  kind: "connection",
237
111
  name: `${input.kind}-developer-configuration`,
@@ -257,11 +131,6 @@ const HIGGSFIELD_PLUGIN = {
257
131
  subject: "user",
258
132
  readToolPatterns: ["read"],
259
133
  writeToolPatterns: ["write"],
260
- skills: [
261
- "higgsfield-generate",
262
- "higgsfield-soul-id",
263
- "higgsfield-product-photoshoot"
264
- ],
265
134
  setup: [{
266
135
  kind: "sandbox",
267
136
  name: "higgsfield-cli",
@@ -269,6 +138,30 @@ const HIGGSFIELD_PLUGIN = {
269
138
  message: "Install the official Higgsfield CLI in the sandbox image with `curl -fsSL https://raw.githubusercontent.com/higgsfield-ai/cli/main/install.sh | sh`, then run `higgsfield auth login` interactively inside each persistent, user-scoped sandbox. Do not bake account credentials into a shared image. Higgsfield generation and editing consume account credits."
270
139
  }]
271
140
  };
141
+ const REMOTION_PLUGIN = {
142
+ kind: "remotion",
143
+ role: "connection",
144
+ packageName: "@assemblyline-agents/remotion",
145
+ helper: "defineRemotionConnection",
146
+ protocol: "cli",
147
+ transport: "sandbox",
148
+ provider: "remotion",
149
+ description: "Remotion composition discovery and rendering through the project CLI inside the active agent sandbox.",
150
+ command: "npx",
151
+ requiredEnv: [],
152
+ optionalEnv: [],
153
+ capabilities: ["sandbox-cli", "media-rendering", "workspace-artifacts"],
154
+ scopes: [],
155
+ subject: "environment",
156
+ readToolPatterns: ["list_compositions", "check_versions"],
157
+ writeToolPatterns: ["render_video", "render_still"],
158
+ setup: [{
159
+ kind: "sandbox",
160
+ name: "remotion-cli",
161
+ required: true,
162
+ message: "Install Remotion and @remotion/cli in the sandbox project. Composition discovery and rendering execute inside the active run sandbox and write artifacts under /workspace."
163
+ }]
164
+ };
272
165
  const MIRROR_PLUGIN = {
273
166
  kind: "mirror",
274
167
  role: "connection",
@@ -291,11 +184,13 @@ const MIRROR_PLUGIN = {
291
184
  "mirror.connected_provider_call",
292
185
  "mirror.create_connections_link",
293
186
  "mirror.query_records",
187
+ "mirror.list_changes",
294
188
  "mirror.get_source",
295
189
  "mirror.live_read",
296
190
  "mirror.sync_now",
297
191
  "mirror.request_action",
298
192
  "mirror.get_pending_approvals",
193
+ "mirror.get_skill",
299
194
  "mirror.approve_code",
300
195
  "mirror.agentcash_wallet_export",
301
196
  "mirror.register_agent",
@@ -305,9 +200,11 @@ const MIRROR_PLUGIN = {
305
200
  readToolPatterns: [
306
201
  "mirror.connected_providers",
307
202
  "mirror.query_records",
203
+ "mirror.list_changes",
308
204
  "mirror.get_source",
309
205
  "mirror.live_read",
310
206
  "mirror.get_pending_approvals",
207
+ "mirror.get_skill",
311
208
  "mirror.whoami"
312
209
  ],
313
210
  writeToolPatterns: [
@@ -319,12 +216,83 @@ const MIRROR_PLUGIN = {
319
216
  "mirror.agentcash_wallet_export",
320
217
  "mirror.register_agent"
321
218
  ],
322
- skill: "mirror",
219
+ eventCatalog: ["source.changed"],
220
+ defaultEvents: ["source.changed"],
221
+ eventMode: "api",
222
+ eventScope: "principal",
323
223
  setup: [{
324
224
  kind: "connection",
325
225
  name: "mirror-oauth-configuration",
326
226
  required: true,
327
- message: "Choose a stable public client id for this agent, set MIRROR_OAUTH_CLIENT_ID, and deploy with a reachable OpenEve connection callback URL. Mirror uses OAuth Authorization Code + PKCE and stores provider credentials behind the user's Mirror account."
227
+ message: "Choose a stable public client id for this agent, set MIRROR_OAUTH_CLIENT_ID, and deploy with a reachable Assembly Line connection callback URL. Mirror uses OAuth Authorization Code + PKCE and stores provider credentials behind the user's Mirror account."
228
+ }]
229
+ };
230
+ const MARGINS_PLUGIN = {
231
+ kind: "margins",
232
+ role: "connection",
233
+ packageName: "@assemblyline-agents/margins",
234
+ helper: "defineMarginsConnection",
235
+ protocol: "mcp",
236
+ transport: "http",
237
+ provider: "margins",
238
+ description: "Resource-scoped collaborative Markdown pages, folders, comments, suggestions, and conflict-safe edits through Margins.",
239
+ defaultUrl: "https://margins.artificialillumination.co/mcp",
240
+ urlEnv: "MARGINS_MCP_URL",
241
+ requiredEnv: [],
242
+ optionalEnv: [
243
+ "MARGINS_MCP_URL",
244
+ "MARGINS_ISSUER",
245
+ "MARGINS_AGENT_ID",
246
+ "MARGINS_AGENT_NAME",
247
+ "MARGINS_AGENT_RUNTIME",
248
+ "MARGINS_AGENT_HARNESS"
249
+ ],
250
+ capabilities: [
251
+ "mcp",
252
+ "host-side-pairing",
253
+ "rotating-bearer-grants",
254
+ "streamable-http",
255
+ "resource-scoped",
256
+ "collaborative-markdown",
257
+ "conflict-safe-writes"
258
+ ],
259
+ scopes: ["margins"],
260
+ subject: "user",
261
+ tools: {
262
+ allow: [
263
+ "margins_status",
264
+ "margins_context",
265
+ "margins_review",
266
+ "margins_map",
267
+ "margins_graph",
268
+ "margins_create_file",
269
+ "margins_comment",
270
+ "margins_edit",
271
+ "margins_suggest",
272
+ "margins_history",
273
+ "margins_library"
274
+ ]
275
+ },
276
+ readToolPatterns: [
277
+ "margins_status",
278
+ "margins_context",
279
+ "margins_review",
280
+ "margins_map",
281
+ "margins_graph",
282
+ "margins_history",
283
+ "margins_library"
284
+ ],
285
+ writeToolPatterns: [
286
+ "margins_create_file",
287
+ "margins_comment",
288
+ "margins_edit",
289
+ "margins_suggest"
290
+ ],
291
+ setup: [{
292
+ kind: "connection",
293
+ name: "margins-binding-packet",
294
+ required: true,
295
+ message: "In Margins, create an agent invite for the exact page, folder, or workspace and paste its short-lived one-time binding packet into the agent chat. No developer OAuth registration or long-lived token environment variable is required."
328
296
  }]
329
297
  };
330
298
  const PROVENANCE_PLUGIN = {
@@ -382,11 +350,6 @@ const PROVENANCE_PLUGIN = {
382
350
  "provenance.agent_activity"
383
351
  ],
384
352
  writeToolPatterns: ["provenance.register_agent"],
385
- skills: [
386
- "provenance-reconstruction",
387
- "provenance-handoff-bundle",
388
- "provenance-ambient-capture"
389
- ],
390
353
  setup: [{
391
354
  kind: "connection",
392
355
  name: "provenance-oauth-configuration",
@@ -395,7 +358,55 @@ const PROVENANCE_PLUGIN = {
395
358
  }]
396
359
  };
397
360
  const CONNECTION_PLUGIN_CATALOG = [
361
+ {
362
+ kind: "1password",
363
+ role: "connection",
364
+ packageName: "@assemblyline-agents/1password",
365
+ helper: "defineOnePasswordConnection",
366
+ protocol: "sdk",
367
+ provider: "1password",
368
+ description: "1Password vault discovery, item search and retrieval, and secret resolution through the official SDK.",
369
+ requiredEnv: ["OP_SERVICE_ACCOUNT_TOKEN"],
370
+ optionalEnv: [],
371
+ capabilities: ["sdk", "direct-api", "live-tools", "service-account", "vaults", "items", "secrets"],
372
+ scopes: [],
373
+ subject: "environment",
374
+ tools: {
375
+ allow: ["list_vaults", "list_items", "search_items", "get_item", "resolve_secret"]
376
+ },
377
+ readToolPatterns: ["list_vaults", "list_items", "search_items", "get_item", "resolve_secret"],
378
+ writeToolPatterns: [],
379
+ setup: [{
380
+ kind: "connection",
381
+ name: "onepassword-service-account",
382
+ required: true,
383
+ message: "Create a 1Password service account for this agent, share only the vaults the agent should be able to use, and set its token in OP_SERVICE_ACCOUNT_TOKEN. Every readable item and concealed field in those vaults is available to the agent."
384
+ }]
385
+ },
386
+ {
387
+ kind: "a2a",
388
+ role: "connection",
389
+ packageName: "@assemblyline-agents/a2a",
390
+ helper: "defineA2AConnection",
391
+ protocol: "a2a",
392
+ provider: "a2a",
393
+ description: "Discover and delegate work to an independently deployed agent through the A2A v1.0 protocol.",
394
+ requiredEnv: [],
395
+ optionalEnv: [],
396
+ capabilities: ["a2a", "agent-card-discovery", "remote-agent-tasks", "json-rpc"],
397
+ scopes: [],
398
+ subject: "environment",
399
+ readToolPatterns: ["regex:^(?!cancel_task$).+"],
400
+ writeToolPatterns: ["cancel_task"],
401
+ setup: [{
402
+ kind: "connection",
403
+ name: "a2a-peer-configuration",
404
+ required: true,
405
+ message: "Configure an allowlisted Agent Card URL and a peer-scoped service credential for the remote agent."
406
+ }]
407
+ },
398
408
  HIGGSFIELD_PLUGIN,
409
+ MARGINS_PLUGIN,
399
410
  MIRROR_PLUGIN,
400
411
  PROVENANCE_PLUGIN,
401
412
  {
@@ -420,78 +431,310 @@ const CONNECTION_PLUGIN_CATALOG = [
420
431
  "arcads_get_upload_url",
421
432
  "regex:^arcads_(?!get_(?!upload_url$)|list|search|watch).+"
422
433
  ],
423
- skill: "arcads",
424
434
  setup: [{
425
435
  kind: "connection",
426
436
  name: "arcads-oauth-configuration",
427
437
  required: true,
428
- message: "Register an OAuth client with https://api.arcads.ai/oauth/register, set ARCADS_MCP_CLIENT_ID, and register the OpenEve connection callback URL. Arcads generation and editing consume account credits."
438
+ message: "Register an OAuth client with https://api.arcads.ai/oauth/register, set ARCADS_MCP_CLIENT_ID, and register the Assembly Line connection callback URL. Arcads generation and editing consume account credits."
429
439
  }]
430
440
  },
431
- catalogEntry({
441
+ {
442
+ kind: "attio",
443
+ role: "connection",
444
+ packageName: "@assemblyline-agents/attio",
445
+ helper: "defineAttioConnection",
446
+ protocol: "mcp",
447
+ transport: "http",
448
+ provider: "attio",
449
+ description: "Attio CRM records, lists, notes, tasks, comments, email and meeting intelligence, and reporting through Attio's official hosted MCP server.",
450
+ defaultUrl: "https://mcp.attio.com/mcp",
451
+ urlEnv: "ATTIO_MCP_URL",
452
+ requiredEnv: ["ATTIO_MCP_CLIENT_ID"],
453
+ optionalEnv: ["ATTIO_MCP_URL", "ATTIO_MCP_REDIRECT_URI"],
454
+ capabilities: ["mcp", "oauth", "pkce", "refresh-token", "live-tools", "streamable-http", "crm", "semantic-search", "reporting"],
455
+ scopes: ["mcp", "offline_access", "openid"],
456
+ subject: "user",
457
+ tools: {
458
+ allow: [
459
+ "search-records",
460
+ "list-records",
461
+ "get-records-by-ids",
462
+ "create-record",
463
+ "upsert-record",
464
+ "update-record",
465
+ "merge-records",
466
+ "list-attribute-definitions",
467
+ "list-lists",
468
+ "list-list-attribute-definitions",
469
+ "list-records-in-list",
470
+ "add-record-to-list",
471
+ "update-list",
472
+ "update-list-entry-by-id",
473
+ "update-list-entry-by-record-id",
474
+ "create-comment",
475
+ "list-comments",
476
+ "list-comment-replies",
477
+ "delete-comment",
478
+ "create-note",
479
+ "search-notes-by-metadata",
480
+ "semantic-search-notes",
481
+ "get-note-body",
482
+ "update-note",
483
+ "list-tasks",
484
+ "create-task",
485
+ "update-task",
486
+ "search-meetings",
487
+ "search-call-recordings-by-metadata",
488
+ "semantic-search-call-recordings",
489
+ "get-call-recording",
490
+ "search-emails-by-metadata",
491
+ "semantic-search-emails",
492
+ "get-email-content",
493
+ "list-workspace-members",
494
+ "list-workspace-teams",
495
+ "whoami",
496
+ "run-basic-report",
497
+ "query-particle-sql"
498
+ ]
499
+ },
500
+ readToolPatterns: [
501
+ "search-records",
502
+ "list-records",
503
+ "get-records-by-ids",
504
+ "list-attribute-definitions",
505
+ "list-lists",
506
+ "list-list-attribute-definitions",
507
+ "list-records-in-list",
508
+ "list-comments",
509
+ "list-comment-replies",
510
+ "search-notes-by-metadata",
511
+ "semantic-search-notes",
512
+ "get-note-body",
513
+ "list-tasks",
514
+ "search-meetings",
515
+ "search-call-recordings-by-metadata",
516
+ "semantic-search-call-recordings",
517
+ "get-call-recording",
518
+ "search-emails-by-metadata",
519
+ "semantic-search-emails",
520
+ "get-email-content",
521
+ "list-workspace-members",
522
+ "list-workspace-teams",
523
+ "whoami",
524
+ "run-basic-report",
525
+ "query-particle-sql"
526
+ ],
527
+ writeToolPatterns: [
528
+ "create-record",
529
+ "upsert-record",
530
+ "update-record",
531
+ "merge-records",
532
+ "add-record-to-list",
533
+ "update-list",
534
+ "update-list-entry-by-id",
535
+ "update-list-entry-by-record-id",
536
+ "create-comment",
537
+ "delete-comment",
538
+ "create-note",
539
+ "update-note",
540
+ "create-task",
541
+ "update-task"
542
+ ],
543
+ setup: [{
544
+ kind: "connection",
545
+ name: "attio-mcp-oauth",
546
+ required: true,
547
+ message: "Register a public OAuth client at https://app.attio.com/oauth/register for the Assembly Line connection callback, set ATTIO_MCP_CLIENT_ID, then let each user authorize Attio. For a shared company agent, explicitly set subject: \"workspace\" and preauthorize a dedicated Attio member through the protected operator connection flow."
548
+ }]
549
+ },
550
+ {
432
551
  kind: "gmail",
433
- displayName: "Gmail",
552
+ role: "connection",
553
+ packageName: "@assemblyline-agents/gmail",
434
554
  helper: "defineGmailConnection",
435
- description: "Gmail threads, messages, attachments, drafts, and sends through an independently authorized MCP connection.",
436
- urlEnv: "GMAIL_MCP_URL",
437
- tokenEnv: "GMAIL_MCP_TOKEN",
555
+ protocol: "http",
556
+ provider: "gmail",
557
+ description: "Gmail threads, messages, attachments, drafts, and sends through the Gmail REST API.",
558
+ defaultBaseUrl: "https://gmail.googleapis.com/gmail/v1",
559
+ baseUrlEnv: "GMAIL_API_BASE_URL",
560
+ requiredEnv: ["GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET"],
561
+ optionalEnv: ["GOOGLE_REDIRECT_URI", "GMAIL_API_BASE_URL"],
562
+ capabilities: ["http-api", "oauth", "pkce", "refresh-token", "live-tools"],
438
563
  scopes: [
439
- "openid",
440
- "email",
441
- "profile",
442
564
  "https://www.googleapis.com/auth/gmail.readonly",
443
565
  "https://www.googleapis.com/auth/gmail.compose",
444
566
  "https://www.googleapis.com/auth/gmail.send"
445
567
  ],
446
- readToolPatterns: ["rest_get", ...READ_PATTERNS],
447
- writeToolPatterns: ["rest_request", ...WRITE_PATTERNS],
448
- write: true,
449
- setupMessage: "Configure a Gmail-only OAuth grant or MCP bridge for this deployment. Do not reuse an umbrella Google grant that also exposes Calendar or Drive."
450
- }),
451
- catalogEntry({
568
+ subject: "user",
569
+ tools: { allow: [
570
+ "gmail_get_profile", "gmail_list_messages", "gmail_get_message", "gmail_get_attachment",
571
+ "gmail_list_threads", "gmail_get_thread", "gmail_list_labels", "gmail_get_label",
572
+ "gmail_list_drafts", "gmail_get_draft", "gmail_create_draft", "gmail_update_draft",
573
+ "gmail_delete_draft", "gmail_send_draft", "gmail_send_message"
574
+ ] },
575
+ readToolPatterns: [
576
+ "gmail_get_profile", "gmail_list_messages", "gmail_get_message", "gmail_get_attachment",
577
+ "gmail_list_threads", "gmail_get_thread", "gmail_list_labels", "gmail_get_label",
578
+ "gmail_list_drafts", "gmail_get_draft"
579
+ ],
580
+ writeToolPatterns: ["gmail_create_draft", "gmail_update_draft", "gmail_delete_draft", "gmail_send_draft", "gmail_send_message"],
581
+ eventCatalog: ["email.received"],
582
+ defaultEvents: ["email.received"],
583
+ eventMode: "watch",
584
+ eventScope: "principal",
585
+ eventRequiredEnv: ["GOOGLE_CLOUD_PROJECT", "GMAIL_PUBSUB_TOPIC", "GMAIL_PUBSUB_VERIFICATION_TOKEN"],
586
+ setup: [{
587
+ kind: "connection",
588
+ name: "gmail-oauth-configuration",
589
+ required: true,
590
+ message: "Create a Google OAuth web client, enable the Gmail API, set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET, and register the Assembly Line connection callback URL. Gmail authorization is stored as its own connection grant."
591
+ }]
592
+ },
593
+ {
452
594
  kind: "google-calendar",
453
- displayName: "Google Calendar",
595
+ role: "connection",
596
+ packageName: "@assemblyline-agents/google-calendar",
454
597
  helper: "defineGoogleCalendarConnection",
598
+ protocol: "http",
455
599
  provider: "google_calendar",
456
- description: "Google Calendar events, availability, and event changes through an independently authorized MCP connection.",
457
- urlEnv: "GOOGLE_CALENDAR_MCP_URL",
458
- tokenEnv: "GOOGLE_CALENDAR_MCP_TOKEN",
600
+ description: "Google Calendar lists, events, availability, and scheduling through the Google Calendar REST API.",
601
+ defaultBaseUrl: "https://www.googleapis.com/calendar/v3",
602
+ baseUrlEnv: "GOOGLE_CALENDAR_API_BASE_URL",
603
+ requiredEnv: ["GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET"],
604
+ optionalEnv: ["GOOGLE_REDIRECT_URI", "GOOGLE_CALENDAR_API_BASE_URL"],
605
+ capabilities: ["http-api", "oauth", "pkce", "refresh-token", "live-tools"],
459
606
  scopes: [
460
- "openid",
461
- "email",
462
- "profile",
463
607
  "https://www.googleapis.com/auth/calendar.readonly",
464
608
  "https://www.googleapis.com/auth/calendar.events"
465
609
  ],
466
- readToolPatterns: ["rest_get", ...READ_PATTERNS],
467
- writeToolPatterns: ["rest_request", ...WRITE_PATTERNS],
468
- write: true,
469
- setupMessage: "Configure a Google Calendar-only OAuth grant or MCP bridge for this deployment. Do not reuse an umbrella Google grant that also exposes Gmail or Drive."
470
- }),
471
- catalogEntry({
610
+ subject: "user",
611
+ tools: { allow: [
612
+ "google_calendar_list_calendars", "google_calendar_get_calendar", "google_calendar_list_events",
613
+ "google_calendar_get_event", "google_calendar_list_instances", "google_calendar_query_freebusy",
614
+ "google_calendar_create_event", "google_calendar_update_event", "google_calendar_delete_event", "google_calendar_move_event"
615
+ ] },
616
+ readToolPatterns: [
617
+ "google_calendar_list_calendars", "google_calendar_get_calendar", "google_calendar_list_events",
618
+ "google_calendar_get_event", "google_calendar_list_instances", "google_calendar_query_freebusy"
619
+ ],
620
+ writeToolPatterns: ["google_calendar_create_event", "google_calendar_update_event", "google_calendar_delete_event", "google_calendar_move_event"],
621
+ eventCatalog: ["calendar.changed"],
622
+ defaultEvents: ["calendar.changed"],
623
+ eventMode: "watch",
624
+ eventScope: "principal",
625
+ setup: [{
626
+ kind: "connection",
627
+ name: "google-calendar-oauth-configuration",
628
+ required: true,
629
+ message: "Create a Google OAuth web client, enable the Google Calendar API, set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET, and register the Assembly Line connection callback URL. Calendar authorization is stored as its own connection grant."
630
+ }]
631
+ },
632
+ {
472
633
  kind: "google-drive",
473
- displayName: "Google Drive",
634
+ role: "connection",
635
+ packageName: "@assemblyline-agents/google-drive",
474
636
  helper: "defineGoogleDriveConnection",
637
+ protocol: "http",
475
638
  provider: "google_drive",
476
- description: "Google Drive file search, downloads, uploads, organization, and sharing through an independently authorized MCP connection.",
477
- urlEnv: "GOOGLE_DRIVE_MCP_URL",
478
- tokenEnv: "GOOGLE_DRIVE_MCP_TOKEN",
639
+ description: "Google Drive file search, downloads, uploads, organization, and sharing through the Google Drive REST API.",
640
+ defaultBaseUrl: "https://www.googleapis.com",
641
+ baseUrlEnv: "GOOGLE_DRIVE_API_BASE_URL",
642
+ requiredEnv: ["GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET"],
643
+ optionalEnv: ["GOOGLE_REDIRECT_URI", "GOOGLE_DRIVE_API_BASE_URL"],
644
+ capabilities: ["http-api", "oauth", "pkce", "refresh-token", "binary-transfer", "live-tools"],
479
645
  scopes: [
480
- "openid",
481
- "email",
482
- "profile",
646
+ "https://www.googleapis.com/auth/drive.readonly",
483
647
  "https://www.googleapis.com/auth/drive"
484
648
  ],
485
- readToolPatterns: ["rest_get", ...READ_PATTERNS],
486
- writeToolPatterns: ["rest_request", ...WRITE_PATTERNS],
487
- write: true,
488
- setupMessage: "Configure a Google Drive-only OAuth grant or MCP bridge for this deployment. Do not reuse an umbrella Google grant that also exposes Gmail or Calendar."
489
- }),
649
+ subject: "user",
650
+ tools: { allow: [
651
+ "google_drive_get_about", "google_drive_list_shared_drives", "google_drive_get_shared_drive",
652
+ "google_drive_list_files", "google_drive_get_file", "google_drive_download_file", "google_drive_export_file",
653
+ "google_drive_list_permissions", "google_drive_get_permission", "google_drive_create_file",
654
+ "google_drive_update_file", "google_drive_upload_file_content", "google_drive_copy_file", "google_drive_delete_file",
655
+ "google_drive_create_permission", "google_drive_update_permission", "google_drive_delete_permission"
656
+ ] },
657
+ readToolPatterns: [
658
+ "google_drive_get_about", "google_drive_list_shared_drives", "google_drive_get_shared_drive",
659
+ "google_drive_list_files", "google_drive_get_file", "google_drive_download_file", "google_drive_export_file",
660
+ "google_drive_list_permissions", "google_drive_get_permission"
661
+ ],
662
+ writeToolPatterns: [
663
+ "google_drive_create_file", "google_drive_update_file", "google_drive_upload_file_content", "google_drive_copy_file",
664
+ "google_drive_delete_file", "google_drive_create_permission", "google_drive_update_permission", "google_drive_delete_permission"
665
+ ],
666
+ eventCatalog: ["drive.changed"],
667
+ defaultEvents: ["drive.changed"],
668
+ eventMode: "watch",
669
+ eventScope: "principal",
670
+ setup: [{
671
+ kind: "connection",
672
+ name: "google-drive-oauth-configuration",
673
+ required: true,
674
+ message: "Create a Google OAuth web client, enable the Google Drive API, set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET, and register the Assembly Line connection callback URL. Drive authorization is stored as its own connection grant."
675
+ }]
676
+ },
490
677
  catalogEntry({ kind: "github", displayName: "GitHub", helper: "defineGitHubMcpConnection", packageName: "@assemblyline-agents/github", description: "GitHub repositories, issues, pull requests, and Actions through GitHub MCP.", defaultUrl: "https://api.githubcopilot.com/mcp/", urlEnv: "GITHUB_MCP_URL", tokenEnv: "GITHUB_MCP_TOKEN", write: true }),
678
+ {
679
+ kind: "github-app",
680
+ role: "connection",
681
+ packageName: "@assemblyline-agents/github",
682
+ helper: "defineGitHubAppConnection",
683
+ protocol: "credential",
684
+ provider: "github",
685
+ description: "Host-only GitHub App installation credentials for Git and the GitHub CLI inside an agent sandbox.",
686
+ requiredEnv: [
687
+ "GITHUB_APP_ID",
688
+ "GITHUB_APP_PRIVATE_KEY"
689
+ ],
690
+ optionalEnv: [
691
+ "GITHUB_APP_INSTALLATION_ID",
692
+ "GITHUB_APP_SLUG",
693
+ "GITHUB_APP_CLIENT_ID",
694
+ "GITHUB_APP_CLIENT_SECRET",
695
+ "GITHUB_APP_WEBHOOK_SECRET",
696
+ "GITHUB_API_URL",
697
+ "GITHUB_OAUTH_URL"
698
+ ],
699
+ capabilities: ["sandbox-credentials", "github-app", "git", "github-cli"],
700
+ scopes: [],
701
+ subject: "user",
702
+ readToolPatterns: [],
703
+ writeToolPatterns: [],
704
+ eventCatalog: [
705
+ "issues.opened", "issues.edited", "issues.closed", "issue_comment.created",
706
+ "pull_request.opened", "pull_request.synchronize", "pull_request.closed",
707
+ "pull_request_review.submitted", "push", "workflow_run.completed",
708
+ "installation.created", "installation.deleted", "installation_repositories.added",
709
+ "installation_repositories.removed"
710
+ ],
711
+ defaultEvents: ["issues.opened", "issue_comment.created", "pull_request.opened", "pull_request_review.submitted", "push", "workflow_run.completed"],
712
+ eventMode: "manual",
713
+ eventScope: "connection",
714
+ eventRequiredEnv: ["GITHUB_APP_WEBHOOK_SECRET"],
715
+ setup: [{
716
+ kind: "connection",
717
+ name: "github-app-developer-configuration",
718
+ required: true,
719
+ message: "Create and install a GitHub App, choose its repository access and permissions in GitHub, then store its credentials in the Assembly Line host secret store."
720
+ }]
721
+ },
491
722
  catalogEntry({ kind: "slack", displayName: "Slack", helper: "defineSlackConnection", packageName: "@assemblyline-agents/slack", description: "Slack workspace search, channels, messages, files, and users through Slack MCP.", defaultUrl: "https://mcp.slack.com/mcp", urlEnv: "SLACK_MCP_URL", tokenEnv: "SLACK_MCP_TOKEN", write: true }),
492
723
  catalogEntry({ kind: "telegram", displayName: "Telegram", helper: "defineTelegramConnection", packageName: "@assemblyline-agents/telegram", description: "Telegram account tools through a developer-operated MCP bridge.", urlEnv: "TELEGRAM_MCP_URL", tokenEnv: "TELEGRAM_MCP_TOKEN" }),
493
- catalogEntry({ kind: "strava", displayName: "Strava", helper: "defineStravaConnection", description: "Strava profile and fitness activity tools through a developer-configured MCP server.", urlEnv: "STRAVA_MCP_URL", tokenEnv: "STRAVA_MCP_TOKEN" }),
494
- catalogEntry({ kind: "polar", displayName: "Polar", helper: "definePolarConnection", description: "Polar workout and heart-rate tools through a developer-configured MCP server.", urlEnv: "POLAR_MCP_URL", tokenEnv: "POLAR_MCP_TOKEN" }),
724
+ catalogEntry({
725
+ kind: "strava", displayName: "Strava", helper: "defineStravaConnection",
726
+ description: "Strava profile and fitness activity tools through a developer-configured MCP server.", urlEnv: "STRAVA_MCP_URL", tokenEnv: "STRAVA_MCP_TOKEN",
727
+ eventCatalog: ["activity.create", "activity.update", "activity.delete", "athlete.update"],
728
+ defaultEvents: ["activity.create", "activity.update", "activity.delete", "athlete.update"], eventMode: "api", eventScope: "connection",
729
+ eventRequiredEnv: ["STRAVA_CLIENT_ID", "STRAVA_CLIENT_SECRET", "STRAVA_WEBHOOK_SIGNING_SECRET"]
730
+ }),
731
+ catalogEntry({
732
+ kind: "polar", displayName: "Polar", helper: "definePolarConnection",
733
+ description: "Polar workout and heart-rate tools through a developer-configured MCP server.", urlEnv: "POLAR_MCP_URL", tokenEnv: "POLAR_MCP_TOKEN",
734
+ eventCatalog: ["EXERCISE", "SLEEP", "CONTINUOUS_HEART_RATE", "SLEEP_WISE_CIRCADIAN_BEDTIME", "SLEEP_WISE_ALERTNESS", "ACTIVITY_SUMMARY", "PHYSICAL_INFORMATION"],
735
+ defaultEvents: ["EXERCISE", "SLEEP", "CONTINUOUS_HEART_RATE"], eventMode: "api", eventScope: "connection",
736
+ eventRequiredEnv: ["POLAR_CLIENT_ID", "POLAR_CLIENT_SECRET"]
737
+ }),
495
738
  catalogEntry({ kind: "spotify", displayName: "Spotify", helper: "defineSpotifyConnection", description: "Spotify library, playlist, and playback tools through a developer-configured MCP server.", urlEnv: "SPOTIFY_MCP_URL", tokenEnv: "SPOTIFY_MCP_TOKEN", write: true }),
496
739
  catalogEntry({ kind: "xai", displayName: "xAI", helper: "defineXaiConnection", description: "xAI and X search tools through a developer-configured MCP server.", urlEnv: "XAI_MCP_URL", tokenEnv: "XAI_MCP_TOKEN" }),
497
740
  catalogEntry({
@@ -516,25 +759,354 @@ const CONNECTION_PLUGIN_CATALOG = [
516
759
  "web_fetch_exa",
517
760
  "web_search_advanced_exa"
518
761
  ],
519
- setupMessage: "Exa's hosted MCP works without credentials. Optionally set EXA_API_KEY to raise production rate limits; OpenEve sends it only as the x-api-key header."
762
+ setupMessage: "Exa's hosted MCP works without credentials. Optionally set EXA_API_KEY to raise production rate limits; Assembly Line sends it only as the x-api-key header."
763
+ }),
764
+ catalogEntry({
765
+ kind: "plaid", displayName: "Plaid", helper: "definePlaidConnection",
766
+ description: "Read-only Plaid financial tools through a developer-configured MCP bridge.", urlEnv: "PLAID_MCP_URL", tokenEnv: "PLAID_MCP_TOKEN",
767
+ eventCatalog: ["transactions.changed", "item.changed", "auth.changed", "identity.changed", "assets.changed", "holdings.changed", "investments.changed", "liabilities.changed", "payment.changed", "transfer.changed", "income.changed"],
768
+ defaultEvents: ["transactions.changed", "item.changed"], eventMode: "api", eventScope: "connection",
769
+ eventRequiredEnv: ["PLAID_CLIENT_ID", "PLAID_SECRET"]
520
770
  }),
521
- catalogEntry({ kind: "plaid", displayName: "Plaid", helper: "definePlaidConnection", description: "Read-only Plaid financial tools through a developer-configured MCP bridge.", urlEnv: "PLAID_MCP_URL", tokenEnv: "PLAID_MCP_TOKEN" }),
522
771
  catalogEntry({ kind: "granola", displayName: "Granola", helper: "defineGranolaConnection", description: "Granola meeting notes, transcripts, and action items through Granola MCP.", defaultUrl: "https://mcp.granola.ai/mcp", urlEnv: "GRANOLA_MCP_URL", tokenEnv: "GRANOLA_MCP_TOKEN" }),
523
- catalogEntry({ kind: "linear", displayName: "Linear", helper: "defineLinearConnection", description: "Linear issues, projects, cycles, and teams through Linear MCP.", defaultUrl: "https://mcp.linear.app/mcp", urlEnv: "LINEAR_MCP_URL", tokenEnv: "LINEAR_MCP_TOKEN", write: true }),
524
- catalogEntry({ kind: "notion", displayName: "Notion", helper: "defineNotionConnection", description: "Notion pages, databases, comments, and workspace search through Notion MCP.", defaultUrl: "https://mcp.notion.com/mcp", urlEnv: "NOTION_MCP_URL", tokenEnv: "NOTION_MCP_TOKEN", write: true }),
525
- catalogEntry({ kind: "monday", displayName: "monday.com", helper: "defineMondayConnection", description: "monday.com boards, items, workspaces, and docs through Platform MCP.", defaultUrl: "https://mcp.monday.com/mcp", urlEnv: "MONDAY_MCP_URL", tokenEnv: "MONDAY_MCP_TOKEN", write: true }),
526
- catalogEntry({ kind: "jira", displayName: "Jira", helper: "defineJiraConnection", description: "Jira issues, projects, transitions, and JQL search through Atlassian MCP.", defaultUrl: "https://mcp.atlassian.com/v1/mcp/authv2", urlEnv: "JIRA_MCP_URL", tokenEnv: "JIRA_MCP_TOKEN", write: true }),
527
- catalogEntry({ kind: "hubspot", displayName: "HubSpot", helper: "defineHubSpotConnection", description: "HubSpot CRM records and associations through HubSpot MCP.", defaultUrl: "https://mcp.hubspot.com", urlEnv: "HUBSPOT_MCP_URL", tokenEnv: "HUBSPOT_MCP_TOKEN" }),
528
- catalogEntry({ kind: "figma", displayName: "Figma", helper: "defineFigmaConnection", description: "Figma design, FigJam, Slides, and Dev Mode context through Figma MCP.", defaultUrl: "https://mcp.figma.com/mcp", urlEnv: "FIGMA_MCP_URL", tokenEnv: "FIGMA_MCP_TOKEN", write: true }),
772
+ {
773
+ kind: "grata",
774
+ role: "connection",
775
+ packageName: "@assemblyline-agents/grata",
776
+ helper: "defineGrataConnection",
777
+ protocol: "mcp",
778
+ transport: "http",
779
+ provider: "grata",
780
+ description: "Private-company, ownership, funding, transaction, filing, contact, conference, and deal intelligence through Grata's official hosted MCP server.",
781
+ defaultUrl: "https://mcp.grata.com",
782
+ urlEnv: "GRATA_MCP_URL",
783
+ requiredEnv: ["GRATA_MCP_CLIENT_ID", "GRATA_MCP_CLIENT_SECRET"],
784
+ optionalEnv: ["GRATA_MCP_URL", "GRATA_MCP_REDIRECT_URI"],
785
+ capabilities: ["mcp", "oauth", "pkce", "refresh-token", "live-tools", "streamable-http", "private-market-intelligence"],
786
+ scopes: ["openid", "profile", "email", "offline_access"],
787
+ subject: "user",
788
+ readToolPatterns: READ_PATTERNS,
789
+ writeToolPatterns: [
790
+ ...WRITE_PATTERNS,
791
+ "regex:(^|[-_])export([-_]|$)"
792
+ ],
793
+ setup: [{
794
+ kind: "connection",
795
+ name: "grata-mcp-oauth",
796
+ required: true,
797
+ message: "Register an OAuth client using client_secret_post with the selected Grata MCP region's /register endpoint for the Assembly Line connection callback, set GRATA_MCP_CLIENT_ID and GRATA_MCP_CLIENT_SECRET, then let each user authorize their Grata seat. Set GRATA_MCP_URL=https://eu-mcp.grata.com/ for European users."
798
+ }]
799
+ },
800
+ catalogEntry({
801
+ kind: "linear", displayName: "Linear", helper: "defineLinearConnection",
802
+ description: "Linear issues, projects, cycles, and teams through Linear MCP.", defaultUrl: "https://mcp.linear.app/mcp", urlEnv: "LINEAR_MCP_URL", tokenEnv: "LINEAR_MCP_TOKEN", write: true,
803
+ eventCatalog: ["issue.create", "issue.update", "issue.remove", "comment.create", "comment.update", "comment.remove", "project.create", "project.update", "project.remove", "cycle.create", "cycle.update", "cycle.remove", "document.create", "document.update", "document.remove", "customer.create", "customer.update", "customer.remove", "user.create", "user.update", "user.remove", "agentSessionEvent.created", "agentSessionEvent.prompted", "linear.changed"],
804
+ defaultEvents: ["issue.create", "issue.update", "comment.create", "comment.update", "project.update", "agentSessionEvent.created", "agentSessionEvent.prompted", "linear.changed"],
805
+ eventMode: "manual", eventScope: "principal", eventRequiredEnv: ["LINEAR_WEBHOOK_SECRET"]
806
+ }),
807
+ catalogEntry({
808
+ kind: "notion", displayName: "Notion", helper: "defineNotionConnection",
809
+ description: "Notion pages, databases, comments, and workspace search through Notion MCP.", defaultUrl: "https://mcp.notion.com/mcp", urlEnv: "NOTION_MCP_URL", tokenEnv: "NOTION_MCP_TOKEN", write: true,
810
+ eventCatalog: [
811
+ "page.content_updated", "page.created", "page.deleted", "page.locked", "page.moved", "page.properties_updated", "page.undeleted", "page.unlocked",
812
+ "database.content_updated", "database.created", "database.deleted", "database.moved", "database.schema_updated", "database.undeleted",
813
+ "data_source.content_updated", "data_source.created", "data_source.deleted", "data_source.moved", "data_source.schema_updated", "data_source.undeleted",
814
+ "comment.created", "comment.deleted", "comment.updated"
815
+ ],
816
+ defaultEvents: ["page.content_updated", "page.created", "page.deleted", "page.properties_updated", "data_source.schema_updated", "comment.created"],
817
+ eventMode: "manual", eventScope: "principal"
818
+ }),
819
+ catalogEntry({
820
+ kind: "monday", displayName: "monday.com", helper: "defineMondayConnection",
821
+ description: "monday.com boards, items, workspaces, and docs through Platform MCP.", defaultUrl: "https://mcp.monday.com/mcp", urlEnv: "MONDAY_MCP_URL", tokenEnv: "MONDAY_MCP_TOKEN", write: true,
822
+ eventCatalog: ["create_item", "change_column_value", "change_status_column_value", "change_name", "item_moved_to_any_group", "item_deleted", "item_archived", "create_update"],
823
+ defaultEvents: ["create_item", "change_column_value", "change_status_column_value", "item_deleted", "create_update"], eventMode: "api", eventScope: "principal",
824
+ eventRequiredEnv: ["MONDAY_SIGNING_SECRET"]
825
+ }),
826
+ catalogEntry({
827
+ kind: "jira", displayName: "Jira", helper: "defineJiraConnection",
828
+ description: "Jira issues, projects, transitions, and JQL search through Atlassian MCP.", defaultUrl: "https://mcp.atlassian.com/v1/mcp/authv2", urlEnv: "JIRA_MCP_URL", tokenEnv: "JIRA_MCP_TOKEN", write: true,
829
+ eventCatalog: ["jira:issue_created", "jira:issue_updated", "jira:issue_deleted", "comment_created", "comment_updated", "comment_deleted", "issue_property_set", "issue_property_deleted"],
830
+ defaultEvents: ["jira:issue_created", "jira:issue_updated", "comment_created", "comment_updated"], eventMode: "api", eventScope: "principal"
831
+ }),
832
+ catalogEntry({
833
+ kind: "hubspot", displayName: "HubSpot", helper: "defineHubSpotConnection",
834
+ description: "HubSpot CRM records and associations through HubSpot MCP.", defaultUrl: "https://mcp.hubspot.com", urlEnv: "HUBSPOT_MCP_URL", tokenEnv: "HUBSPOT_MCP_TOKEN",
835
+ eventCatalog: ["contact.creation", "contact.deletion", "contact.propertyChange", "company.creation", "company.deletion", "company.propertyChange", "deal.creation", "deal.deletion", "deal.propertyChange", "ticket.creation", "ticket.deletion", "ticket.propertyChange"],
836
+ defaultEvents: ["contact.creation", "contact.deletion", "company.creation", "company.deletion", "deal.creation", "deal.deletion", "ticket.creation", "ticket.deletion"],
837
+ eventMode: "api", eventScope: "connection", eventRequiredEnv: ["HUBSPOT_APP_ID", "HUBSPOT_DEVELOPER_API_KEY", "HUBSPOT_CLIENT_SECRET"]
838
+ }),
839
+ catalogEntry({
840
+ kind: "figma", displayName: "Figma", helper: "defineFigmaConnection",
841
+ description: "Figma design, FigJam, Slides, and Dev Mode context through Figma MCP.",
842
+ defaultUrl: "https://mcp.figma.com/mcp", urlEnv: "FIGMA_MCP_URL", tokenEnv: "FIGMA_MCP_TOKEN", write: true,
843
+ eventCatalog: ["FILE_UPDATE", "FILE_DELETE", "FILE_VERSION_UPDATE", "LIBRARY_PUBLISH"],
844
+ defaultEvents: ["FILE_UPDATE", "FILE_DELETE"], eventMode: "api", eventScope: "principal"
845
+ }),
529
846
  catalogEntry({ kind: "paper", displayName: "Paper", helper: "definePaperConnection", description: "Paper design tools through a developer-exposed local MCP bridge.", urlEnv: "PAPER_MCP_URL", tokenEnv: "PAPER_MCP_TOKEN", tokenRequired: false, write: true }),
530
- catalogEntry({ kind: "sentry", displayName: "Sentry", helper: "defineSentryConnection", description: "Sentry issues, events, projects, and teams through Sentry MCP.", defaultUrl: "https://mcp.sentry.dev/mcp", urlEnv: "SENTRY_MCP_URL", tokenEnv: "SENTRY_MCP_TOKEN", write: true }),
531
- catalogEntry({ kind: "supabase", displayName: "Supabase", helper: "defineSupabaseConnection", description: "Supabase projects, databases, docs, and Edge Functions through Supabase MCP.", defaultUrl: "https://mcp.supabase.com/mcp", urlEnv: "SUPABASE_MCP_URL", tokenEnv: "SUPABASE_MCP_TOKEN", write: true }),
532
- catalogEntry({ kind: "metabase", displayName: "Metabase", helper: "defineMetabaseConnection", description: "Metabase semantic-layer queries, questions, and dashboards through an instance MCP endpoint.", urlEnv: "METABASE_MCP_URL", tokenEnv: "METABASE_MCP_TOKEN", tokenRequired: false, write: true }),
533
- catalogEntry({ kind: "cloudflare", displayName: "Cloudflare", helper: "defineCloudflareConnection", description: "Cloudflare API and account tools through Cloudflare MCP.", defaultUrl: "https://mcp.cloudflare.com/mcp", urlEnv: "CLOUDFLARE_MCP_URL", tokenEnv: "CLOUDFLARE_MCP_TOKEN", write: true }),
534
- catalogEntry({ kind: "vercel", displayName: "Vercel", helper: "defineVercelConnection", description: "Vercel projects, deployments, logs, and teams through Vercel MCP.", defaultUrl: "https://mcp.vercel.com", urlEnv: "VERCEL_MCP_URL", tokenEnv: "VERCEL_MCP_TOKEN", write: true }),
535
- catalogEntry({ kind: "railway", displayName: "Railway", helper: "defineRailwayConnection", packageName: "@assemblyline-agents/railway", description: "Railway projects, services, variables, and deployments through Railway MCP.", defaultUrl: "https://mcp.railway.com", urlEnv: "RAILWAY_MCP_URL", tokenEnv: "RAILWAY_MCP_TOKEN", write: true }),
847
+ catalogEntry({
848
+ kind: "sentry", displayName: "Sentry", helper: "defineSentryConnection",
849
+ description: "Sentry issues, events, projects, and teams through Sentry MCP.", defaultUrl: "https://mcp.sentry.dev/mcp", urlEnv: "SENTRY_MCP_URL", tokenEnv: "SENTRY_MCP_TOKEN", write: true,
850
+ eventCatalog: ["event.created", "event.alert"], defaultEvents: ["event.created", "event.alert"], eventMode: "api", eventScope: "principal"
851
+ }),
852
+ catalogEntry({
853
+ kind: "supabase", displayName: "Supabase", helper: "defineSupabaseConnection",
854
+ description: "Supabase projects, databases, docs, and Edge Functions through Supabase MCP.", defaultUrl: "https://mcp.supabase.com/mcp", urlEnv: "SUPABASE_MCP_URL", tokenEnv: "SUPABASE_MCP_TOKEN", write: true,
855
+ eventCatalog: ["row.inserted", "row.updated", "row.deleted"], defaultEvents: ["row.inserted", "row.updated", "row.deleted"], eventMode: "api", eventScope: "principal",
856
+ eventRequiredEnv: ["SUPABASE_WEBHOOK_SECRET"]
857
+ }),
858
+ catalogEntry({
859
+ kind: "metabase", displayName: "Metabase", helper: "defineMetabaseConnection",
860
+ description: "Metabase semantic-layer queries, questions, and dashboards through an instance MCP endpoint.", urlEnv: "METABASE_MCP_URL", tokenEnv: "METABASE_MCP_TOKEN", tokenRequired: false, write: true,
861
+ eventCatalog: ["alert.triggered"], defaultEvents: ["alert.triggered"], eventMode: "manual", eventScope: "connection",
862
+ eventRequiredEnv: ["METABASE_WEBHOOK_SECRET"]
863
+ }),
864
+ catalogEntry({
865
+ kind: "cloudflare", displayName: "Cloudflare", helper: "defineCloudflareConnection",
866
+ description: "Cloudflare API and account tools through Cloudflare MCP.", defaultUrl: "https://mcp.cloudflare.com/mcp", urlEnv: "CLOUDFLARE_MCP_URL", tokenEnv: "CLOUDFLARE_MCP_TOKEN", write: true,
867
+ eventCatalog: ["notification.received"], defaultEvents: ["notification.received"], eventMode: "api", eventScope: "principal",
868
+ eventRequiredEnv: ["CLOUDFLARE_WEBHOOK_SECRET"]
869
+ }),
870
+ catalogEntry({
871
+ kind: "vercel", displayName: "Vercel", helper: "defineVercelConnection",
872
+ description: "Vercel projects, deployments, logs, and teams through Vercel MCP.", defaultUrl: "https://mcp.vercel.com", urlEnv: "VERCEL_MCP_URL", tokenEnv: "VERCEL_MCP_TOKEN", write: true,
873
+ eventCatalog: ["deployment.created", "deployment.succeeded", "deployment.promoted", "deployment.error", "deployment.cancelled", "project.created", "project.removed", "project.renamed", "project.env.created", "project.env.updated", "project.env.deleted", "firewall.attack.detected"],
874
+ defaultEvents: ["deployment.created", "deployment.succeeded", "deployment.error", "deployment.cancelled"], eventMode: "api", eventScope: "principal"
875
+ }),
876
+ catalogEntry({
877
+ kind: "railway", displayName: "Railway", helper: "defineRailwayConnection", packageName: "@assemblyline-agents/railway",
878
+ description: "Railway projects, services, variables, and deployments through Railway MCP.", defaultUrl: "https://mcp.railway.com", urlEnv: "RAILWAY_MCP_URL", tokenEnv: "RAILWAY_MCP_TOKEN", write: true,
879
+ eventCatalog: ["deployment.changed", "alert.triggered"], defaultEvents: ["deployment.changed", "alert.triggered"], eventMode: "manual", eventScope: "connection"
880
+ }),
536
881
  catalogEntry({ kind: "refero", displayName: "Refero", helper: "defineReferoConnection", description: "Refero design references, screens, and product flows through Refero MCP.", defaultUrl: "https://api.refero.design/mcp", urlEnv: "REFERO_MCP_URL", tokenEnv: "REFERO_MCP_BEARER_TOKEN" }),
882
+ catalogEntry({
883
+ kind: "agentmail",
884
+ displayName: "AgentMail",
885
+ helper: "defineAgentMailConnection",
886
+ description: "AgentMail inboxes, threads, messages, drafts, and attachments through the official hosted MCP server.",
887
+ defaultUrl: "https://mcp.agentmail.to/mcp",
888
+ urlEnv: "AGENTMAIL_MCP_URL",
889
+ tokenEnv: "AGENTMAIL_API_KEY",
890
+ tokenHeader: "x-api-key",
891
+ subject: "environment",
892
+ tools: {
893
+ allow: [
894
+ "list_inboxes",
895
+ "get_inbox",
896
+ "create_inbox",
897
+ "update_inbox",
898
+ "delete_inbox",
899
+ "list_threads",
900
+ "search_threads",
901
+ "get_thread",
902
+ "update_thread",
903
+ "delete_thread",
904
+ "list_messages",
905
+ "search_messages",
906
+ "send_message",
907
+ "reply_to_message",
908
+ "forward_message",
909
+ "update_message",
910
+ "create_draft",
911
+ "list_drafts",
912
+ "get_draft",
913
+ "update_draft",
914
+ "send_draft",
915
+ "delete_draft",
916
+ "get_attachment",
917
+ "auth_me"
918
+ ]
919
+ },
920
+ readToolPatterns: [
921
+ "list_inboxes",
922
+ "get_inbox",
923
+ "list_threads",
924
+ "search_threads",
925
+ "get_thread",
926
+ "list_messages",
927
+ "search_messages",
928
+ "list_drafts",
929
+ "get_draft",
930
+ "get_attachment",
931
+ "auth_me"
932
+ ],
933
+ writeToolPatterns: [
934
+ "create_inbox",
935
+ "update_inbox",
936
+ "delete_inbox",
937
+ "update_thread",
938
+ "delete_thread",
939
+ "send_message",
940
+ "reply_to_message",
941
+ "forward_message",
942
+ "update_message",
943
+ "create_draft",
944
+ "update_draft",
945
+ "send_draft",
946
+ "delete_draft"
947
+ ],
948
+ write: true,
949
+ eventCatalog: [
950
+ "message.received", "message.received.spam", "message.received.blocked",
951
+ "message.received.unauthenticated", "message.sent", "message.delivered",
952
+ "message.bounced", "message.complained", "message.rejected", "domain.verified"
953
+ ],
954
+ defaultEvents: ["message.received"],
955
+ eventMode: "api",
956
+ eventScope: "connection",
957
+ setupMessage: "Create an AgentMail API key, set AGENTMAIL_API_KEY on the Assembly Line runtime host, and keep inbox and sender scope owned by the provider account."
958
+ }),
959
+ catalogEntry({
960
+ kind: "resend",
961
+ displayName: "Resend",
962
+ helper: "defineResendConnection",
963
+ description: "Transactional email, broadcasts, contacts, domains, templates, automations, and delivery data through Resend's official hosted MCP server.",
964
+ defaultUrl: "https://mcp.resend.com/mcp",
965
+ urlEnv: "RESEND_MCP_URL",
966
+ tokenEnv: "RESEND_API_KEY",
967
+ subject: "environment",
968
+ tools: {
969
+ block: [
970
+ "connect-to-editor",
971
+ "create-api-key",
972
+ "create-webhook",
973
+ "get-webhook"
974
+ ]
975
+ },
976
+ readToolPatterns: ["regex:^(get|list)-"],
977
+ writeToolPatterns: [
978
+ "get-tiptap-json-content",
979
+ "regex:^(add|batch-add|batch-remove|cancel|compose|create|disconnect|duplicate|manage|publish|remove|revoke|send|update|verify)-"
980
+ ],
981
+ write: true,
982
+ eventCatalog: [
983
+ "email.sent", "email.delivered", "email.delivery_delayed", "email.failed",
984
+ "email.opened", "email.clicked", "email.bounced", "email.complained",
985
+ "email.received", "email.scheduled", "email.suppressed",
986
+ "domain.created", "domain.updated", "domain.deleted",
987
+ "contact.created", "contact.updated", "contact.deleted"
988
+ ],
989
+ defaultEvents: ["email.received", "email.delivered", "email.failed", "email.bounced"],
990
+ eventMode: "api",
991
+ eventScope: "connection",
992
+ setupMessage: "Create a team-scoped Resend API key, set RESEND_API_KEY on the Assembly Line runtime host, and verify the sending domain. Full-platform reads require a full_access key; restrict the connection's visible tools when using a sending_access key."
993
+ }),
537
994
  catalogEntry({ kind: "agentcash", displayName: "AgentCash", helper: "defineAgentCashConnection", description: "Paid API discovery, schema, balance, and request tools through an AgentCash MCP bridge.", urlEnv: "AGENTCASH_MCP_URL", tokenEnv: "AGENTCASH_MCP_BRIDGE_TOKEN", write: true }),
995
+ catalogEntry({
996
+ kind: "treg",
997
+ displayName: "Treg",
998
+ helper: "defineTregConnection",
999
+ description: "External API discovery, pricing, balance, team inventory, and credential-injected calls through Treg's hosted tool catalog.",
1000
+ defaultUrl: "https://treg.to/mcp/",
1001
+ urlEnv: "TREG_MCP_URL",
1002
+ tokenEnv: "TREG_TOKEN",
1003
+ tools: {
1004
+ allow: [
1005
+ "catalog_search",
1006
+ "catalog_get",
1007
+ "catalog_request",
1008
+ "call",
1009
+ "balance",
1010
+ "my_tools"
1011
+ ]
1012
+ },
1013
+ readToolPatterns: ["catalog_search", "catalog_get", "balance", "my_tools"],
1014
+ writeToolPatterns: ["catalog_request", "call"],
1015
+ write: true,
1016
+ setupMessage: "Create an organization-scoped or agent token in Treg, set TREG_TOKEN on the Assembly Line runtime, and review whether Treg writes require approval. The call tool can spend prepaid balance or mutate an upstream service."
1017
+ }),
1018
+ {
1019
+ kind: "x",
1020
+ role: "connection",
1021
+ packageName: "@assemblyline-agents/x",
1022
+ helper: "defineXConnection",
1023
+ protocol: "http",
1024
+ provider: "x",
1025
+ description: "Connected X account identity, private bookmarks, and reviewed post or reply publishing through X API v2.",
1026
+ defaultBaseUrl: "https://api.x.com/2",
1027
+ baseUrlEnv: "X_API_BASE_URL",
1028
+ requiredEnv: ["X_API_CLIENT_ID", "X_API_CLIENT_SECRET"],
1029
+ optionalEnv: ["X_API_REDIRECT_URI", "X_API_BASE_URL"],
1030
+ capabilities: ["http-api", "oauth", "pkce", "refresh-token", "live-tools", "bookmarks", "publishing"],
1031
+ scopes: ["bookmark.read", "tweet.read", "tweet.write", "users.read", "offline.access"],
1032
+ subject: "user",
1033
+ tools: {
1034
+ allow: ["x_get_authenticated_user", "x_list_bookmarks", "x_create_post"]
1035
+ },
1036
+ readToolPatterns: ["x_get_authenticated_user", "x_list_bookmarks"],
1037
+ writeToolPatterns: ["x_create_post"],
1038
+ setup: [{
1039
+ kind: "connection",
1040
+ name: "x-developer-configuration",
1041
+ required: true,
1042
+ message: "Create a confidential X OAuth 2.0 App, enable the reviewed bookmark and post scopes, set X_API_CLIENT_ID and X_API_CLIENT_SECRET, and register the Assembly Line connection callback URL. Authorization Code + PKCE stores a refreshable per-user grant; X API usage and costs remain developer-owned."
1043
+ }]
1044
+ },
1045
+ {
1046
+ kind: "dropbox",
1047
+ role: "connection",
1048
+ packageName: "@assemblyline-agents/dropbox",
1049
+ helper: "defineDropboxConnection",
1050
+ protocol: "http",
1051
+ provider: "dropbox",
1052
+ description: "Dropbox account, file and folder metadata, search, temporary content links, and reviewed file operations through the Dropbox API.",
1053
+ defaultBaseUrl: "https://api.dropboxapi.com/2",
1054
+ baseUrlEnv: "DROPBOX_API_BASE_URL",
1055
+ requiredEnv: ["DROPBOX_APP_KEY", "DROPBOX_APP_SECRET"],
1056
+ optionalEnv: ["DROPBOX_REDIRECT_URI", "DROPBOX_API_BASE_URL"],
1057
+ capabilities: ["http-api", "oauth", "pkce", "refresh-token", "live-tools"],
1058
+ scopes: [
1059
+ "account_info.read",
1060
+ "files.metadata.read",
1061
+ "files.content.read",
1062
+ "files.content.write",
1063
+ "sharing.read",
1064
+ "sharing.write"
1065
+ ],
1066
+ subject: "user",
1067
+ tools: {
1068
+ allow: [
1069
+ "users_get_current_account",
1070
+ "users_get_space_usage",
1071
+ "files_get_metadata",
1072
+ "files_list_folder",
1073
+ "files_list_folder_continue",
1074
+ "files_search_v2",
1075
+ "files_search_continue_v2",
1076
+ "files_get_temporary_link",
1077
+ "sharing_list_shared_links",
1078
+ "files_create_folder_v2",
1079
+ "files_copy_v2",
1080
+ "files_move_v2",
1081
+ "files_delete_v2",
1082
+ "sharing_create_shared_link_with_settings"
1083
+ ]
1084
+ },
1085
+ readToolPatterns: [
1086
+ "users_get_current_account",
1087
+ "users_get_space_usage",
1088
+ "files_get_metadata",
1089
+ "files_list_folder",
1090
+ "files_list_folder_continue",
1091
+ "files_search_v2",
1092
+ "files_search_continue_v2",
1093
+ "files_get_temporary_link",
1094
+ "sharing_list_shared_links"
1095
+ ],
1096
+ writeToolPatterns: [
1097
+ "files_create_folder_v2",
1098
+ "files_copy_v2",
1099
+ "files_move_v2",
1100
+ "files_delete_v2",
1101
+ "sharing_create_shared_link_with_settings"
1102
+ ],
1103
+ setup: [{
1104
+ kind: "connection",
1105
+ name: "dropbox-developer-configuration",
1106
+ required: true,
1107
+ message: "Register one Dropbox API app, enable the scopes required by this connection, set DROPBOX_APP_KEY and DROPBOX_APP_SECRET, and register the Assembly Line connection callback URL. OAuth Authorization Code + PKCE requests offline access for refreshable user grants."
1108
+ }]
1109
+ },
538
1110
  {
539
1111
  kind: "soundcloud",
540
1112
  role: "connection",
@@ -553,12 +1125,11 @@ const CONNECTION_PLUGIN_CATALOG = [
553
1125
  tools: { block: ["post_tracks"] },
554
1126
  readToolPatterns: ["regex:^get_"],
555
1127
  writeToolPatterns: ["regex:^(post|put|patch|delete)_"],
556
- skill: "soundcloud",
557
1128
  setup: [{
558
1129
  kind: "connection",
559
1130
  name: "soundcloud-developer-configuration",
560
1131
  required: true,
561
- message: "Register a SoundCloud application and set SOUNDCLOUD_CLIENT_ID and SOUNDCLOUD_CLIENT_SECRET. OpenEve handles OAuth 2.1 PKCE; the developer owns the app and redirect URI."
1132
+ message: "Register a SoundCloud application and set SOUNDCLOUD_CLIENT_ID and SOUNDCLOUD_CLIENT_SECRET. Assembly Line handles OAuth 2.1 PKCE; the developer owns the app and redirect URI."
562
1133
  }]
563
1134
  },
564
1135
  catalogEntry({
@@ -573,7 +1144,12 @@ const CONNECTION_PLUGIN_CATALOG = [
573
1144
  tools: { allow: ["get_session", "get_session_messages", "list_sessions", "list_browser_profiles", "run_session", "send_task", "stop_session"] },
574
1145
  readToolPatterns: ["get_session", "get_session_messages", "list_sessions", "list_browser_profiles"],
575
1146
  writeToolPatterns: ["run_session", "send_task", "stop_session"],
576
- setupMessage: "Set BROWSER_USE_API_KEY for the OpenEve host. Browser profiles, cost limits, and write authority remain developer-controlled."
1147
+ eventCatalog: ["agent.task.status_update"],
1148
+ defaultEvents: ["agent.task.status_update"],
1149
+ eventMode: "manual",
1150
+ eventScope: "connection",
1151
+ eventRequiredEnv: ["BROWSER_USE_WEBHOOK_SECRET"],
1152
+ setupMessage: "Set BROWSER_USE_API_KEY for the Assembly Line host. Browser profiles, cost limits, and write authority remain developer-controlled."
577
1153
  }),
578
1154
  catalogEntry({
579
1155
  kind: "orgo",
@@ -628,7 +1204,7 @@ const CONNECTION_PLUGIN_CATALOG = [
628
1204
  "execute_python"
629
1205
  ],
630
1206
  optionalEnv: ["ORGO_API_BASE_URL"],
631
- setupMessage: "Set ORGO_API_KEY on the OpenEve runtime host. The developer owns Orgo workspaces, account limits, auto-stop policy, login state, and billing; the packaged bridge strips VNC credentials from results."
1207
+ setupMessage: "Set ORGO_API_KEY on the Assembly Line runtime host. The developer owns Orgo workspaces, account limits, auto-stop policy, login state, and billing; the packaged bridge strips VNC credentials from results."
632
1208
  }),
633
1209
  catalogEntry({
634
1210
  kind: "peekaboo",
@@ -645,22 +1221,22 @@ const CONNECTION_PLUGIN_CATALOG = [
645
1221
  },
646
1222
  readToolPatterns: ["inspect_ui", "list", "permissions"],
647
1223
  writeToolPatterns: ["click", "type", "hotkey", "scroll", "drag", "swipe", "move", "set_value", "perform_action", "app", "window", "menu", "dock", "dialog", "space"],
648
- setupMessage: "Local deployment only: install Peekaboo on the OpenEve Mac (macOS 15+), grant that host process Accessibility and Screen Recording permissions, and use the local deploy target. Hosted targets are rejected."
1224
+ setupMessage: "Local deployment only: install Peekaboo on the Assembly Line Mac (macOS 15+), grant that host process Accessibility and Screen Recording permissions, and use the local deploy target. Hosted targets are rejected."
649
1225
  }),
650
1226
  catalogEntry({
651
1227
  kind: "computer-use",
652
- displayName: "OpenEve Computer Use",
1228
+ displayName: "Assembly Line Computer Use",
653
1229
  helper: "defineComputerUseConnection",
654
- description: "End-to-end encrypted accessibility and input automation on a paired Mac through the OpenEve device relay.",
1230
+ description: "End-to-end encrypted accessibility and input automation on a paired Mac through the Assembly Line device relay.",
655
1231
  transport: "relay",
656
- defaultUrl: "https://computer-use.openeve.dev/v1",
657
- urlEnv: "OPENEVE_COMPUTER_USE_RELAY_URL",
658
- credentialEnv: "OPENEVE_COMPUTER_USE_BINDING",
1232
+ defaultUrl: "https://computer-use.artificialillumination.co/v1",
1233
+ urlEnv: "ASSEMBLY_LINE_COMPUTER_USE_RELAY_URL",
1234
+ credentialEnv: "ASSEMBLY_LINE_COMPUTER_USE_BINDING",
659
1235
  subject: "environment",
660
1236
  tools: { allow: ["inspect_ui", "list", "permissions", "click", "type", "hotkey", "scroll", "drag", "swipe", "move", "set_value", "perform_action", "app", "window", "menu", "dock", "dialog", "space"] },
661
1237
  readToolPatterns: ["inspect_ui", "list", "permissions"],
662
1238
  writeToolPatterns: ["click", "type", "hotkey", "scroll", "drag", "swipe", "move", "set_value", "perform_action", "app", "window", "menu", "dock", "dialog", "space"],
663
- setupMessage: "Install OpenEve Agent Builder on the Mac, enable Computer Host, pair this deployment, and set the generated OPENEVE_COMPUTER_USE_BINDING secret on the remote runtime. The binding is device-scoped and must not be placed in prompts or source control."
1239
+ setupMessage: "Install Assembly Line Agent Builder on the Mac, enable Computer Host, pair this deployment, and set the generated ASSEMBLY_LINE_COMPUTER_USE_BINDING secret on the remote runtime. The binding is device-scoped and must not be placed in prompts or source control."
664
1240
  }),
665
1241
  catalogEntry({
666
1242
  kind: "ffmpeg",
@@ -689,101 +1265,18 @@ const CONNECTION_PLUGIN_CATALOG = [
689
1265
  "extract_frames",
690
1266
  "reframe_vertical"
691
1267
  ],
692
- setupMessage: "Install ffmpeg and ffprobe on the OpenEve runtime host. The plugin keeps all media paths inside its configured workspace root and exposes typed operations instead of arbitrary FFmpeg flags."
1268
+ setupMessage: "Install ffmpeg and ffprobe on the Assembly Line runtime host. The plugin keeps all media paths inside its configured workspace root and exposes typed operations instead of arbitrary FFmpeg flags."
693
1269
  }),
694
- catalogEntry({
695
- kind: "remotion",
696
- displayName: "Remotion",
697
- helper: "defineRemotionConnection",
698
- description: "Workspace-scoped Remotion composition discovery, version checks, video renders, and still renders through the project CLI.",
699
- transport: "stdio",
700
- subject: "environment",
701
- tools: {
702
- allow: [
703
- "list_compositions",
704
- "check_versions",
705
- "render_video",
706
- "render_still"
707
- ]
708
- },
709
- readToolPatterns: ["list_compositions", "check_versions"],
710
- writeToolPatterns: ["render_video", "render_still"],
711
- setupMessage: "Install Remotion and @remotion/cli in the configured project. OpenEve uses Remotion's supported CLI and Agent Skills workflow; it does not depend on Remotion's deprecated hosted MCP server."
712
- })
1270
+ REMOTION_PLUGIN
713
1271
  ];
714
- function validatePluginAccess(plugin, access) {
715
- if (!access)
716
- throw new Error(`${plugin.helper}: access must explicitly select read and write authority.`);
717
- if (access.write !== false && plugin.writeToolPatterns.length === 0) {
718
- throw new Error(`${plugin.helper}: ${plugin.provider} is a read-only plugin and cannot enable writes.`);
719
- }
720
- }
721
- function pluginAccessDefinition(plugin, access) {
722
- return {
723
- read: { tools: [...plugin.readToolPatterns] },
724
- write: access.write === false
725
- ? false
726
- : {
727
- tools: [...plugin.writeToolPatterns],
728
- approval: normalizePluginApproval(access.write.approval)
729
- }
730
- };
731
- }
732
- function tokenAuth(tokenEnv) {
733
- if (!tokenEnv)
734
- return undefined;
735
- return ({ env }) => ({
736
- principalType: "user",
737
- displayName: `${tokenEnv} bearer token`,
738
- getToken: async () => {
739
- const token = env[tokenEnv]?.trim();
740
- if (!token)
741
- throw new Error(`Missing ${tokenEnv}. Configure the provider credential or pass a custom auth definition.`);
742
- return { token };
743
- }
744
- });
745
- }
746
- function environmentValue(name) {
747
- if (!name || typeof process === "undefined")
748
- return undefined;
749
- return process.env[name]?.trim() || undefined;
750
- }
751
- function tokenHeader(name, tokenEnv) {
752
- if (!tokenEnv)
753
- return undefined;
754
- return ({ env }) => {
755
- const token = env[tokenEnv]?.trim();
756
- if (!token)
757
- throw new Error(`Missing ${tokenEnv}. Configure the provider credential or pass custom headers.`);
758
- return { [name]: token };
759
- };
760
- }
761
- function mergeHeaders(first, second) {
762
- if (!first)
763
- return second;
764
- if (!second)
765
- return first;
766
- return async (context) => ({
767
- ...(await resolveHeaders(first, context)),
768
- ...(await resolveHeaders(second, context))
769
- });
770
- }
771
- async function resolveHeaders(definition, context) {
772
- if (typeof definition === "function")
773
- return definition(context);
774
- const resolved = {};
775
- for (const [name, value] of Object.entries(definition)) {
776
- resolved[name] = await resolveHeaderValue(value, context);
777
- }
778
- return resolved;
779
- }
780
- async function resolveHeaderValue(value, context) {
781
- return typeof value === "function" ? value(context) : value;
782
- }
783
1272
  function cloneToolFilter(filter) {
784
1273
  if (!filter)
785
1274
  return undefined;
786
- return "allow" in filter ? { allow: [...filter.allow] } : { block: [...filter.block] };
1275
+ if ("allow" in filter)
1276
+ return { allow: [...filter.allow] };
1277
+ if ("block" in filter)
1278
+ return { block: [...filter.block] };
1279
+ return { allOf: filter.allOf.map((child) => cloneToolFilter(child)) };
787
1280
  }
788
1281
  function cloneHostRequirements(requirements) {
789
1282
  return {
@@ -792,11 +1285,6 @@ function cloneHostRequirements(requirements) {
792
1285
  ...(requirements.platforms ? { platforms: [...requirements.platforms] } : {})
793
1286
  };
794
1287
  }
795
- function normalizePluginApproval(approval) {
796
- if (approval === "always" || approval === "once" || approval === "never")
797
- return { mode: approval };
798
- return approval;
799
- }
800
1288
  function cloneMetadata(entry) {
801
1289
  return {
802
1290
  ...entry,
@@ -806,18 +1294,24 @@ function cloneMetadata(entry) {
806
1294
  scopes: [...(entry.scopes ?? [])],
807
1295
  readToolPatterns: [...entry.readToolPatterns],
808
1296
  writeToolPatterns: [...entry.writeToolPatterns],
809
- ...(entry.skills ? { skills: [...entry.skills] } : {}),
810
1297
  ...(entry.tools ? { tools: cloneToolFilter(entry.tools) } : {}),
811
1298
  ...(entry.hostRequirements ? { hostRequirements: cloneHostRequirements(entry.hostRequirements) } : {})
812
1299
  };
813
1300
  }
814
- function isPluginModule(value) {
815
- if (!value || typeof value !== "object")
816
- return false;
817
- const connections = value.connections;
818
- return connections === undefined || (Array.isArray(connections) && connections.every((entry) => Boolean(entry) && entry.role === "connection" && typeof entry.kind === "string" && typeof entry.helper === "string"));
819
- }
820
- export function connectionPluginBinding(metadata) {
821
- return { kind: metadata.kind };
1301
+ function cloneToolPackMetadata(entry) {
1302
+ return {
1303
+ ...entry,
1304
+ tools: entry.tools.map((tool) => ({ ...tool })),
1305
+ ...(entry.config ? {
1306
+ config: {
1307
+ ...entry.config,
1308
+ ...(entry.config.options ? { options: structuredClone(entry.config.options) } : {})
1309
+ }
1310
+ } : {}),
1311
+ ...(entry.skills ? { skills: [...entry.skills] } : {}),
1312
+ ...(entry.requiredEnv ? { requiredEnv: [...entry.requiredEnv] } : {}),
1313
+ ...(entry.optionalEnv ? { optionalEnv: [...entry.optionalEnv] } : {}),
1314
+ ...(entry.setup ? { setup: entry.setup.map((step) => ({ ...step })) } : {})
1315
+ };
822
1316
  }
823
1317
  //# sourceMappingURL=plugin.js.map