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

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/.turbo/turbo-build.log +1 -1
  2. package/dist/__tests__/utils/mock-providers.d.ts +2 -1
  3. package/dist/__tests__/utils/mock-providers.d.ts.map +1 -1
  4. package/dist/__tests__/utils/mock-providers.js.map +1 -1
  5. package/dist/config/remote-config.d.ts +51 -0
  6. package/dist/config/remote-config.d.ts.map +1 -1
  7. package/dist/config/remote-config.js +74 -0
  8. package/dist/config/remote-config.js.map +1 -1
  9. package/dist/config.d.ts +1 -1
  10. package/dist/config.d.ts.map +1 -1
  11. package/dist/config.js +4 -1
  12. package/dist/config.js.map +1 -1
  13. package/dist/delegation/did-key-resolver.d.ts +64 -0
  14. package/dist/delegation/did-key-resolver.d.ts.map +1 -0
  15. package/dist/delegation/did-key-resolver.js +159 -0
  16. package/dist/delegation/did-key-resolver.js.map +1 -0
  17. package/dist/delegation/utils.d.ts +76 -0
  18. package/dist/delegation/utils.d.ts.map +1 -1
  19. package/dist/delegation/utils.js +117 -0
  20. package/dist/delegation/utils.js.map +1 -1
  21. package/dist/identity/user-did-manager.d.ts +95 -12
  22. package/dist/identity/user-did-manager.d.ts.map +1 -1
  23. package/dist/identity/user-did-manager.js +107 -25
  24. package/dist/identity/user-did-manager.js.map +1 -1
  25. package/dist/index.d.ts +5 -2
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +23 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/runtime/base.d.ts +25 -8
  30. package/dist/runtime/base.d.ts.map +1 -1
  31. package/dist/runtime/base.js +74 -21
  32. package/dist/runtime/base.js.map +1 -1
  33. package/dist/services/session-registration.service.d.ts.map +1 -1
  34. package/dist/services/session-registration.service.js +10 -90
  35. package/dist/services/session-registration.service.js.map +1 -1
  36. package/dist/services/tool-protection.service.d.ts +5 -2
  37. package/dist/services/tool-protection.service.d.ts.map +1 -1
  38. package/dist/services/tool-protection.service.js +72 -24
  39. package/dist/services/tool-protection.service.js.map +1 -1
  40. package/dist/utils/base58.d.ts +31 -0
  41. package/dist/utils/base58.d.ts.map +1 -0
  42. package/dist/utils/base58.js +103 -0
  43. package/dist/utils/base58.js.map +1 -0
  44. package/package.json +3 -3
  45. package/src/__tests__/identity/user-did-manager.test.ts +64 -45
  46. package/src/__tests__/integration/full-flow.test.ts +23 -10
  47. package/src/__tests__/runtime/base-extensions.test.ts +23 -21
  48. package/src/__tests__/runtime/proof-client-did.test.ts +19 -18
  49. package/src/__tests__/services/agentshield-integration.test.ts +10 -3
  50. package/src/__tests__/services/tool-protection-merged-config.test.ts +485 -0
  51. package/src/__tests__/services/tool-protection.service.test.ts +18 -11
  52. package/src/config/__tests__/merged-config.spec.ts +445 -0
  53. package/src/config/remote-config.ts +90 -0
  54. package/src/config.ts +3 -0
  55. package/src/delegation/__tests__/did-key-resolver.test.ts +265 -0
  56. package/src/delegation/did-key-resolver.ts +179 -0
  57. package/src/delegation/utils.ts +179 -0
  58. package/src/identity/user-did-manager.ts +185 -29
  59. package/src/index.ts +36 -1
  60. package/src/runtime/base.ts +84 -21
  61. package/src/services/session-registration.service.ts +26 -121
  62. package/src/services/tool-protection.service.ts +125 -56
  63. package/src/utils/base58.ts +109 -0
  64. package/coverage/coverage-final.json +0 -57
@@ -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
  });