@slashfi/agents-sdk 0.34.1 → 0.36.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 (91) hide show
  1. package/README.md +2 -1
  2. package/dist/agent-definitions/auth.d.ts +3 -3
  3. package/dist/agent-definitions/auth.d.ts.map +1 -1
  4. package/dist/agent-definitions/auth.js +10 -4
  5. package/dist/agent-definitions/auth.js.map +1 -1
  6. package/dist/agent-definitions/config.d.ts.map +1 -1
  7. package/dist/agent-definitions/config.js.map +1 -1
  8. package/dist/agent-definitions/integrations.d.ts +12 -3
  9. package/dist/agent-definitions/integrations.d.ts.map +1 -1
  10. package/dist/agent-definitions/integrations.js +35 -16
  11. package/dist/agent-definitions/integrations.js.map +1 -1
  12. package/dist/agent-definitions/remote-registry.d.ts.map +1 -1
  13. package/dist/agent-definitions/remote-registry.js +17 -22
  14. package/dist/agent-definitions/remote-registry.js.map +1 -1
  15. package/dist/agent-definitions/users.d.ts.map +1 -1
  16. package/dist/agent-definitions/users.js.map +1 -1
  17. package/dist/auth-governance.js.map +1 -1
  18. package/dist/call-agent-schema.d.ts.map +1 -1
  19. package/dist/call-agent-schema.js +1 -2
  20. package/dist/call-agent-schema.js.map +1 -1
  21. package/dist/cjs/agent-definitions/auth.js +10 -4
  22. package/dist/cjs/agent-definitions/auth.js.map +1 -1
  23. package/dist/cjs/agent-definitions/config.js.map +1 -1
  24. package/dist/cjs/agent-definitions/integrations.js +35 -16
  25. package/dist/cjs/agent-definitions/integrations.js.map +1 -1
  26. package/dist/cjs/agent-definitions/remote-registry.js +17 -22
  27. package/dist/cjs/agent-definitions/remote-registry.js.map +1 -1
  28. package/dist/cjs/agent-definitions/users.js.map +1 -1
  29. package/dist/cjs/auth-governance.js.map +1 -1
  30. package/dist/cjs/call-agent-schema.js +1 -2
  31. package/dist/cjs/call-agent-schema.js.map +1 -1
  32. package/dist/cjs/define.js.map +1 -1
  33. package/dist/cjs/events.js.map +1 -1
  34. package/dist/cjs/index.js +6 -2
  35. package/dist/cjs/index.js.map +1 -1
  36. package/dist/cjs/key-manager.js.map +1 -1
  37. package/dist/cjs/registry-consumer.js +60 -15
  38. package/dist/cjs/registry-consumer.js.map +1 -1
  39. package/dist/cjs/registry.js +61 -11
  40. package/dist/cjs/registry.js.map +1 -1
  41. package/dist/cjs/server.js +143 -192
  42. package/dist/cjs/server.js.map +1 -1
  43. package/dist/cjs/types.js +13 -0
  44. package/dist/cjs/types.js.map +1 -1
  45. package/dist/define.d.ts.map +1 -1
  46. package/dist/define.js.map +1 -1
  47. package/dist/events.d.ts +85 -9
  48. package/dist/events.d.ts.map +1 -1
  49. package/dist/events.js.map +1 -1
  50. package/dist/index.d.ts +3 -2
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +1 -0
  53. package/dist/index.js.map +1 -1
  54. package/dist/key-manager.d.ts.map +1 -1
  55. package/dist/key-manager.js +1 -1
  56. package/dist/key-manager.js.map +1 -1
  57. package/dist/registry-consumer.d.ts +8 -8
  58. package/dist/registry-consumer.d.ts.map +1 -1
  59. package/dist/registry-consumer.js +60 -15
  60. package/dist/registry-consumer.js.map +1 -1
  61. package/dist/registry.d.ts +16 -1
  62. package/dist/registry.d.ts.map +1 -1
  63. package/dist/registry.js +61 -11
  64. package/dist/registry.js.map +1 -1
  65. package/dist/server.d.ts +1 -1
  66. package/dist/server.d.ts.map +1 -1
  67. package/dist/server.js +136 -185
  68. package/dist/server.js.map +1 -1
  69. package/dist/types.d.ts +38 -0
  70. package/dist/types.d.ts.map +1 -1
  71. package/dist/types.js +10 -1
  72. package/dist/types.js.map +1 -1
  73. package/package.json +1 -1
  74. package/src/agent-definitions/auth.ts +31 -14
  75. package/src/agent-definitions/config.ts +4 -4
  76. package/src/agent-definitions/integrations.ts +119 -63
  77. package/src/agent-definitions/remote-registry.ts +65 -38
  78. package/src/agent-definitions/users.ts +36 -3
  79. package/src/auth-governance.ts +2 -2
  80. package/src/call-agent-schema.test.ts +4 -1
  81. package/src/call-agent-schema.ts +4 -3
  82. package/src/consumer.test.ts +4 -1
  83. package/src/define.ts +18 -12
  84. package/src/events.ts +83 -9
  85. package/src/hooks.test.ts +439 -0
  86. package/src/index.ts +14 -1
  87. package/src/key-manager.ts +9 -2
  88. package/src/registry-consumer.ts +85 -24
  89. package/src/registry.ts +88 -13
  90. package/src/server.ts +215 -239
  91. package/src/types.ts +62 -0
