@kya-os/mcp-i-core 1.3.10-canary.clientinfo.20251126124133 → 1.3.11

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 (90) hide show
  1. package/.claude/settings.local.json +9 -0
  2. package/.turbo/turbo-build.log +1 -1
  3. package/.turbo/turbo-test$colon$coverage.log +3419 -3072
  4. package/.turbo/turbo-test.log +1805 -1680
  5. package/coverage/coverage-final.json +59 -56
  6. package/dist/config/remote-config.d.ts +51 -0
  7. package/dist/config/remote-config.d.ts.map +1 -1
  8. package/dist/config/remote-config.js +74 -0
  9. package/dist/config/remote-config.js.map +1 -1
  10. package/dist/config.d.ts +1 -1
  11. package/dist/config.d.ts.map +1 -1
  12. package/dist/config.js +4 -1
  13. package/dist/config.js.map +1 -1
  14. package/dist/delegation/did-key-resolver.d.ts +64 -0
  15. package/dist/delegation/did-key-resolver.d.ts.map +1 -0
  16. package/dist/delegation/did-key-resolver.js +159 -0
  17. package/dist/delegation/did-key-resolver.js.map +1 -0
  18. package/dist/delegation/utils.d.ts +76 -0
  19. package/dist/delegation/utils.d.ts.map +1 -1
  20. package/dist/delegation/utils.js +117 -0
  21. package/dist/delegation/utils.js.map +1 -1
  22. package/dist/identity/idp-token-resolver.d.ts +17 -1
  23. package/dist/identity/idp-token-resolver.d.ts.map +1 -1
  24. package/dist/identity/idp-token-resolver.js +34 -6
  25. package/dist/identity/idp-token-resolver.js.map +1 -1
  26. package/dist/identity/idp-token-storage.interface.d.ts +38 -7
  27. package/dist/identity/idp-token-storage.interface.d.ts.map +1 -1
  28. package/dist/identity/idp-token-storage.interface.js +2 -0
  29. package/dist/identity/idp-token-storage.interface.js.map +1 -1
  30. package/dist/identity/user-did-manager.d.ts +95 -12
  31. package/dist/identity/user-did-manager.d.ts.map +1 -1
  32. package/dist/identity/user-did-manager.js +107 -25
  33. package/dist/identity/user-did-manager.js.map +1 -1
  34. package/dist/index.d.ts +6 -3
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +24 -2
  37. package/dist/index.js.map +1 -1
  38. package/dist/runtime/base.d.ts +25 -8
  39. package/dist/runtime/base.d.ts.map +1 -1
  40. package/dist/runtime/base.js +74 -21
  41. package/dist/runtime/base.js.map +1 -1
  42. package/dist/services/session-registration.service.d.ts.map +1 -1
  43. package/dist/services/session-registration.service.js +10 -90
  44. package/dist/services/session-registration.service.js.map +1 -1
  45. package/dist/services/tool-context-builder.d.ts +18 -1
  46. package/dist/services/tool-context-builder.d.ts.map +1 -1
  47. package/dist/services/tool-context-builder.js +63 -10
  48. package/dist/services/tool-context-builder.js.map +1 -1
  49. package/dist/services/tool-protection.service.d.ts +6 -3
  50. package/dist/services/tool-protection.service.d.ts.map +1 -1
  51. package/dist/services/tool-protection.service.js +89 -34
  52. package/dist/services/tool-protection.service.js.map +1 -1
  53. package/dist/utils/base58.d.ts +31 -0
  54. package/dist/utils/base58.d.ts.map +1 -0
  55. package/dist/utils/base58.js +103 -0
  56. package/dist/utils/base58.js.map +1 -0
  57. package/dist/utils/did-helpers.d.ts +33 -0
  58. package/dist/utils/did-helpers.d.ts.map +1 -1
  59. package/dist/utils/did-helpers.js +53 -0
  60. package/dist/utils/did-helpers.js.map +1 -1
  61. package/package.json +3 -3
  62. package/src/__tests__/identity/user-did-manager.test.ts +64 -45
  63. package/src/__tests__/integration/full-flow.test.ts +23 -10
  64. package/src/__tests__/runtime/base-extensions.test.ts +23 -21
  65. package/src/__tests__/runtime/proof-client-did.test.ts +19 -18
  66. package/src/__tests__/services/agentshield-integration.test.ts +10 -3
  67. package/src/__tests__/services/tool-protection-merged-config.test.ts +485 -0
  68. package/src/__tests__/services/tool-protection.service.test.ts +18 -11
  69. package/src/config/__tests__/merged-config.spec.ts +445 -0
  70. package/src/config/remote-config.ts +90 -0
  71. package/src/config.ts +3 -0
  72. package/src/delegation/__tests__/did-key-resolver.test.ts +265 -0
  73. package/src/delegation/__tests__/vc-issuer.test.ts +1 -1
  74. package/src/delegation/did-key-resolver.ts +179 -0
  75. package/src/delegation/utils.ts +179 -0
  76. package/src/identity/idp-token-resolver.ts +41 -7
  77. package/src/identity/idp-token-storage.interface.ts +42 -7
  78. package/src/identity/user-did-manager.ts +185 -29
  79. package/src/index.ts +42 -3
  80. package/src/runtime/base.ts +84 -21
  81. package/src/services/session-registration.service.ts +26 -121
  82. package/src/services/tool-context-builder.ts +75 -10
  83. package/src/services/tool-protection.service.ts +176 -88
  84. package/src/utils/__tests__/did-helpers.test.ts +55 -0
  85. package/src/utils/base58.ts +109 -0
  86. package/src/utils/did-helpers.ts +60 -0
  87. package/dist/__tests__/utils/mock-providers.d.ts +0 -103
  88. package/dist/__tests__/utils/mock-providers.d.ts.map +0 -1
  89. package/dist/__tests__/utils/mock-providers.js +0 -293
  90. package/dist/__tests__/utils/mock-providers.js.map +0 -1
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * User DID Manager Tests
3
3
  *
