@kya-os/mcp-i 0.1.0-alpha.2.2 → 0.1.0-alpha.2.4

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 (58) hide show
  1. package/README.md +258 -58
  2. package/dist/auto.d.ts +0 -12
  3. package/dist/auto.js +3 -14
  4. package/dist/crypto.d.ts +10 -26
  5. package/dist/crypto.js +117 -37
  6. package/dist/dev-helper.d.ts +3 -0
  7. package/dist/dev-helper.js +54 -0
  8. package/dist/encrypted-storage.d.ts +11 -0
  9. package/dist/encrypted-storage.js +73 -0
  10. package/dist/index.d.ts +33 -48
  11. package/dist/index.js +267 -191
  12. package/dist/logger.d.ts +32 -0
  13. package/dist/logger.js +66 -0
  14. package/dist/registry/index.d.ts +12 -0
  15. package/dist/registry/index.js +56 -0
  16. package/dist/registry/knowthat.d.ts +13 -0
  17. package/dist/registry/knowthat.js +88 -0
  18. package/dist/rotation.d.ts +35 -0
  19. package/dist/rotation.js +102 -0
  20. package/dist/storage.d.ts +41 -0
  21. package/dist/storage.js +163 -0
  22. package/dist/transport.d.ts +34 -0
  23. package/dist/transport.js +207 -0
  24. package/dist/types.d.ts +80 -17
  25. package/dist/types.js +0 -4
  26. package/package.json +36 -8
  27. package/dist/__tests__/challenge-response.test.d.ts +0 -5
  28. package/dist/__tests__/challenge-response.test.d.ts.map +0 -1
  29. package/dist/__tests__/challenge-response.test.js +0 -218
  30. package/dist/__tests__/challenge-response.test.js.map +0 -1
  31. package/dist/__tests__/crypto.test.d.ts +0 -5
  32. package/dist/__tests__/crypto.test.d.ts.map +0 -1
  33. package/dist/__tests__/crypto.test.js +0 -153
  34. package/dist/__tests__/crypto.test.js.map +0 -1
  35. package/dist/auto-enhance.d.ts +0 -41
  36. package/dist/auto-enhance.d.ts.map +0 -1
  37. package/dist/auto-enhance.js +0 -193
  38. package/dist/auto-enhance.js.map +0 -1
  39. package/dist/auto-init.d.ts +0 -12
  40. package/dist/auto-init.d.ts.map +0 -1
  41. package/dist/auto-init.js +0 -166
  42. package/dist/auto-init.js.map +0 -1
  43. package/dist/auto.d.ts.map +0 -1
  44. package/dist/auto.js.map +0 -1
  45. package/dist/crypto.d.ts.map +0 -1
  46. package/dist/crypto.js.map +0 -1
  47. package/dist/index.d.ts.map +0 -1
  48. package/dist/index.js.map +0 -1
  49. package/dist/patch.d.ts +0 -22
  50. package/dist/patch.d.ts.map +0 -1
  51. package/dist/patch.js +0 -164
  52. package/dist/patch.js.map +0 -1
  53. package/dist/transparent.d.ts +0 -40
  54. package/dist/transparent.d.ts.map +0 -1
  55. package/dist/transparent.js +0 -167
  56. package/dist/transparent.js.map +0 -1
  57. package/dist/types.d.ts.map +0 -1
  58. package/dist/types.js.map +0 -1
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.TransportFactory = exports.RuntimeDetector = exports.AxiosTransport = exports.FetchTransport = void 0;
37
+ class FetchTransport {
38
+ async post(url, data, options) {
39
+ const controller = new AbortController();
40
+ const timeout = options?.timeout || 30000;
41
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
42
+ try {
43
+ const response = await fetch(url, {
44
+ method: 'POST',
45
+ headers: {
46
+ 'Content-Type': 'application/json',
47
+ ...options?.headers
48
+ },
49
+ body: JSON.stringify(data),
50
+ signal: controller.signal
51
+ });
52
+ clearTimeout(timeoutId);
53
+ if (!response.ok) {
54
+ const error = await response.text();
55
+ throw new Error(`HTTP ${response.status}: ${error}`);
56
+ }
57
+ const responseData = await response.json();
58
+ return {
59
+ data: responseData,
60
+ status: response.status,
61
+ headers: Object.fromEntries(response.headers.entries())
62
+ };
63
+ }
64
+ catch (error) {
65
+ clearTimeout(timeoutId);
66
+ if (error.name === 'AbortError') {
67
+ throw new Error('Request timeout');
68
+ }
69
+ throw error;
70
+ }
71
+ }
72
+ async get(url, options) {
73
+ const controller = new AbortController();
74
+ const timeout = options?.timeout || 30000;
75
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
76
+ try {
77
+ const response = await fetch(url, {
78
+ method: 'GET',
79
+ headers: options?.headers,
80
+ signal: controller.signal
81
+ });
82
+ clearTimeout(timeoutId);
83
+ if (!response.ok) {
84
+ const error = await response.text();
85
+ throw new Error(`HTTP ${response.status}: ${error}`);
86
+ }
87
+ const responseData = await response.json();
88
+ return {
89
+ data: responseData,
90
+ status: response.status,
91
+ headers: Object.fromEntries(response.headers.entries())
92
+ };
93
+ }
94
+ catch (error) {
95
+ clearTimeout(timeoutId);
96
+ if (error.name === 'AbortError') {
97
+ throw new Error('Request timeout');
98
+ }
99
+ throw error;
100
+ }
101
+ }
102
+ }
103
+ exports.FetchTransport = FetchTransport;
104
+ class AxiosTransport {
105
+ async post(url, data, options) {
106
+ const axios = await this.getAxios();
107
+ try {
108
+ const response = await axios.post(url, data, {
109
+ timeout: options?.timeout || 30000,
110
+ headers: options?.headers
111
+ });
112
+ return {
113
+ data: response.data,
114
+ status: response.status,
115
+ headers: response.headers
116
+ };
117
+ }
118
+ catch (error) {
119
+ if (error.response?.status === 429) {
120
+ throw new Error('Rate limit exceeded. Please try again later.');
121
+ }
122
+ throw new Error(error.response?.data?.message ||
123
+ error.message ||
124
+ 'Request failed');
125
+ }
126
+ }
127
+ async get(url, options) {
128
+ const axios = await this.getAxios();
129
+ try {
130
+ const response = await axios.get(url, {
131
+ timeout: options?.timeout || 30000,
132
+ headers: options?.headers
133
+ });
134
+ return {
135
+ data: response.data,
136
+ status: response.status,
137
+ headers: response.headers
138
+ };
139
+ }
140
+ catch (error) {
141
+ throw new Error(error.response?.data?.message ||
142
+ error.message ||
143
+ 'Request failed');
144
+ }
145
+ }
146
+ async getAxios() {
147
+ if (!this.axiosInstance) {
148
+ const axiosModule = await Promise.resolve().then(() => __importStar(require('axios')));
149
+ this.axiosInstance = axiosModule.default;
150
+ }
151
+ return this.axiosInstance;
152
+ }
153
+ }
154
+ exports.AxiosTransport = AxiosTransport;
155
+ class RuntimeDetector {
156
+ static isEdgeRuntime() {
157
+ return !!(globalThis.EdgeRuntime ||
158
+ process.env.NEXT_RUNTIME === 'edge' ||
159
+ process.env.VERCEL_EDGE ||
160
+ globalThis.Deno ||
161
+ globalThis.Bun);
162
+ }
163
+ static isNodeRuntime() {
164
+ return !!(process.versions?.node &&
165
+ !this.isEdgeRuntime());
166
+ }
167
+ static hasFetch() {
168
+ return typeof globalThis.fetch === 'function';
169
+ }
170
+ static isLambda() {
171
+ return !!(process.env.AWS_LAMBDA_FUNCTION_NAME ||
172
+ process.env.LAMBDA_TASK_ROOT ||
173
+ process.env._HANDLER);
174
+ }
175
+ }
176
+ exports.RuntimeDetector = RuntimeDetector;
177
+ class TransportFactory {
178
+ static create(options) {
179
+ const transportType = options?.transport || 'auto';
180
+ if (transportType === 'fetch') {
181
+ if (!RuntimeDetector.hasFetch()) {
182
+ throw new Error('Fetch is not available in this runtime');
183
+ }
184
+ return new FetchTransport();
185
+ }
186
+ if (transportType === 'axios') {
187
+ return new AxiosTransport();
188
+ }
189
+ if (transportType === 'auto') {
190
+ if (RuntimeDetector.isEdgeRuntime() && RuntimeDetector.hasFetch()) {
191
+ return new FetchTransport();
192
+ }
193
+ if (RuntimeDetector.isLambda() && RuntimeDetector.hasFetch()) {
194
+ return new FetchTransport();
195
+ }
196
+ if (RuntimeDetector.isNodeRuntime()) {
197
+ return new AxiosTransport();
198
+ }
199
+ if (RuntimeDetector.hasFetch()) {
200
+ return new FetchTransport();
201
+ }
202
+ return new AxiosTransport();
203
+ }
204
+ throw new Error(`Unknown transport type: ${transportType}`);
205
+ }
206
+ }
207
+ exports.TransportFactory = TransportFactory;
package/dist/types.d.ts CHANGED
@@ -1,15 +1,81 @@
1
- /**
2
- * Type definitions for MCP-I challenge-response authentication
3
- */
1
+ export type RegistryName = string;
2
+ export type RegistryTier = 'verified';
3
+ export interface RegistryConfig {
4
+ include?: string[] | 'verified';
5
+ exclude?: string[];
6
+ }
7
+ export interface RegistryStatus {
8
+ name: string;
9
+ status: 'active' | 'pending' | 'failed';
10
+ registeredAt?: string;
11
+ type?: 'primary' | 'secondary';
12
+ error?: string;
13
+ }
14
+ export interface RegistryAdapter {
15
+ name: string;
16
+ type: 'primary' | 'secondary';
17
+ publish(data: any): Promise<any>;
18
+ verify?(did: string): Promise<boolean>;
19
+ }
20
+ export interface RegistryPublishData {
21
+ did: string;
22
+ name: string;
23
+ description?: string;
24
+ repository?: string;
25
+ publicKey: string;
26
+ metadata?: Record<string, any>;
27
+ }
28
+ export interface RegistryPublishResult {
29
+ success: boolean;
30
+ registryAgentId?: string;
31
+ profileUrl?: string;
32
+ error?: string;
33
+ }
34
+ export type DirectoryPreference = string[] | 'verified' | 'none';
35
+ export type DirectoryName = 'smithery' | 'glama' | string;
4
36
  export interface MCPIdentityOptions {
5
37
  name?: string;
6
38
  description?: string;
7
39
  repository?: string;
8
40
  apiEndpoint?: string;
9
41
  persistencePath?: string;
42
+ storage?: 'file' | 'memory' | 'auto';
43
+ memoryKey?: string;
44
+ transport?: 'axios' | 'fetch' | 'auto';
10
45
  timestampTolerance?: number;
11
46
  enableNonceTracking?: boolean;
12
- forceNew?: boolean;
47
+ encryptionPassword?: string;
48
+ directories?: DirectoryPreference;
49
+ mode?: 'development' | 'production';
50
+ logger?: Logger;
51
+ logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'silent';
52
+ }
53
+ export interface MCPServer {
54
+ setRequestHandler(method: string, handler: Function): void;
55
+ connect(transport: any): Promise<void>;
56
+ serverInfo?: {
57
+ capabilities?: Record<string, any>;
58
+ };
59
+ }
60
+ export interface MCPMiddleware {
61
+ (server: MCPServer, identity: any): void;
62
+ }
63
+ export interface MCPRequest<T = any> {
64
+ method: string;
65
+ params?: T;
66
+ }
67
+ export interface MCPResponse<T = any> {
68
+ content?: T;
69
+ error?: {
70
+ code: number;
71
+ message: string;
72
+ };
73
+ }
74
+ export interface Logger {
75
+ debug(message: string, ...args: any[]): void;
76
+ info(message: string, ...args: any[]): void;
77
+ warn(message: string, ...args: any[]): void;
78
+ error(message: string, ...args: any[]): void;
13
79
  }