package/src/server.ts CHANGED
@@ -31,9 +31,10 @@ import {
31
31
  processSecretParams,
32
32
  } from "./agent-definitions/secrets.js";
33
33
  import { createBM25Index } from "./bm25.js";
34
- import { verifyJwt } from "./jwt.js";
35
- import type { SigningKey } from "./jwt.js";
36
34
  import {
35
+ verifyJwt,
36
+ type AgentJwtPayload,
37
+ type SigningKey,
37
38
  buildJwks,
38
39
  exportSigningKey,
39
40
  generateSigningKey,
@@ -44,8 +45,6 @@ import {
44
45
  } from "./jwt.js";
45
46
  import { type OIDCProviderConfig, createOIDCSignIn } from "./oidc-signin.js";
46
47
  import type { AgentRegistry } from "./registry.js";
47
- import type { AgentDefinition, CallAgentRequest } from "./types.js";
48
-
49
48
  import {
50
49
  callAgentInputSchema,
51
50
  callAgentValidationSchema,
@@ -53,7 +52,33 @@ import {
53
52
  listAgentsValidationSchema,
54
53
  nullTolerant,
55
54
  zodToOpenAiJsonSchema,
55
+ type CallAgentExecuteToolRequest,
56
+ type CallerType,
56
57
  } from "./call-agent-schema.js";
58
+ import type {
59
+ AgentDefinition,
60
+ AuthClientCredentialsTokenResult,
61
+ CallAgentRequest,
62
+ ExchangeTokenToolResult,
63
+ } from "./types.js";
64
+ import {
65
+ isCallAgentErrorResponse,
66
+ isExchangeTokenLinkedSuccess,
67
+ isExchangeTokenNeedsIdentity,
68
+ } from "./types.js";
69
+
70
+ /** JWT payload claims used for reverse registry registration (jwt_exchange). */
71
+ interface RegistryAssertionPayload {
72
+ type?: string;
73
+ iss?: string;
74
+ name?: string;
75
+ tenantId?: string;
76
+ }
77
+
78
+ function parseProxyCallerType(raw: string | null): CallerType {
79
+ if (raw === "agent" || raw === "user" || raw === "system") return raw;
80
+ return "agent";
81
+ }
57
82
 
58
83
  // ============================================
59
84
  // Server Types
@@ -231,7 +256,6 @@ export interface AuthConfig {
231
256
  tokenTtl?: number;
232
257
  }
233
258
 
234
-
235
259
  // Auth governance — single source of truth for visibility/access control
236
260
  export {
237
261
  type ResolvedAuth,
@@ -539,8 +563,12 @@ export function createAgentServer(
539
563
  ...(options.registry && {
540
564
  registry: {
541
565
  version: options.registry.version ?? "1.0",
542
- ...(options.registry.features && { features: options.registry.features }),
543
- ...(options.registry.oauthCallbackUrl && { oauthCallbackUrl: options.registry.oauthCallbackUrl }),
566
+ ...(options.registry.features && {
567
+ features: options.registry.features,
568
+ }),
569
+ ...(options.registry.oauthCallbackUrl && {
570
+ oauthCallbackUrl: options.registry.oauthCallbackUrl,
571
+ }),
544
572
  },
545
573
  }),
546
574
  },
@@ -598,9 +626,11 @@ export function createAgentServer(
598
626
  case "call_agent": {
599
627
  // Validate + strip nulls (OpenAI convention: null = absent)
600
628
  const parsed = callAgentValidate.safeParse(args);
601
- const req = (parsed.success
602
- ? (parsed.data as Record<string, unknown>).request ?? parsed.data
603
- : (args.request ?? args)) as CallAgentRequest;
629
+ const req = (
630
+ parsed.success
631
+ ? ((parsed.data as Record<string, unknown>).request ?? parsed.data)
632
+ : (args.request ?? args)
633
+ ) as CallAgentRequest;
604
634
 
605
635
  // Inject auth context
606
636
  if (auth) {
@@ -615,18 +645,19 @@ export function createAgentServer(
615
645
  }
616
646
 
617
647
  // Process secret params: resolve refs, store raw secrets
618
- if ((req as any).params && secretStore) {
648
+ if (req.action === "execute_tool" && req.params && secretStore) {
649
+ const execReq: CallAgentExecuteToolRequest = req;
619
650
  const ownerId = auth?.callerId ?? "anonymous";
620
- const agent = registry.get(req.path);
621
- const tool = agent?.tools.find((t) => t.name === (req as any).tool);
622
- const schema = tool?.inputSchema as any;
651
+ const agent = registry.get(execReq.path);
652
+ const tool = agent?.tools.find((t) => t.name === execReq.tool);
653
+ const schema = tool?.inputSchema;
623
654
  const { resolved } = await processSecretParams(
624
- (req as any).params as Record<string, unknown>,
625
- schema,
655
+ execReq.params as Record<string, unknown>,
656
+ schema as Parameters<typeof processSecretParams>[1],
626
657
  secretStore,
627
658
  ownerId,
628
659
  );
629
- (req as any).params = resolved;
660
+ execReq.params = resolved;
630
661
  }
631
662
 
632
663
  const result = await registry.call(req);
@@ -634,102 +665,113 @@ export function createAgentServer(
634
665
  }
635
666
 
636
667
  case "list_agents": {
637
- const { query: listQuery, limit: listLimit, cursor: listCursor } =
638
- listAgentsValidate.parse(args);
639
- const agents = registry.list();
640
- let visible = agents.filter((agent) => canSeeAgent(agent, auth));
641
-
642
- // Decode cursor if provided
643
- const after = listCursor
644
- ? (JSON.parse(
645
- Buffer.from(listCursor, "base64url").toString(),
646
- ) as { path: string; score?: number })
647
- : undefined;
648
-
649
- const pageSize = listLimit ?? 20;
650
- let page: typeof visible;
651
- let nextCursor: string | undefined;
652
-
653
- if (listQuery) {
654
- // BM25 search — ranked by score desc, path asc for tie-breaking
655
- const docs = visible.map((agent, i) => ({
656
- id: String(i),
657
- text: [
658
- agent.path,
659
- agent.config?.name ?? "",
660
- agent.config?.description ?? "",
661
- ...agent.tools
662
- .filter((t) => canSeeTool(t, auth))
663
- .map((t) => `${t.name} ${t.description}`),
664
- ].join(" "),
665
- }));
666
- const index = createBM25Index(docs);
667
- const ranked = index.search(listQuery);
668
-
669
- // Build scored list
670
- type ScoredAgent = (typeof visible)[number] & { _score: number };
671
- let scored: ScoredAgent[] = ranked.map((r) => ({
672
- ...visible[Number(r.id)],
673
- _score: r.score,
674
- }));
668
+ const {
669
+ query: listQuery,
670
+ limit: listLimit,
671
+ cursor: listCursor,
672
+ } = listAgentsValidate.parse(args);
673
+
674
+ const result = await registry.listAgents(
675
+ { query: listQuery, limit: listLimit, cursor: listCursor },
676
+ async (allAgents) => {
677
+ let visible = allAgents.filter((agent) => canSeeAgent(agent, auth));
678
+
679
+ // Decode cursor if provided
680
+ const after = listCursor
681
+ ? (JSON.parse(Buffer.from(listCursor, "base64url").toString()) as {
682
+ path: string;
683
+ score?: number;
684
+ })
685
+ : undefined;
686
+
687
+ const pageSize = listLimit ?? 20;
688
+ let page: typeof visible;
689
+ let nextCursor: string | undefined;
690
+
691
+ if (listQuery) {
692
+ // BM25 search — ranked by score desc, path asc for tie-breaking
693
+ const docs = visible.map((agent, i) => ({
694
+ id: String(i),
695
+ text: [
696
+ agent.path,
697
+ agent.config?.name ?? "",
698
+ agent.config?.description ?? "",
699
+ ...agent.tools
700
+ .filter((t) => canSeeTool(t, auth))
701
+ .map((t) => `${t.name} ${t.description}`),
702
+ ].join(" "),
703
+ }));
704
+ const index = createBM25Index(docs);
705
+ const ranked = index.search(listQuery);
706
+
707
+ // Build scored list
708
+ type ScoredAgent = (typeof visible)[number] & { _score: number };
709
+ let scored: ScoredAgent[] = ranked.map((r) => ({
710
+ ...visible[Number(r.id)],
711
+ _score: r.score,
712
+ }));
713
+
714
+ // Apply cursor: skip past the after position
715
+ if (after?.score !== undefined) {
716
+ scored = scored.filter(
717
+ (a) =>
718
+ a._score < after.score! ||
719
+ (a._score === after.score! && a.path > after.path),
720
+ );
721
+ }
675
722
 
676
- // Apply cursor: skip past the after position
677
- if (after?.score !== undefined) {
678
- scored = scored.filter(
679
- (a) =>
680
- a._score < after.score! ||
681
- (a._score === after.score! && a.path > after.path),
682
- );
683
- }
723
+ page = scored.slice(0, pageSize);
724
+ if (scored.length > pageSize) {
725
+ const last = scored[pageSize - 1] as ScoredAgent;
726
+ nextCursor = Buffer.from(
727
+ JSON.stringify({ path: last.path, score: last._score }),
728
+ ).toString("base64url");
729
+ }
730
+ } else {
731
+ // Alphabetical listing — sorted by path
732
+ visible.sort((a, b) => a.path.localeCompare(b.path));
684
733
 
685
- page = scored.slice(0, pageSize);
686
- if (scored.length > pageSize) {
687
- const last = scored[pageSize - 1] as ScoredAgent;
688
- nextCursor = Buffer.from(
689
- JSON.stringify({ path: last.path, score: last._score }),
690
- ).toString("base64url");
691
- }
692
- } else {
693
- // Alphabetical listing — sorted by path
694
- visible.sort((a, b) => a.path.localeCompare(b.path));
734
+ // Apply cursor: skip past afterPath
735
+ if (after) {
736
+ visible = visible.filter((a) => a.path > after.path);
737
+ }
695
738
 
696
- // Apply cursor: skip past afterPath
697
- if (after) {
698
- visible = visible.filter((a) => a.path > after.path);
699
- }
739
+ page = visible.slice(0, pageSize);
740
+ if (visible.length > pageSize) {
741
+ const last = page[page.length - 1];
742
+ nextCursor = Buffer.from(
743
+ JSON.stringify({ path: last.path }),
744
+ ).toString("base64url");
745
+ }
746
+ }
700
747
 
701
- page = visible.slice(0, pageSize);
702
- if (visible.length > pageSize) {
703
- const last = page[page.length - 1];
704
- nextCursor = Buffer.from(
705
- JSON.stringify({ path: last.path }),
706
- ).toString("base64url");
707
- }
708
- }
748
+ return {
749
+ success: true as const,
750
+ total: allAgents.filter((a) => canSeeAgent(a, auth)).length,
751
+ nextCursor,
752
+ agents: page.map((agent) => ({
753
+ path: agent.path,
754
+ name: agent.config?.name,
755
+ description: agent.config?.description,
756
+ supportedActions: agent.config?.supportedActions,
757
+ integration: agent.config?.integration || null,
758
+ security: agent.config?.security
759
+ ? { type: agent.config.security.type }
760
+ : undefined,
761
+ resources: agent.config?.resources?.map((r) => ({
762
+ uri: r.uri,
763
+ name: r.name,
764
+ mimeType: r.mimeType,
765
+ })),
766
+ tools: agent.tools
767
+ .filter((t) => canSeeTool(t, auth))
768
+ .map((t) => t.name),
769
+ })),
770
+ };
771
+ },
772
+ );
709
773
 
710
- return mcpResult({
711
- success: true,
712
- total: agents.filter((a) => canSeeAgent(a, auth)).length,
713
- nextCursor,
714
- agents: page.map((agent) => ({
715
- path: agent.path,
716
- name: agent.config?.name,
717
- description: agent.config?.description,
718
- supportedActions: agent.config?.supportedActions,
719
- integration: agent.config?.integration || null,
720
- security: agent.config?.security
721
- ? { type: agent.config.security.type }
722
- : undefined,
723
- resources: agent.config?.resources?.map((r) => ({
724
- uri: r.uri,
725
- name: r.name,
726
- mimeType: r.mimeType,
727
- })),
728
- tools: agent.tools
729
- .filter((t) => canSeeTool(t, auth))
730
- .map((t) => t.name),
731
- })),
732
- });
774
+ return mcpResult(result);
733
775
  }
734
776
 
735
777
  default:
@@ -798,27 +840,36 @@ export function createAgentServer(
798
840
  callerType: "system",
799
841
  });
800
842
 
801
- const exchangeResult = (result as any)?.result;
802
- // If the tool call failed, forward the error
803
- if ((result as any)?.success === false) {
843
+ if (isCallAgentErrorResponse(result)) {
804
844
  return jsonResponse(
805
845
  {
806
846
  error: "server_error",
807
- error_description:
808
- (result as any)?.error ?? "Exchange tool failed",
847
+ error_description: result.error ?? "Exchange tool failed",
809
848
  raw: JSON.stringify(result)?.slice(0, 300),
810
849
  },
811
850
  500,
812
851
  );
813
852
  }
814
853
 
854
+ if (!("result" in result)) {
855
+ return jsonResponse(
856
+ {
857
+ error: "server_error",
858
+ error_description: `Unexpected exchange response: ${JSON.stringify(result)?.slice(0, 300)}`,
859
+ },
860
+ 500,
861
+ );
862
+ }
863
+
864
+ const exchangeResult = result.result as ExchangeTokenToolResult;
865
+
815
866
  // ── Reverse registration: if caller is an agent-registry, auto-store connection ──
816
867
  try {
817
868
  const assertionParts = assertion.split(".");
818
869
  if (assertionParts.length === 3) {
819
870
  const assertionPayload = JSON.parse(
820
871
  Buffer.from(assertionParts[1], "base64url").toString(),
821
- ) as any;
872
+ ) as RegistryAssertionPayload;
822
873
  if (
823
874
  assertionPayload.type === "agent-registry" &&
824
875
  assertionPayload.iss
@@ -844,7 +895,7 @@ export function createAgentServer(
844
895
  } else {
845
896
  console.error(
846
897
  "[jwt_exchange] Reverse connection failed:",
847
- (addResult as any).error,
898
+ addResult.error,
848
899
  );
849
900
  }
850
901
  }
@@ -867,7 +918,7 @@ export function createAgentServer(
867
918
  }
868
919
 
869
920
  // User not linked yet — needs OAuth identity linking
870
- if (exchangeResult.needsAuth) {
921
+ if (isExchangeTokenNeedsIdentity(exchangeResult)) {
871
922
  const baseUrl = resolveBaseUrl(req);
872
923
  const authorizeUrl = new URL(`${baseUrl}${basePath}/oauth/authorize`);
873
924
  authorizeUrl.searchParams.set("token", assertion);
@@ -890,7 +941,10 @@ export function createAgentServer(
890
941
  }
891
942
 
892
943
  // User found — sign a local access token
893
- if (exchangeResult.userId && serverSigningKeys.length > 0) {
944
+ if (
945
+ isExchangeTokenLinkedSuccess(exchangeResult) &&
946
+ serverSigningKeys.length > 0
947
+ ) {
894
948
  const sigKey = serverSigningKeys[0];
895
949
  const token = await signJwtES256(
896
950
  {
@@ -951,8 +1005,28 @@ export function createAgentServer(
951
1005
  callerType: "system",
952
1006
  });
953
1007
 
954
- const tokenResult = (result as any)?.result;
955
- if (!tokenResult?.accessToken) {
1008
+ if (isCallAgentErrorResponse(result)) {
1009
+ return jsonResponse(
1010
+ {
1011
+ error: "invalid_client",
1012
+ error_description: result.error ?? "Authentication failed",
1013
+ },
1014
+ 401,
1015
+ );
1016
+ }
1017
+
1018
+ if (!("result" in result)) {
1019
+ return jsonResponse(
1020
+ {
1021
+ error: "invalid_client",
1022
+ error_description: "Authentication failed",
1023
+ },
1024
+ 401,
1025
+ );
1026
+ }
1027
+
1028
+ const tokenResult = result.result as AuthClientCredentialsTokenResult;
1029
+ if (tokenResult.accessToken == null) {
956
1030
  return jsonResponse(
957
1031
  {
958
1032
  error: "invalid_client",
@@ -1020,7 +1094,7 @@ export function createAgentServer(
1020
1094
  if (actorId) {
1021
1095
  return {
1022
1096
  callerId: actorId,
1023
- callerType: (actorType as any) ?? "agent",
1097
+ callerType: parseProxyCallerType(actorType),
1024
1098
  scopes: ["*"],
1025
1099
  claims: {},
1026
1100
  };
@@ -1119,12 +1193,12 @@ export function createAgentServer(
1119
1193
  claims = result as unknown as Record<string, unknown>;
1120
1194
  break;
1121
1195
  }
1122
- } catch (e: any) {
1196
+ } catch (e: unknown) {
1123
1197
  console.log(
1124
1198
  "[oauth/authorize] verify",
1125
1199
  issuerUrl,
1126
1200
  "-> ERROR:",
1127
- e.message,
1201
+ e instanceof Error ? e.message : String(e),
1128
1202
  );
1129
1203
  }
1130
1204
  }
@@ -1190,24 +1264,6 @@ export function createAgentServer(
1190
1264
  return cors ? addCors(res) : res;
1191
1265
  }
1192
1266
 
1193
- // ── GET /.well-known/configuration → Server discovery (deprecated, use MCP initialize capabilities) ──
1194
- if (path === "/.well-known/configuration" && req.method === "GET") {
1195
- const baseUrl = resolveBaseUrl(req);
1196
- const res = jsonResponse({
1197
- issuer: baseUrl,
1198
- jwks_uri: `${baseUrl}/.well-known/jwks.json`,
1199
- token_endpoint: `${baseUrl}/oauth/token`,
1200
- agents_endpoint: `${baseUrl}/list`,
1201
- call_endpoint: baseUrl,
1202
- supported_grant_types: ["client_credentials", "jwt_exchange"],
1203
- authorization_endpoint: `${baseUrl}/oauth/authorize`,
1204
- ...(oidcSignIn
1205
- ? { signin_endpoint: `${baseUrl}/signin/authorize` }
1206
- : {}),
1207
- });
1208
- return cors ? addCors(res) : res;
1209
- }
1210
-
1211
1267
  // ── GET /.well-known/oauth-authorization-server → OAuth Server Metadata (RFC 8414) ──
1212
1268
  // Only exposed when the server requires auth (private registries).
1213
1269
  // Public registries (e.g. registry.slash.com) skip this entirely.
@@ -1215,7 +1271,9 @@ export function createAgentServer(
1215
1271
  path === "/.well-known/oauth-authorization-server" &&
1216
1272
  req.method === "GET"
1217
1273
  ) {
1218
- if (!(options.registry?.oauthCallbackUrl || serverSigningKeys.length > 0)) {
1274
+ if (
1275
+ !(options.registry?.oauthCallbackUrl || serverSigningKeys.length > 0)
1276
+ ) {
1219
1277
  const res = new Response("Not Found", { status: 404 });
1220
1278
  return cors ? addCors(res) : res;
1221
1279
  }
@@ -1226,7 +1284,11 @@ export function createAgentServer(
1226
1284
  token_endpoint: `${baseUrl}/oauth/token`,
1227
1285
  jwks_uri: `${baseUrl}/.well-known/jwks.json`,
1228
1286
  response_types_supported: ["code"],
1229
- grant_types_supported: ["authorization_code", "client_credentials", "jwt_exchange"],
1287
+ grant_types_supported: [
1288
+ "authorization_code",
1289
+ "client_credentials",
1290
+ "jwt_exchange",
1291
+ ],
1230
1292
  code_challenge_methods_supported: ["S256"],
1231
1293
  token_endpoint_auth_methods_supported: ["client_secret_post", "none"],
1232
1294
  ...(options.registry?.oauthCallbackUrl && {
@@ -1236,98 +1298,6 @@ export function createAgentServer(
1236
1298
  return cors ? addCors(res) : res;
1237
1299
  }
1238
1300
 
1239
- // ── GET /list → List agents (──
1240
- if (path === "/list" && req.method === "GET") {
1241
- const agents = registry.list();
1242
- let visible = agents.filter((agent) =>
1243
- canSeeAgent(agent, effectiveAuth),
1244
- );
1245
-
1246
- const searchQuery = url.searchParams.get("q");
1247
- const searchLimit = url.searchParams.get("limit");
1248
- const searchCursor = url.searchParams.get("cursor");
1249
-
1250
- // Decode cursor
1251
- const httpAfter = searchCursor
1252
- ? (JSON.parse(
1253
- Buffer.from(searchCursor, "base64url").toString(),
1254
- ) as { path: string; score?: number })
1255
- : undefined;
1256
-
1257
- const httpPageSize = searchLimit ? Number(searchLimit) : 20;
1258
- let httpPage: typeof visible;
1259
- let httpNextCursor: string | undefined;
1260
-
1261
- if (searchQuery) {
1262
- const docs = visible.map((agent, i) => ({
1263
- id: String(i),
1264
- text: [
1265
- agent.path,
1266
- agent.config?.name ?? "",
1267
- agent.config?.description ?? "",
1268
- ...agent.tools
1269
- .filter((t) => canSeeTool(t, effectiveAuth))
1270
- .map((t) => `${t.name} ${t.description}`),
1271
- ].join(" "),
1272
- }));
1273
- const index = createBM25Index(docs);
1274
- const ranked = index.search(searchQuery);
1275
-
1276
- type ScoredAgent = (typeof visible)[number] & { _score: number };
1277
- let scored: ScoredAgent[] = ranked.map((r) => ({
1278
- ...visible[Number(r.id)],
1279
- _score: r.score,
1280
- }));
1281
-
1282
- if (httpAfter?.score !== undefined) {
1283
- scored = scored.filter(
1284
- (a) =>
1285
- a._score < httpAfter.score! ||
1286
- (a._score === httpAfter.score! && a.path > httpAfter.path),
1287
- );
1288
- }
1289
-
1290
- httpPage = scored.slice(0, httpPageSize);
1291
- if (scored.length > httpPageSize) {
1292
- const last = scored[httpPageSize - 1] as ScoredAgent;
1293
- httpNextCursor = Buffer.from(
1294
- JSON.stringify({ path: last.path, score: last._score }),
1295
- ).toString("base64url");
1296
- }
1297
- } else {
1298
- visible.sort((a, b) => a.path.localeCompare(b.path));
1299
- if (httpAfter) {
1300
- visible = visible.filter((a) => a.path > httpAfter.path);
1301
- }
1302
- httpPage = visible.slice(0, httpPageSize);
1303
- if (visible.length > httpPageSize) {
1304
- const last = httpPage[httpPage.length - 1];
1305
- httpNextCursor = Buffer.from(
1306
- JSON.stringify({ path: last.path }),
1307
- ).toString("base64url");
1308
- }
1309
- }
1310
-
1311
- const res = jsonResponse({
1312
- total: agents.filter((a) => canSeeAgent(a, effectiveAuth)).length,
1313
- nextCursor: httpNextCursor,
1314
- agents: httpPage.map((agent) => ({
1315
- path: agent.path,
1316
- name: agent.config?.name,
1317
- description: agent.config?.description,
1318
- supportedActions: agent.config?.supportedActions,
1319
- integration: agent.config?.integration || null,
1320
- tools: agent.tools
1321
- .filter((t) => canSeeTool(t, effectiveAuth))
1322
- .map((t) => ({
1323
- name: t.name,
1324
- description: t.description,
1325
- })),
1326
- })),
1327
- });
1328
- return cors ? addCors(res) : res;
1329
- }
1330
-
1331
1301
  // ── GET /agents → List public agents (discovery endpoint) ──
1332
1302
  if (path === "/agents" && req.method === "GET") {
1333
1303
  const agents = registry.list();
@@ -1342,7 +1312,7 @@ export function createAgentServer(
1342
1312
  name: agent.config?.name,
1343
1313
  description:
1344
1314
  agent.config?.description ?? agent.entrypoint?.slice(0, 200),
1345
- mode: agent.mode ?? 'direct',
1315
+ mode: agent.mode ?? "direct",
1346
1316
  ...(agent.upstream && { upstream: agent.upstream }),
1347
1317
  tools: getVisibleTools(agent, effectiveAuth).map((t) => ({
1348
1318
  name: t.name,
@@ -1369,7 +1339,7 @@ export function createAgentServer(
1369
1339
  name: agent.config?.name,
1370
1340
  description:
1371
1341
  agent.config?.description ?? agent.entrypoint?.slice(0, 200),
1372
- mode: agent.mode ?? 'direct',
1342
+ mode: agent.mode ?? "direct",
1373
1343
  ...(agent.upstream && { upstream: agent.upstream }),
1374
1344
  tools: getVisibleTools(agent, effectiveAuth).map((t) => ({
1375
1345
  name: t.name,
@@ -1595,7 +1565,7 @@ export function createAgentServer(
1595
1565
  hostname,
1596
1566
  fetch,
1597
1567
  });
1598
- (this as any).url = `http://${hostname}:${port}`;
1568
+ this.url = `http://${hostname}:${port}`;
1599
1569
  console.log(
1600
1570
  `[agents-sdk] Server listening on http://${hostname}:${port}`,
1601
1571
  );
@@ -1605,7 +1575,7 @@ export function createAgentServer(
1605
1575
  if (serverInstance) {
1606
1576
  serverInstance.stop();
1607
1577
  serverInstance = null;
1608
- (this as any).url = null;
1578
+ this.url = null;
1609
1579
  }
1610
1580
  },
1611
1581
 
@@ -1618,8 +1588,14 @@ export function createAgentServer(
1618
1588
  );
1619
1589
  }
1620
1590
  const key = serverSigningKeys[0];
1591
+ const payload: Omit<AgentJwtPayload, "iat" | "exp"> = {
1592
+ sub: "system",
1593
+ name: "atlas-os",
1594
+ scopes: ["*"],
1595
+ ...(claims as Partial<Omit<AgentJwtPayload, "iat" | "exp">>),
1596
+ };
1621
1597
  return signJwtES256(
1622
- { sub: "system", name: "atlas-os", scopes: ["*"], ...claims } as any,
1598
+ payload,
1623
1599
  key.privateKey,
1624
1600
  key.kid,
1625
1601
  options.serverName ?? "agents-sdk",