4
- * Tests for ephemeral user DID generation and management.
4
+ * Phase 5: Anonymous Sessions Until OAuth
5
+ * Tests for user DID lookup and storage (no ephemeral generation).
5
6
  */
6
7
 
7
8
  import { describe, test, expect, beforeEach, vi } from 'vitest';
@@ -26,36 +27,37 @@ describe('UserDidManager', () => {
26
27
  });
27
28
  });
28
29
 
29
- describe('getOrCreateUserDid', () => {
30
- test('should generate new did:key for new session', async () => {
31
- const sessionId = 'session-123';
32
-
33
- // Mock generateKeyPair to return valid base64 keys
34
- const mockKeyPair = {
35
- privateKey: Buffer.from(new Uint8Array(32).fill(1)).toString('base64'),
36
- publicKey: Buffer.from(new Uint8Array(32).fill(2)).toString('base64'),
37
- };
38
- vi.spyOn(cryptoProvider, 'generateKeyPair').mockResolvedValue(mockKeyPair);
39
-
40
- const userDid = await manager.getOrCreateUserDid(sessionId);
30
+ describe('getOrCreateUserDid (Phase 5)', () => {
31
+ test('should return null for new session without existing DID', async () => {
32
+ const sessionId = 'session-123';
33
+ (storage.get as ReturnType<typeof vi.fn>).mockResolvedValue(null);
41
34
 
42
- expect(userDid).toMatch(/^did:key:z/);
43
- expect(userDid.length).toBeGreaterThan(40);
44
- });
35
+ // Phase 5: No ephemeral DID generation - returns null for anonymous session
36
+ const userDid = await manager.getOrCreateUserDid(sessionId);
45
37
 
46
- test('should return same DID for same session', async () => {
38
+ expect(userDid).toBeNull();
39
+ });
40
+
41
+ test('should return same null for same session (cache hit)', async () => {
47
42
  const sessionId = 'session-123';
43
+ (storage.get as ReturnType<typeof vi.fn>).mockResolvedValue(null);
44
+
48
45
  const did1 = await manager.getOrCreateUserDid(sessionId);
49
46
  const did2 = await manager.getOrCreateUserDid(sessionId);
50
47
 
51
- expect(did1).toBe(did2);
48
+ expect(did1).toBeNull();
49
+ expect(did2).toBeNull();
52
50
  });
53
51
 
54
- test('should return different DIDs for different sessions', async () => {
52
+ test('should return null for different sessions without OAuth', async () => {
53
+ (storage.get as ReturnType<typeof vi.fn>).mockResolvedValue(null);
54
+
55
55
  const did1 = await manager.getOrCreateUserDid('session-1');
56
56
  const did2 = await manager.getOrCreateUserDid('session-2');
57
57
 
58
- expect(did1).not.toBe(did2);
58
+ // Phase 5: Both sessions are anonymous (null userDid)
59
+ expect(did1).toBeNull();
60
+ expect(did2).toBeNull();
59
61
  });
60
62
 
61
63
  test('should retrieve DID from storage if available', async () => {
@@ -69,33 +71,42 @@ describe('UserDidManager', () => {
69
71
  expect(storage.get).toHaveBeenCalledWith(sessionId);
70
72
  });
71
73
 
72
- test('should store new DID in storage', async () => {
74
+ test('should not call storage.set for new sessions (Phase 5)', async () => {
73
75
  const sessionId = 'session-123';
76
+ (storage.get as ReturnType<typeof vi.fn>).mockResolvedValue(null);
77
+
78
+ // Phase 5: No DID generated, no storage write
74
79
  const did = await manager.getOrCreateUserDid(sessionId);
75
80
 
76
- expect(storage.set).toHaveBeenCalledWith(sessionId, did, 1800);
81
+ expect(did).toBeNull();
82
+ expect(storage.set).not.toHaveBeenCalled();
77
83
  });
78
84
 
79
- test('should use cache for subsequent calls', async () => {
85
+ test('should use cache for existing DID on subsequent calls', async () => {
80
86
  const sessionId = 'session-123';
87
+ const storedDid = 'did:key:zTestStoredDID';
88
+ (storage.get as ReturnType<typeof vi.fn>).mockResolvedValue(storedDid);
89
+
81
90
  const did1 = await manager.getOrCreateUserDid(sessionId);
82
-
83
- // Clear storage mock to ensure cache is used
91
+
92
+ // Clear storage mock - next call should use cache
93
+ (storage.get as ReturnType<typeof vi.fn>).mockReset();
84
94
  (storage.get as ReturnType<typeof vi.fn>).mockResolvedValue(null);
85
-
95
+
86
96
  const did2 = await manager.getOrCreateUserDid(sessionId);
87
97
 
88
- expect(did1).toBe(did2);
89
- expect(storage.get).not.toHaveBeenCalledTimes(2); // Cache hit
98
+ expect(did1).toBe(storedDid);
99
+ expect(did2).toBe(storedDid); // Cache hit
90
100
  });
91
101
 
92
- test('should work without storage provider', async () => {
102
+ test('should return null without storage provider (Phase 5)', async () => {
93
103
  const ephemeralManager = new UserDidManager({
94
104
  crypto: cryptoProvider,
95
105
  });
96
106
 
107
+ // Phase 5: No storage, no OAuth → anonymous session (null)
97
108
  const did = await ephemeralManager.getOrCreateUserDid('session-123');
98
- expect(did).toMatch(/^did:key:z/);
109
+ expect(did).toBeNull();
99
110
  });
100
111
  });
101
112
 
@@ -158,16 +169,23 @@ describe('UserDidManager', () => {
158
169
  });
159
170
 
160
171
  describe('DID format validation', () => {
161
- test('should generate valid did:key format', async () => {
162
- const did = await manager.getOrCreateUserDid('session-123');
163
-
172
+ test('should return stored DID if it has valid did:key format', async () => {
173
+ const sessionId = 'session-123';
174
+ const validDid = 'did:key:z6MkhaXgBZDvotDUGnNPEFXjSNbMoRmbW2BgUjH9tmp1hQ1R';
175
+ (storage.get as ReturnType<typeof vi.fn>).mockResolvedValue(validDid);
176
+
177
+ const did = await manager.getOrCreateUserDid(sessionId);
178
+
164
179
  // did:key format: did:key:z<base58-encoded-multicodec-key>
180
+ expect(did).not.toBeNull();
165
181
  expect(did).toMatch(/^did:key:z[1-9A-HJ-NP-Za-km-z]+$/);
166
182
  });
167
183
 
168
- test('should generate different DIDs each time generateUserDid is called', async () => {
169
- const dids = new Set<string>();
170
-
184
+ test('should return null for new sessions without OAuth (Phase 5)', async () => {
185
+ // Phase 5: getOrCreateUserDid returns null for new sessions without existing DID
186
+ // No ephemeral DID generation - sessions stay anonymous until OAuth
187
+ const dids = new Set<string | null>();
188
+
171
189
  for (let i = 0; i < 10; i++) {
172
190
  const manager = new UserDidManager({
173
191
  crypto: cryptoProvider,
@@ -176,28 +194,29 @@ describe('UserDidManager', () => {
176
194
  dids.add(did);
177
195
  }
178
196
 
179
- // All DIDs should be unique
180
- expect(dids.size).toBe(10);
197
+ // Phase 5: All DIDs should be null (no generation)
198
+ expect(dids.size).toBe(1);
199
+ expect(dids.has(null)).toBe(true);
181
200
  });
182
201
  });
183
202
 
184
203
  describe('error handling', () => {
185
- test('should handle storage.get errors gracefully', async () => {
204
+ test('should handle storage.get errors gracefully (Phase 5)', async () => {
186
205
  const sessionId = 'session-123';
187
206
  (storage.get as ReturnType<typeof vi.fn>).mockRejectedValue(new Error('Storage error'));
188
207
 
189
- // Should still generate DID despite storage error
208
+ // Phase 5: Returns null when storage errors occur (no ephemeral generation)
190
209
  const did = await manager.getOrCreateUserDid(sessionId);
191
- expect(did).toMatch(/^did:key:z/);
210
+ expect(did).toBeNull();
192
211
  });
193
212
 
194
- test('should handle storage.set errors gracefully', async () => {
213
+ test('should return null when no existing DID found (Phase 5)', async () => {
195
214
  const sessionId = 'session-123';
196
- (storage.set as ReturnType<typeof vi.fn>).mockRejectedValue(new Error('Storage error'));
215
+ (storage.get as ReturnType<typeof vi.fn>).mockResolvedValue(null);
197
216
 
198
- // Should still return DID despite storage error
217
+ // Phase 5: Returns null instead of generating ephemeral DID
199
218
  const did = await manager.getOrCreateUserDid(sessionId);
200
- expect(did).toMatch(/^did:key:z/);
219
+ expect(did).toBeNull();
201
220
  });
202
221
 
203
222
  test('should handle storage.delete errors gracefully', async () => {
@@ -358,14 +358,20 @@ describe("Full Flow Integration", () => {
358
358
  });
359
359
 
360
360
  describe("AgentShield integration flow", () => {
361
- test("should fetch tool protection config from AgentShield", async () => {
361
+ test("should fetch tool protection config from AgentShield merged config", async () => {
362
+ // Merged config format - tools embedded at config.toolProtection.tools
362
363
  const apiResponse = {
363
364
  success: true,
364
365
  data: {
365
- toolProtections: {
366
- protected_tool: {
367
- requiresDelegation: true,
368
- requiredScopes: ["scope1"],
366
+ config: {
367
+ toolProtection: {
368
+ source: 'agentshield',
369
+ tools: {
370
+ protected_tool: {
371
+ requiresDelegation: true,
372
+ requiredScopes: ["scope1"],
373
+ },
374
+ },
369
375
  },
370
376
  },
371
377
  },
@@ -384,22 +390,29 @@ describe("Full Flow Integration", () => {
384
390
  expect(config.toolProtections.protected_tool.requiresDelegation).toBe(
385
391
  true
386
392
  );
393
+ // Now calls /config endpoint (not /tool-protections)
387
394
  expect(global.fetch).toHaveBeenCalledWith(
388
395
  expect.stringContaining(
389
- "/api/v1/bouncer/projects/test-project/tool-protections"
396
+ "/api/v1/bouncer/projects/test-project/config"
390
397
  ),
391
398
  expect.any(Object)
392
399
  );
393
400
  });
394
401
 
395
402
  test("should cache tool protection config", async () => {
403
+ // Merged config format - tools embedded at config.toolProtection.tools
396
404
  const apiResponse = {
397
405
  success: true,
398
406
  data: {
399
- toolProtections: {
400
- tool1: {
401
- requiresDelegation: true,
402
- requiredScopes: ["scope1"],
407
+ config: {
408
+ toolProtection: {
409
+ source: 'agentshield',
410
+ tools: {
411
+ tool1: {
412
+ requiresDelegation: true,
413
+ requiredScopes: ["scope1"],
414
+ },
415
+ },
403
416
  },
404
417
  },
405
418
  },
@@ -108,7 +108,8 @@ describe('MCPIRuntimeBase - Base Extensions', () => {
108
108
  });
109
109
 
110
110
  describe('handleHandshake with user DID generation', () => {
111
- it('should generate user DID when enabled', async () => {
111
+ it('should start session as anonymous (Phase 5)', async () => {
112
+ // Phase 5: Sessions start anonymous - userDid is only set after OAuth
112
113
  const configWithUserDid = {
113
114
  ...config,
114
115
  identity: {
@@ -124,11 +125,16 @@ describe('MCPIRuntimeBase - Base Extensions', () => {
124
125
  audience: 'https://client.example.com'
125
126
  });
126
127
 
127
- expect(response.userDid).toBeDefined();
128
- expect(response.userDid).toMatch(/^did:key:z/);
128
+ // Phase 5: userDid is undefined in response - session is anonymous
129
+ expect(response.userDid).toBeUndefined();
130
+
131
+ // Check session's identityState
132
+ const session = await runtimeWithUserDid.getCurrentSession();
133
+ expect(session.identityState).toBe('anonymous');
129
134
  });
130
135
 
131
- it('should use provided clientDid over generated userDid', async () => {
136
+ it('should use provided clientDid with anonymous session (Phase 5)', async () => {
137
+ // Phase 5: clientDid can be set while session stays anonymous (no userDid)
132
138
  const configWithUserDid = {
133
139
  ...config,
134
140
  identity: {
@@ -147,13 +153,10 @@ describe('MCPIRuntimeBase - Base Extensions', () => {
147
153
 
148
154
  const session = await runtimeWithUserDid.getCurrentSession();
149
155
  expect(session.clientDid).toBe('did:key:zprovided123');
150
-
151
- // When userDid generation is enabled, it should be generated even when clientDid is provided
152
- // This is a critical assertion - if userDid is missing, the test should fail
153
- expect(session.userDid).toBeDefined();
154
- expect(session.userDid).toMatch(/^did:key:z/);
155
- // userDid should be different from clientDid
156
- expect(session.userDid).not.toBe(session.clientDid);
156
+
157
+ // Phase 5: userDid is undefined - session is anonymous until OAuth
158
+ expect(session.userDid).toBeUndefined();
159
+ expect(session.identityState).toBe('anonymous');
157
160
  });
158
161
 
159
162
  it('should handle user DID generation errors gracefully', async () => {
@@ -168,25 +171,24 @@ describe('MCPIRuntimeBase - Base Extensions', () => {
168
171
  const runtimeWithUserDid = new MCPIRuntimeBase(configWithUserDid);
169
172
  await runtimeWithUserDid.initialize();
170
173
 
171
- // Mock userDidManager to throw error
174
+ // Phase 5: getOrCreateUserDid now returns null instead of generating ephemeral DIDs
175
+ // Sessions start anonymous - no userDid at handshake
172
176
  const userDidManager = (runtimeWithUserDid as any).userDidManager;
173
177
  const originalGetOrCreate = userDidManager.getOrCreateUserDid;
174
- userDidManager.getOrCreateUserDid = vi.fn().mockRejectedValue(new Error('DID generation failed'));
175
-
176
- const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
178
+ userDidManager.getOrCreateUserDid = vi.fn().mockResolvedValue(null);
177
179
 
178
180
  const response = await runtimeWithUserDid.handleHandshake({
179
181
  audience: 'https://client.example.com'
180
182
  });
181
183
 
182
- // Should still succeed without userDid
184
+ // Should succeed with anonymous session (no userDid)
183
185
  expect(response.sessionId).toBeDefined();
184
- expect(consoleWarnSpy).toHaveBeenCalledWith(
185
- expect.stringContaining('[MCP-I] Failed to generate user DID'),
186
- expect.any(Error)
187
- );
188
186
 
189
- consoleWarnSpy.mockRestore();
187
+ // Phase 5: Session should be anonymous without userDid
188
+ const session = await runtimeWithUserDid.getCurrentSession();
189
+ expect(session.userDid).toBeUndefined();
190
+ expect(session.identityState).toBe('anonymous');
191
+
190
192
  userDidManager.getOrCreateUserDid = originalGetOrCreate;
191
193
  });
192
194
  });
@@ -143,8 +143,8 @@ describe('MCPIRuntimeBase - Proof Client DID', () => {
143
143
  expect(session.clientDid).toBe('did:key:zhandshake123');
144
144
  });
145
145
 
146
- it('should handle userDid from handshake session', async () => {
147
- // Initialize runtime with user DID generation enabled
146
+ it('should handle anonymous session from handshake (Phase 5)', async () => {
147
+ // Phase 5: Sessions start anonymous - no userDid at handshake
148
148
  const configWithUserDid = {
149
149
  ...config,
150
150
  identity: {
@@ -162,12 +162,12 @@ describe('MCPIRuntimeBase - Proof Client DID', () => {
162
162
 
163
163
  const session = await runtimeWithUserDid.getCurrentSession();
164
164
  expect(session).toBeDefined();
165
-
166
- // When userDid generation is enabled, it should be generated and available
167
- // This is a critical assertion - if userDid is missing, the test should fail
168
- expect(session.userDid).toBeDefined();
169
- expect(session.userDid).toMatch(/^did:key:z/);
170
-
165
+
166
+ // Phase 5: Sessions start anonymous without userDid
167
+ // userDid is only set after OAuth identity resolution
168
+ expect(session.userDid).toBeUndefined();
169
+ expect(session.identityState).toBe('anonymous');
170
+
171
171
  const proof = await runtimeWithUserDid.createProof(
172
172
  { test: 'data' },
173
173
  session
@@ -234,7 +234,8 @@ describe('MCPIRuntimeBase - Proof Client DID', () => {
234
234
  expect(session.clientDid).toBe('did:key:zclient789');
235
235
  });
236
236
 
237
- it('should use generated userDid as clientDid when no clientDid provided', async () => {
237
+ it('should handle anonymous session when no clientDid provided (Phase 5)', async () => {
238
+ // Phase 5: Sessions start anonymous - userDid and clientDid may both be undefined
238
239
  const configWithUserDid = {
239
240
  ...config,
240
241
  identity: {
@@ -252,15 +253,15 @@ describe('MCPIRuntimeBase - Proof Client DID', () => {
252
253
 
253
254
  const session = await runtimeWithUserDid.getCurrentSession();
254
255
  expect(session).toBeDefined();
255
-
256
- // When userDid generation is enabled, it should be generated and available
257
- // This is a critical assertion - if userDid is missing, the test should fail
258
- expect(session.userDid).toBeDefined();
259
- expect(session.userDid).toMatch(/^did:key:z/);
260
-
261
- // clientDid should be set to userDid if no explicit clientDid provided
262
- expect(session.clientDid || session.userDid).toBeDefined();
263
-
256
+
257
+ // Phase 5: Sessions start anonymous without userDid
258
+ // userDid is only set after OAuth identity resolution
259
+ expect(session.userDid).toBeUndefined();
260
+ expect(session.identityState).toBe('anonymous');
261
+
262
+ // clientDid can also be undefined in anonymous sessions
263
+ // Both will be set after OAuth completes
264
+
264
265
  // Verify proof includes the session
265
266
  const proof = await runtimeWithUserDid.createProof(
266
267
  { test: 'data' },
@@ -144,11 +144,17 @@ describe('AgentShield Integration', () => {
144
144
  });
145
145
 
146
146
  describe('Endpoint Selection', () => {
147
- test('should use project-scoped endpoint when projectId is available', async () => {
147
+ test('should use project-scoped /config endpoint when projectId is available', async () => {
148
+ // Merged config format - tools embedded at config.toolProtection.tools
148
149
  const apiResponse = {
149
150
  success: true,
150
151
  data: {
151
- toolProtections: {},
152
+ config: {
153
+ toolProtection: {
154
+ source: 'agentshield',
155
+ tools: {},
156
+ },
157
+ },
152
158
  },
153
159
  metadata: {},
154
160
  };
@@ -160,8 +166,9 @@ describe('AgentShield Integration', () => {
160
166
 
161
167
  await service.getToolProtectionConfig(mockAgentDid);
162
168
 
169
+ // Now calls /config endpoint (not /tool-protections)
163
170
  expect(global.fetch).toHaveBeenCalledWith(
164
- `${baseUrl}/api/v1/bouncer/projects/test-project-123/tool-protections`,
171
+ `${baseUrl}/api/v1/bouncer/projects/test-project-123/config`,
165
172
  expect.any(Object)
166
173
  );
167
174
  });