14
80
  export interface AutoRegisterResponse {
15
81
  success: boolean;
@@ -32,19 +98,22 @@ export interface PersistedIdentity {
32
98
  agentId: string;
33
99
  agentSlug: string;
34
100
  registeredAt: string;
101
+ directories?: DirectoryPreference;
102
+ }
103
+ export interface RegistrationData {
104
+ name: string;
105
+ description?: string;
106
+ repository?: string;
107
+ publicKey?: string;
108
+ directories?: DirectoryPreference;
109
+ metadata?: Record<string, any>;
35
110
  }
36
- /**
37
- * MCP-I Challenge structure
38
- */
39
111
  export interface Challenge {
40
112
  nonce: string;
41
113
  timestamp: number;
42
114
  verifier_did?: string;
43
115
  scope?: string[];
44
116
  }
45
- /**
46
- * MCP-I Challenge Response structure
47
- */
48
117
  export interface ChallengeResponse {
49
118
  did: string;
50
119
  signature: string;
@@ -52,9 +121,6 @@ export interface ChallengeResponse {
52
121
  nonce: string;
53
122
  publicKey?: string;
54
123
  }
55
- /**
56
- * MCP-I Capabilities advertisement
57
- */
58
124
  export interface MCPICapabilities {
59
125
  version: string;
60
126
  did: string;
@@ -63,10 +129,8 @@ export interface MCPICapabilities {
63
129
  handshakeSupported: boolean;
64
130
  handshakeEndpoint?: string;
65
131
  verificationEndpoint?: string;
132
+ registry?: string;
66
133
  }
67
- /**
68
- * Response with MCP-I identity attached
69
- */
70
134
  export interface SignedResponse<T = any> {
71
135
  [key: string]: any;
72
136
  _mcp_identity: {
@@ -76,4 +140,3 @@ export interface SignedResponse<T = any> {
76
140
  conformanceLevel?: number;
77
141
  };
78
142
  }
79
- //# sourceMappingURL=types.d.ts.map
package/dist/types.js CHANGED
@@ -1,6 +1,2 @@
1
1
  "use strict";
2
- /**
3
- * Type definitions for MCP-I challenge-response authentication
4
- */
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- //# sourceMappingURL=types.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kya-os/mcp-i",
3
- "version": "0.1.0-alpha.2.2",
4
- "description": "Ultra-light MCP Identity auto-registration - 2 lines to agent identity",
3
+ "version": "0.1.0-alpha.2.4",
4
+ "description": "Production-ready MCP Identity with automatic registration, key rotation, and optimized performance",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {
@@ -14,6 +14,11 @@
14
14
  "types": "./dist/auto.d.ts",
15
15
  "import": "./dist/auto.js",
16
16
  "require": "./dist/auto.js"
17
+ },
18
+ "./registry": {
19
+ "types": "./dist/registry/index.d.ts",
20
+ "import": "./dist/registry/index.js",
21
+ "require": "./dist/registry/index.js"
17
22
  }
18
23
  },
19
24
  "files": [
@@ -22,25 +27,48 @@
22
27
  "LICENSE"
23
28
  ],
24
29
  "scripts": {
25
- "build": "tsc",
30
+ "build": "tsc -p tsconfig.prod.json",
31
+ "build:dev": "tsc",
32
+ "clean": "rm -rf dist",
26
33
  "test": "vitest",
27
34
  "test:watch": "vitest watch",
28
35
  "test:coverage": "vitest run --coverage",
29
- "prepublishOnly": "npm run build"
36
+ "prepublishOnly": "npm run clean && npm run build",
37
+ "size": "npm pack --dry-run && echo 'Bundled size:' && tar -tzf *.tgz | wc -c"
30
38
  },
31
39
  "keywords": [
32
40
  "mcp",
33
41
  "mcp-i",
42
+ "model-context-protocol",
34
43
  "identity",
35
44
  "agent",
36
- "auto-registration",
37
- "did"
45
+ "ai-agent",
46
+ "cryptographic-identity",
47
+ "did",
48
+ "decentralized-identity",
49
+ "authentication",
50
+ "ed25519"
38
51
  ],
52
+ "repository": {
53
+ "type": "git",
54
+ "url": "https://github.com/kya-os/mcp-i.git"
55
+ },
56
+ "bugs": {
57
+ "url": "https://github.com/kya-os/mcp-i/issues"
58
+ },
59
+ "homepage": "https://github.com/kya-os/mcp-i#readme",
39
60
  "author": "Dylan Hobbs <dylan@vouched.id>",
40
61
  "license": "MIT",
41
62
  "dependencies": {
42
- "@noble/ed25519": "^2.1.0",
43
- "axios": "^1.6.7"
63
+ "@noble/ed25519": "^2.1.0"
64
+ },
65
+ "peerDependencies": {
66
+ "axios": "^1.6.0"
67
+ },
68
+ "peerDependenciesMeta": {
69
+ "axios": {
70
+ "optional": true
71
+ }
44
72
  },
45
73
  "devDependencies": {
46
74
  "@types/node": "^20.0.0",
@@ -1,5 +0,0 @@
1
- /**
2
- * Tests for challenge-response authentication
3
- */
4
- export {};
5
- //# sourceMappingURL=challenge-response.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"challenge-response.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/challenge-response.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -1,218 +0,0 @@
1
- "use strict";
2
- /**
3
- * Tests for challenge-response authentication
4
- */
5
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- var desc = Object.getOwnPropertyDescriptor(m, k);
8
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
- desc = { enumerable: true, get: function() { return m[k]; } };
10
- }
11
- Object.defineProperty(o, k2, desc);
12
- }) : (function(o, m, k, k2) {
13
- if (k2 === undefined) k2 = k;
14
- o[k2] = m[k];
15
- }));
16
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
- Object.defineProperty(o, "default", { enumerable: true, value: v });
18
- }) : function(o, v) {
19
- o["default"] = v;
20
- });
21
- var __importStar = (this && this.__importStar) || (function () {
22
- var ownKeys = function(o) {
23
- ownKeys = Object.getOwnPropertyNames || function (o) {
24
- var ar = [];
25
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
- return ar;
27
- };
28
- return ownKeys(o);
29
- };
30
- return function (mod) {
31
- if (mod && mod.__esModule) return mod;
32
- var result = {};
33
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
- __setModuleDefault(result, mod);
35
- return result;
36
- };
37
- })();
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- const vitest_1 = require("vitest");
40
- const index_1 = require("../index");
41
- const crypto = __importStar(require("../crypto"));
42
- // Mock axios for auto-registration
43
- vitest_1.vi.mock('axios');
44
- // Mock fs for identity persistence
45
- vitest_1.vi.mock('fs', () => ({
46
- existsSync: vitest_1.vi.fn(() => false),
47
- readFileSync: vitest_1.vi.fn(),
48
- writeFileSync: vitest_1.vi.fn()
49
- }));
50
- (0, vitest_1.describe)('MCPIdentity Challenge-Response', () => {
51
- let identity;
52
- let keyPair;
53
- (0, vitest_1.beforeEach)(async () => {
54
- // Mock environment to have pre-existing identity
55
- keyPair = await crypto.generateKeyPair();
56
- process.env.AGENT_DID = 'did:web:knowthat.ai:agents:test-agent';
57
- process.env.AGENT_PUBLIC_KEY = keyPair.publicKey;
58
- process.env.AGENT_PRIVATE_KEY = keyPair.privateKey;
59
- process.env.AGENT_ID = 'agent-123';
60
- process.env.AGENT_SLUG = 'test-agent';
61
- identity = await index_1.MCPIdentity.init();
62
- });
63
- (0, vitest_1.afterEach)(() => {
64
- // Clean up environment
65
- delete process.env.AGENT_DID;
66
- delete process.env.AGENT_PUBLIC_KEY;
67
- delete process.env.AGENT_PRIVATE_KEY;
68
- delete process.env.AGENT_ID;
69
- delete process.env.AGENT_SLUG;
70
- });
71
- (0, vitest_1.describe)('respondToChallenge', () => {
72
- (0, vitest_1.it)('should successfully respond to a valid challenge', async () => {
73
- const challenge = {
74
- nonce: crypto.generateNonce(),
75
- timestamp: Date.now(),
76
- verifier_did: 'did:web:example.com:verifier',
77
- scope: ['read', 'write']
78
- };
79
- const response = await identity.respondToChallenge(challenge);
80
- (0, vitest_1.expect)(response).toMatchObject({
81
- did: 'did:web:knowthat.ai:agents:test-agent',
82
- nonce: challenge.nonce,
83
- publicKey: keyPair.publicKey
84
- });
85
- (0, vitest_1.expect)(response.signature).toBeDefined();
86
- (0, vitest_1.expect)(response.timestamp).toBeGreaterThanOrEqual(challenge.timestamp);
87
- // Verify the signature
88
- const messageComponents = [
89
- challenge.nonce,
90
- challenge.timestamp.toString(),
91
- response.did,
92
- challenge.verifier_did || '',
93
- (challenge.scope || []).join(',')
94
- ];
95
- const message = messageComponents.join(':');
96
- const isValid = await identity.verify(message, response.signature);
97
- (0, vitest_1.expect)(isValid).toBe(true);
98
- });
99
- (0, vitest_1.it)('should reject expired challenges', async () => {
100
- const challenge = {
101
- nonce: crypto.generateNonce(),
102
- timestamp: Date.now() - 120000, // 2 minutes ago
103
- };
104
- await (0, vitest_1.expect)(identity.respondToChallenge(challenge))
105
- .rejects.toThrow('Challenge expired');
106
- });
107
- (0, vitest_1.it)('should reject challenges with future timestamps', async () => {
108
- const challenge = {
109
- nonce: crypto.generateNonce(),
110
- timestamp: Date.now() + 60000, // 1 minute in future
111
- };
112
- await (0, vitest_1.expect)(identity.respondToChallenge(challenge))
113
- .rejects.toThrow('Challenge timestamp is in the future');
114
- });
115
- (0, vitest_1.it)('should reject reused nonces when tracking is enabled', async () => {
116
- const challenge = {
117
- nonce: crypto.generateNonce(),
118
- timestamp: Date.now(),
119
- };
120
- // First use should succeed
121
- await identity.respondToChallenge(challenge);
122
- // Second use should fail
123
- await (0, vitest_1.expect)(identity.respondToChallenge(challenge))
124
- .rejects.toThrow('Nonce already used');
125
- });
126
- (0, vitest_1.it)('should handle challenges without optional fields', async () => {
127
- const challenge = {
128
- nonce: crypto.generateNonce(),
129
- timestamp: Date.now(),
130
- };
131
- const response = await identity.respondToChallenge(challenge);
132
- (0, vitest_1.expect)(response).toMatchObject({
133
- did: 'did:web:knowthat.ai:agents:test-agent',
134
- nonce: challenge.nonce,
135
- });
136
- // Verify signature with empty optional fields
137
- const messageComponents = [
138
- challenge.nonce,
139
- challenge.timestamp.toString(),
140
- response.did,
141
- '', // No verifier_did
142
- '' // No scope
143
- ];
144
- const message = messageComponents.join(':');
145
- const isValid = await identity.verify(message, response.signature);
146
- (0, vitest_1.expect)(isValid).toBe(true);
147
- });
148
- });
149
- (0, vitest_1.describe)('timestamp tolerance', () => {
150
- (0, vitest_1.it)('should accept challenges within tolerance window', async () => {
151
- // Create identity with 5 second tolerance
152
- const strictIdentity = await index_1.MCPIdentity.init({
153
- timestampTolerance: 5000
154
- });
155
- const challenge = {
156
- nonce: crypto.generateNonce(),
157
- timestamp: Date.now() - 4000, // 4 seconds ago
158
- };
159
- // Should succeed
160
- const response = await strictIdentity.respondToChallenge(challenge);
161
- (0, vitest_1.expect)(response).toBeDefined();
162
- });
163
- (0, vitest_1.it)('should reject challenges outside tolerance window', async () => {
164
- // Create identity with 5 second tolerance
165
- const strictIdentity = await index_1.MCPIdentity.init({
166
- timestampTolerance: 5000,
167
- forceNew: true
168
- });
169
- const challenge = {
170
- nonce: crypto.generateNonce(),
171
- timestamp: Date.now() - 6000, // 6 seconds ago
172
- };
173
- // Should fail
174
- await (0, vitest_1.expect)(strictIdentity.respondToChallenge(challenge))
175
- .rejects.toThrow('Challenge expired');
176
- });
177
- });
178
- (0, vitest_1.describe)('nonce tracking', () => {
179
- (0, vitest_1.it)('should allow disabling nonce tracking', async () => {
180
- const identityNoTracking = await index_1.MCPIdentity.init({
181
- enableNonceTracking: false,
182
- forceNew: true
183
- });
184
- const challenge = {
185
- nonce: crypto.generateNonce(),
186
- timestamp: Date.now(),
187
- };
188
- // Should succeed multiple times
189
- await identityNoTracking.respondToChallenge(challenge);
190
- await identityNoTracking.respondToChallenge(challenge);
191
- // No error thrown
192
- (0, vitest_1.expect)(true).toBe(true);
193
- });
194
- });
195
- (0, vitest_1.describe)('getCapabilities', () => {
196
- (0, vitest_1.it)('should advertise MCP-I capabilities', () => {
197
- const capabilities = identity.getCapabilities();
198
- (0, vitest_1.expect)(capabilities.version).toBe('1.0');
199
- (0, vitest_1.expect)(capabilities.did).toBe('did:web:knowthat.ai:agents:test-agent');
200
- (0, vitest_1.expect)(capabilities.conformanceLevel).toBe(2);
201
- (0, vitest_1.expect)(capabilities.handshakeSupported).toBe(true);
202
- (0, vitest_1.expect)(capabilities.handshakeEndpoint).toBe('/_mcp-i/handshake');
203
- (0, vitest_1.expect)(capabilities.verificationEndpoint).toBe('https://knowthat.ai/api/agents/did:web:knowthat.ai:agents:test-agent/verify');
204
- (0, vitest_1.expect)(capabilities.publicKey).toBeDefined();
205
- (0, vitest_1.expect)(capabilities.publicKey).toMatch(/^[A-Za-z0-9+/]+=*$/); // Base64 format
206
- });
207
- });
208
- (0, vitest_1.describe)('static methods', () => {
209
- (0, vitest_1.it)('should generate nonces', () => {
210
- const nonce1 = index_1.MCPIdentity.generateNonce();
211
- const nonce2 = index_1.MCPIdentity.generateNonce();
212
- (0, vitest_1.expect)(nonce1).toHaveLength(64);
213
- (0, vitest_1.expect)(nonce2).toHaveLength(64);
214
- (0, vitest_1.expect)(nonce1).not.toEqual(nonce2);
215
- });
216
- });
217
- });
218
- //# sourceMappingURL=challenge-response.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"challenge-response.test.js","sourceRoot":"","sources":["../../src/__tests__/challenge-response.test.ts"],"names":[],"mappings":"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"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Tests for cryptographic utilities
3
- */
4
- export {};
5
- //# sourceMappingURL=crypto.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"crypto.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/crypto.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}