@slashfi/agents-sdk 0.7.0 → 0.9.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 (64) hide show
  1. package/dist/agent-definitions/auth.d.ts +17 -0
  2. package/dist/agent-definitions/auth.d.ts.map +1 -1
  3. package/dist/agent-definitions/auth.js +135 -1
  4. package/dist/agent-definitions/auth.js.map +1 -1
  5. package/dist/agent-definitions/integrations.d.ts +28 -12
  6. package/dist/agent-definitions/integrations.d.ts.map +1 -1
  7. package/dist/agent-definitions/integrations.js +239 -41
  8. package/dist/agent-definitions/integrations.js.map +1 -1
  9. package/dist/agent-definitions/remote-registry.d.ts +32 -0
  10. package/dist/agent-definitions/remote-registry.d.ts.map +1 -0
  11. package/dist/agent-definitions/remote-registry.js +460 -0
  12. package/dist/agent-definitions/remote-registry.js.map +1 -0
  13. package/dist/index.d.ts +12 -5
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +8 -2
  16. package/dist/index.js.map +1 -1
  17. package/dist/integration-interface.d.ts +37 -0
  18. package/dist/integration-interface.d.ts.map +1 -0
  19. package/dist/integration-interface.js +94 -0
  20. package/dist/integration-interface.js.map +1 -0
  21. package/dist/integrations-store.d.ts +33 -0
  22. package/dist/integrations-store.d.ts.map +1 -0
  23. package/dist/integrations-store.js +50 -0
  24. package/dist/integrations-store.js.map +1 -0
  25. package/dist/jwt.d.ts +86 -17
  26. package/dist/jwt.d.ts.map +1 -1
  27. package/dist/jwt.js +140 -17
  28. package/dist/jwt.js.map +1 -1
  29. package/dist/registry.d.ts +7 -0
  30. package/dist/registry.d.ts.map +1 -1
  31. package/dist/registry.js +14 -21
  32. package/dist/registry.js.map +1 -1
  33. package/dist/secret-collection.d.ts +37 -0
  34. package/dist/secret-collection.d.ts.map +1 -0
  35. package/dist/secret-collection.js +37 -0
  36. package/dist/secret-collection.js.map +1 -0
  37. package/dist/server.d.ts +41 -42
  38. package/dist/server.d.ts.map +1 -1
  39. package/dist/server.js +232 -555
  40. package/dist/server.js.map +1 -1
  41. package/dist/types.d.ts +24 -2
  42. package/dist/types.d.ts.map +1 -1
  43. package/package.json +5 -2
  44. package/src/agent-definitions/auth.ts +187 -1
  45. package/src/agent-definitions/integrations.ts +287 -55
  46. package/src/agent-definitions/remote-registry.ts +621 -0
  47. package/src/index.ts +22 -5
  48. package/src/integration-interface.ts +118 -0
  49. package/src/integrations-store.ts +84 -0
  50. package/src/jwt.ts +233 -65
  51. package/src/registry.ts +23 -2
  52. package/src/secret-collection.ts +66 -0
  53. package/src/server.ts +268 -647
  54. package/src/types.ts +28 -2
  55. package/dist/slack-oauth.d.ts +0 -27
  56. package/dist/slack-oauth.d.ts.map +0 -1
  57. package/dist/slack-oauth.js +0 -48
  58. package/dist/slack-oauth.js.map +0 -1
  59. package/dist/web-pages.d.ts +0 -8
  60. package/dist/web-pages.d.ts.map +0 -1
  61. package/dist/web-pages.js +0 -169
  62. package/dist/web-pages.js.map +0 -1
  63. package/src/slack-oauth.ts +0 -66
  64. package/src/web-pages.ts +0 -178
@@ -18,13 +18,13 @@
18
18
  * const registry = createAgentRegistry();
19
19
  * registry.register(createIntegrationsAgent({
20
20
  * store: myIntegrationStore,
21
- * callbackBaseUrl: 'https://myapp.com/integrations/callback',
21
+ * callbackBaseUrl: 'https://myapp.com/oauth/callback',
22
22
  * }));
