@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
package/README.md CHANGED
@@ -1,10 +1,34 @@
1
1
  # @kya-os/mcp-i
2
2
 
3
- Ultra-light MCP Identity auto-registration. Give any MCP server a verifiable identity with just 2 lines of code.
3
+ The SEO package for AI agents. Register your MCP server and get automatic directory listings in 2 lines of code.
4
4
 
5
- ## The Vision
5
+ [![npm version](https://img.shields.io/npm/v/@kya-os/mcp-i.svg)](https://www.npmjs.com/package/@kya-os/mcp-i)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![MCP-I Conformance](https://img.shields.io/badge/MCP--I-Level%202-green)](https://modelcontextprotocol-identity.io)
6
8
 
7
- Make MCP-I adoption a no-brainer for the hundreds of thousands of MCP servers. Zero friction, immediate benefits.
9
+ ## Why Your MCP Server Needs This
10
+
11
+ **For MCP Server Developers:**
12
+
13
+ - **Get a DID** - Your agent gets a permanent, cryptographic identity from knowthat.ai
14
+ - **Automatic Directory Listings** - Submit to multiple directories with zero extra work
15
+ - **Build Reputation** - Every interaction is signed and verifiable
16
+ - **Future-Proof** - Ready for the decentralized agent ecosystem
17
+ - **Production-Ready** - Optimized for Lambda, Edge, Next.js, and traditional deployments
18
+
19
+ **For Directory Maintainers:**
20
+
21
+ - **Easy Integration** - List MCP-I compliant agents automatically
22
+ - **Verified Agents** - Only list agents with cryptographic proof
23
+ - **Join the Network** - Tap into the growing MCP-I ecosystem
24
+
25
+ ## How It Works
26
+
27
+ 1. **Identity Registration**: Your agent is registered with knowthat.ai (the MCP-I registry)
28
+ 2. **DID Generation**: You get a `did:web:knowthat.ai:agents:your-agent` identifier
29
+ 3. **Directory Submission**: Based on your preferences, knowthat.ai submits your agent to directories
30
+ 4. **Cryptographic Signing**: All agent responses are signed with your private key
31
+ 5. **Verification**: Anyone can verify your agent's identity and authenticity
8
32
 
9
33
  ## Installation
10
34
 
@@ -12,86 +36,262 @@ Make MCP-I adoption a no-brainer for the hundreds of thousands of MCP servers. Z
12
36
  npm install @kya-os/mcp-i
13
37
  ```
14
38
 
15
- ## Usage
39
+ ## Quick Start
16
40
 
17
- ### Option 1: Zero Configuration (Recommended)
41
+ ### 1. Zero Configuration (Recommended)
18
42
 
19
43
  ```typescript
20
- import "@kya-os/mcp-i/auto"; // That's it! Your server now has identity
44
+ import "@kya-os/mcp-i/auto";
45
+ // That's it! Your server now has cryptographic identity
21
46
  ```
22
47
 
23
- ### Option 2: With Configuration
48
+ ### 2. Production Configuration
24
49
 
25
50
  ```typescript
26
51
  import { enableMCPIdentity } from "@kya-os/mcp-i";
27
52
 
53
+ const identity = await enableMCPIdentity({
54
+ name: "Production Agent",
55
+
56
+ // Auto-detect runtime (Lambda, Edge, Node.js)
57
+ storage: "auto",
58
+ transport: "auto",
59
+
60
+ // Encrypt private keys at rest
61
+ encryptionPassword: process.env.AGENT_KEY_PASSWORD,
62
+
63
+ // Professional logging
64
+ logLevel: "error", // or 'silent' for production
65
+
66
+ // Directory preferences (optional)
67
+ directories: "verified", // List on all verified directories
68
+ // OR directories: ["smithery", "glama"] // Specific directories
69
+ // OR directories: "none" // No directory listings
70
+ });
71
+
72
+ // Enable automatic key rotation
73
+ await identity.enableAutoRotation({
74
+ maxAge: 90 * 24 * 60 * 60 * 1000, // 90 days
75
+ maxSignatures: 1_000_000, // 1M signatures
76
+ });
77
+ ```
78
+
79
+ ### 3. Lambda/Edge Runtime
80
+
81
+ ```typescript
82
+ // Automatic configuration for serverless
83
+ const identity = await enableMCPIdentity({
84
+ name: "Serverless Agent",
85
+ storage: "memory", // No file system needed
86
+ transport: "fetch", // Native fetch for edge
87
+ logLevel: "silent", // No console output
88
+ });
89
+ ```
90
+
91
+ ## Production Features
92
+
93
+ ### Performance Optimizations
94
+
95
+ - **Lazy Loading**: Crypto libraries load only when needed
96
+ - **Signature Caching**: Repeated signatures are 10x faster
97
+ - **Precomputed Values**: DIDs and keys cached in memory
98
+ - **Optimized Transport**: Auto-selects axios vs fetch
99
+
100
+ ### Security Features
101
+
102
+ - **Key Encryption**: Private keys encrypted with AES-256-GCM
103
+ - **Key Rotation**: Automatic rotation based on age/usage
104
+ - **Nonce Tracking**: Prevents replay attacks
105
+ - **Timestamp Validation**: Configurable tolerance windows
106
+
107
+ ### Runtime Support
108
+
109
+ - **AWS Lambda**: Automatic memory storage
110
+ - **Vercel Edge**: Native fetch transport
111
+ - **Cloudflare Workers**: Full compatibility
112
+ - **Node.js**: Traditional file storage
113
+
114
+ ### Directory Listings
115
+
116
+ ```typescript
117
+ // Configure directory listings
28
118
  await enableMCPIdentity({
29
- name: "Calendar Booker",
30
- description: "Professional calendar booking for AI agents",
31
- repository: "https://github.com/awesome-dev/calendar-booker"
119
+ name: "My Agent",
120
+
121
+ // Option 1: List on all verified directories
122
+ directories: "verified",
123
+
124
+ // Option 2: List on specific directories
125
+ directories: ["smithery", "glama"],
126
+
127
+ // Option 3: No directory listings (registry only)
128
+ directories: "none",
32
129
  });
130
+
131
+ // Directory preferences are sent to knowthat.ai
132
+ // The registry handles submissions to your chosen directories
33
133
  ```
34
134
 
35
- ## What Happens
36
-
37
- 1. **First Run**: Automatically registers with knowthat.ai and gets a DID
38
- 2. **Identity Saved**: Persists to `.env.local` and `.mcp-identity.json`
39
- 3. **All Responses Signed**: Every response includes `_mcp_identity` field
40
- 4. **MCP-I Handshake**: Automatically handles challenge-response authentication
41
- 5. **Capabilities Advertised**: Server advertises MCP-I support to clients
42
-
43
- ## Example Response
44
-
45
- ```json
46
- {
47
- "content": [{
48
- "type": "text",
49
- "text": "Event booked successfully!"
50
- }],
51
- "_mcp_identity": {
52
- "did": "did:web:knowthat.ai:agents:calendar-booker",
53
- "signature": "0x3045...",
54
- "timestamp": "2025-01-31T10:00:00Z",
55
- "conformanceLevel": 2
56
- }
135
+ ## Advanced Usage
136
+
137
+ ### Key Rotation
138
+
139
+ ```typescript
140
+ // Check key health
141
+ const health = identity.checkKeyHealth();
142
+ console.log(`Key age: ${health.age}ms`);
143
+ console.log(`Signatures: ${health.signatureCount}`);
144
+ console.log(`Should rotate: ${health.shouldRotate}`);
145
+
146
+ // Manual rotation
147
+ const result = await identity.rotateKeys("security-policy");
148
+ if (result.success) {
149
+ console.log(`Grace period ends: ${result.gracePeriodEnd}`);
57
150
  }
151
+
152
+ // Automatic rotation
153
+ await identity.enableAutoRotation({
154
+ maxAge: 30 * 24 * 60 * 60 * 1000, // 30 days
155
+ maxSignatures: 500_000, // 500k signatures
156
+ });
58
157
  ```
59
158
 
60
- ## Benefits
159
+ ### Edit/Claim URLs
61
160
 
62
- - ✅ **Verification Badge** on Smithery and other directories
63
- - 🔝 **Priority Discovery** in search results
64
- - 🔐 **Access to Identity-Aware APIs** with higher rate limits
65
- - 📊 **Analytics & Reputation** tracking
66
- - 🛡️ **Protection Against Impersonation**
161
+ ```typescript
162
+ // Get signed URLs for editing
163
+ const { editUrl, claimUrl } = await identity.requestEditAccess();
67
164
 
68
- ## How It Works
165
+ // Edit URL - for existing agents
166
+ console.log("Edit your agent:", editUrl);
69
167
 
70
- The package automatically:
71
- 1. Patches the MCP Server class to inject identity into all responses
72
- 2. Handles MCP-I challenge-response authentication
73
- 3. Advertises capabilities in server info
74
- 4. Works with all transports (STDIO, SSE, HTTP)
168
+ // Claim URL - for draft/unclaimed agents
169
+ console.log("Claim your agent:", claimUrl);
170
+ ```
75
171
 
76
- ## Environment Variables
172
+ ### Custom Storage
77
173
 
78
- After first run, these are saved automatically:
174
+ ```typescript
175
+ // Encrypted file storage
176
+ await enableMCPIdentity({
177
+ storage: "file",
178
+ persistencePath: "/secure/location/.identity",
179
+ encryptionPassword: "strong-password",
180
+ });
181
+
182
+ // Memory storage with custom key
183
+ await enableMCPIdentity({
184
+ storage: "memory",
185
+ memoryKey: "agent-123", // Useful for multiple agents
186
+ });
187
+ ```
188
+
189
+ ### Custom Logger
190
+
191
+ ```typescript
192
+ await enableMCPIdentity({
193
+ logger: {
194
+ debug: (msg, ...args) => myLogger.debug(msg, args),
195
+ info: (msg, ...args) => myLogger.info(msg, args),
196
+ warn: (msg, ...args) => myLogger.warn(msg, args),
197
+ error: (msg, ...args) => myLogger.error(msg, args),
198
+ },
199
+ });
200
+ ```
201
+
202
+ ## API Reference
203
+
204
+ ### `enableMCPIdentity(options?)`
205
+
206
+ Main function to enable identity for your MCP server.
207
+
208
+ **Options:**
209
+
210
+ ```typescript
211
+ interface MCPIdentityOptions {
212
+ // Basic info
213
+ name?: string;
214
+ description?: string;
215
+ repository?: string;
216
+
217
+ // Storage
218
+ storage?: "file" | "memory" | "auto";
219
+ persistencePath?: string;
220
+ memoryKey?: string;
221
+ encryptionPassword?: string;
222
+
223
+ // Transport
224
+ transport?: "axios" | "fetch" | "auto";
225
+
226
+ // Security
227
+ timestampTolerance?: number; // Default: 60000ms
228
+ enableNonceTracking?: boolean; // Default: true
229
+
230
+ // Directory listings
231
+ directories?: string[] | "verified" | "none"; // Default: "verified"
232
+
233
+ // Development
234
+ mode?: "development" | "production";
235
+
236
+ // Logging
237
+ logger?: Logger;
238
+ logLevel?: "debug" | "info" | "warn" | "error" | "silent";
239
+ }
240
+ ```
241
+
242
+ ### `MCPIdentity` Methods
243
+
244
+ - `sign(message)`: Sign with caching
245
+ - `verify(message, signature, publicKey?)`: Verify signatures
246
+ - `respondToChallenge(challenge)`: MCP-I authentication
247
+ - `signResponse(response)`: Add identity to responses
248
+ - `requestEditAccess()`: Get edit/claim URLs
249
+ - `rotateKeys(reason?)`: Manual key rotation
250
+ - `enableAutoRotation(policy?)`: Automatic rotation
251
+ - `checkKeyHealth()`: Key rotation status
252
+
253
+ ## Files Created
79
254
 
80
- ```bash
81
- AGENT_DID="did:web:knowthat.ai:agents:your-agent"
82
- AGENT_PUBLIC_KEY="base64-encoded-public-key"
83
- AGENT_PRIVATE_KEY="base64-encoded-private-key"
84
- AGENT_ID="uuid"
85
- AGENT_SLUG="your-agent-slug"
86
255
  ```
256
+ .mcp-identity.json # Your agent's identity (encrypted if password set)
257
+ ```
258
+
259
+ ## Security Best Practices
260
+
261
+ 1. **Use encryption in production**: Always set `encryptionPassword`
262
+ 2. **Enable key rotation**: Set up automatic rotation policies
263
+ 3. **Secure storage**: Use appropriate file permissions
264
+ 4. **Monitor key health**: Check rotation status regularly
265
+ 5. **Add to .gitignore**: Never commit identity files
266
+
267
+ ## Performance Tips
268
+
269
+ 1. **Use memory storage** for Lambda/Edge runtimes
270
+ 2. **Enable signature caching** (automatic)
271
+ 3. **Use 'silent' log level** in production
272
+ 4. **Let transport auto-select** based on runtime
273
+ 5. **Preload identity** during cold starts
274
+
275
+ ## Troubleshooting
276
+
277
+ ### Lambda/Edge Issues
278
+
279
+ - Ensure `storage: 'memory'` or `'auto'`
280
+ - Use `transport: 'fetch'` for edge runtimes
281
+ - Set `logLevel: 'silent'` to avoid console issues
282
+
283
+ ### Key Rotation Failures
284
+
285
+ - Check network connectivity to knowthat.ai
286
+ - Verify current keys are not corrupted
287
+ - Manual rotation: `await identity.rotateKeys('recovery')`
87
288
 
88
- ## Security
289
+ ### Performance Issues
89
290
 
90
- - Private keys are stored locally, never sent to knowthat.ai
91
- - All responses are cryptographically signed with Ed25519
92
- - Challenge-response prevents replay attacks
93
- - Nonce tracking prevents reuse
291
+ - Verify signature caching is working
292
+ - Check lazy loading (should see delayed first signature)
293
+ - Use memory storage when possible
94
294
 
95
295
  ## License
96
296
 
97
- MIT
297
+ MIT
package/dist/auto.d.ts CHANGED
@@ -1,13 +1 @@
1
- /**
2
- * Auto-initialization for MCP Identity
3
- *
4
- * Just import this file to automatically enable MCP-I for any MCP server:
5
- *
6
- * ```typescript
7
- * import "@kya-os/mcp-i/auto";
8
- * ```
9
- *
10
- * That's it! Your MCP server now has identity.
11
- */
12
1
  export {};
13
- //# sourceMappingURL=auto.d.ts.map
package/dist/auto.js CHANGED
@@ -1,24 +1,13 @@
1
1
  "use strict";
2
- /**
3
- * Auto-initialization for MCP Identity
4
- *
5
- * Just import this file to automatically enable MCP-I for any MCP server:
6
- *
7
- * ```typescript
8
- * import "@kya-os/mcp-i/auto";
9
- * ```
10
- *
11
- * That's it! Your MCP server now has identity.
12
- */
13
2
  Object.defineProperty(exports, "__esModule", { value: true });
14
3
  const index_1 = require("./index");
15
- // Auto-initialize on import
4
+ const logger_1 = require("./logger");
16
5
  (async () => {
17
6
  try {
18
7
  await (0, index_1.enableMCPIdentity)();
19
8
  }
20
9
  catch (error) {
21
- console.error('[MCP-I] Failed to auto-initialize:', error);
10
+ const logger = (0, logger_1.getLogger)();
11
+ logger.error('[MCP-I] Failed to auto-initialize:', error);
22
12
  }
23
13
  })();
24
- //# sourceMappingURL=auto.js.map
package/dist/crypto.d.ts CHANGED
@@ -1,32 +1,16 @@
1
- /**
2
- * Cryptographic utilities for MCP-I
3
- * Implements Ed25519 signing and verification for challenge-response authentication
4
- */
5
- /**
6
- * Generate a new Ed25519 key pair
7
- */
8
- export declare function generateKeyPair(): Promise<{
1
+ export interface PrecomputedKeyPair {
9
2
  publicKey: string;
10
3
  privateKey: string;
11
- }>;
12
- /**
13
- * Sign a message with Ed25519
14
- */
4
+ publicKeyBytes?: Uint8Array;
5
+ privateKeyBytes?: Uint8Array;
6
+ }
7
+ export declare function generateKeyPair(): Promise<PrecomputedKeyPair>;
15
8
  export declare function sign(message: string | Buffer, privateKeyBase64: string): Promise<string>;
16
- /**
17
- * Verify an Ed25519 signature
18
- */
19
9
  export declare function verify(message: string | Buffer, signatureBase64: string, publicKeyBase64: string): Promise<boolean>;
20
- /**
21
- * Generate a cryptographically secure nonce
22
- */
23
- export declare function generateNonce(length?: number): string;
24
- /**
25
- * Constant-time string comparison to prevent timing attacks
26
- */
10
+ export declare function generateNonce(length?: number): Promise<string>;
11
+ export declare function generateNonceSync(length?: number): string;
27
12
  export declare function constantTimeEqual(a: string, b: string): boolean;
28
- /**
29
- * Convert Ed25519 public key to did:key format
30
- */
31
13
  export declare function publicKeyToDid(publicKeyBase64: string): string;
32
- //# sourceMappingURL=crypto.d.ts.map
14
+ export declare function encrypt(data: string, password: string): Promise<string>;
15
+ export declare function decrypt(encryptedData: string, password: string): Promise<string>;
16
+ export declare function clearCache(): void;
package/dist/crypto.js CHANGED
@@ -1,8 +1,4 @@
1
1
  "use strict";
2
- /**
3
- * Cryptographic utilities for MCP-I
4
- * Implements Ed25519 signing and verification for challenge-response authentication
5
- */
6
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
3
  if (k2 === undefined) k2 = k;
8
4
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -41,57 +37,93 @@ exports.generateKeyPair = generateKeyPair;
41
37
  exports.sign = sign;
42
38
  exports.verify = verify;
43
39
  exports.generateNonce = generateNonce;
40
+ exports.generateNonceSync = generateNonceSync;
44
41
  exports.constantTimeEqual = constantTimeEqual;
45
42
  exports.publicKeyToDid = publicKeyToDid;
46
- const ed25519 = __importStar(require("@noble/ed25519"));
47
- const crypto_1 = require("crypto");
48
- /**
49
- * Generate a new Ed25519 key pair
50
- */
43
+ exports.encrypt = encrypt;
44
+ exports.decrypt = decrypt;
45
+ exports.clearCache = clearCache;
46
+ let ed25519 = null;
47
+ let cryptoModule = null;
48
+ const signatureCache = new Map();
49
+ const MAX_CACHE_SIZE = 100;
50
+ async function loadEd25519() {
51
+ if (!ed25519) {
52
+ ed25519 = await Promise.resolve().then(() => __importStar(require('@noble/ed25519')));
53
+ }
54
+ return ed25519;
55
+ }
56
+ async function loadCrypto() {
57
+ if (!cryptoModule) {
58
+ cryptoModule = await Promise.resolve().then(() => __importStar(require('crypto')));
59
+ }
60
+ return cryptoModule;
61
+ }
51
62
  async function generateKeyPair() {
52
- const privateKey = ed25519.utils.randomPrivateKey();
53
- const publicKey = await ed25519.getPublicKeyAsync(privateKey);
63
+ const ed = await loadEd25519();
64
+ const privateKeyBytes = ed.utils.randomPrivateKey();
65
+ const publicKeyBytes = await ed.getPublicKeyAsync(privateKeyBytes);
66
+ const publicKey = Buffer.from(publicKeyBytes).toString('base64');
67
+ const privateKey = Buffer.from(privateKeyBytes).toString('base64');
54
68
  return {
55
- publicKey: Buffer.from(publicKey).toString('base64'),
56
- privateKey: Buffer.from(privateKey).toString('base64')
69
+ publicKey,
70
+ privateKey,
71
+ publicKeyBytes,
72
+ privateKeyBytes
57
73
  };
58
74
  }
59
- /**
60
- * Sign a message with Ed25519
61
- */
62
75
  async function sign(message, privateKeyBase64) {
76
+ const messageStr = typeof message === 'string' ? message : message.toString('base64');
77
+ const cacheKey = `${privateKeyBase64}:${messageStr}`;
78
+ const cached = signatureCache.get(cacheKey);
79
+ if (cached) {
80
+ return cached;
81
+ }
82
+ const ed = await loadEd25519();
63
83
  const messageBuffer = typeof message === 'string'
64
84
  ? Buffer.from(message, 'utf-8')
65
85
  : message;
66
86
  const privateKey = Buffer.from(privateKeyBase64, 'base64');
67
- const signature = await ed25519.signAsync(messageBuffer, privateKey);
68
- return Buffer.from(signature).toString('base64');
87
+ const signature = await ed.signAsync(messageBuffer, privateKey);
88
+ const signatureBase64 = Buffer.from(signature).toString('base64');
89
+ if (signatureCache.size >= MAX_CACHE_SIZE) {
90
+ const firstKey = signatureCache.keys().next().value;
91
+ if (firstKey) {
92
+ signatureCache.delete(firstKey);
93
+ }
94
+ }
95
+ signatureCache.set(cacheKey, signatureBase64);
96
+ return signatureBase64;
69
97
  }
70
- /**
71
- * Verify an Ed25519 signature
72
- */
73
98
  async function verify(message, signatureBase64, publicKeyBase64) {
74
99
  try {
100
+ const ed = await loadEd25519();
75
101
  const messageBuffer = typeof message === 'string'
76
102
  ? Buffer.from(message, 'utf-8')
77
103
  : message;
78
104
  const signature = Buffer.from(signatureBase64, 'base64');
79
105
  const publicKey = Buffer.from(publicKeyBase64, 'base64');
80
- return await ed25519.verifyAsync(signature, messageBuffer, publicKey);
106
+ return await ed.verifyAsync(signature, messageBuffer, publicKey);
81
107
  }
82
108
  catch {
83
109
  return false;
84
110
  }
85
111
  }
86
- /**
87
- * Generate a cryptographically secure nonce
88
- */
89
- function generateNonce(length = 32) {
90
- return (0, crypto_1.randomBytes)(length).toString('hex');
112
+ async function generateNonce(length = 32) {
113
+ const crypto = await loadCrypto();
114
+ return crypto.randomBytes(length).toString('hex');
115
+ }
116
+ function generateNonceSync(length = 32) {
117
+ if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.getRandomValues) {
118
+ const bytes = new Uint8Array(length);
119
+ globalThis.crypto.getRandomValues(bytes);
120
+ return Buffer.from(bytes).toString('hex');
121
+ }
122
+ else {
123
+ const crypto = require('crypto');
124
+ return crypto.randomBytes(length).toString('hex');
125
+ }
91
126
  }
92
- /**
93
- * Constant-time string comparison to prevent timing attacks
94
- */
95
127
  function constantTimeEqual(a, b) {
96
128
  if (a.length !== b.length) {
97
129
  return false;
@@ -102,16 +134,64 @@ function constantTimeEqual(a, b) {
102
134
  }
103
135
  return result === 0;
104
136
  }
105
- /**
106
- * Convert Ed25519 public key to did:key format
107
- */
108
137
  function publicKeyToDid(publicKeyBase64) {
109
138
  const publicKey = Buffer.from(publicKeyBase64, 'base64');
110
- // Multicodec ed25519-pub header (0xed 0x01)
111
139
  const multicodec = Buffer.from([0xed, 0x01]);
112
140
  const multikey = Buffer.concat([multicodec, publicKey]);
113
- // Base58 encode (simplified - in production use a proper base58 library)
114
- // For now, just return a placeholder
115
141
  return `did:key:z${multikey.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '')}`;
116
142
  }
117
- //# sourceMappingURL=crypto.js.map
143
+ async function encrypt(data, password) {
144
+ const encoder = new TextEncoder();
145
+ const salt = new Uint8Array(16);
146
+ globalThis.crypto.getRandomValues(salt);
147
+ const keyMaterial = await globalThis.crypto.subtle.importKey('raw', encoder.encode(password), 'PBKDF2', false, ['deriveKey']);
148
+ const key = await globalThis.crypto.subtle.deriveKey({
149
+ name: 'PBKDF2',
150
+ salt,
151
+ iterations: 100000,
152
+ hash: 'SHA-256'
153
+ }, keyMaterial, { name: 'AES-GCM', length: 256 }, false, ['encrypt']);
154
+ const iv = new Uint8Array(12);
155
+ globalThis.crypto.getRandomValues(iv);
156
+ const encrypted = await globalThis.crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, encoder.encode(data));
157
+ const combined = new Uint8Array(salt.length + iv.length + encrypted.byteLength);
158
+ combined.set(salt);
159
+ combined.set(iv, salt.length);
160
+ combined.set(new Uint8Array(encrypted), salt.length + iv.length);
161
+ return 'enc:' + Buffer.from(combined).toString('base64');
162
+ }
163
+ async function decrypt(encryptedData, password) {
164
+ let dataToDecrypt = encryptedData;
165
+ if (encryptedData.startsWith('enc:')) {
166
+ dataToDecrypt = encryptedData.slice(4);
167
+ }
168
+ if (!dataToDecrypt || dataToDecrypt.length < 44) {
169
+ return encryptedData;
170
+ }
171
+ const encoder = new TextEncoder();
172
+ const decoder = new TextDecoder();
173
+ try {
174
+ const combined = Buffer.from(dataToDecrypt, 'base64');
175
+ if (combined.length < 29) {
176
+ return encryptedData;
177
+ }
178
+ const salt = combined.slice(0, 16);
179
+ const iv = combined.slice(16, 28);
180
+ const encrypted = combined.slice(28);
181
+ const keyMaterial = await globalThis.crypto.subtle.importKey('raw', encoder.encode(password), 'PBKDF2', false, ['deriveKey']);
182
+ const key = await globalThis.crypto.subtle.deriveKey({
183
+ name: 'PBKDF2',
184
+ salt: new Uint8Array(salt),
185
+ iterations: 100000,
186
+ hash: 'SHA-256'
187
+ }, keyMaterial, { name: 'AES-GCM', length: 256 }, false, ['decrypt']);
188
+ const decrypted = await globalThis.crypto.subtle.decrypt({ name: 'AES-GCM', iv: new Uint8Array(iv) }, key, new Uint8Array(encrypted));
189
+ return decoder.decode(decrypted);
190
+ }
191
+ catch (error) {
192
+ throw new Error('Failed to decrypt data: invalid password or corrupted data');
193
+ }
194
+ }
195
+ function clearCache() {
196
+ signatureCache.clear();
197
+ }
@@ -0,0 +1,3 @@
1
+ import { MCPIdentity } from './index';
2
+ export declare function initWithDevExperience(options?: any): Promise<MCPIdentity>;
3
+ export declare function showAgentStatus(identity: MCPIdentity): void;