23
23
  * ```
24
24
  */
25
25
 
26
26
  import { defineAgent, defineTool } from "../define.js";
27
- import { pendingCollections, generateCollectionToken } from "../server.js";
27
+ import { pendingCollections, generateCollectionToken } from "../secret-collection.js";
28
28
  import type { AgentDefinition, ToolContext, ToolDefinition } from "../types.js";
29
29
 
30
30
  // ============================================
@@ -99,7 +99,11 @@ export interface IntegrationApiConfig {
99
99
  export interface ProviderConfig {
100
100
  id: string;
101
101
  name: string;
102
- type: "rest" | "graphql" | "agent-registry";
102
+ /**
103
+ * Agent path that handles this integration type.
104
+ * @integrations dispatches setup/connect/call to that agent's integrationMethods.
105
+ */
106
+ agentPath: string;
103
107
  /**
104
108
  * Scope of the integration:
105
109
  * - 'user': per-user tokens (Slack, Notion, Linear)
@@ -108,7 +112,7 @@ export interface ProviderConfig {
108
112
  scope?: "user" | "tenant";
109
113
  docs?: { llmsTxt?: string; human?: string[] };
110
114
  auth?: IntegrationOAuthConfig;
111
- api: IntegrationApiConfig;
115
+ api?: IntegrationApiConfig;
112
116
  }
113
117
 
114
118
  // ============================================
@@ -131,18 +135,9 @@ export interface GraphqlCallInput {
131
135
  variables?: Record<string, unknown>;
132
136
  }
133
137
 
134
- export interface AgentRegistryCallInput {
135
- provider: string;
136
- type: "agent-registry";
137
- agent: string;
138
- tool: string;
139
- params?: Record<string, unknown>;
140
- }
141
-
142
138
  export type IntegrationCallInput =
143
139
  | RestCallInput
144
- | GraphqlCallInput
145
- | AgentRegistryCallInput;
140
+ | GraphqlCallInput;
146
141
 
147
142
  // ============================================
148
143
  // User Connection (stored token)
@@ -273,6 +268,7 @@ function buildAuthHeaders(
273
268
  config: ProviderConfig,
274
269
  accessToken: string,
275
270
  ): Record<string, string> {
271
+ if (!config.api) return {};
276
272
  const { auth } = config.api;
277
273
  const headerName = auth.headerName ?? "Authorization";
278
274
  const prefix = auth.prefix ?? "Bearer";
@@ -433,7 +429,7 @@ async function executeRestCall(
433
429
  input: RestCallInput,
434
430
  accessToken: string,
435
431
  ): Promise<unknown> {
436
- const url = new URL(input.path, config.api.baseUrl);
432
+ const url = new URL(input.path, config.api?.baseUrl);
437
433
  if (input.query) {
438
434
  for (const [k, v] of Object.entries(input.query)) {
439
435
  url.searchParams.set(k, v);
@@ -442,7 +438,7 @@ async function executeRestCall(
442
438
 
443
439
  const headers: Record<string, string> = {
444
440
  ...buildAuthHeaders(config, accessToken),
445
- ...(config.api.defaultHeaders ?? {}),
441
+ ...(config.api?.defaultHeaders ?? {}),
446
442
  };
447
443
 
448
444
  if (input.body) {
@@ -471,9 +467,10 @@ async function executeGraphqlCall(
471
467
  const headers: Record<string, string> = {
472
468
  "Content-Type": "application/json",
473
469
  ...buildAuthHeaders(config, accessToken),
474
- ...(config.api.defaultHeaders ?? {}),
470
+ ...(config.api?.defaultHeaders ?? {}),
475
471
  };
476
472
 
473
+ if (!config.api?.baseUrl) throw new Error("No baseUrl configured for this provider");
477
474
  const response = await fetch(config.api.baseUrl, {
478
475
  method: "POST",
479
476
  headers,
@@ -491,6 +488,23 @@ export interface IntegrationsAgentOptions {
491
488
  /** Integration store backend */
492
489
  store: IntegrationStore;
493
490
 
491
+ /**
492
+ * Callback to list all registered agents.
493
+ * Used by list_integrations to discover agents with integrationMethods.
494
+ * Typically wired to registry.list().
495
+ */
496
+ getAgents?: () => AgentDefinition[];
497
+
498
+ /** Registry instance for calling other agents' internal tools */
499
+ registry?: {
500
+ call(request: any): Promise<any>;
501
+ };
502
+
503
+ /** Integrations store for tracking installed integrations */
504
+ integrationsStore?: {
505
+ create(input: { agentPath: string; config: Record<string, unknown>; installedBy?: string; tenantId?: string }): Promise<any>;
506
+ };
507
+
494
508
  /** Secret store for storing/resolving client credentials and tokens */
495
509
  secretStore: {
496
510
  store(value: string, ownerId: string): Promise<string>;
@@ -500,7 +514,7 @@ export interface IntegrationsAgentOptions {
500
514
 
501
515
  /**
502
516
  * Base URL for OAuth callbacks.
503
- * The callback URL will be: `${callbackBaseUrl}/${providerId}`
517
+ * The OAuth redirect_uri. Provider is encoded in the state param.
504
518
  */
505
519
  callbackBaseUrl?: string;
506
520
  }
@@ -521,7 +535,7 @@ const SYSTEM_OWNER = "__integrations__";
521
535
  export function createIntegrationsAgent(
522
536
  options: IntegrationsAgentOptions,
523
537
  ): AgentDefinition {
524
- const { store, callbackBaseUrl, secretStore } = options;
538
+ const { store, callbackBaseUrl, secretStore, getAgents, integrationsStore } = options;
525
539
 
526
540
  // ---- setup_integration ----
527
541
  const setupTool = defineTool({
@@ -539,10 +553,9 @@ export function createIntegrationsAgent(
539
553
  description: "Provider ID (e.g. 'linear', 'notion')",
540
554
  },
541
555
  name: { type: "string", description: "Display name" },
542
- type: {
556
+ agentPath: {
543
557
  type: "string",
544
- enum: ["rest", "graphql", "agent-registry"],
545
- description: "Integration type",
558
+ description: "Agent path that handles this integration (e.g. '@remote-registry', '@databases'). Omit for simple REST/GraphQL integrations.",
546
559
  },
547
560
  scope: {
548
561
  type: "string",
@@ -647,7 +660,7 @@ export function createIntegrationsAgent(
647
660
  const config: ProviderConfig = {
648
661
  id: input.id,
649
662
  name: input.name,
650
- type: input.type,
663
+ agentPath: input.agentPath,
651
664
  scope: input.scope,
652
665
  docs: input.docs,
653
666
  auth: input.auth,
@@ -667,11 +680,121 @@ export function createIntegrationsAgent(
667
680
  }
668
681
 
669
682
  await store.upsertProvider(config);
683
+
684
+ // Also track in integrations table
685
+ if (integrationsStore) {
686
+ try {
687
+ await integrationsStore.create({
688
+ agentPath: config.agentPath ?? `@${config.id}`,
689
+ config: { providerId: config.id, ...input },
690
+ installedBy: _ctx.callerId,
691
+ });
692
+ } catch {}
693
+ }
694
+
670
695
  result.provider = config;
671
696
  return result;
672
697
  },
673
698
  });
674
699
 
700
+
701
+ // ---- discover_integrations ----
702
+ const discoverTool = defineTool({
703
+ name: "discover_integrations",
704
+ description:
705
+ "Discover available integration types that can be set up. " +
706
+ "Returns a catalog of integrations with their setup/connect schemas " +
707
+ "so you know what parameters to pass to setup_integration.",
708
+ visibility: "public" as const,
709
+ inputSchema: {
710
+ type: "object" as const,
711
+ properties: {
712
+ query: {
713
+ type: "string",
714
+ description: "Search query to filter integrations by name or description",
715
+ },
716
+ category: {
717
+ type: "string",
718
+ description: "Filter by category (e.g. 'infrastructure', 'communication')",
719
+ },
720
+ },
721
+ },
722
+ execute: async (
723
+ input: { query?: string; category?: string },
724
+ _ctx: ToolContext,
725
+ ) => {
726
+ const catalog: Array<{
727
+ provider: string;
728
+ agentPath?: string;
729
+ displayName: string;
730
+ icon?: string;
731
+ category?: string;
732
+ description?: string;
733
+ setupSchema?: Record<string, unknown>;
734
+ connectSchema?: Record<string, unknown>;
735
+ hasOAuth?: boolean;
736
+ }> = [];
737
+
738
+ // 1. Agent-backed integrations
739
+ if (getAgents) {
740
+ for (const agent of getAgents()) {
741
+ if (agent.config?.integration) {
742
+ const ic = agent.config.integration;
743
+ catalog.push({
744
+ provider: ic.provider,
745
+ agentPath: agent.path,
746
+ displayName: ic.displayName,
747
+ icon: ic.icon,
748
+ category: ic.category,
749
+ description: ic.description,
750
+ setupSchema: ic.setupSchema,
751
+ connectSchema: ic.connectSchema,
752
+ });
753
+ }
754
+ }
755
+ }
756
+
757
+ // 2. DB-stored providers (legacy OAuth)
758
+ const providers = await store.listProviders();
759
+ for (const p of providers) {
760
+ // Skip if already in catalog from agent scan
761
+ if (catalog.some((c) => c.provider === p.id)) continue;
762
+ catalog.push({
763
+ provider: p.id,
764
+ displayName: p.name,
765
+ agentPath: p.agentPath,
766
+ hasOAuth: !!p.auth,
767
+ connectSchema: p.auth
768
+ ? {
769
+ type: "object",
770
+ description: "OAuth flow — use connect_integration to start",
771
+ properties: {
772
+ provider: { type: "string", const: p.id },
773
+ },
774
+ }
775
+ : undefined,
776
+ });
777
+ }
778
+
779
+ // 3. Filter
780
+ let results = catalog;
781
+ if (input.query) {
782
+ const q = input.query.toLowerCase();
783
+ results = results.filter(
784
+ (r) =>
785
+ r.provider.toLowerCase().includes(q) ||
786
+ r.displayName.toLowerCase().includes(q) ||
787
+ (r.description?.toLowerCase().includes(q) ?? false),
788
+ );
789
+ }
790
+ if (input.category) {
791
+ results = results.filter((r) => r.category === input.category);
792
+ }
793
+
794
+ return { integrations: results };
795
+ },
796
+ });
797
+
675
798
  // ---- list_integrations ----
676
799
  const listTool = defineTool({
677
800
  name: "list_integrations",
@@ -692,15 +815,64 @@ export function createIntegrationsAgent(
692
815
  const userId = input.userId ?? ctx.callerId;
693
816
  const connections = userId ? await store.listConnections(userId) : [];
694
817
 
695
- return {
696
- providers: providers.map((p) => ({
818
+ // Build unified integrations list
819
+ const integrations: Array<Record<string, unknown>> = [];
820
+
821
+ // 1. DB-stored providers (legacy OAuth integrations)
822
+ for (const p of providers) {
823
+ integrations.push({
697
824
  id: p.id,
698
825
  name: p.name,
699
- type: p.type,
826
+ provider: p.id,
827
+ agentPath: p.agentPath,
700
828
  scope: p.scope ?? "user",
701
829
  hasOAuth: !!p.auth,
702
830
  connected: connections.some((c) => c.providerId === p.id),
703
- })),
831
+ });
832
+ }
833
+
834
+ // 2. Agent-backed integrations (agents with config.integration + integrationMethods)
835
+ if (getAgents) {
836
+ const agents = getAgents();
837
+ for (const agent of agents) {
838
+ if (agent.integrationMethods?.list && agent.config?.integration) {
839
+ const meta = {
840
+ provider: agent.config.integration.provider,
841
+ agentPath: agent.path,
842
+ displayName: agent.config.integration.displayName,
843
+ icon: agent.config.integration.icon,
844
+ category: agent.config.integration.category,
845
+ description: agent.config.integration.description,
846
+ };
847
+ try {
848
+ const result = await agent.integrationMethods.list({}, { ...ctx, provider: agent.config.integration.provider });
849
+ if (result.success && result.data) {
850
+ // Flatten: if data has an array field, each item becomes an integration
851
+ const items = Array.isArray(result.data)
852
+ ? result.data
853
+ : Object.values(result.data as Record<string, unknown>).find(Array.isArray) as unknown[] ?? [];
854
+ for (const item of items) {
855
+ integrations.push({
856
+ ...meta,
857
+ ...(typeof item === "object" && item !== null ? item as Record<string, unknown> : { value: item }),
858
+ });
859
+ }
860
+ // If no items found but agent exists, include it as a provider entry
861
+ if (items.length === 0) {
862
+ integrations.push({ ...meta, id: meta.provider });
863
+ }
864
+ } else {
865
+ integrations.push({ ...meta, id: meta.provider });
866
+ }
867
+ } catch {
868
+ integrations.push({ ...meta, id: meta.provider });
869
+ }
870
+ }
871
+ }
872
+ }
873
+
874
+ return {
875
+ integrations,
704
876
  connections: connections.map((c) => ({
705
877
  providerId: c.providerId,
706
878
  connectedAt: c.connectedAt,
@@ -763,7 +935,7 @@ export function createIntegrationsAgent(
763
935
  return { error: "No callbackBaseUrl configured for OAuth flows" };
764
936
 
765
937
  const oauth = config.auth;
766
- const redirectUri = `${callbackBaseUrl}/${config.id}`;
938
+ const redirectUri = callbackBaseUrl;
767
939
  const userId = input.userId ?? ctx.callerId;
768
940
 
769
941
  // Resolve client ID from secret store
@@ -806,7 +978,7 @@ export function createIntegrationsAgent(
806
978
  redirect_uri: redirectUri,
807
979
  response_type: "code",
808
980
  ...(scopeStr ? { scope: scopeStr } : {}),
809
- state: input.state ?? JSON.stringify({ userId, providerId: config.id, redirectUrl: input.redirectUrl ?? "/" }),
981
+ state: input.state ?? btoa(JSON.stringify({ userId, providerId: config.id, redirectUrl: input.redirectUrl ?? "/" })),
810
982
  ...(oauth.authUrlExtraParams ?? {}),
811
983
  });
812
984
 
@@ -831,8 +1003,8 @@ export function createIntegrationsAgent(
831
1003
  provider: { type: "string", description: "Provider ID" },
832
1004
  type: {
833
1005
  type: "string",
834
- enum: ["rest", "graphql", "agent-registry"],
835
- description: "Call type",
1006
+ enum: ["rest", "graphql"],
1007
+ description: "Call type (rest or graphql)",
836
1008
  },
837
1009
  // REST fields
838
1010
  method: {
@@ -924,7 +1096,7 @@ export function createIntegrationsAgent(
924
1096
  }
925
1097
  }
926
1098
 
927
- // Execute the call
1099
+ // Execute the call based on type
928
1100
  switch (input.type) {
929
1101
  case "rest":
930
1102
  return executeRestCall(
@@ -952,27 +1124,8 @@ export function createIntegrationsAgent(
952
1124
  accessToken,
953
1125
  );
954
1126
 
955
- case "agent-registry": {
956
- // For agent-registry, forward the call to the remote agent server
957
- const baseUrl = config.api.baseUrl;
958
- const response = await fetch(`${baseUrl}/call`, {
959
- method: "POST",
960
- headers: {
961
- "Content-Type": "application/json",
962
- ...buildAuthHeaders(config, accessToken),
963
- },
964
- body: JSON.stringify({
965
- action: "execute_tool",
966
- path: input.agent,
967
- tool: input.tool,
968
- params: input.params ?? {},
969
- }),
970
- });
971
- return response.json();
972
- }
973
-
974
1127
  default:
975
- return { error: `Unknown integration type: ${input.type}` };
1128
+ return { error: `Unknown call type: ${input.type}. Use 'rest' or 'graphql'.` };
976
1129
  }
977
1130
  },
978
1131
  });
@@ -1013,7 +1166,7 @@ export function createIntegrationsAgent(
1013
1166
  let userId = ctx.callerId;
1014
1167
  if (input.state) {
1015
1168
  try {
1016
- const parsed = JSON.parse(input.state);
1169
+ const parsed = JSON.parse(atob(input.state));
1017
1170
  if (parsed.userId) userId = parsed.userId;
1018
1171
  } catch {}
1019
1172
  }
@@ -1030,7 +1183,7 @@ export function createIntegrationsAgent(
1030
1183
  return { error: "Failed to resolve client credentials." };
1031
1184
  }
1032
1185
 
1033
- const redirectUri = `${callbackBaseUrl}/${config.id}`;
1186
+ const redirectUri = callbackBaseUrl;
1034
1187
  const result = await exchangeCodeForToken(
1035
1188
  config,
1036
1189
  input.code,
@@ -1059,6 +1212,7 @@ export function createIntegrationsAgent(
1059
1212
  provider: config.id,
1060
1213
  userId,
1061
1214
  connectedAt: connection.connectedAt,
1215
+ accessToken: result.accessToken,
1062
1216
  };
1063
1217
  },
1064
1218
  });
@@ -1175,7 +1329,7 @@ export function createIntegrationsAgent(
1175
1329
  });
1176
1330
 
1177
1331
  // Build callback URL from callbackBaseUrl
1178
- const baseUrl = callbackBaseUrl?.replace(/\/integrations\/callback$/, "") ?? "";
1332
+ const baseUrl = callbackBaseUrl?.replace(/\/oauth\/callback$/, "").replace(/\/integrations\/callback$/, "") ?? "";
1179
1333
 
1180
1334
  return {
1181
1335
  url: `${baseUrl}/secrets/form/${token}`,
@@ -1185,6 +1339,81 @@ export function createIntegrationsAgent(
1185
1339
  },
1186
1340
  });
1187
1341
 
1342
+
1343
+ // ---- Facade: discover_integrations (aggregates from all agents) ----
1344
+ const discoverFacadeTool = defineTool({
1345
+ name: "discover_integrations",
1346
+ description: "Discover all available integrations across all registered agents.",
1347
+ visibility: "public" as const,
1348
+ inputSchema: { type: "object" as const, properties: {} },
1349
+ execute: async () => {
1350
+ const agents = getAgents?.() ?? [];
1351
+ const results: any[] = [];
1352
+ if (options.registry) {
1353
+ for (const agent of agents) {
1354
+ const hasDiscoverTool = agent.tools?.some((t: any) => t.name === 'discover_integrations');
1355
+ if (hasDiscoverTool) {
1356
+ try {
1357
+ const res = await options.registry.call({
1358
+ action: 'execute_tool',
1359
+ path: agent.path,
1360
+ tool: 'discover_integrations',
1361
+ params: {},
1362
+ callerId: '@integrations',
1363
+ callerType: 'system',
1364
+ });
1365
+ if (res?.result && Array.isArray(res.result)) {
1366
+ results.push(...res.result);
1367
+ }
1368
+ } catch {}
1369
+ }
1370
+ }
1371
+ }
1372
+ return results;
1373
+ },
1374
+ });
1375
+
1376
+ // ---- Facade: list_integrations (aggregates from all agents) ----
1377
+ const listFacadeTool = defineTool({
1378
+ name: "list_integrations",
1379
+ description: "List all installed integrations across all agents.",
1380
+ visibility: "public" as const,
1381
+ inputSchema: {
1382
+ type: "object" as const,
1383
+ properties: {
1384
+ agent_path: { type: "string", description: "Filter by agent path" },
1385
+ },
1386
+ },
1387
+ execute: async (input: { agent_path?: string }) => {
1388
+ const agents = getAgents?.() ?? [];
1389
+ const results: any[] = [];
1390
+ if (options.registry) {
1391
+ const targetAgents = input.agent_path
1392
+ ? agents.filter((a: any) => a.path === input.agent_path)
1393
+ : agents;
1394
+ for (const agent of targetAgents) {
1395
+ const hasListTool = agent.tools?.some((t: any) => t.name === 'list_integrations');
1396
+ if (hasListTool) {
1397
+ try {
1398
+ const res = await options.registry.call({
1399
+ action: 'execute_tool',
1400
+ path: agent.path,
1401
+ tool: 'list_integrations',
1402
+ params: {},
1403
+ callerId: '@integrations',
1404
+ callerType: 'system',
1405
+ });
1406
+ if (res?.result && Array.isArray(res.result)) {
1407
+ results.push(...res.result);
1408
+ }
1409
+ } catch {}
1410
+ }
1411
+ }
1412
+ }
1413
+ return results;
1414
+ },
1415
+ });
1416
+
1188
1417
  return defineAgent({
1189
1418
  path: "@integrations",
1190
1419
  entrypoint:
@@ -1198,12 +1427,15 @@ export function createIntegrationsAgent(
1198
1427
  visibility: "public",
1199
1428
  tools: [
1200
1429
  setupTool,
1430
+ discoverTool,
1201
1431
  listTool,
1202
1432
  getTool,
1203
1433
  connectTool,
1204
1434
  callTool,
1205
1435
  callbackTool,
1206
1436
  collectSecretsTool,
1437
+ discoverFacadeTool,
1438
+ listFacadeTool,
1207
1439
  ] as ToolDefinition[],
1208
1440
  });
1209
1441
  }